diff --git a/backend/server.js b/backend/server.js index b1a02110..ecc8022c 100755 --- a/backend/server.js +++ b/backend/server.js @@ -73,8 +73,6 @@ app.use('/user', require('./routes/user')); checkAuth = passport.authenticate('jwt', {session: false}); app.use(checkAuth); -if(process.env.NODE_ENV != 'test') - pluginManager.init(); // ROUTES WITH AUTH app.use('/campaign', require('./routes/campaign')); @@ -83,9 +81,46 @@ app.use('/concept', require('./routes/concept')) app.use('/admin', require('./routes/admin')) // GET localhost:8081/concept/list +const pluginData = pluginManager.init(); +app.use('/', pluginData.router); + // SETUP IO require('./io/campaign')(socket.getIo()); + +// DEBUG ROUTER +function print (path, layer) { + if (layer.route) { + layer.route.stack.forEach(print.bind(null, path.concat(split(layer.route.path)))) + } else if (layer.name === 'router' && layer.handle.stack) { + layer.handle.stack.forEach(print.bind(null, path.concat(split(layer.regexp)))) + } else if (layer.method) { + console.log('%s /%s', + layer.method.toUpperCase(), + path.concat(split(layer.regexp)).filter(Boolean).join('/')) + } + } + + function split (thing) { + if (typeof thing === 'string') { + return thing.split('/') + } else if (thing.fast_slash) { + return '' + } else { + var match = thing.toString() + .replace('\\/?', '') + .replace('(?=\\/|$)', '$') + .match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//) + return match + ? match[1].replace(/\\(.)/g, '$1').split('/') + : '' + } + } + + app._router.stack.forEach(print.bind(null, [])) +// END DEBUG + + // LISTEN server.listen(PORT, () => { console.log("Dragonroll backend started"); diff --git a/backend/services/api.js b/backend/services/api.js index b2dee7fc..4a2796b5 100644 --- a/backend/services/api.js +++ b/backend/services/api.js @@ -1,6 +1,9 @@ const mongoose = require("mongoose"); const Schema = mongoose.Schema; +const express = require('express'); +const router = express.Router(); + /** * Class for managing the backend api * @hideconstructor @@ -15,7 +18,7 @@ class BackendApi { */ constructor(plugin){ this.#_plugin = plugin; - this.#_router = new BackendRouter(plugin.package); + this.#_router = new BackendRouter(`/plugin/${plugin.package}`); } /** @@ -26,6 +29,10 @@ class BackendApi { return this.#_router; } + get _router(){ + return router; + } + /** * Returns a new database model for the plugin * @param {String} name @@ -40,7 +47,11 @@ class BackendApi { * }); */ createModel(name, schema){ - return new BackendModel(name, this.#_plugin, schema); + return new BackendModel(name, this.#_plugin.package, schema); + } + + createModule(id){ + return new BackendModule(this.#_plugin, id); } }; @@ -59,32 +70,32 @@ class BackendRouter { * Hola * @param {String} route */ - get(route){ - + get(route, callback){ + router.get(this.#_root + route, callback); } /** * @param {String} route * */ - post(route){ - + post(route, callback){ + router.post(this.#_root + route, callback); } /** * @param {String} route * */ - put(route){ - + put(route, callback){ + router.put(this.#_root + route, callback); } /** * @param {String} route * */ - delete(route){ - + delete(route, callback){ + router.delete(this.#_root + route, callback); } /** @@ -103,20 +114,41 @@ class BackendRouter { } } +class BackendModule { + #_plugin; + #_id; + #_router; + + constructor(plugin, id){ + this.#_plugin = plugin; + this.#_id = id; + this.#_router = new BackendRouter(`/module/${plugin.package}/${id}`) + } + + get router(){ + return this.#_router; + } + + createModel(name, schema){ + return new BackendModel(name, `${this.#_plugin.package}/${this.#_id}`, schema); + } +} + /** * @hideconstructor */ class BackendModel { #_name; - #_plugin; + #_prefix; #_schema; + #_mongoSchema; - constructor(name, plugin, schema){ + constructor(name, prefix, schema){ this.#_name = name; - this.#_plugin = plugin; - this.#_schema = schema; - this.#_mongoSchema = mongoose.model(`${plugin}/${name}`, new Schema(schema)); + this.#_prefix = prefix; + this.#_schema = ParseSchema(schema); + this.#_mongoSchema = mongoose.model(`${prefix}/${name}`, new Schema(schema)); } /** @@ -176,19 +208,27 @@ class BackendModel { } }; -/** - * @hideconstructor - */ -class BackendModelDocument { - - - save(){ +function ParseSchema(schema){ + const typeTable = { + String: String, + Object: Object, + ObjectId: mongoose.Types.ObjectId, + Boolean: Boolean, + Date: Date, + }; + + let newSchema = structuredClone(schema); + // Codi molt guai + for(const key in newSchema){ + if(Array.isArray(newSchema[key].type)) + newSchema[key][0].type = [ typeTable[newSchema[key][0].type] ]; + else + newSchema[key].type = typeTable[newSchema[key].type]; } + return newSchema; } - - module.exports = { BackendApi } \ No newline at end of file diff --git a/backend/services/plugins.js b/backend/services/plugins.js index 64884c76..c311bab1 100644 --- a/backend/services/plugins.js +++ b/backend/services/plugins.js @@ -1,6 +1,8 @@ const fs = require('fs'); const path = require('path') const BackendApi = require('./api').BackendApi +const express = require('express'); +const router = express.Router(); const basePath = path.resolve(__dirname, '../') console.log(basePath) @@ -25,8 +27,16 @@ function init(){ // Execute main Object.keys(plugins).forEach(k => { - plugins[k].payload.Main(new BackendApi(plugins[k].info)) - }) + let pluginApi = new BackendApi(plugins[k].info); + plugins[k].payload.Main(pluginApi); + router.use(pluginApi._router); + }); + + + + return { + router + } } module.exports = { diff --git a/client/src/services/Api.js b/client/src/services/Api.js index 1e3c82e3..1ff24d28 100644 --- a/client/src/services/Api.js +++ b/client/src/services/Api.js @@ -24,7 +24,7 @@ class ClientApi { */ constructor(plugin){ this.#_plugin = plugin - this.#_router = new ClientRouter(plugin.package) + this.#_router = new ClientRouter(`/plugin/${plugin.package}`) this.#_windows = new ClientWindows(plugin.package) this.#_socket = new ClientSocket(plugin.package) } @@ -144,6 +144,8 @@ class ClientView { class ClientModule { #_plugin; #_id; + #_router; + #_title; #_description; #_version; @@ -153,13 +155,12 @@ class ClientModule { #_init; #_exit; - #_character_sheet; - #_item_sheet; - #_item_prompt; + constructor(plugin, id){ this.#_plugin = plugin; this.#_id = id; + this.#_router = new ClientRouter(`/module/${plugin.package}/${id}`); } /** @@ -196,34 +197,14 @@ class ClientModule { set exit(exit){ this.#_exit = exit; } - /** - * - * @param {ClientView} window - */ - setCharacterSheet(window){ - this.#_character_sheet = window; - } - - /** - * - * @param {ClientView} window - */ - setItemSheet(window){ - this.#_item_sheet = window; - } - - /** - * - * @param {ClientView} window - */ - setItemPrompt(window){ - this.#_item_prompt = window; - } - setButtons(buttons){ this.#_buttons = buttons; } + get router(){ + return this.#_router; + } + /** * Gets the module info in a json format * @returns {Object} @@ -236,11 +217,6 @@ class ClientModule { version: this.#_version, color: this.#_color, icon: this.#_icon, - windows: { - character_sheet: this.#_character_sheet, - item_sheet: this.#_item_sheet, - create_item_prompt: this.#_item_prompt, - }, init: this.#_init, exit: () => {}, buttons: this.#_buttons diff --git a/plugins/dnd-5e/backend/main.js b/plugins/dnd-5e/backend/main.js index 2b6e41a1..01c2ad69 100644 --- a/plugins/dnd-5e/backend/main.js +++ b/plugins/dnd-5e/backend/main.js @@ -1,6 +1,29 @@ // Entrypoint -function Main(Api){ +let Api; + +function Main(api){ + Api = api; + console.log("Hello World from backend!"); + + // Create our module in the backend. We only need the package name, it must be equal to the one that + // we made inside the client + let dndModule = Api.createModule('dnd-5e'); + + let itemModel = Api.createModel("item", { + name: { type: "String", required: true, default: "New Concept"}, + type: { type: "String", required: true, default: "Concept" }, + info: { type: "Object" }, // For preview only + data: { type: "Object" }, // Advanced item + book: { type: "ObjectId", ref: "Book"}, + campaign: { type: "ObjectId", ref: "Campaign"}, + }); + + dndModule.router.get('/test', (req, res) => { + console.log("FUNCIONA!!!!"); + }) + + // Api.router.createModelRoutes(itemModel, 'item'); } -export { Main }; \ No newline at end of file +export { Main, Api }; \ No newline at end of file