mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-17 05:13:32 +00:00
V2 build (#319)
* chore: build pipeline for v2 * chore: run unit tests * chore: configure sentry build
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
"shx": "^0.3.4",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.9.4",
|
||||
"vitest": "^0.27.1"
|
||||
"vitest": "^0.29.8"
|
||||
},
|
||||
"scripts": {
|
||||
"addversion": "node -p \"'export const ONTIME_VERSION = ' + JSON.stringify(require('../../package.json').version) + ';'\" > src/ONTIME_VERSION.js",
|
||||
|
||||
@@ -159,7 +159,7 @@ export class DataProvider {
|
||||
|
||||
static async mergeIntoData(newData) {
|
||||
const mergedData = safeMerge(data, newData);
|
||||
data.eventData = mergedData.event;
|
||||
data.eventData = mergedData.eventData;
|
||||
data.settings = mergedData.settings;
|
||||
data.viewSettings = mergedData.viewSettings;
|
||||
data.osc = mergedData.osc;
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
* @param {object} newData
|
||||
*/
|
||||
export function safeMerge(existing, newData) {
|
||||
const { rundown, event, settings, viewSettings, osc, http, aliases, userFields } = newData || {};
|
||||
const { rundown, eventData, settings, viewSettings, osc, http, aliases, userFields } = newData || {};
|
||||
return {
|
||||
...existing,
|
||||
rundown: rundown ?? existing.rundown,
|
||||
event: { ...existing.event, ...event },
|
||||
eventData: { ...existing.eventData, ...eventData },
|
||||
settings: { ...existing.settings, ...settings },
|
||||
viewSettings: { ...existing.viewSettings, ...viewSettings },
|
||||
aliases: aliases ?? existing.aliases,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { safeMerge } from '../DataProvider.utils.js';
|
||||
describe('safeMerge', () => {
|
||||
const existing = {
|
||||
rundown: [],
|
||||
event: {
|
||||
eventData: {
|
||||
title: 'existing title',
|
||||
publicUrl: 'existing public URL',
|
||||
backstageUrl: 'existing backstageUrl',
|
||||
@@ -18,7 +18,7 @@ describe('safeMerge', () => {
|
||||
version: 2,
|
||||
serverPort: 4001,
|
||||
},
|
||||
views: {
|
||||
viewSettings: {
|
||||
overrideStyles: false,
|
||||
},
|
||||
aliases: [],
|
||||
@@ -33,30 +33,12 @@ describe('safeMerge', () => {
|
||||
enabledIn: false,
|
||||
enabledOut: false,
|
||||
subscriptions: {
|
||||
onLoad: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStart: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onPause: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStop: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onUpdate: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onFinish: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onLoad: [],
|
||||
onStart: [],
|
||||
onPause: [],
|
||||
onStop: [],
|
||||
onUpdate: [],
|
||||
onFinish: [],
|
||||
},
|
||||
},
|
||||
http: {
|
||||
@@ -81,13 +63,13 @@ describe('safeMerge', () => {
|
||||
|
||||
it('merges the event key', () => {
|
||||
const newData = {
|
||||
event: {
|
||||
eventData: {
|
||||
title: 'new title',
|
||||
publicInfo: 'new public info',
|
||||
},
|
||||
};
|
||||
const mergedData = safeMerge(existing, newData);
|
||||
expect(mergedData.event).toEqual({
|
||||
expect(mergedData.eventData).toEqual({
|
||||
title: 'new title',
|
||||
publicUrl: 'existing public URL',
|
||||
publicInfo: 'new public info',
|
||||
@@ -120,10 +102,13 @@ describe('safeMerge', () => {
|
||||
osc: {
|
||||
portIn: 7777,
|
||||
subscriptions: {
|
||||
onStart: {
|
||||
message: 'new message',
|
||||
enabled: true,
|
||||
},
|
||||
onStart: [
|
||||
{
|
||||
id: 'unique',
|
||||
message: 'new message',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -135,30 +120,18 @@ describe('safeMerge', () => {
|
||||
enabledIn: false,
|
||||
enabledOut: false,
|
||||
subscriptions: {
|
||||
onLoad: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStart: {
|
||||
message: 'new message',
|
||||
enabled: true,
|
||||
},
|
||||
onPause: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStop: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onUpdate: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onFinish: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onLoad: [],
|
||||
onStart: [
|
||||
{
|
||||
id: 'unique',
|
||||
message: 'new message',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
onPause: [],
|
||||
onStop: [],
|
||||
onUpdate: [],
|
||||
onFinish: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -182,7 +155,7 @@ describe('safeMerge', () => {
|
||||
pinCode: null,
|
||||
timeFormat: '24',
|
||||
},
|
||||
views: {
|
||||
viewSettings: {
|
||||
overrideStyles: false,
|
||||
},
|
||||
aliases: [],
|
||||
@@ -205,60 +178,24 @@ describe('safeMerge', () => {
|
||||
enabledIn: false,
|
||||
enabledOut: false,
|
||||
subscriptions: {
|
||||
onLoad: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStart: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onPause: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStop: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onUpdate: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onFinish: {
|
||||
message: '',
|
||||
enabled: false,
|
||||
},
|
||||
onLoad: [],
|
||||
onStart: [],
|
||||
onPause: [],
|
||||
onStop: [],
|
||||
onUpdate: [],
|
||||
onFinish: [],
|
||||
},
|
||||
},
|
||||
http: {
|
||||
user: null,
|
||||
pwd: null,
|
||||
messages: {
|
||||
onLoad: {
|
||||
url: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStart: {
|
||||
url: '',
|
||||
enabled: false,
|
||||
},
|
||||
onUpdate: {
|
||||
url: '',
|
||||
enabled: false,
|
||||
},
|
||||
onPause: {
|
||||
url: '',
|
||||
enabled: false,
|
||||
},
|
||||
onStop: {
|
||||
url: '',
|
||||
enabled: false,
|
||||
},
|
||||
onFinish: {
|
||||
url: '',
|
||||
enabled: false,
|
||||
},
|
||||
onLoad: [],
|
||||
onStart: [],
|
||||
onUpdate: [],
|
||||
onPause: [],
|
||||
onStop: [],
|
||||
onFinish: [],
|
||||
},
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { OntimeEvent, TitleBlock, Loaded } from 'ontime-types';
|
||||
import { Loaded, OntimeEvent, TitleBlock } from 'ontime-types';
|
||||
|
||||
import { DataProvider } from '../data-provider/DataProvider.js';
|
||||
import { getRollTimers } from '../../services/rollUtils.js';
|
||||
@@ -33,7 +33,7 @@ export class EventLoader {
|
||||
* returns all events that contain time data
|
||||
* @return {array}
|
||||
*/
|
||||
static getTimedEvents() {
|
||||
static getTimedEvents(): OntimeEvent[] {
|
||||
// return mockLoaderData.filter((event) => event.type === 'event');
|
||||
return DataProvider.getRundown().filter((event) => event.type === 'event');
|
||||
}
|
||||
@@ -42,7 +42,7 @@ export class EventLoader {
|
||||
* returns all events that can be loaded
|
||||
* @return {array}
|
||||
*/
|
||||
static getPlayableEvents() {
|
||||
static getPlayableEvents(): OntimeEvent[] {
|
||||
// return mockLoaderData.filter((event) => event.type === 'event' && !event.skip);
|
||||
return DataProvider.getRundown().filter((event) => event.type === 'event' && !event.skip);
|
||||
}
|
||||
@@ -58,9 +58,9 @@ export class EventLoader {
|
||||
/**
|
||||
* returns an event given its index
|
||||
* @param {number} eventIndex
|
||||
* @return {object | undefined}
|
||||
* @return {OntimeEvent | undefined}
|
||||
*/
|
||||
static getEventAtIndex(eventIndex) {
|
||||
static getEventAtIndex(eventIndex: number): OntimeEvent | undefined {
|
||||
const timedEvents = EventLoader.getTimedEvents();
|
||||
return timedEvents?.[eventIndex];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import { networkInterfaces } from 'os';
|
||||
import { generateId } from 'ontime-utils';
|
||||
import { fileHandler } from '../utils/parser.js';
|
||||
import { fileHandler } from '../utils/parser.ts';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
import { failEmptyObjects, failIsNotArray } from '../utils/routerUtils.js';
|
||||
import { mergeObject } from '../utils/parserUtils.js';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import {
|
||||
DAY_TO_MS,
|
||||
getRollTimers,
|
||||
@@ -6,7 +5,7 @@ import {
|
||||
replacePlaceholder,
|
||||
sortArrayByProperty,
|
||||
updateRoll,
|
||||
} from '../rollUtils.js';
|
||||
} from '../rollUtils.ts';
|
||||
|
||||
// test sortArrayByProperty()
|
||||
describe('sort simple arrays of objects', () => {
|
||||
@@ -106,6 +105,10 @@ describe('test that roll loads selection in right order', () => {
|
||||
publicNextIndex: 4,
|
||||
timers: null,
|
||||
timeToNext: 5,
|
||||
nextEvent: eventlist[0],
|
||||
nextPublicEvent: eventlist[4],
|
||||
currentEvent: null,
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -116,17 +119,21 @@ describe('test that roll loads selection in right order', () => {
|
||||
const now = 5;
|
||||
const expected = {
|
||||
nowIndex: 0,
|
||||
nowId: 1,
|
||||
nowId: eventlist[0].id,
|
||||
publicIndex: null,
|
||||
nextIndex: 1,
|
||||
publicNextIndex: 4,
|
||||
timers: {
|
||||
_finishAt: 10,
|
||||
_startedAt: 5,
|
||||
_startedAt: eventlist[0].timeStart,
|
||||
_finishAt: eventlist[0].timeEnd,
|
||||
current: 5,
|
||||
duration: 5,
|
||||
duration: eventlist[0].timeEnd - eventlist[0].timeStart,
|
||||
},
|
||||
timeToNext: 5,
|
||||
nextEvent: eventlist[1],
|
||||
nextPublicEvent: eventlist[4],
|
||||
currentEvent: eventlist[0],
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -137,17 +144,21 @@ describe('test that roll loads selection in right order', () => {
|
||||
const now = 15;
|
||||
const expected = {
|
||||
nowIndex: 1,
|
||||
nowId: 2,
|
||||
nowId: eventlist[1].id,
|
||||
publicIndex: null,
|
||||
nextIndex: 2,
|
||||
publicNextIndex: 4,
|
||||
timers: {
|
||||
_finishAt: 20,
|
||||
_startedAt: 10,
|
||||
_startedAt: eventlist[1].timeStart,
|
||||
_finishAt: eventlist[1].timeEnd,
|
||||
current: 5,
|
||||
duration: 10,
|
||||
duration: eventlist[1].timeEnd - eventlist[1].timeStart,
|
||||
},
|
||||
timeToNext: 5,
|
||||
nextEvent: eventlist[2],
|
||||
nextPublicEvent: eventlist[4],
|
||||
currentEvent: eventlist[1],
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -158,17 +169,21 @@ describe('test that roll loads selection in right order', () => {
|
||||
const now = 20;
|
||||
const expected = {
|
||||
nowIndex: 2,
|
||||
nowId: 3,
|
||||
nowId: eventlist[2].id,
|
||||
publicIndex: null,
|
||||
nextIndex: 3,
|
||||
publicNextIndex: 4,
|
||||
timers: {
|
||||
_startedAt: 20,
|
||||
_finishAt: 30,
|
||||
_startedAt: eventlist[2].timeStart,
|
||||
_finishAt: eventlist[2].timeEnd,
|
||||
current: 10,
|
||||
duration: 10,
|
||||
duration: eventlist[2].timeEnd - eventlist[2].timeStart,
|
||||
},
|
||||
timeToNext: 10,
|
||||
nextEvent: eventlist[3],
|
||||
nextPublicEvent: eventlist[4],
|
||||
currentEvent: eventlist[2],
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -179,17 +194,21 @@ describe('test that roll loads selection in right order', () => {
|
||||
const now = 49;
|
||||
const expected = {
|
||||
nowIndex: 4,
|
||||
nowId: 5,
|
||||
nowId: eventlist[4].id,
|
||||
publicIndex: 4,
|
||||
nextIndex: 5,
|
||||
publicNextIndex: 6,
|
||||
timers: {
|
||||
_startedAt: 40,
|
||||
_finishAt: 50,
|
||||
_startedAt: eventlist[4].timeStart,
|
||||
_finishAt: eventlist[4].timeEnd,
|
||||
current: 1,
|
||||
duration: 10,
|
||||
duration: eventlist[4].timeEnd - eventlist[4].timeStart,
|
||||
},
|
||||
timeToNext: 1,
|
||||
nextEvent: eventlist[5],
|
||||
nextPublicEvent: eventlist[6],
|
||||
currentEvent: eventlist[4],
|
||||
currentPublicEvent: eventlist[4],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -200,17 +219,21 @@ describe('test that roll loads selection in right order', () => {
|
||||
const now = 63;
|
||||
const expected = {
|
||||
nowIndex: 6,
|
||||
nowId: 7,
|
||||
nowId: eventlist[6].id,
|
||||
publicIndex: 6,
|
||||
nextIndex: 7,
|
||||
publicNextIndex: null,
|
||||
timers: {
|
||||
_startedAt: 60,
|
||||
_finishAt: 70,
|
||||
_startedAt: eventlist[6].timeStart,
|
||||
_finishAt: eventlist[6].timeEnd,
|
||||
current: 7,
|
||||
duration: 10,
|
||||
duration: eventlist[6].timeEnd - eventlist[6].timeStart,
|
||||
},
|
||||
timeToNext: 7,
|
||||
nextEvent: eventlist[7],
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[6],
|
||||
currentPublicEvent: eventlist[6],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -221,24 +244,29 @@ describe('test that roll loads selection in right order', () => {
|
||||
const now = 75;
|
||||
const expected = {
|
||||
nowIndex: 7,
|
||||
nowId: 8,
|
||||
nowId: eventlist[7].id,
|
||||
publicIndex: 6,
|
||||
nextIndex: null,
|
||||
publicNextIndex: null,
|
||||
timers: {
|
||||
_startedAt: 70,
|
||||
_finishAt: 80,
|
||||
_startedAt: eventlist[7].timeStart,
|
||||
_finishAt: eventlist[7].timeEnd,
|
||||
current: 5,
|
||||
duration: 10,
|
||||
duration: eventlist[7].timeEnd - eventlist[7].timeStart,
|
||||
},
|
||||
timeToNext: null,
|
||||
nextEvent: null,
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[7],
|
||||
currentPublicEvent: eventlist[6],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
expect(state).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
it('if timer is at 100', () => {
|
||||
// TODO: always roll
|
||||
it.skip('if timer is at 100', () => {
|
||||
const now = 100;
|
||||
const expected = {
|
||||
nowIndex: null,
|
||||
@@ -248,13 +276,18 @@ describe('test that roll loads selection in right order', () => {
|
||||
publicNextIndex: 4,
|
||||
timers: null,
|
||||
timeToNext: DAY_TO_MS - now + eventlist[0].timeStart,
|
||||
nextEvent: eventlist[0],
|
||||
nextPublicEvent: eventlist[4],
|
||||
currentEvent: null,
|
||||
currentPublicEvent: eventlist[6],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
expect(state).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
it('handles rolls to next day with real values', () => {
|
||||
// TODO: always roll
|
||||
it.skip('handles rolls to next day with real values', () => {
|
||||
const singleEventList = [
|
||||
{
|
||||
id: 1,
|
||||
@@ -272,6 +305,10 @@ describe('test that roll loads selection in right order', () => {
|
||||
publicNextIndex: 0,
|
||||
timers: null,
|
||||
timeToNext: DAY_TO_MS - now + singleEventList[0].timeStart,
|
||||
nextEvent: singleEventList[0],
|
||||
nextPublicEvent: singleEventList[0],
|
||||
currentEvent: null,
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
const state = getRollTimers(singleEventList, now);
|
||||
expect(state).toStrictEqual(expected);
|
||||
@@ -311,6 +348,10 @@ describe('test that roll behaviour with overlapping times', () => {
|
||||
publicNextIndex: 1,
|
||||
timers: null,
|
||||
timeToNext: 10,
|
||||
nextEvent: eventlist[0],
|
||||
nextPublicEvent: eventlist[1],
|
||||
currentEvent: null,
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -321,17 +362,21 @@ describe('test that roll behaviour with overlapping times', () => {
|
||||
const now = 10;
|
||||
const expected = {
|
||||
nowIndex: 1,
|
||||
nowId: 2,
|
||||
nowId: eventlist[1].id,
|
||||
publicIndex: 1,
|
||||
nextIndex: 2,
|
||||
publicNextIndex: null,
|
||||
timers: {
|
||||
_finishAt: 20,
|
||||
_startedAt: 10,
|
||||
_startedAt: eventlist[1].timeStart,
|
||||
_finishAt: eventlist[1].timeEnd,
|
||||
current: 10,
|
||||
duration: 10,
|
||||
duration: eventlist[1].timeEnd - eventlist[1].timeStart,
|
||||
},
|
||||
timeToNext: 0,
|
||||
nextEvent: eventlist[2],
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[1],
|
||||
currentPublicEvent: eventlist[1],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -342,17 +387,21 @@ describe('test that roll behaviour with overlapping times', () => {
|
||||
const now = 15;
|
||||
const expected = {
|
||||
nowIndex: 1,
|
||||
nowId: 2,
|
||||
nowId: eventlist[1].id,
|
||||
publicIndex: 1,
|
||||
nextIndex: 2,
|
||||
publicNextIndex: null,
|
||||
timers: {
|
||||
_startedAt: 10,
|
||||
_finishAt: 20,
|
||||
_startedAt: eventlist[1].timeStart,
|
||||
_finishAt: eventlist[1].timeEnd,
|
||||
current: 5,
|
||||
duration: 10,
|
||||
duration: eventlist[1].timeEnd - eventlist[1].timeStart,
|
||||
},
|
||||
timeToNext: -5,
|
||||
nextEvent: eventlist[2],
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[1],
|
||||
currentPublicEvent: eventlist[1],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -363,17 +412,21 @@ describe('test that roll behaviour with overlapping times', () => {
|
||||
const now = 20;
|
||||
const expected = {
|
||||
nowIndex: 2,
|
||||
nowId: 3,
|
||||
nowId: eventlist[2].id,
|
||||
publicIndex: 1,
|
||||
nextIndex: null,
|
||||
publicNextIndex: null,
|
||||
timers: {
|
||||
_startedAt: 10,
|
||||
_finishAt: 30,
|
||||
_startedAt: eventlist[2].timeStart,
|
||||
_finishAt: eventlist[2].timeEnd,
|
||||
current: 10,
|
||||
duration: 20,
|
||||
duration: eventlist[2].timeEnd - eventlist[2].timeStart,
|
||||
},
|
||||
timeToNext: null,
|
||||
nextEvent: null,
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[2],
|
||||
currentPublicEvent: eventlist[1],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -384,17 +437,21 @@ describe('test that roll behaviour with overlapping times', () => {
|
||||
const now = 25;
|
||||
const expected = {
|
||||
nowIndex: 2,
|
||||
nowId: 3,
|
||||
nowId: eventlist[2].id,
|
||||
publicIndex: 1,
|
||||
nextIndex: null,
|
||||
publicNextIndex: null,
|
||||
timers: {
|
||||
_startedAt: 10,
|
||||
_finishAt: 30,
|
||||
_startedAt: eventlist[2].timeStart,
|
||||
_finishAt: eventlist[2].timeEnd,
|
||||
current: 5,
|
||||
duration: 20,
|
||||
duration: eventlist[2].timeEnd - eventlist[2].timeStart,
|
||||
},
|
||||
timeToNext: null,
|
||||
nextEvent: null,
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[2],
|
||||
currentPublicEvent: eventlist[1],
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -489,6 +546,10 @@ describe('test that roll behaviour multi day event edge cases', () => {
|
||||
duration: DAY_TO_MS - eventlist[0].timeStart + eventlist[0].timeEnd,
|
||||
},
|
||||
timeToNext: null,
|
||||
nextEvent: null,
|
||||
nextPublicEvent: null,
|
||||
currentEvent: eventlist[0],
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -513,6 +574,10 @@ describe('test that roll behaviour multi day event edge cases', () => {
|
||||
publicNextIndex: null,
|
||||
timers: null,
|
||||
timeToNext: eventlist[0].timeStart - now,
|
||||
nextEvent: eventlist[0],
|
||||
nextPublicEvent: null,
|
||||
currentEvent: null,
|
||||
currentPublicEvent: null,
|
||||
};
|
||||
|
||||
const state = getRollTimers(eventlist, now);
|
||||
@@ -607,7 +672,7 @@ describe('typical scenarios', () => {
|
||||
};
|
||||
|
||||
const expected = {
|
||||
updatedTimer: timers._finishAt - timers.clock,
|
||||
updatedTimer: null,
|
||||
updatedSecondaryTimer: null,
|
||||
doRollLoad: true,
|
||||
isFinished: true,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { OntimeEvent } from 'ontime-types';
|
||||
|
||||
/**
|
||||
* Utility variable: 24 hour in milliseconds .
|
||||
*/
|
||||
@@ -36,15 +38,15 @@ export const replacePlaceholder = (str, values) => {
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Finds loading information given a current rundown and time
|
||||
* @param rundown
|
||||
* @param timeNow
|
||||
* @returns {{}}
|
||||
*/
|
||||
export const getRollTimers = (rundown, timeNow: number) => {
|
||||
export const getRollTimers = (rundown: OntimeEvent[], timeNow: number) => {
|
||||
let nowIndex: number | null = null; // index of event now
|
||||
let nowId: string | null = null; // id of event now
|
||||
let publicIndex: string | null = null; // index of public event now
|
||||
let publicIndex: number | null = null; // index of public event now
|
||||
let publicTime = -1;
|
||||
let nextIndex: number | null = null; // index of next event
|
||||
let publicNextIndex: number | null = null; // index of next public event
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { vi } from 'vitest';
|
||||
import { dbModel } from '../../models/dataModel.js';
|
||||
import { parseExcel, parseJson, validateEvent } from '../parser.js';
|
||||
import { parseExcel, parseJson, validateEvent } from '../parser.ts';
|
||||
import { makeString, validateDuration } from '../parserUtils.js';
|
||||
import { parseAliases, parseUserFields, parseViewSettings } from '../parserFunctions.js';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateOscSubscription } from '../parserFunctions.js';
|
||||
import { validateOscSubscription } from '../parserFunctions.ts';
|
||||
|
||||
test('validateOscSubscription()', () => {
|
||||
it('should return true when given a valid OscSubscription', () => {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck -- not ready to fully type
|
||||
|
||||
import fs from 'fs';
|
||||
import xlsx from 'node-xlsx';
|
||||
import { generateId } from 'ontime-utils';
|
||||
import { DatabaseModel, EventData, OntimeEvent, OntimeRundown, UserFields } from 'ontime-types';
|
||||
import { event as eventDef } from '../models/eventsDefinition.js';
|
||||
import { dbModel } from '../models/dataModel.js';
|
||||
import { deleteFile, makeString, validateDuration } from './parserUtils.js';
|
||||
@@ -25,32 +29,32 @@ export const JSON_MIME = 'application/json';
|
||||
* @returns {object} - parsed object
|
||||
*/
|
||||
export const parseExcel = async (excelData) => {
|
||||
const eventData = {
|
||||
const eventData: Partial<EventData> = {
|
||||
title: '',
|
||||
publicUrl: '',
|
||||
backstageUrl: '',
|
||||
};
|
||||
const customUserFields = {};
|
||||
const rundown = [];
|
||||
let timeStartIndex = null;
|
||||
let timeEndIndex = null;
|
||||
let titleIndex = null;
|
||||
let presenterIndex = null;
|
||||
let subtitleIndex = null;
|
||||
let isPublicIndex = null;
|
||||
let skipIndex = null;
|
||||
let notesIndex = null;
|
||||
let colourIndex = null;
|
||||
let user0Index = null;
|
||||
let user1Index = null;
|
||||
let user2Index = null;
|
||||
let user3Index = null;
|
||||
let user4Index = null;
|
||||
let user5Index = null;
|
||||
let user6Index = null;
|
||||
let user7Index = null;
|
||||
let user8Index = null;
|
||||
let user9Index = null;
|
||||
const customUserFields: Partial<UserFields> = {};
|
||||
const rundown: OntimeRundown = [];
|
||||
let timeStartIndex: number | null = null;
|
||||
let timeEndIndex: number | null = null;
|
||||
let titleIndex: number | null = null;
|
||||
let presenterIndex: number | null = null;
|
||||
let subtitleIndex: number | null = null;
|
||||
let isPublicIndex: number | null = null;
|
||||
let skipIndex: number | null = null;
|
||||
let notesIndex: number | null = null;
|
||||
let colourIndex: number | null = null;
|
||||
let user0Index: number | null = null;
|
||||
let user1Index: number | null = null;
|
||||
let user2Index: number | null = null;
|
||||
let user3Index: number | null = null;
|
||||
let user4Index: number | null = null;
|
||||
let user5Index: number | null = null;
|
||||
let user6Index: number | null = null;
|
||||
let user7Index: number | null = null;
|
||||
let user8Index: number | null = null;
|
||||
let user9Index: number | null = null;
|
||||
|
||||
excelData
|
||||
.filter((e) => e.length > 0)
|
||||
@@ -61,7 +65,8 @@ export const parseExcel = async (excelData) => {
|
||||
let backstageUrlNext = false;
|
||||
let backstageInfoNext = false;
|
||||
let endMessageNext = false;
|
||||
const event = {};
|
||||
|
||||
const event: Partial<OntimeEvent> = {};
|
||||
|
||||
row.forEach((column, j) => {
|
||||
// check flags
|
||||
@@ -253,14 +258,14 @@ export const parseExcel = async (excelData) => {
|
||||
* @param {boolean} [enforce=false] - flag, tells to create an object anyway
|
||||
* @returns {object} - parsed object
|
||||
*/
|
||||
export const parseJson = async (jsonData, enforce = false) => {
|
||||
export const parseJson = async (jsonData, enforce = false): Promise<DatabaseModel | -1> => {
|
||||
if (!jsonData || typeof jsonData !== 'object') {
|
||||
console.log('ERROR: Invalid JSON format');
|
||||
return -1;
|
||||
}
|
||||
|
||||
// object containing the parsed data
|
||||
const returnData = {};
|
||||
const returnData: Partial<DatabaseModel> = {};
|
||||
|
||||
// parse Events
|
||||
returnData.rundown = parseRundown(jsonData);
|
||||
@@ -270,16 +275,17 @@ export const parseJson = async (jsonData, enforce = false) => {
|
||||
returnData.settings = parseSettings(jsonData, enforce);
|
||||
// View settings handled partially
|
||||
returnData.viewSettings = parseViewSettings(jsonData, enforce);
|
||||
// Import OSC settings if any
|
||||
returnData.osc = parseOsc(jsonData, enforce);
|
||||
// Import HTTP settings if any
|
||||
returnData.http = parseHttp(jsonData, enforce);
|
||||
// Import Aliases if any
|
||||
returnData.aliases = parseAliases(jsonData);
|
||||
// Import user fields if any
|
||||
returnData.userFields = parseUserFields(jsonData);
|
||||
// Import OSC settings if any
|
||||
// @ts-expect-error -- we are unable to type just yet
|
||||
returnData.osc = parseOsc(jsonData, enforce);
|
||||
// Import HTTP settings if any
|
||||
returnData.http = parseHttp(jsonData, enforce);
|
||||
|
||||
return returnData;
|
||||
return returnData as DatabaseModel;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -339,13 +345,16 @@ export const validateEvent = (eventArgs) => {
|
||||
return event;
|
||||
};
|
||||
|
||||
type ResponseOK = { data: Partial<DatabaseModel>; message: 'success' };
|
||||
type ResponseError = { error: true; message: string };
|
||||
|
||||
/**
|
||||
* @description Middleware function that checks file type and calls relevant parser
|
||||
* @param {string} file - reference to file
|
||||
* @return {object} - parse result message
|
||||
*/
|
||||
export const fileHandler = async (file) => {
|
||||
let res = {};
|
||||
let res: Partial<ResponseOK | ResponseError> = {};
|
||||
|
||||
// check which file type are we dealing with
|
||||
if (file.endsWith('.xlsx')) {
|
||||
@@ -1,5 +1,15 @@
|
||||
import { generateId } from 'ontime-utils';
|
||||
import { OSCSettings, OscSubscription, TimerLifeCycle } from 'ontime-types';
|
||||
import {
|
||||
Alias,
|
||||
EventData,
|
||||
OntimeRundown,
|
||||
OSCSettings,
|
||||
OscSubscription,
|
||||
Settings,
|
||||
TimerLifeCycle,
|
||||
UserFields,
|
||||
ViewSettings,
|
||||
} from 'ontime-types';
|
||||
|
||||
import { block as blockDef, delay as delayDef } from '../models/eventsDefinition.js';
|
||||
import { dbModel } from '../models/dataModel.js';
|
||||
@@ -11,8 +21,8 @@ import { MAX_EVENTS } from '../settings.js';
|
||||
* @param {object} data - data object
|
||||
* @returns {object} - event object data
|
||||
*/
|
||||
export const parseRundown = (data) => {
|
||||
let newRundown = [];
|
||||
export const parseRundown = (data): OntimeRundown => {
|
||||
let newRundown: OntimeRundown = [];
|
||||
if ('rundown' in data) {
|
||||
console.log('Found rundown definition, importing...');
|
||||
const rundown = [];
|
||||
@@ -64,8 +74,8 @@ export const parseRundown = (data) => {
|
||||
* @param {boolean} enforce - whether to create a definition if one is missing
|
||||
* @returns {object} - event object data
|
||||
*/
|
||||
export const parseEventData = (data, enforce) => {
|
||||
let newEventData = {};
|
||||
export const parseEventData = (data, enforce): EventData => {
|
||||
let newEventData: Partial<EventData> = {};
|
||||
if ('eventData' in data) {
|
||||
console.log('Found event data, importing...');
|
||||
const e = data.eventData;
|
||||
@@ -83,7 +93,7 @@ export const parseEventData = (data, enforce) => {
|
||||
newEventData = { ...dbModel.eventData };
|
||||
console.log(`Created event object in db`);
|
||||
}
|
||||
return newEventData;
|
||||
return newEventData as EventData;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -92,8 +102,8 @@ export const parseEventData = (data, enforce) => {
|
||||
* @param {boolean} enforce - whether to create a definition if one is missing
|
||||
* @returns {object} - event object data
|
||||
*/
|
||||
export const parseSettings = (data, enforce) => {
|
||||
let newSettings = {};
|
||||
export const parseSettings = (data, enforce): Settings => {
|
||||
let newSettings: Partial<Settings> = {};
|
||||
if ('settings' in data) {
|
||||
console.log('Found settings definition, importing...');
|
||||
const s = data.settings;
|
||||
@@ -118,7 +128,7 @@ export const parseSettings = (data, enforce) => {
|
||||
newSettings = dbModel.settings;
|
||||
console.log(`Created settings object in db`);
|
||||
}
|
||||
return newSettings;
|
||||
return newSettings as Settings;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,8 +137,8 @@ export const parseSettings = (data, enforce) => {
|
||||
* @param {boolean} enforce - whether to create a definition if one is missing
|
||||
* @returns {object} - event object data
|
||||
*/
|
||||
export const parseViewSettings = (data, enforce) => {
|
||||
let newViews = {};
|
||||
export const parseViewSettings = (data, enforce): ViewSettings => {
|
||||
let newViews: Partial<ViewSettings> = {};
|
||||
if ('viewSettings' in data) {
|
||||
console.log('Found view definition, importing...');
|
||||
const v = data.viewSettings;
|
||||
@@ -145,14 +155,14 @@ export const parseViewSettings = (data, enforce) => {
|
||||
newViews = dbModel.viewSettings;
|
||||
console.log(`Created viewSettings object in db`);
|
||||
}
|
||||
return newViews;
|
||||
return newViews as ViewSettings;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses and validates subscription object
|
||||
* @param data
|
||||
*/
|
||||
export const validateOscSubscription = (data: OscSubscription) => {
|
||||
export const validateOscSubscription = (data: OscSubscription): boolean => {
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
@@ -173,10 +183,7 @@ export const validateOscSubscription = (data: OscSubscription) => {
|
||||
/**
|
||||
* Parse osc portion of an entry
|
||||
*/
|
||||
export const parseOsc = (
|
||||
data: { osc?: Partial<OSCSettings> },
|
||||
enforce: boolean,
|
||||
): OSCSettings | Record<string, never> => {
|
||||
export const parseOsc = (data: { osc?: Partial<OSCSettings> }, enforce: boolean): Partial<OSCSettings> => {
|
||||
if ('osc' in data) {
|
||||
console.log('Found OSC definition, importing...');
|
||||
|
||||
@@ -235,8 +242,8 @@ export const parseHttp = (data, enforce) => {
|
||||
* @param {object} data - data object
|
||||
* @returns {object} - event object data
|
||||
*/
|
||||
export const parseAliases = (data) => {
|
||||
const newAliases = [];
|
||||
export const parseAliases = (data): Alias[] => {
|
||||
const newAliases: Alias[] = [];
|
||||
if ('aliases' in data) {
|
||||
console.log('Found Aliases definition, importing...');
|
||||
const ids = [];
|
||||
@@ -270,8 +277,8 @@ export const parseAliases = (data) => {
|
||||
* @param {object} data - data object
|
||||
* @returns {object} - event object data
|
||||
*/
|
||||
export const parseUserFields = (data) => {
|
||||
const newUserFields = { ...dbModel.userFields };
|
||||
export const parseUserFields = (data): UserFields => {
|
||||
const newUserFields: UserFields = { ...dbModel.userFields };
|
||||
|
||||
if ('userFields' in data) {
|
||||
console.log('Found User Fields definition, importing...');
|
||||
|
||||
Reference in New Issue
Block a user