feat: add modular plugin system and documentation
This commit is contained in:
@@ -88,6 +88,49 @@ function findFFprobe() {
|
|||||||
app.locals.ffmpegPath = findFFmpeg();
|
app.locals.ffmpegPath = findFFmpeg();
|
||||||
app.locals.ffprobePath = findFFprobe();
|
app.locals.ffprobePath = findFFprobe();
|
||||||
|
|
||||||
|
// Dynamic services loader - collects exports from files in ./services
|
||||||
|
const fs = require('fs');
|
||||||
|
const services = {};
|
||||||
|
try {
|
||||||
|
const servicesDir = path.join(__dirname, 'services');
|
||||||
|
const serviceFiles = fs.readdirSync(servicesDir).filter(f => f.endsWith('.js'));
|
||||||
|
for (const file of serviceFiles) {
|
||||||
|
const name = file.replace(/\.js$/, '');
|
||||||
|
try {
|
||||||
|
services[name] = require(path.join(servicesDir, file));
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Failed to load service ${file}:`, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('No services directory found or failed to read services:', e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugin loader: loads any .js file inside server/plugins and calls the
|
||||||
|
// exported function with (app, services).
|
||||||
|
try {
|
||||||
|
const pluginsDir = path.join(__dirname, 'plugins');
|
||||||
|
if (fs.existsSync(pluginsDir)) {
|
||||||
|
const pluginFiles = fs.readdirSync(pluginsDir).filter(f => f.endsWith('.js'));
|
||||||
|
for (const file of pluginFiles) {
|
||||||
|
const pluginPath = path.join(pluginsDir, file);
|
||||||
|
try {
|
||||||
|
const plugin = require(pluginPath);
|
||||||
|
if (typeof plugin === 'function') {
|
||||||
|
plugin(app, services);
|
||||||
|
console.log(`Loaded plugin: ${file}`);
|
||||||
|
} else {
|
||||||
|
console.warn(`Plugin ${file} does not export a function, skipping.`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to load plugin ${file}:`, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Plugin loader failed:', err.message);
|
||||||
|
}
|
||||||
|
|
||||||
// API Routes
|
// API Routes
|
||||||
app.use('/api/auth', require('./routes/auth'));
|
app.use('/api/auth', require('./routes/auth'));
|
||||||
app.use('/api/sources', require('./routes/sources'));
|
app.use('/api/sources', require('./routes/sources'));
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# 🔌 NodeCast TV Plugin System
|
||||||
|
|
||||||
|
This directory allows you to extend the functionality of **NodeCast TV** without modifying the core source code. The server automatically detects and loads any `.js` file placed in this folder at startup.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ How It Works
|
||||||
|
|
||||||
|
The plugin loader in `server/index.js` scans this directory and expects each file to export a **initialization function**.
|
||||||
|
|
||||||
|
When the server starts, it calls this function and passes the internal Express instance and the loaded services.
|
||||||
|
|
||||||
|
### Plugin Signature
|
||||||
|
Each plugin must follow this structure:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* @param {Object} app - The Express application instance
|
||||||
|
* @param {Object} services - Object containing all internal services (db, syncService, etc.)
|
||||||
|
*/
|
||||||
|
module.exports = function(app, services) {
|
||||||
|
// Your logic here
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = function(app, services) {
|
||||||
|
console.log("🚀 Plugin 'Hello' activé !");
|
||||||
|
|
||||||
|
//route de test accessible sur http://localhost:3000/api/hello
|
||||||
|
app.get('/api/hello', (req, res) => {
|
||||||
|
res.json({ message: "Le système de plugin fonctionne !" });
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user