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