Skip to content

Commit

Permalink
refactor: patch project
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed Jul 2, 2024
1 parent e47e5f5 commit 73f8717
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
9 changes: 1 addition & 8 deletions apps/server/src/api-data/db/db.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,15 @@ import { getErrorMessage } from 'ontime-utils';

import type { Request, Response } from 'express';

import { failEmptyObjects } from '../../utils/routerUtils.js';
import { doesProjectExist, handleUploaded } from '../../services/project-service/projectServiceUtils.js';
import * as projectService from '../../services/project-service/ProjectService.js';

export async function patchPartialProjectFile(req: Request, res: Response<DatabaseModel | ErrorResponse>) {
// all fields are optional in validation
if (failEmptyObjects(req.body, res)) {
res.status(400).send({ message: 'No field found to patch' });
return;
}

try {
const { rundown, project, settings, viewSettings, urlPresets, customFields, osc, http } = req.body;
const patchDb: DatabaseModel = { rundown, project, settings, viewSettings, urlPresets, customFields, osc, http };

const newData = await projectService.applyDataModel(patchDb);
const newData = await projectService.patchCurrentProject(patchDb);

res.status(200).send(newData);
} catch (error) {
Expand Down
11 changes: 10 additions & 1 deletion apps/server/src/api-data/db/db.validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,22 @@ export const validateNewProject = [
* @description Validates request for pathing data in the project.
*/
export const validatePatchProject = [
// Custom validator to ensure the body is not empty
(req: Request, res: Response, next: NextFunction) => {
if (Object.keys(req.body).length === 0) {
return res.status(422).json({ errors: [{ msg: 'Request body cannot be empty' }] });
}
next();
},

body('rundown').isArray().optional({ nullable: false }),
body('project').isObject().optional({ nullable: false }),
body('settings').isObject().optional({ nullable: false }),
body('viewSettings').isObject().optional({ nullable: false }),
body('aliases').isArray().optional({ nullable: false }),
body('urlPresets').isArray().optional({ nullable: false }),
body('customFields').isObject().optional({ nullable: false }),
body('osc').isObject().optional({ nullable: false }),
body('http').isObject().optional({ nullable: false }),

(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
Expand Down
13 changes: 8 additions & 5 deletions apps/server/src/services/project-service/ProjectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { httpIntegration } from '../integration-service/HttpIntegration.js';

import { parseProjectFile } from './projectFileUtils.js';
import { doesProjectExist, getPathToProject, getProjectFiles } from './projectServiceUtils.js';
import { parseRundown } from '../../utils/parserFunctions.js';

// init dependencies
init();
Expand Down Expand Up @@ -173,7 +174,7 @@ export async function createProject(filename: string, projectData: ProjectData)

// apply data to running services
// we dont need to parse since we are creating a new file
await applyDataModel(data);
await patchCurrentProject(data);

// update app state to point to new value
appStateProvider.setLastLoadedProject(uniqueFileName);
Expand Down Expand Up @@ -222,16 +223,18 @@ export async function getInfo(): Promise<GetInfo> {
/**
* applies a partial database model
*/
// TODO: should be private as part of a load
export async function applyDataModel(data: Partial<DatabaseModel>) {
export async function patchCurrentProject(data: Partial<DatabaseModel>) {
runtimeService.stop();

// TODO: allow partial project merge from options
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- we need to remove the fields before meging
const { rundown, customFields, ...rest } = data;
// we can pass some stuff straight to the data provider
const newData = await DataProvider.mergeIntoData(rest);

// ... but rundown and custom fields need to be checked
if (rundown != null) {
initRundown(rundown, customFields ?? {});
const result = parseRundown(data);
initRundown(result.rundown, result.customFields);
}

return newData;
Expand Down

0 comments on commit 73f8717

Please sign in to comment.