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