mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-15 04:13:47 +00:00
fix; osc subscriptions (#392)
* style: fix typo * refactor: convert to typescript * refactor: convert to typescript * refactor: create patch for osc subscriptions * fix: issue with subscription invalidation
This commit is contained in:
@@ -269,6 +269,27 @@ export const getOSC = async (req, res) => {
|
||||
res.status(200).send(osc);
|
||||
};
|
||||
|
||||
export const postOscSubscriptions = async (req, res) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const oscSubscriptions = req.body;
|
||||
const oscSettings = DataProvider.getOsc();
|
||||
oscSettings.subscriptions = oscSubscriptions;
|
||||
await DataProvider.setOsc(oscSettings);
|
||||
|
||||
// TODO: this update could be more granular, checking that relevant data was changed
|
||||
const { message } = oscIntegration.init(oscSettings);
|
||||
logger.info('RX', message);
|
||||
|
||||
res.send(oscSettings).status(200);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/osc'
|
||||
// Returns ACK message
|
||||
export const postOSC = async (req, res) => {
|
||||
|
||||
+31
-2
@@ -1,5 +1,5 @@
|
||||
import { body, check, validationResult } from 'express-validator';
|
||||
import { validateOscSubscription } from '../utils/parserFunctions.js';
|
||||
import { validateOscObject, validateOscSubscriptionEntry } from '../utils/parserFunctions.js';
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/views
|
||||
@@ -81,7 +81,36 @@ export const validateOSC = [
|
||||
body('enabledOut').exists().isBoolean(),
|
||||
body('subscriptions')
|
||||
.isObject()
|
||||
.custom((value) => validateOscSubscription(value)),
|
||||
.custom((value) => validateOscObject(value)),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/osc-subscriptions
|
||||
*/
|
||||
export const validateOscSubscription = [
|
||||
body('onLoad')
|
||||
.isArray()
|
||||
.custom((value) => validateOscSubscriptionEntry(value)),
|
||||
body('onStart')
|
||||
.isArray()
|
||||
.custom((value) => validateOscSubscriptionEntry(value)),
|
||||
body('onPause')
|
||||
.isArray()
|
||||
.custom((value) => validateOscSubscriptionEntry(value)),
|
||||
body('onStop')
|
||||
.isArray()
|
||||
.custom((value) => validateOscSubscriptionEntry(value)),
|
||||
body('onUpdate')
|
||||
.isArray()
|
||||
.custom((value) => validateOscSubscriptionEntry(value)),
|
||||
body('onFinish')
|
||||
.isArray()
|
||||
.custom((value) => validateOscSubscriptionEntry(value)),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
+2
-3
@@ -1,7 +1,6 @@
|
||||
import express from 'express';
|
||||
// import event controller
|
||||
import { getEventData, postEventData } from '../controllers/eventDataController.ts';
|
||||
import { eventDataSanitizer } from '../controllers/eventDataController.validate.ts';
|
||||
import { getEventData, postEventData } from '../controllers/eventDataController.js';
|
||||
import { eventDataSanitizer } from '../controllers/eventDataController.validate.js';
|
||||
|
||||
export const router = express.Router();
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
postAliases,
|
||||
postNew,
|
||||
postOSC,
|
||||
postOscSubscriptions,
|
||||
postSettings,
|
||||
postUserFields,
|
||||
postViewSettings,
|
||||
@@ -21,6 +22,7 @@ import {
|
||||
import {
|
||||
validateAliases,
|
||||
validateOSC,
|
||||
validateOscSubscription,
|
||||
validateSettings,
|
||||
validateUserFields,
|
||||
viewValidator,
|
||||
@@ -71,5 +73,8 @@ router.get('/osc', getOSC);
|
||||
// create route between controller and '/ontime/osc' endpoint
|
||||
router.post('/osc', validateOSC, postOSC);
|
||||
|
||||
// create route between controller and '/ontime/osc-subscriptions' endpoint
|
||||
router.post('/osc-subscriptions', validateOscSubscription, postOscSubscriptions);
|
||||
|
||||
// create route between controller and '/ontime/new' endpoint
|
||||
router.post('/new', eventDataSanitizer, postNew);
|
||||
@@ -1,5 +1,4 @@
|
||||
import express from 'express';
|
||||
// import playback controllers
|
||||
import {
|
||||
pbGet,
|
||||
pbLoad,
|
||||
@@ -5,7 +5,7 @@ import IIntegration, { TimerLifeCycleKey } from './IIntegration.js';
|
||||
import { parseTemplateNested } from './integrationUtils.js';
|
||||
import { isObject } from '../../utils/varUtils.js';
|
||||
import { dbModel } from '../../models/dataModel.js';
|
||||
import { validateOscSubscription } from '../../utils/parserFunctions.js';
|
||||
import { validateOscObject } from '../../utils/parserFunctions.js';
|
||||
|
||||
type Action = TimerLifeCycleKey | string;
|
||||
|
||||
@@ -58,7 +58,7 @@ export class OscIntegration implements IIntegration {
|
||||
}
|
||||
|
||||
initSubscriptions(subscriptionOptions: OscSubscription) {
|
||||
if (validateOscSubscription(subscriptionOptions)) {
|
||||
if (validateOscObject(subscriptionOptions)) {
|
||||
this.subscriptions = { ...subscriptionOptions };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { validateOscSubscription } from '../parserFunctions.ts';
|
||||
import { validateOscObject } from '../parserFunctions.ts';
|
||||
|
||||
test('validateOscSubscription()', () => {
|
||||
it('should return true when given a valid OscSubscription', () => {
|
||||
@@ -11,35 +11,35 @@ test('validateOscSubscription()', () => {
|
||||
onFinish: [{ id: '6', message: 'test', enabled: false }],
|
||||
};
|
||||
|
||||
const result = validateOscSubscription(validSubscription);
|
||||
const result = validateOscObject(validSubscription);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when given undefined', () => {
|
||||
const result = validateOscSubscription(undefined);
|
||||
const result = validateOscObject(undefined);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when given null', () => {
|
||||
const result = validateOscSubscription(null);
|
||||
const result = validateOscObject(null);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when given an empty object', () => {
|
||||
const result = validateOscSubscription({});
|
||||
const result = validateOscObject({});
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when given an empty array', () => {
|
||||
const result = validateOscSubscription([]);
|
||||
const result = validateOscObject([]);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when given an object that is not an OscSubscription', () => {
|
||||
const invalidObject = { foo: 'bar' };
|
||||
|
||||
const result = validateOscSubscription(invalidObject);
|
||||
const result = validateOscObject(invalidObject);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
@@ -54,7 +54,7 @@ test('validateOscSubscription()', () => {
|
||||
onFinish: [{ id: '6', message: 'test', enabled: false }],
|
||||
};
|
||||
|
||||
const result = validateOscSubscription(invalidSubscription);
|
||||
const result = validateOscObject(invalidSubscription);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
@@ -69,7 +69,7 @@ test('validateOscSubscription()', () => {
|
||||
onFinish: [{ id: '6', message: 'test', enabled: 'not a boolean' }],
|
||||
};
|
||||
|
||||
const result = validateOscSubscription(invalidSubscription);
|
||||
const result = validateOscObject(invalidSubscription);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
@@ -84,7 +84,7 @@ test('validateOscSubscription()', () => {
|
||||
onFinish: [{ id: '6', message: 'test', enabled: 'not a boolean' }],
|
||||
};
|
||||
|
||||
const result = validateOscSubscription(invalidSubscription);
|
||||
const result = validateOscObject(invalidSubscription);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
OntimeRundown,
|
||||
OSCSettings,
|
||||
OscSubscription,
|
||||
OscSubscriptionOptions,
|
||||
Settings,
|
||||
TimerLifeCycle,
|
||||
UserFields,
|
||||
@@ -164,11 +165,24 @@ export const parseViewSettings = (data, enforce): ViewSettings => {
|
||||
return newViews as ViewSettings;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses and validates subscription entry
|
||||
* @param data
|
||||
*/
|
||||
export const validateOscSubscriptionEntry = (data: OscSubscriptionOptions): boolean => {
|
||||
for (const subscription in data) {
|
||||
if (typeof data[subscription].message !== 'string' || typeof data[subscription].enabled !== 'boolean') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses and validates subscription object
|
||||
* @param data
|
||||
*/
|
||||
export const validateOscSubscription = (data: OscSubscription): boolean => {
|
||||
export const validateOscObject = (data: OscSubscription): boolean => {
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
@@ -178,7 +192,7 @@ export const validateOscSubscription = (data: OscSubscription): boolean => {
|
||||
return false;
|
||||
}
|
||||
for (const subscription of data[key]) {
|
||||
if (!subscription.id || typeof subscription.message !== 'string' || typeof subscription.enabled !== 'boolean') {
|
||||
if (typeof subscription.message !== 'string' || typeof subscription.enabled !== 'boolean') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -194,7 +208,7 @@ export const parseOsc = (data: { osc?: Partial<OSCSettings> }, enforce: boolean)
|
||||
console.log('Found OSC definition, importing...');
|
||||
|
||||
const loadedConfig = data?.osc || {};
|
||||
const validatedSubscriptions = validateOscSubscription(loadedConfig.subscriptions)
|
||||
const validatedSubscriptions = validateOscObject(loadedConfig.subscriptions)
|
||||
? loadedConfig.subscriptions
|
||||
: dbModel.osc.subscriptions;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user