-import decache from 'decache'
-import * as express from 'express'
+import express from 'express'
import { createReadStream, createWriteStream } from 'fs'
-import { outputFile, readJSON } from 'fs-extra'
+import { ensureDir, outputFile, readJSON } from 'fs-extra'
import { basename, join } from 'path'
+import { decachePlugin } from '@server/helpers/decache'
import { MOAuthTokenUser, MUser } from '@server/types/models'
-import { RegisterServerHookOptions } from '@shared/models/plugins/register-server-hook.model'
-import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks'
+import { getCompleteLocale } from '@shared/core-utils'
import {
- ClientScript,
- PluginPackageJson,
- PluginTranslationPaths as PackagePluginTranslations
-} from '../../../shared/models/plugins/plugin-package-json.model'
-import { PluginTranslation } from '../../../shared/models/plugins/plugin-translation.model'
+ ClientScriptJSON,
+ PluginPackageJSON,
+ PluginTranslation,
+ PluginTranslationPathsJSON,
+ RegisterServerHookOptions
+} from '@shared/models'
+import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks'
import { PluginType } from '../../../shared/models/plugins/plugin.type'
-import { ServerHook, ServerHookName } from '../../../shared/models/plugins/server-hook.model'
+import { ServerHook, ServerHookName } from '../../../shared/models/plugins/server/server-hook.model'
import { isLibraryCodeValid, isPackageJSONValid } from '../../helpers/custom-validators/plugins'
import { logger } from '../../helpers/logger'
import { CONFIG } from '../../initializers/config'
path: string
staticDirs: { [name: string]: string }
- clientScripts: { [name: string]: ClientScript }
+ clientScripts: { [name: string]: ClientScriptJSON }
css: string[]
logger.info('Regenerating registered plugin CSS to global file.')
await this.regeneratePluginGlobalCSS()
}
+
+ ClientHtml.invalidCache()
}
// ###################### Installation ######################
uninstalled: false,
peertubeEngine: packageJSON.engine.peertube
}, { returning: true })
- } catch (err) {
- logger.error('Cannot install plugin %s, removing it...', toInstall, { err })
+
+ logger.info('Successful installation of plugin %s.', toInstall)
+
+ await this.registerPluginOrTheme(plugin)
+ } catch (rootErr) {
+ logger.error('Cannot install plugin %s, removing it...', toInstall, { err: rootErr })
try {
- await removeNpmPlugin(npmName)
+ await this.uninstall(npmName)
} catch (err) {
- logger.error('Cannot remove plugin %s after failed installation.', toInstall, { err })
+ logger.error('Cannot uninstall plugin %s after failed installation.', toInstall, { err })
+
+ try {
+ await removeNpmPlugin(npmName)
+ } catch (err) {
+ logger.error('Cannot remove plugin %s after failed installation.', toInstall, { err })
+ }
}
- throw err
+ throw rootErr
}
- logger.info('Successful installation of plugin %s.', toInstall)
-
- await this.registerPluginOrTheme(plugin)
-
return plugin
}
registerHelpers = result.registerStore
}
- const clientScripts: { [id: string]: ClientScript } = {}
+ const clientScripts: { [id: string]: ClientScriptJSON } = {}
for (const c of packageJSON.clientScripts) {
clientScripts[c.script] = c
}
}
await this.addTranslations(plugin, npmName, packageJSON.translations)
+
+ ClientHtml.invalidCache()
}
- private async registerPlugin (plugin: PluginModel, pluginPath: string, packageJSON: PluginPackageJson) {
+ private async registerPlugin (plugin: PluginModel, pluginPath: string, packageJSON: PluginPackageJSON) {
const npmName = PluginModel.buildNpmName(plugin.name, plugin.type)
// Delete cache if needed
const modulePath = join(pluginPath, packageJSON.library)
- decache(modulePath)
+ decachePlugin(pluginPath, modulePath)
const library: PluginLibrary = require(modulePath)
if (!isLibraryCodeValid(library)) {
}
const { registerOptions, registerStore } = this.getRegisterHelpers(npmName, plugin)
- library.register(registerOptions)
- .catch(err => logger.error('Cannot register plugin %s.', npmName, { err }))
+
+ await ensureDir(registerOptions.peertubeHelpers.plugin.getDataDirectoryPath())
+
+ await library.register(registerOptions)
logger.info('Add plugin %s CSS to global file.', npmName)
// ###################### Translations ######################
- private async addTranslations (plugin: PluginModel, npmName: string, translationPaths: PackagePluginTranslations) {
+ private async addTranslations (plugin: PluginModel, npmName: string, translationPaths: PluginTranslationPathsJSON) {
for (const locale of Object.keys(translationPaths)) {
const path = translationPaths[locale]
const json = await readJSON(join(this.getPluginPath(plugin.name, plugin.type), path))
- if (!this.translations[locale]) this.translations[locale] = {}
- this.translations[locale][npmName] = json
+ const completeLocale = getCompleteLocale(locale)
- logger.info('Added locale %s of plugin %s.', locale, npmName)
+ if (!this.translations[completeLocale]) this.translations[completeLocale] = {}
+ this.translations[completeLocale][npmName] = json
+
+ logger.info('Added locale %s of plugin %s.', completeLocale, npmName)
}
}
// ###################### CSS ######################
private resetCSSGlobalFile () {
- ClientHtml.invalidCache()
-
return outputFile(PLUGIN_GLOBAL_CSS_PATH, '')
}
for (const cssPath of cssRelativePaths) {
await this.concatFiles(join(pluginPath, cssPath), PLUGIN_GLOBAL_CSS_PATH)
}
-
- ClientHtml.invalidCache()
}
private concatFiles (input: string, output: string) {
private getPackageJSON (pluginName: string, pluginType: PluginType) {
const pluginPath = join(this.getPluginPath(pluginName, pluginType), 'package.json')
- return readJSON(pluginPath) as Promise<PluginPackageJson>
+ return readJSON(pluginPath) as Promise<PluginPackageJSON>
}
private getPluginPath (pluginName: string, pluginType: PluginType) {
}
}
- private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) {
+ private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJSON, pluginType: PluginType) {
if (!packageJSON.staticDirs) packageJSON.staticDirs = {}
if (!packageJSON.css) packageJSON.css = []
if (!packageJSON.clientScripts) packageJSON.clientScripts = []