plugin.init

Massimo Melina committed Jan 17, 2022 at 14:59 UTC eda3465e4007af1c8dcf6bda99ba4c7463a917d5
3 files changed +25 -19
README.md
+16 -13
@@ -133,13 +133,15 @@ This file is javascript module that is supposed to expose one or more of the sup
133 To interrupt other middlewares on this http request, return `true`.
134 If you want to execute something in the "upstream" of middlewares, return a function.
135
136 -- `unload: () => void` callback called when unloading a plugin. This is a good place for example to clearInterval().
136 +- `unload: function` called when unloading a plugin. This is a good place for example to clearInterval().
137 - `onDirEntry: ({ entry: DirEntry, listPath: string }) => void | false` by providing this callback you can manipulate the record
138 that is sent to the frontend (`entry`), or you can return false to exclude this entry from the results.
139 +- `init: function` called when the plugin is initialized.
140 + If you need to use the `api` object immediately after the plugin is loaded, be sure to put your code in this callback.
141 - `api: object` if your plugin exports an empty object with name `api`, it will be filled with useful functions.
142 You'll just need this line
143 ```js
142 - const api = exports.api = {}
144 + exports.api = {}
145 ```
146 Now let's have a look at what you'll find inside.
147 - `getConfig(key: string): any` this is the way to go if you need some configuration to do your job.
@@ -152,17 +154,18 @@ This file is javascript module that is supposed to expose one or more of the sup
154 message: Hi there!
155 ```
156 Now you can use `api.getConfig('message')` to read it.
155 -
156 - Beware: `api` object is filled just after plugin initialization. So it will be empty if you use it right-away, but it will
157 - be good if you use it inside a callback. If you need to do something with it at the very start, then please make your code like this
158 - ```js
159 -
160 - setTimeout(() => { // delay execution just a bit
161 - console.log('getting my message correctly', api.getConfig('message')) // this is good
162 - })
163 - //console.log( api.getConfig('message') ) // this would fail because the api object is still empty
164 - ```
165 -
157 + - `srcDir: string` this can be useful if you need to import some extra function not available in `api`.
158 + ```js
159 + exports.api = {}
160 + exports.init = function() {
161 + const { BUILD_TIMESTAMP } = require(exports.api.srcDir + '/index')
162 + console.log(BUILD_TIMESTAMP)
163 + }
164 + ```
165 + You *should* try to keep this kind of behavior at its minimum, as name of sources and of elements in them are subject to change.
166 + If you need something for your plugin that's not covered by `api`, you can test it with this method,
167 + but you should then discuss it on the forum because an addition to `api` is your best option for making a future-proof plugin.
168 +
169 Each plug-in can have a `public` folder, and its files will be accessible at `/~/plugins/PLUGIN_NAME/FILENAME`.
170
171
package-lock.json
+1 -1
@@ -26,7 +26,7 @@
26 "yaml": "^2.0.0-10"
27 },
28 "bin": {
29 - "hfs": "dist/index.js"
29 + "hfs": "dist/src/index.js"
30 },
31 "devDependencies": {
32 "@types/archiver": "^5.1.1",
src/plugins.ts
+8 -5
@@ -140,11 +140,14 @@ async function rescan() {
140 const data = await import(f)
141 deleteModule(require.resolve(f)) // avoid caching
142 new Plugin(k, data, unwatch)
143 - if (data.api)
144 - Object.assign(data.api, {
145 - getConfig: (cfgKey: string) =>
146 - getConfig('plugins_config')?.[k]?.[cfgKey]
147 - })
143 + const { api } = data
144 + if (!api) return
145 + Object.assign(api, {
146 + srcDir: __dirname,
147 + getConfig: (cfgKey: string) =>
148 + getConfig('plugins_config')?.[k]?.[cfgKey]
149 + })
150 + await data.init?.call(api)
151 } catch (e) {
152 console.log('plugin error:', e)
153 }