From 9fa6ca160a9dda057c3980c6ee19f0ee426fd0a0 Mon Sep 17 00:00:00 2001
From: Chocobozzz <me@florianbigard.com>
Date: Wed, 17 Jul 2019 15:46:51 +0200
Subject: [PATCH] Some plugins fixes and doc enhancements

---
 client/src/app/core/plugins/plugin.service.ts | 11 ++++++--
 server/initializers/constants.ts              |  2 +-
 server/lib/plugins/plugin-manager.ts          | 12 ++++----
 server/models/server/plugin.ts                |  9 ++++++
 shared/models/plugins/plugin-library.model.ts |  2 +-
 support/doc/plugins/quickstart.md             | 28 ++++++++++++-------
 6 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts
index 525740a01..af330c2eb 100644
--- a/client/src/app/core/plugins/plugin.service.ts
+++ b/client/src/app/core/plugins/plugin.service.ts
@@ -125,8 +125,15 @@ export class PluginService {
 
     for (const hook of this.hooks[hookName]) {
       try {
-        if (wait) result = await hook.handler(param)
-        else result = hook.handler()
+        const p = hook.handler(param)
+
+        if (wait) {
+          result = await p
+        } else if (p.catch) {
+          p.catch((err: Error) => {
+            console.error('Cannot run hook %s of script %s of plugin %s.', hookName, hook.plugin, hook.clientScript, err)
+          })
+        }
       } catch (err) {
         console.error('Cannot run hook %s of script %s of plugin %s.', hookName, hook.plugin, hook.clientScript, err)
       }
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 93ccb7da8..1111fd97f 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -19,7 +19,7 @@ const LAST_MIGRATION_VERSION = 400
 // ---------------------------------------------------------------------------
 
 const API_VERSION = 'v1'
-const PEERTUBE_VERSION = process.env.npm_package_version || 'unknown'
+const PEERTUBE_VERSION = require(join(root(), 'package.json')).version
 
 const PAGINATION = {
   COUNT: {
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index 9e4ec5adf..570b56193 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -104,10 +104,12 @@ export class PluginManager {
 
     for (const hook of this.hooks[hookName]) {
       try {
+        const p = hook.handler(param)
+
         if (wait) {
-          result = await hook.handler(param)
-        } else {
-          result = hook.handler()
+          result = await p
+        } else if (p.catch) {
+          p.catch(err => logger.warn('Hook %s of plugin %s thrown an error.', hookName, hook.pluginName, { err }))
         }
       } catch (err) {
         logger.error('Cannot run hook %s of plugin %s.', hookName, hook.pluginName, { err })
@@ -329,7 +331,7 @@ export class PluginManager {
       registerSetting,
       settingsManager,
       storageManager
-    })
+    }).catch(err => logger.error('Cannot register plugin %s.', npmName, { err }))
 
     logger.info('Add plugin %s CSS to global file.', npmName)
 
@@ -365,7 +367,7 @@ export class PluginManager {
   private async regeneratePluginGlobalCSS () {
     await this.resetCSSGlobalFile()
 
-    for (const key of Object.keys(this.registeredPlugins)) {
+    for (const key of Object.keys(this.getRegisteredPlugins())) {
       const plugin = this.registeredPlugins[key]
 
       await this.addCSSToGlobalFile(plugin.path, plugin.css)
diff --git a/server/models/server/plugin.ts b/server/models/server/plugin.ts
index 50963ba57..f39b97ef0 100644
--- a/server/models/server/plugin.ts
+++ b/server/models/server/plugin.ts
@@ -156,6 +156,15 @@ export class PluginModel extends Model<PluginModel> {
     return PluginModel.findOne(query)
       .then((c: any) => {
         if (!c) return undefined
+        const value = c.value
+
+        if (typeof value === 'string' && value.startsWith('{')) {
+          try {
+            return JSON.parse(value)
+          } catch {
+            return value
+          }
+        }
 
         return c.value
       })
diff --git a/shared/models/plugins/plugin-library.model.ts b/shared/models/plugins/plugin-library.model.ts
index df6499b6b..fd90a3b46 100644
--- a/shared/models/plugins/plugin-library.model.ts
+++ b/shared/models/plugins/plugin-library.model.ts
@@ -1,7 +1,7 @@
 import { RegisterOptions } from './register-options.model'
 
 export interface PluginLibrary {
-  register: (options: RegisterOptions) => void
+  register: (options: RegisterOptions) => Promise<any>
 
   unregister: () => Promise<any>
 }
diff --git a/support/doc/plugins/quickstart.md b/support/doc/plugins/quickstart.md
index a018aa50a..0e125e707 100644
--- a/support/doc/plugins/quickstart.md
+++ b/support/doc/plugins/quickstart.md
@@ -18,10 +18,13 @@ A plugin registers functions in JavaScript to execute when PeerTube (server and
 Example:
 
 ```js
-registerHook({
-  target: 'action:application.listening',
-  handler: () => displayHelloWorld()
-})
+// This register function is called by PeerTube, and **must** return a promise
+async function register ({ registerHook }) {
+  registerHook({
+    target: 'action:application.listening',
+    handler: () => displayHelloWorld()
+  })
+}
 ```
 
 On server side, these hooks are registered by the `library` file defined in `package.json`.
@@ -65,9 +68,7 @@ or `/themes/{theme-name}/{theme-version}/static/` routes.
 
 Plugins can declare CSS files that PeerTube will automatically inject in the client.
 
-### Server helpers
-
-**Only for plugins**
+### Server helpers (only for plugins)
 
 #### Settings
 
@@ -94,7 +95,7 @@ Example:
 
 ```js
 const value = await storageManager.getData('mykey')
-await storageManager.storeData('mykey', 'myvalue')
+await storageManager.storeData('mykey', { subkey: 'value' })
 ```
 
 ### Publishing
@@ -169,12 +170,13 @@ If you don't need static directories, use an empty `object`:
 }
 ```
 
-And if you don't need CSS files, use an empty `array`:
+And if you don't need CSS or client script files, use an empty `array`:
 
 ```json
 {
   ...,
   "css": [],
+  "clientScripts": [],
   ...
 }
 ```
@@ -196,9 +198,15 @@ You'll need to have a local PeerTube instance:
 
 ```
 $ npm run build -- --light
+```
+
+ * Build the CLI:
+ 
+```
+$ npm run setup:cli
 ```
  
- * Run it  (you can access to your instance on http://localhost:9000): 
+ * Run PeerTube (you can access to your instance on http://localhost:9000): 
 
 ```
 $ NODE_ENV=test npm start
-- 
2.25.1