mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 22:49:18 +00:00
refactor: validation
This commit is contained in:
@@ -3,12 +3,12 @@ import {
|
|||||||
Alias,
|
Alias,
|
||||||
DatabaseModel,
|
DatabaseModel,
|
||||||
GetInfo,
|
GetInfo,
|
||||||
HTTPSettings,
|
HttpSettings,
|
||||||
OntimeRundown,
|
OntimeRundown,
|
||||||
OSCSettings,
|
OSCSettings,
|
||||||
|
OscSubscription,
|
||||||
ProjectData,
|
ProjectData,
|
||||||
Settings,
|
Settings,
|
||||||
Subscription,
|
|
||||||
UserFields,
|
UserFields,
|
||||||
ViewSettings,
|
ViewSettings,
|
||||||
} from 'ontime-types';
|
} from 'ontime-types';
|
||||||
@@ -109,7 +109,7 @@ export async function getOSC(): Promise<OSCSettings> {
|
|||||||
* @description HTTP request to retrieve http settings
|
* @description HTTP request to retrieve http settings
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export async function getHTTP(): Promise<HTTPSettings> {
|
export async function getHTTP(): Promise<HttpSettings> {
|
||||||
const res = await axios.get(`${ontimeURL}/http`);
|
const res = await axios.get(`${ontimeURL}/http`);
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ export async function getHTTP(): Promise<HTTPSettings> {
|
|||||||
* @description HTTP request to mutate http settings
|
* @description HTTP request to mutate http settings
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export async function postHTTP(data: HTTPSettings) {
|
export async function postHTTP(data: HttpSettings) {
|
||||||
return axios.post(`${ontimeURL}/http`, data);
|
return axios.post(`${ontimeURL}/http`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ export async function postOSC(data: OSCSettings) {
|
|||||||
* @description HTTP request to mutate osc subscriptions
|
* @description HTTP request to mutate osc subscriptions
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export async function postOscSubscriptions(data: Subscription) {
|
export async function postOscSubscriptions(data: OscSubscription) {
|
||||||
return axios.post(`${ontimeURL}/osc-subscriptions`, data);
|
return axios.post(`${ontimeURL}/osc-subscriptions`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||||
import { HTTPSettings } from 'ontime-types';
|
import { HttpSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
|
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
|
||||||
import { HTTP_SETTINGS } from '../api/apiConstants';
|
import { HTTP_SETTINGS } from '../api/apiConstants';
|
||||||
@@ -20,7 +20,7 @@ export function useHttpSettings() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// we need to jump through some hoops because of the type op port
|
// we need to jump through some hoops because of the type op port
|
||||||
return { data: data! as unknown as HTTPSettings, status, isFetching, isError, refetch };
|
return { data: data! as unknown as HttpSettings, status, isFetching, isError, refetch };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePostHttpSettings() {
|
export function usePostHttpSettings() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { HTTPSettings } from 'ontime-types';
|
import { HttpSettings } from 'ontime-types';
|
||||||
|
|
||||||
export const httpPlaceholder: HTTPSettings = {
|
export const httpPlaceholder: HttpSettings = {
|
||||||
enabledOut: false,
|
enabledOut: false,
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
onLoad: [],
|
onLoad: [],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { Switch } from '@chakra-ui/react';
|
import { Switch } from '@chakra-ui/react';
|
||||||
import type { HTTPSettings } from 'ontime-types';
|
import type { HttpSettings } from 'ontime-types';
|
||||||
import { TimerLifeCycle } from 'ontime-types';
|
import { TimerLifeCycle } from 'ontime-types';
|
||||||
|
|
||||||
import { useHttpSettings, usePostHttpSettings } from '../../../../common/hooks-query/useHttpSettings';
|
import { useHttpSettings, usePostHttpSettings } from '../../../../common/hooks-query/useHttpSettings';
|
||||||
@@ -24,7 +24,7 @@ export default function HttpIntegration() {
|
|||||||
register,
|
register,
|
||||||
reset,
|
reset,
|
||||||
formState: { isSubmitting, isDirty, isValid },
|
formState: { isSubmitting, isDirty, isValid },
|
||||||
} = useForm<HTTPSettings>({
|
} = useForm<HttpSettings>({
|
||||||
mode: 'onBlur',
|
mode: 'onBlur',
|
||||||
defaultValues: data,
|
defaultValues: data,
|
||||||
values: data,
|
values: data,
|
||||||
@@ -45,9 +45,9 @@ export default function HttpIntegration() {
|
|||||||
reset(data);
|
reset(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async (values: HTTPSettings) => {
|
const onSubmit = async (values: HttpSettings) => {
|
||||||
try {
|
try {
|
||||||
const newSettings: HTTPSettings = {
|
const newSettings: HttpSettings = {
|
||||||
enabledOut: Boolean(values.enabledOut),
|
enabledOut: Boolean(values.enabledOut),
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
onLoad: values.subscriptions.onLoad ?? [],
|
onLoad: values.subscriptions.onLoad ?? [],
|
||||||
@@ -59,8 +59,6 @@ export default function HttpIntegration() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('debug will submit', newSettings);
|
|
||||||
|
|
||||||
await mutateAsync(newSettings);
|
await mutateAsync(newSettings);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
emitError(`Error setting HTML: ${error}`);
|
emitError(`Error setting HTML: ${error}`);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Control, useFieldArray, UseFormRegister } from 'react-hook-form';
|
|||||||
import { Button, IconButton, Input, Switch } from '@chakra-ui/react';
|
import { Button, IconButton, Input, Switch } from '@chakra-ui/react';
|
||||||
import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp';
|
import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp';
|
||||||
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
|
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
|
||||||
import { HTTPSettings, TimerLifeCycle } from 'ontime-types';
|
import { HttpSettings, TimerLifeCycle } from 'ontime-types';
|
||||||
|
|
||||||
import { useEmitLog } from '../../../../common/stores/logger';
|
import { useEmitLog } from '../../../../common/stores/logger';
|
||||||
import { startsWithHttp } from '../../../../common/utils/regex';
|
import { startsWithHttp } from '../../../../common/utils/regex';
|
||||||
@@ -16,8 +16,8 @@ interface SubscriptionRowProps {
|
|||||||
subtitle: string;
|
subtitle: string;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
setShowSection: (cycle: TimerLifeCycle) => void;
|
setShowSection: (cycle: TimerLifeCycle) => void;
|
||||||
register: UseFormRegister<HTTPSettings>;
|
register: UseFormRegister<HttpSettings>;
|
||||||
control: Control<HTTPSettings>;
|
control: Control<HttpSettings>;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { HTTPSettings, LogOrigin, OSCSettings } from 'ontime-types';
|
import { HttpSettings, LogOrigin, OSCSettings } from 'ontime-types';
|
||||||
|
|
||||||
import 'dotenv/config';
|
import 'dotenv/config';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
@@ -194,7 +194,7 @@ export const startOSCServer = async (overrideConfig = null) => {
|
|||||||
/**
|
/**
|
||||||
* starts integrations
|
* starts integrations
|
||||||
*/
|
*/
|
||||||
export const startIntegrations = async (config?: { osc: OSCSettings; http: HTTPSettings }) => {
|
export const startIntegrations = async (config?: { osc: OSCSettings; http: HttpSettings }) => {
|
||||||
checkStart(OntimeStartOrder.InitIO);
|
checkStart(OntimeStartOrder.InitIO);
|
||||||
|
|
||||||
const { osc, http } = config ?? DataProvider.getData();
|
const { osc, http } = config ?? DataProvider.getData();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { LogOrigin } from 'ontime-types';
|
import { LogOrigin } from 'ontime-types';
|
||||||
import type { Alias, DatabaseModel, GetInfo, HTTPSettings, ProjectData } from 'ontime-types';
|
import type { Alias, DatabaseModel, GetInfo, HttpSettings, ProjectData } from 'ontime-types';
|
||||||
|
|
||||||
import { RequestHandler, Request, Response } from 'express';
|
import { RequestHandler, Request, Response } from 'express';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
@@ -335,7 +335,7 @@ export const postOscSubscriptions = async (req, res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create controller for GET request to '/ontime/http'
|
// Create controller for GET request to '/ontime/http'
|
||||||
export const getHTTP = async (_req, res: Response<HTTPSettings>) => {
|
export const getHTTP = async (_req, res: Response<HttpSettings>) => {
|
||||||
const http = DataProvider.getHttp();
|
const http = DataProvider.getHttp();
|
||||||
res.status(200).send(http);
|
res.status(200).send(http);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { body, check, validationResult } from 'express-validator';
|
import { body, check, validationResult } from 'express-validator';
|
||||||
import { validateOscObject, validateSubscriptionEntry } from '../utils/parserFunctions.js';
|
import {
|
||||||
|
validateHttpSubscriptionObject,
|
||||||
|
validateOscSubscriptionObject,
|
||||||
|
validateOscSubscriptionCycle,
|
||||||
|
} from '../utils/parserFunctions.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Validates object for POST /ontime/views
|
* @description Validates object for POST /ontime/views
|
||||||
@@ -82,7 +86,7 @@ export const validateOSC = [
|
|||||||
body('enabledOut').exists().isBoolean(),
|
body('enabledOut').exists().isBoolean(),
|
||||||
body('subscriptions')
|
body('subscriptions')
|
||||||
.isObject()
|
.isObject()
|
||||||
.custom((value) => validateOscObject(value)),
|
.custom((value) => validateOscSubscriptionObject(value)),
|
||||||
(req, res, next) => {
|
(req, res, next) => {
|
||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||||
@@ -97,7 +101,7 @@ export const validateHTTP = [
|
|||||||
body('enabledOut').exists().isBoolean(),
|
body('enabledOut').exists().isBoolean(),
|
||||||
body('subscriptions')
|
body('subscriptions')
|
||||||
.isObject()
|
.isObject()
|
||||||
.custom((value) => validateOscObject(value)),
|
.custom((value) => validateHttpSubscriptionObject(value)),
|
||||||
(req, res, next) => {
|
(req, res, next) => {
|
||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||||
@@ -108,25 +112,25 @@ export const validateHTTP = [
|
|||||||
/**
|
/**
|
||||||
* @description Validates object for POST /ontime/osc-subscriptions
|
* @description Validates object for POST /ontime/osc-subscriptions
|
||||||
*/
|
*/
|
||||||
export const validateSubscription = [
|
export const validateOscSubscription = [
|
||||||
body('onLoad')
|
body('onLoad')
|
||||||
.isArray()
|
.isArray()
|
||||||
.custom((value) => validateSubscriptionEntry(value)),
|
.custom((value) => validateOscSubscriptionCycle(value)),
|
||||||
body('onStart')
|
body('onStart')
|
||||||
.isArray()
|
.isArray()
|
||||||
.custom((value) => validateSubscriptionEntry(value)),
|
.custom((value) => validateOscSubscriptionCycle(value)),
|
||||||
body('onPause')
|
body('onPause')
|
||||||
.isArray()
|
.isArray()
|
||||||
.custom((value) => validateSubscriptionEntry(value)),
|
.custom((value) => validateOscSubscriptionCycle(value)),
|
||||||
body('onStop')
|
body('onStop')
|
||||||
.isArray()
|
.isArray()
|
||||||
.custom((value) => validateSubscriptionEntry(value)),
|
.custom((value) => validateOscSubscriptionCycle(value)),
|
||||||
body('onUpdate')
|
body('onUpdate')
|
||||||
.isArray()
|
.isArray()
|
||||||
.custom((value) => validateSubscriptionEntry(value)),
|
.custom((value) => validateOscSubscriptionCycle(value)),
|
||||||
body('onFinish')
|
body('onFinish')
|
||||||
.isArray()
|
.isArray()
|
||||||
.custom((value) => validateSubscriptionEntry(value)),
|
.custom((value) => validateOscSubscriptionCycle(value)),
|
||||||
(req, res, next) => {
|
(req, res, next) => {
|
||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
validateAliases,
|
validateAliases,
|
||||||
validateOSC,
|
validateOSC,
|
||||||
validateSubscription,
|
validateOscSubscriptionObject,
|
||||||
validatePatchProjectFile,
|
validatePatchProjectFile,
|
||||||
validateSettings,
|
validateSettings,
|
||||||
validateUserFields,
|
validateUserFields,
|
||||||
@@ -86,7 +86,7 @@ router.get('/osc', getOSC);
|
|||||||
router.post('/osc', validateOSC, postOSC);
|
router.post('/osc', validateOSC, postOSC);
|
||||||
|
|
||||||
// create route between controller and '/ontime/osc-subscriptions' endpoint
|
// create route between controller and '/ontime/osc-subscriptions' endpoint
|
||||||
router.post('/osc-subscriptions', validateSubscription, postOscSubscriptions);
|
router.post('/osc-subscriptions', validateOscSubscriptionObject, postOscSubscriptions);
|
||||||
|
|
||||||
// create route between controller and '/ontime/http' endpoint
|
// create route between controller and '/ontime/http' endpoint
|
||||||
router.get('/http', getHTTP);
|
router.get('/http', getHTTP);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
//TODO: cleanup stuff left over from OSC copy
|
//TODO: cleanup stuff left over from OSC copy
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import { HTTPSettings, LogOrigin, Subscription } from 'ontime-types';
|
import { HttpSettings, HttpSubscription, HttpSubscriptionOptions, LogOrigin } from 'ontime-types';
|
||||||
|
|
||||||
import IIntegration, { TimerLifeCycleKey } from './IIntegration.js';
|
import IIntegration, { TimerLifeCycleKey } from './IIntegration.js';
|
||||||
import { parseTemplateNested } from './integrationUtils.js';
|
import { parseTemplateNested } from './integrationUtils.js';
|
||||||
import { dbModel } from '../../models/dataModel.js';
|
import { dbModel } from '../../models/dataModel.js';
|
||||||
import { validateHttpObject } from '../../utils/parserFunctions.js';
|
import { validateHttpSubscriptionEntry } from '../../utils/parserFunctions.js';
|
||||||
import { logger } from '../../classes/Logger.js';
|
import { logger } from '../../classes/Logger.js';
|
||||||
|
|
||||||
import { URL } from 'node:url';
|
import { URL } from 'node:url';
|
||||||
@@ -15,9 +15,9 @@ type Action = TimerLifeCycleKey | string;
|
|||||||
* @description Class contains logic towards outgoing HTTP communications
|
* @description Class contains logic towards outgoing HTTP communications
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
export class HttpIntegration implements IIntegration {
|
export class HttpIntegration implements IIntegration<HttpSubscriptionOptions> {
|
||||||
protected httpAgent: null | http.Agent;
|
protected httpAgent: null | http.Agent;
|
||||||
subscriptions: Subscription;
|
subscriptions: HttpSubscription;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.httpAgent = null;
|
this.httpAgent = null;
|
||||||
@@ -27,7 +27,7 @@ export class HttpIntegration implements IIntegration {
|
|||||||
/**
|
/**
|
||||||
* Initializes httpClient
|
* Initializes httpClient
|
||||||
*/
|
*/
|
||||||
init(config: HTTPSettings) {
|
init(config: HttpSettings) {
|
||||||
const { subscriptions, enabledOut } = config;
|
const { subscriptions, enabledOut } = config;
|
||||||
|
|
||||||
if (!enabledOut) {
|
if (!enabledOut) {
|
||||||
@@ -60,8 +60,9 @@ export class HttpIntegration implements IIntegration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initSubscriptions(subscriptionOptions: Subscription) {
|
initSubscriptions(subscriptionOptions: HttpSubscription) {
|
||||||
if (validateHttpObject(subscriptionOptions)) {
|
// TODO: here we have to validate the entire subscription object
|
||||||
|
if (validateHttpSubscriptionEntry(subscriptionOptions)) {
|
||||||
this.subscriptions = { ...subscriptionOptions };
|
this.subscriptions = { ...subscriptionOptions };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { TimerLifeCycle, Subscription } from 'ontime-types';
|
|||||||
|
|
||||||
export type TimerLifeCycleKey = keyof typeof TimerLifeCycle;
|
export type TimerLifeCycleKey = keyof typeof TimerLifeCycle;
|
||||||
|
|
||||||
export default interface IIntegration {
|
export default interface IIntegration<T> {
|
||||||
subscriptions: Subscription;
|
subscriptions: Subscription<T>;
|
||||||
init: (config: unknown) => OperationReturn;
|
init: (config: unknown) => OperationReturn;
|
||||||
dispatch: (action: TimerLifeCycleKey, state?: object) => OperationReturn;
|
dispatch: (action: TimerLifeCycleKey, state?: object) => OperationReturn;
|
||||||
emit: (...args: unknown[]) => unknown;
|
emit: (...args: unknown[]) => unknown;
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import IIntegration, { TimerLifeCycleKey } from './IIntegration.js';
|
|||||||
import { eventStore } from '../../stores/EventStore.js';
|
import { eventStore } from '../../stores/EventStore.js';
|
||||||
|
|
||||||
class IntegrationService {
|
class IntegrationService {
|
||||||
private integrations: IIntegration[];
|
private integrations: IIntegration<unknown>[];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.integrations = [];
|
this.integrations = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
register(integrationService: IIntegration) {
|
register(integrationService: IIntegration<unknown>) {
|
||||||
this.integrations.push(integrationService);
|
this.integrations.push(integrationService);
|
||||||
}
|
}
|
||||||
|
|
||||||
unregister(integrationService: IIntegration) {
|
unregister(integrationService: IIntegration<unknown>) {
|
||||||
this.integrations = this.integrations.filter((int) => int !== integrationService);
|
this.integrations = this.integrations.filter((int) => int !== integrationService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { ArgumentType, Client, Message } from 'node-osc';
|
import { ArgumentType, Client, Message } from 'node-osc';
|
||||||
import { OSCSettings, Subscription } from 'ontime-types';
|
import { OSCSettings, OscSubscription, OscSubscriptionOptions } from 'ontime-types';
|
||||||
|
|
||||||
import IIntegration, { TimerLifeCycleKey } from './IIntegration.js';
|
import IIntegration, { TimerLifeCycleKey } from './IIntegration.js';
|
||||||
import { parseTemplateNested } from './integrationUtils.js';
|
import { parseTemplateNested } from './integrationUtils.js';
|
||||||
import { isObject } from '../../utils/varUtils.js';
|
import { isObject } from '../../utils/varUtils.js';
|
||||||
import { dbModel } from '../../models/dataModel.js';
|
import { dbModel } from '../../models/dataModel.js';
|
||||||
import { validateOscObject } from '../../utils/parserFunctions.js';
|
import { validateOscSubscriptionObject } from '../../utils/parserFunctions.js';
|
||||||
|
|
||||||
type Action = TimerLifeCycleKey | string;
|
type Action = TimerLifeCycleKey | string;
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@ type Action = TimerLifeCycleKey | string;
|
|||||||
* @description Class contains logic towards outgoing OSC communications
|
* @description Class contains logic towards outgoing OSC communications
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
export class OscIntegration implements IIntegration {
|
export class OscIntegration implements IIntegration<OscSubscriptionOptions> {
|
||||||
protected oscClient: null | Client;
|
protected oscClient: null | Client;
|
||||||
subscriptions: Subscription;
|
subscriptions: OscSubscription;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.oscClient = null;
|
this.oscClient = null;
|
||||||
@@ -65,8 +65,8 @@ export class OscIntegration implements IIntegration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initSubscriptions(subscriptionOptions: Subscription) {
|
initSubscriptions(subscriptionOptions: OscSubscription) {
|
||||||
if (validateOscObject(subscriptionOptions)) {
|
if (validateOscSubscriptionObject(subscriptionOptions)) {
|
||||||
this.subscriptions = { ...subscriptionOptions };
|
this.subscriptions = { ...subscriptionOptions };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
import { validateOscObject } from '../parserFunctions.ts';
|
|
||||||
|
|
||||||
test('validateOscSubscription()', () => {
|
|
||||||
it('should return true when given a valid OscSubscription', () => {
|
|
||||||
const validSubscription = {
|
|
||||||
onLoad: [{ id: '1', message: 'test', enabled: true }],
|
|
||||||
onStart: [{ id: '2', message: 'test', enabled: false }],
|
|
||||||
onPause: [{ id: '3', message: 'test', enabled: true }],
|
|
||||||
onStop: [{ id: '4', message: 'test', enabled: false }],
|
|
||||||
onUpdate: [{ id: '5', message: 'test', enabled: true }],
|
|
||||||
onFinish: [{ id: '6', message: 'test', enabled: false }],
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = validateOscObject(validSubscription);
|
|
||||||
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given undefined', () => {
|
|
||||||
const result = validateOscObject(undefined);
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given null', () => {
|
|
||||||
const result = validateOscObject(null);
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given an empty object', () => {
|
|
||||||
const result = validateOscObject({});
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given an empty array', () => {
|
|
||||||
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 = validateOscObject(invalidObject);
|
|
||||||
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given an OscSubscription with a missing property', () => {
|
|
||||||
const invalidSubscription = {
|
|
||||||
onLoad: [{ id: '1', message: 'test', enabled: true }],
|
|
||||||
onStart: [{ id: '2', message: 'test', enabled: false }],
|
|
||||||
onPause: [{ id: '3', message: 'test', enabled: true }],
|
|
||||||
// Missing onStop
|
|
||||||
onUpdate: [{ id: '5', message: 'test', enabled: true }],
|
|
||||||
onFinish: [{ id: '6', message: 'test', enabled: false }],
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = validateOscObject(invalidSubscription);
|
|
||||||
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when given an OscSubscription with an invalid property value', () => {
|
|
||||||
const invalidSubscription = {
|
|
||||||
onLoad: [{ id: '1', message: 'test', enabled: true }],
|
|
||||||
onStart: [{ id: '2', message: 'test', enabled: false }],
|
|
||||||
onPause: [{ id: '3', message: 'test', enabled: true }],
|
|
||||||
onStop: [{ id: '4', message: 'test', enabled: false }],
|
|
||||||
onUpdate: [{ id: '5', message: 'test', enabled: true }],
|
|
||||||
onFinish: [{ id: '6', message: 'test', enabled: 'not a boolean' }],
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = validateOscObject(invalidSubscription);
|
|
||||||
|
|
||||||
expect(result).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true if the message field is empty', () => {
|
|
||||||
const invalidSubscription = {
|
|
||||||
onLoad: [{ id: '1', message: 'test', enabled: true }],
|
|
||||||
onStart: [{ id: '2', message: '', enabled: false }],
|
|
||||||
onPause: [{ id: '3', message: '', enabled: true }],
|
|
||||||
onStop: [{ id: '4', message: 'test', enabled: false }],
|
|
||||||
onUpdate: [{ id: '5', message: 'test', enabled: true }],
|
|
||||||
onFinish: [{ id: '6', message: 'test', enabled: 'not a boolean' }],
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = validateOscObject(invalidSubscription);
|
|
||||||
|
|
||||||
expect(result).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
import { HttpSubscription, OscSubscription } from 'ontime-types';
|
||||||
|
import {
|
||||||
|
validateOscSubscriptionObject,
|
||||||
|
validateOscSubscriptionCycle,
|
||||||
|
validateHttpSubscriptionCycle,
|
||||||
|
validateHttpSubscriptionObject,
|
||||||
|
} from '../parserFunctions.js';
|
||||||
|
|
||||||
|
describe('validateOscSubscriptionCycle()', () => {
|
||||||
|
it('should return false when given an OscSubscription with an invalid property value', () => {
|
||||||
|
const invalidEntry = [{ message: 'test', enabled: 'not a boolean' }];
|
||||||
|
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateOscSubscriptionCycle(invalidEntry);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validateOscSubscriptionObject()', () => {
|
||||||
|
it('should return true when given a valid OscSubscription', () => {
|
||||||
|
const validSubscription: OscSubscription = {
|
||||||
|
onLoad: [{ message: 'test', enabled: true }],
|
||||||
|
onStart: [{ message: 'test', enabled: false }],
|
||||||
|
onPause: [{ message: 'test', enabled: true }],
|
||||||
|
onStop: [{ message: 'test', enabled: false }],
|
||||||
|
onUpdate: [{ message: 'test', enabled: true }],
|
||||||
|
onFinish: [{ message: 'test', enabled: false }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = validateOscSubscriptionObject(validSubscription);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given undefined', () => {
|
||||||
|
const result = validateOscSubscriptionObject(undefined);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given null', () => {
|
||||||
|
const result = validateOscSubscriptionObject(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an empty object', () => {
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateOscSubscriptionObject({});
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an empty array', () => {
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateOscSubscriptionObject([]);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an object that is not an OscSubscription', () => {
|
||||||
|
const invalidObject = { foo: 'bar' };
|
||||||
|
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateOscSubscriptionObject(invalidObject);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an OscSubscription with a missing property', () => {
|
||||||
|
const invalidSubscription = {
|
||||||
|
onLoad: [{ message: 'test', enabled: true }],
|
||||||
|
onStart: [{ message: 'test', enabled: false }],
|
||||||
|
onPause: [{ message: 'test', enabled: true }],
|
||||||
|
// Missing onStop
|
||||||
|
onUpdate: [{ message: 'test', enabled: true }],
|
||||||
|
onFinish: [{ message: 'test', enabled: false }],
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateOscSubscriptionObject(invalidSubscription);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validateHttpSubscriptionCycle()', () => {
|
||||||
|
it('should return false when given an HttpSubscription with an invalid property value', () => {
|
||||||
|
const invalidBoolean = [{ message: 'http://', enabled: 'not a boolean' }];
|
||||||
|
const invalidHttp = [{ message: 'test', enabled: true }];
|
||||||
|
const noHttps = [{ message: 'https://test', enabled: true }];
|
||||||
|
const noEmpty = [{ message: '', enabled: true }];
|
||||||
|
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
expect(validateHttpSubscriptionCycle(invalidBoolean)).toBe(false);
|
||||||
|
|
||||||
|
expect(validateHttpSubscriptionCycle(invalidHttp)).toBe(false);
|
||||||
|
expect(validateHttpSubscriptionCycle(noHttps)).toBe(false);
|
||||||
|
expect(validateHttpSubscriptionCycle(noEmpty)).toBe(false);
|
||||||
|
});
|
||||||
|
it('should return true when given an HttpSubscription matches definition', () => {
|
||||||
|
const validHttp = [{ message: 'http://', enabled: true }];
|
||||||
|
|
||||||
|
const result = validateHttpSubscriptionCycle(validHttp);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validateHttpSubscriptionObject()', () => {
|
||||||
|
it('should return true when given a valid HttpSubscription', () => {
|
||||||
|
const validSubscription: HttpSubscription = {
|
||||||
|
onLoad: [{ message: 'http://', enabled: true }],
|
||||||
|
onStart: [{ message: 'http://', enabled: false }],
|
||||||
|
onPause: [{ message: 'http://', enabled: true }],
|
||||||
|
onStop: [{ message: 'http://', enabled: false }],
|
||||||
|
onUpdate: [{ message: 'http://', enabled: true }],
|
||||||
|
onFinish: [{ message: 'http://', enabled: false }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = validateHttpSubscriptionObject(validSubscription);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given undefined', () => {
|
||||||
|
const result = validateHttpSubscriptionObject(undefined);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given null', () => {
|
||||||
|
const result = validateHttpSubscriptionObject(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an empty object', () => {
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateOscSubscriptionObject({});
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an empty array', () => {
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateHttpSubscriptionObject([]);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an object that is not an HttpSubscription', () => {
|
||||||
|
const invalidObject = { foo: 'bar' };
|
||||||
|
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateHttpSubscriptionObject(invalidObject);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when given an HttpSubscription with a missing property', () => {
|
||||||
|
const invalidSubscription = {
|
||||||
|
onLoad: [{ message: 'http://', enabled: true }],
|
||||||
|
onStart: [{ message: 'http://', enabled: false }],
|
||||||
|
onPause: [{ message: 'http://', enabled: true }],
|
||||||
|
// Missing onStop
|
||||||
|
onUpdate: [{ message: 'http://', enabled: true }],
|
||||||
|
onFinish: [{ message: 'http://', enabled: false }],
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-expect-error -- since this comes from the client, we check things that typescript would have caught
|
||||||
|
const result = validateHttpSubscriptionObject(invalidSubscription);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -2,15 +2,17 @@ import { generateId } from 'ontime-utils';
|
|||||||
import {
|
import {
|
||||||
Alias,
|
Alias,
|
||||||
OntimeRundown,
|
OntimeRundown,
|
||||||
HTTPSettings,
|
HttpSettings,
|
||||||
OSCSettings,
|
OSCSettings,
|
||||||
Subscription,
|
|
||||||
SubscriptionOptions,
|
|
||||||
ProjectData,
|
ProjectData,
|
||||||
Settings,
|
Settings,
|
||||||
TimerLifeCycle,
|
TimerLifeCycle,
|
||||||
UserFields,
|
UserFields,
|
||||||
ViewSettings,
|
ViewSettings,
|
||||||
|
OscSubscription,
|
||||||
|
HttpSubscription,
|
||||||
|
OscSubscriptionOptions,
|
||||||
|
HttpSubscriptionOptions,
|
||||||
} from 'ontime-types';
|
} from 'ontime-types';
|
||||||
|
|
||||||
import { block as blockDef, delay as delayDef } from '../models/eventsDefinition.js';
|
import { block as blockDef, delay as delayDef } from '../models/eventsDefinition.js';
|
||||||
@@ -160,12 +162,12 @@ export const parseViewSettings = (data): ViewSettings => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses and validates subscription entry
|
* Parses and validates OSC subscription cycle options
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export const validateSubscriptionEntry = (data: SubscriptionOptions): boolean => {
|
export const validateOscSubscriptionCycle = (data: OscSubscriptionOptions[]): boolean => {
|
||||||
for (const subscription in data) {
|
for (const subscriptionOption of data) {
|
||||||
if (typeof data[subscription].message !== 'string' || typeof data[subscription].enabled !== 'boolean') {
|
if (typeof subscriptionOption.message !== 'string' || typeof subscriptionOption.enabled !== 'boolean') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,22 +175,23 @@ export const validateSubscriptionEntry = (data: SubscriptionOptions): boolean =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses and validates subscription object
|
* Parses and validates OSC subscription object
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export const validateOscObject = (data: Subscription): boolean => {
|
export const validateOscSubscriptionObject = (data: OscSubscription): boolean => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timerKeys = Object.keys(TimerLifeCycle);
|
const timerKeys = Object.keys(TimerLifeCycle);
|
||||||
for (const key of timerKeys) {
|
for (const key of timerKeys) {
|
||||||
|
// must contains all keys and be an array
|
||||||
if (!(key in data) || !Array.isArray(data[key])) {
|
if (!(key in data) || !Array.isArray(data[key])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const subscription of data[key]) {
|
const isValid = validateOscSubscriptionCycle(data[key]);
|
||||||
if (typeof subscription.message !== 'string' || typeof subscription.enabled !== 'boolean') {
|
if (!isValid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -202,7 +205,7 @@ export const parseOsc = (data: { osc?: Partial<OSCSettings> }): OSCSettings => {
|
|||||||
console.log('Found OSC definition, importing...');
|
console.log('Found OSC definition, importing...');
|
||||||
|
|
||||||
const loadedConfig = data.osc || {};
|
const loadedConfig = data.osc || {};
|
||||||
const validatedSubscriptions = validateOscObject(loadedConfig.subscriptions)
|
const validatedSubscriptions = validateOscSubscriptionObject(loadedConfig.subscriptions)
|
||||||
? loadedConfig.subscriptions
|
? loadedConfig.subscriptions
|
||||||
: dbModel.osc.subscriptions;
|
: dbModel.osc.subscriptions;
|
||||||
|
|
||||||
@@ -218,22 +221,36 @@ export const parseOsc = (data: { osc?: Partial<OSCSettings> }): OSCSettings => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses and validates subscription object
|
* Parses and validates HTTP subscription cycle options
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export const validateHttpObject = (data: Subscription): boolean => {
|
export const validateHttpSubscriptionCycle = (data: HttpSubscriptionOptions[]): boolean => {
|
||||||
|
for (const subscriptionOption of data) {
|
||||||
|
const isHttp = subscriptionOption.message?.startsWith('http://');
|
||||||
|
if (typeof subscriptionOption.message !== 'string' || !isHttp || typeof subscriptionOption.enabled !== 'boolean') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and validates HTTP subscription object
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const validateHttpSubscriptionObject = (data: HttpSubscription): boolean => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const timerKeys = Object.keys(TimerLifeCycle);
|
const timerKeys = Object.keys(TimerLifeCycle);
|
||||||
|
// must contains all keys and be an array
|
||||||
for (const key of timerKeys) {
|
for (const key of timerKeys) {
|
||||||
if (!(key in data) || !Array.isArray(data[key])) {
|
if (!(key in data) || !Array.isArray(data[key])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const subscription of data[key]) {
|
const isValid = validateHttpSubscriptionCycle(data[key]);
|
||||||
if (typeof subscription.message !== 'string' || typeof subscription.enabled !== 'boolean') {
|
if (!isValid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -245,12 +262,12 @@ export const validateHttpObject = (data: Subscription): boolean => {
|
|||||||
* @param {boolean} enforce - whether to create a definition if one is missing
|
* @param {boolean} enforce - whether to create a definition if one is missing
|
||||||
* @returns {object} - event object data
|
* @returns {object} - event object data
|
||||||
*/
|
*/
|
||||||
export const parseHttp = (data: { http?: Partial<HTTPSettings> }): HTTPSettings => {
|
export const parseHttp = (data: { http?: Partial<HttpSettings> }): HttpSettings => {
|
||||||
if ('http' in data) {
|
if ('http' in data) {
|
||||||
console.log('Found HTTP definition, importing...');
|
console.log('Found HTTP definition, importing...');
|
||||||
|
|
||||||
const loadedConfig = data?.http || {};
|
const loadedConfig = data?.http || {};
|
||||||
const validatedSubscriptions = validateHttpObject(loadedConfig.subscriptions)
|
const validatedSubscriptions = validateHttpSubscriptionObject(loadedConfig.subscriptions)
|
||||||
? loadedConfig.subscriptions
|
? loadedConfig.subscriptions
|
||||||
: dbModel.http.subscriptions;
|
: dbModel.http.subscriptions;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { OSCSettings } from './core/OscSettings.type.js';
|
|||||||
import { Settings } from './core/Settings.type.js';
|
import { Settings } from './core/Settings.type.js';
|
||||||
import { UserFields } from './core/UserFields.type.js';
|
import { UserFields } from './core/UserFields.type.js';
|
||||||
import { ViewSettings } from './core/Views.type.js';
|
import { ViewSettings } from './core/Views.type.js';
|
||||||
import { HTTPSettings } from '../index.js';
|
import { HttpSettings } from '../index.js';
|
||||||
|
|
||||||
export type DatabaseModel = {
|
export type DatabaseModel = {
|
||||||
rundown: OntimeRundown;
|
rundown: OntimeRundown;
|
||||||
@@ -15,5 +15,5 @@ export type DatabaseModel = {
|
|||||||
aliases: Alias[];
|
aliases: Alias[];
|
||||||
userFields: UserFields;
|
userFields: UserFields;
|
||||||
osc: OSCSettings;
|
osc: OSCSettings;
|
||||||
http: HTTPSettings;
|
http: HttpSettings;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Subscription } from './Subscription.type.js';
|
import { Subscription } from './Subscription.type.js';
|
||||||
|
|
||||||
type HttpSubscriptionOptions = { message: string; enabled: boolean };
|
export type HttpSubscriptionOptions = { message: string; enabled: boolean };
|
||||||
export type HttpSubscription = Subscription<HttpSubscriptionOptions>;
|
export type HttpSubscription = Subscription<HttpSubscriptionOptions>;
|
||||||
|
|
||||||
export interface HTTPSettings {
|
export interface HttpSettings {
|
||||||
enabledOut: boolean;
|
enabledOut: boolean;
|
||||||
subscriptions: HttpSubscription;
|
subscriptions: HttpSubscription;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Subscription } from './Subscription.type.js';
|
import { Subscription } from './Subscription.type.js';
|
||||||
|
|
||||||
type OscSubscriptionOptions = { message: string; enabled: boolean };
|
export type OscSubscriptionOptions = { message: string; enabled: boolean };
|
||||||
export type OscSubscription = Subscription<OscSubscriptionOptions>;
|
export type OscSubscription = Subscription<OscSubscriptionOptions>;
|
||||||
|
|
||||||
export interface OSCSettings {
|
export interface OSCSettings {
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ export type { UserFields } from './definitions/core/UserFields.type.js';
|
|||||||
export type { Subscription } from './definitions/core/Subscription.type.js';
|
export type { Subscription } from './definitions/core/Subscription.type.js';
|
||||||
|
|
||||||
// ---> OSC
|
// ---> OSC
|
||||||
export type { OSCSettings, OscSubscription } from './definitions/core/OscSettings.type.js';
|
export type { OSCSettings, OscSubscription, OscSubscriptionOptions } from './definitions/core/OscSettings.type.js';
|
||||||
|
|
||||||
// ---> HTTP
|
// ---> HTTP
|
||||||
export type { HTTPSettings, HttpSubscription } from './definitions/core/HttpSettings.type.js';
|
export type { HttpSettings, HttpSubscription, HttpSubscriptionOptions } from './definitions/core/HttpSettings.type.js';
|
||||||
|
|
||||||
// SERVER RESPONSES
|
// SERVER RESPONSES
|
||||||
export type { NetworkInterface, GetInfo } from './api/ontime-controller/BackendResponse.type.js';
|
export type { NetworkInterface, GetInfo } from './api/ontime-controller/BackendResponse.type.js';
|
||||||
|
|||||||
Reference in New Issue
Block a user