]>
Commit | Line | Data |
---|---|---|
1 | import { RegisterClientHelpers } from 'src/types/register-client-option.model' | |
2 | import { getHookType, internalRunHook } from '@shared/core-utils/plugins/hooks' | |
3 | import { | |
4 | ClientHookName, | |
5 | clientHookObject, | |
6 | ClientScript, | |
7 | PluginType, | |
8 | RegisterClientFormFieldOptions, | |
9 | RegisterClientHookOptions, | |
10 | RegisterClientSettingsScript, | |
11 | RegisterClientVideoFieldOptions, | |
12 | ServerConfigPlugin | |
13 | } from '../../../shared/models' | |
14 | import { ClientScript as ClientScriptModule } from '../types/client-script.model' | |
15 | import { importModule } from './utils' | |
16 | ||
17 | interface HookStructValue extends RegisterClientHookOptions { | |
18 | plugin: ServerConfigPlugin | |
19 | clientScript: ClientScript | |
20 | } | |
21 | ||
22 | type Hooks = { [ name: string ]: HookStructValue[] } | |
23 | ||
24 | type PluginInfo = { | |
25 | plugin: ServerConfigPlugin | |
26 | clientScript: ClientScript | |
27 | pluginType: PluginType | |
28 | isTheme: boolean | |
29 | } | |
30 | ||
31 | type FormFields = { | |
32 | video: { | |
33 | commonOptions: RegisterClientFormFieldOptions | |
34 | videoFormOptions: RegisterClientVideoFieldOptions | |
35 | }[] | |
36 | } | |
37 | ||
38 | async function runHook<T> (hooks: Hooks, hookName: ClientHookName, result?: T, params?: any) { | |
39 | if (!hooks[hookName]) return result | |
40 | ||
41 | const hookType = getHookType(hookName) | |
42 | ||
43 | for (const hook of hooks[hookName]) { | |
44 | console.log('Running hook %s of plugin %s.', hookName, hook.plugin.name) | |
45 | ||
46 | result = await internalRunHook(hook.handler, hookType, result, params, err => { | |
47 | console.error('Cannot run hook %s of script %s of plugin %s.', hookName, hook.clientScript.script, hook.plugin.name, err) | |
48 | }) | |
49 | } | |
50 | ||
51 | return result | |
52 | } | |
53 | ||
54 | function loadPlugin (options: { | |
55 | hooks: Hooks | |
56 | pluginInfo: PluginInfo | |
57 | peertubeHelpersFactory: (pluginInfo: PluginInfo) => RegisterClientHelpers | |
58 | formFields?: FormFields | |
59 | onSettingsScripts?: (options: RegisterClientSettingsScript) => void | |
60 | }) { | |
61 | const { hooks, pluginInfo, peertubeHelpersFactory, formFields, onSettingsScripts } = options | |
62 | const { plugin, clientScript } = pluginInfo | |
63 | ||
64 | const registerHook = (options: RegisterClientHookOptions) => { | |
65 | if (clientHookObject[options.target] !== true) { | |
66 | console.error('Unknown hook %s of plugin %s. Skipping.', options.target, plugin.name) | |
67 | return | |
68 | } | |
69 | ||
70 | if (!hooks[options.target]) hooks[options.target] = [] | |
71 | ||
72 | hooks[options.target].push({ | |
73 | plugin, | |
74 | clientScript, | |
75 | target: options.target, | |
76 | handler: options.handler, | |
77 | priority: options.priority || 0 | |
78 | }) | |
79 | } | |
80 | ||
81 | const registerVideoField = (commonOptions: RegisterClientFormFieldOptions, videoFormOptions: RegisterClientVideoFieldOptions) => { | |
82 | if (!formFields) { | |
83 | throw new Error('Video field registration is not supported') | |
84 | } | |
85 | ||
86 | formFields.video.push({ | |
87 | commonOptions, | |
88 | videoFormOptions | |
89 | }) | |
90 | } | |
91 | ||
92 | const registerSettingsScript = (options: RegisterClientSettingsScript) => { | |
93 | if (!onSettingsScripts) { | |
94 | throw new Error('Registering settings script is not supported') | |
95 | } | |
96 | ||
97 | return onSettingsScripts(options) | |
98 | } | |
99 | ||
100 | const peertubeHelpers = peertubeHelpersFactory(pluginInfo) | |
101 | ||
102 | console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name) | |
103 | ||
104 | return importModule(clientScript.script) | |
105 | .then((script: ClientScriptModule) => script.register({ registerHook, registerVideoField, registerSettingsScript, peertubeHelpers })) | |
106 | .then(() => sortHooksByPriority(hooks)) | |
107 | .catch(err => console.error('Cannot import or register plugin %s.', pluginInfo.plugin.name, err)) | |
108 | } | |
109 | ||
110 | export { | |
111 | HookStructValue, | |
112 | Hooks, | |
113 | PluginInfo, | |
114 | FormFields, | |
115 | loadPlugin, | |
116 | runHook | |
117 | } | |
118 | ||
119 | function sortHooksByPriority (hooks: Hooks) { | |
120 | for (const hookName of Object.keys(hooks)) { | |
121 | hooks[hookName].sort((a, b) => { | |
122 | return b.priority - a.priority | |
123 | }) | |
124 | } | |
125 | } |