@@ -20,13 +20,14 @@ import {
2020 APIShowStyleVariantFrom ,
2121 showStyleBaseFrom ,
2222 showStyleVariantFrom ,
23+ validateAPIBlueprintConfigForShowStyle ,
2324} from './typeConversion'
2425import { Rundown } from '@sofie-automation/corelib/dist/dataModel/Rundown'
2526import { DBRundownPlaylist } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
2627import { runUpgradeForShowStyleBase , validateConfigForShowStyleBase } from '../../../migration/upgrades'
27- import { NoteSeverity } from '@sofie-automation/blueprints-integration'
2828import { DBShowStyleVariant } from '@sofie-automation/corelib/dist/dataModel/ShowStyleVariant'
2929import { assertNever } from '@sofie-automation/corelib/dist/lib'
30+ import { checkValidation } from '.'
3031
3132class ShowStylesServerAPI implements ShowStylesRestAPI {
3233 async getShowStyleBases (
@@ -42,9 +43,15 @@ class ShowStylesServerAPI implements ShowStylesRestAPI {
4243 async addShowStyleBase (
4344 _connection : Meteor . Connection ,
4445 _event : string ,
45- showStyleBase : APIShowStyleBase
46+ apiShowStyleBase : APIShowStyleBase
4647 ) : Promise < ClientAPI . ClientResponse < string > > {
47- const showStyle = await showStyleBaseFrom ( showStyleBase )
48+ const blueprintConfigValidation = await validateAPIBlueprintConfigForShowStyle (
49+ apiShowStyleBase ,
50+ protectString ( apiShowStyleBase . blueprintId )
51+ )
52+ checkValidation ( `addShowStyleBase` , blueprintConfigValidation )
53+
54+ const showStyle = await showStyleBaseFrom ( apiShowStyleBase )
4855 if ( ! showStyle ) throw new Meteor . Error ( 400 , `Invalid ShowStyleBase` )
4956 const showStyleId = showStyle . _id
5057 await ShowStyleBases . insertAsync ( showStyle )
@@ -60,16 +67,22 @@ class ShowStylesServerAPI implements ShowStylesRestAPI {
6067 const showStyleBase = await ShowStyleBases . findOneAsync ( showStyleBaseId )
6168 if ( ! showStyleBase ) throw new Meteor . Error ( 404 , `ShowStyleBase ${ showStyleBaseId } does not exist` )
6269
63- return ClientAPI . responseSuccess ( APIShowStyleBaseFrom ( showStyleBase ) )
70+ return ClientAPI . responseSuccess ( await APIShowStyleBaseFrom ( showStyleBase ) )
6471 }
6572
6673 async addOrUpdateShowStyleBase (
6774 _connection : Meteor . Connection ,
6875 _event : string ,
6976 showStyleBaseId : ShowStyleBaseId ,
70- showStyleBase : APIShowStyleBase
77+ apiShowStyleBase : APIShowStyleBase
7178 ) : Promise < ClientAPI . ClientResponse < void > > {
72- const showStyle = await showStyleBaseFrom ( showStyleBase , showStyleBaseId )
79+ const blueprintConfigValidation = await validateAPIBlueprintConfigForShowStyle (
80+ apiShowStyleBase ,
81+ protectString ( apiShowStyleBase . blueprintId )
82+ )
83+ checkValidation ( `addOrUpdateShowStyleBase ${ showStyleBaseId } ` , blueprintConfigValidation )
84+
85+ const showStyle = await showStyleBaseFrom ( apiShowStyleBase , showStyleBaseId )
7386 if ( ! showStyle ) throw new Meteor . Error ( 400 , `Invalid ShowStyleBase` )
7487
7588 const existingShowStyle = await ShowStyleBases . findOneAsync ( showStyleBaseId )
@@ -96,17 +109,73 @@ class ShowStylesServerAPI implements ShowStylesRestAPI {
96109
97110 await ShowStyleBases . upsertAsync ( showStyleBaseId , showStyle )
98111
112+ // wait for the upsert to complete before validation and upgrade read from the showStyleBases collection
113+ await new Promise < void > ( ( resolve ) => setTimeout ( ( ) => resolve ( ) , 200 ) )
114+
99115 const validation = await validateConfigForShowStyleBase ( showStyleBaseId )
100- const validateOK = validation . messages . reduce ( ( acc , msg ) => acc && msg . level === NoteSeverity . INFO , true )
101- if ( ! validateOK ) {
102- const details = JSON . stringify (
103- validation . messages . filter ( ( msg ) => msg . level < NoteSeverity . INFO ) . map ( ( msg ) => msg . message . key ) ,
104- null ,
105- 2
106- )
107- logger . error ( `addOrUpdateShowStyleBase failed validation with errors: ${ details } ` )
108- throw new Meteor . Error ( 409 , `ShowStyleBase ${ showStyleBaseId } has failed validation` , details )
109- }
116+ checkValidation ( `addOrUpdateShowStyleBase ${ showStyleBaseId } ` , validation . messages )
117+
118+ return ClientAPI . responseSuccess ( await runUpgradeForShowStyleBase ( showStyleBaseId ) )
119+ }
120+
121+ async getShowStyleConfig (
122+ _connection : Meteor . Connection ,
123+ _event : string ,
124+ showStyleBaseId : ShowStyleBaseId
125+ ) : Promise < ClientAPI . ClientResponse < object > > {
126+ const showStyleBase = await ShowStyleBases . findOneAsync ( showStyleBaseId )
127+ if ( ! showStyleBase ) throw new Meteor . Error ( 404 , `ShowStyleBase ${ showStyleBaseId } does not exist` )
128+
129+ return ClientAPI . responseSuccess ( ( await APIShowStyleBaseFrom ( showStyleBase ) ) . config )
130+ }
131+
132+ async updateShowStyleConfig (
133+ _connection : Meteor . Connection ,
134+ _event : string ,
135+ showStyleBaseId : ShowStyleBaseId ,
136+ config : object
137+ ) : Promise < ClientAPI . ClientResponse < void > > {
138+ const existingShowStyleBase = await ShowStyleBases . findOneAsync ( showStyleBaseId )
139+ if ( existingShowStyleBase ) {
140+ const rundowns = ( await Rundowns . findFetchAsync (
141+ { showStyleBaseId } ,
142+ { projection : { playlistId : 1 } }
143+ ) ) as Array < Pick < Rundown , 'playlistId' > >
144+ const playlists = ( await RundownPlaylists . findFetchAsync (
145+ { _id : { $in : rundowns . map ( ( r ) => r . playlistId ) } } ,
146+ {
147+ projection : {
148+ activationId : 1 ,
149+ } ,
150+ }
151+ ) ) as Array < Pick < DBRundownPlaylist , 'activationId' > >
152+ if ( playlists . some ( ( playlist ) => playlist . activationId !== undefined ) ) {
153+ throw new Meteor . Error (
154+ 412 ,
155+ `Cannot update ShowStyleBase ${ showStyleBaseId } as it is in use by an active Playlist`
156+ )
157+ }
158+ } else throw new Meteor . Error ( 404 , `ShowStyleBase ${ showStyleBaseId } not found` )
159+
160+ const apiShowStyleBase = await APIShowStyleBaseFrom ( existingShowStyleBase )
161+ apiShowStyleBase . config = config
162+
163+ const blueprintConfigValidation = await validateAPIBlueprintConfigForShowStyle (
164+ apiShowStyleBase ,
165+ protectString ( apiShowStyleBase . blueprintId )
166+ )
167+ checkValidation ( `updateShowStyleConfig ${ showStyleBaseId } ` , blueprintConfigValidation )
168+
169+ const showStyle = await showStyleBaseFrom ( apiShowStyleBase , showStyleBaseId )
170+ if ( ! showStyle ) throw new Meteor . Error ( 400 , `Invalid ShowStyleBase` )
171+
172+ await ShowStyleBases . upsertAsync ( showStyleBaseId , showStyle )
173+
174+ // wait for the upsert to complete before validation and upgrade read from the showStyleBases collection
175+ await new Promise < void > ( ( resolve ) => setTimeout ( ( ) => resolve ( ) , 200 ) )
176+
177+ const validation = await validateConfigForShowStyleBase ( showStyleBaseId )
178+ checkValidation ( `updateShowStyleConfig ${ showStyleBaseId } ` , validation . messages )
110179
111180 return ClientAPI . responseSuccess ( await runUpgradeForShowStyleBase ( showStyleBaseId ) )
112181 }
@@ -185,20 +254,26 @@ class ShowStylesServerAPI implements ShowStylesRestAPI {
185254 const variant = await ShowStyleVariants . findOneAsync ( showStyleVariantId )
186255 if ( ! variant ) throw new Meteor . Error ( 404 , `ShowStyleVariant ${ showStyleVariantId } not found` )
187256
188- return ClientAPI . responseSuccess ( APIShowStyleVariantFrom ( variant ) )
257+ return ClientAPI . responseSuccess ( await APIShowStyleVariantFrom ( showStyleBase , variant ) )
189258 }
190259
191260 async addOrUpdateShowStyleVariant (
192261 _connection : Meteor . Connection ,
193262 _event : string ,
194263 showStyleBaseId : ShowStyleBaseId ,
195264 showStyleVariantId : ShowStyleVariantId ,
196- showStyleVariant : APIShowStyleVariant
265+ apiShowStyleVariant : APIShowStyleVariant
197266 ) : Promise < ClientAPI . ClientResponse < void > > {
198267 const showStyleBase = await ShowStyleBases . findOneAsync ( showStyleBaseId )
199268 if ( ! showStyleBase ) throw new Meteor . Error ( 404 , `ShowStyleBase ${ showStyleBaseId } does not exist` )
200269
201- const showStyle = showStyleVariantFrom ( showStyleVariant , showStyleVariantId )
270+ const blueprintConfigValidation = await validateAPIBlueprintConfigForShowStyle (
271+ apiShowStyleVariant ,
272+ showStyleBase . blueprintId
273+ )
274+ checkValidation ( `addOrUpdateShowStyleVariant ${ showStyleVariantId } ` , blueprintConfigValidation )
275+
276+ const showStyle = showStyleVariantFrom ( apiShowStyleVariant , showStyleVariantId )
202277 if ( ! showStyle ) throw new Meteor . Error ( 400 , `Invalid ShowStyleVariant` )
203278
204279 const existingShowStyle = await ShowStyleVariants . findOneAsync ( showStyleVariantId )
@@ -335,6 +410,37 @@ export function registerRoutes(registerRoute: APIRegisterHook<ShowStylesRestAPI>
335410 }
336411 )
337412
413+ registerRoute < { showStyleBaseId : string } , never , object > (
414+ 'get' ,
415+ '/showstyles/:showStyleBaseId/config' ,
416+ new Map ( [ [ 404 , [ UserErrorMessage . ShowStyleBaseNotFound ] ] ] ) ,
417+ showStylesAPIFactory ,
418+ async ( serverAPI , connection , event , params , _ ) => {
419+ const showStyleBaseId = protectString < ShowStyleBaseId > ( params . showStyleBaseId )
420+ logger . info ( `API GET: ShowStyleBase config ${ showStyleBaseId } ` )
421+
422+ check ( showStyleBaseId , String )
423+ return await serverAPI . getShowStyleConfig ( connection , event , showStyleBaseId )
424+ }
425+ )
426+
427+ registerRoute < { showStyleBaseId : string } , object , void > (
428+ 'put' ,
429+ '/showstyles/:showStyleBaseId/config' ,
430+ new Map ( [
431+ [ 404 , [ UserErrorMessage . ShowStyleBaseNotFound ] ] ,
432+ [ 409 , [ UserErrorMessage . ValidationFailed ] ] ,
433+ ] ) ,
434+ showStylesAPIFactory ,
435+ async ( serverAPI , connection , event , params , body ) => {
436+ const showStyleBaseId = protectString < ShowStyleBaseId > ( params . showStyleBaseId )
437+ logger . info ( `API PUT: Update ShowStyleBase config ${ showStyleBaseId } ` )
438+
439+ check ( showStyleBaseId , String )
440+ return await serverAPI . updateShowStyleConfig ( connection , event , showStyleBaseId , body )
441+ }
442+ )
443+
338444 registerRoute < { showStyleBaseId : string } , never , void > (
339445 'delete' ,
340446 '/showstyles/:showStyleBaseId' ,
0 commit comments