import { logger } from '@server/helpers/logger' import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PLAYLIST_PRIVACIES, VIDEO_PRIVACIES } from '@server/initializers/constants' import { ConstantManager } from '@shared/models/plugins/server/plugin-constant-manager.model' type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' type VideoConstant = Record type UpdatedVideoConstant = { [name in AlterableVideoConstant]: { [ npmName: string]: { added: VideoConstant[] deleted: VideoConstant[] } } } const constantsHash: { [key in AlterableVideoConstant]: VideoConstant } = { language: VIDEO_LANGUAGES, licence: VIDEO_LICENCES, category: VIDEO_CATEGORIES, privacy: VIDEO_PRIVACIES, playlistPrivacy: VIDEO_PLAYLIST_PRIVACIES } export class VideoConstantManagerFactory { private readonly updatedVideoConstants: UpdatedVideoConstant = { playlistPrivacy: { }, privacy: { }, language: { }, licence: { }, category: { } } constructor ( private readonly npmName: string ) {} public resetVideoConstants (npmName: string) { const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category', 'privacy', 'playlistPrivacy' ] for (const type of types) { this.resetConstants({ npmName, type }) } } private resetConstants (parameters: { npmName: string, type: AlterableVideoConstant }) { const { npmName, type } = parameters const updatedConstants = this.updatedVideoConstants[type][npmName] if (!updatedConstants) return for (const added of updatedConstants.added) { delete constantsHash[type][added.key] } for (const deleted of updatedConstants.deleted) { constantsHash[type][deleted.key] = deleted.label } delete this.updatedVideoConstants[type][npmName] } public createVideoConstantManager(type: AlterableVideoConstant): ConstantManager { const { npmName } = this return { addConstant: (key: K, label: string) => this.addConstant({ npmName, type, key, label }), deleteConstant: (key: K) => this.deleteConstant({ npmName, type, key }), getConstantValue: (key: K) => constantsHash[type][key], getConstants: () => constantsHash[type] as Record, resetConstants: () => this.resetConstants({ npmName, type }) } } private addConstant (parameters: { npmName: string type: AlterableVideoConstant key: T label: string }) { const { npmName, type, key, label } = parameters const obj = constantsHash[type] if (obj[key]) { logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key) return false } if (!this.updatedVideoConstants[type][npmName]) { this.updatedVideoConstants[type][npmName] = { added: [], deleted: [] } } this.updatedVideoConstants[type][npmName].added.push({ key: key, label } as VideoConstant) obj[key] = label return true } private deleteConstant (parameters: { npmName: string type: AlterableVideoConstant key: T }) { const { npmName, type, key } = parameters const obj = constantsHash[type] if (!obj[key]) { logger.warn('Cannot delete %s by plugin %s: key %s does not exist.', type, npmName, key) return false } if (!this.updatedVideoConstants[type][npmName]) { this.updatedVideoConstants[type][npmName] = { added: [], deleted: [] } } const updatedConstants = this.updatedVideoConstants[type][npmName] const alreadyAdded = updatedConstants.added.find(a => a.key === key) if (alreadyAdded) { updatedConstants.added.filter(a => a.key !== key) } else if (obj[key]) { updatedConstants.deleted.push({ key, label: obj[key] } as VideoConstant) } delete obj[key] return true } }