Backend dynamic routing
Some checks failed
test / run-tests-client (push) Successful in 43s
test / run-tests-backend (push) Failing after 15s

This commit is contained in:
BinarySandia04 2024-10-14 15:50:47 +02:00
parent c6e07e7b41
commit d005aa3cc1
5 changed files with 147 additions and 63 deletions

View File

@ -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('/')
: '<complex:' + thing.toString() + '>'
}
}
app._router.stack.forEach(print.bind(null, []))
// END DEBUG
// LISTEN
server.listen(PORT, () => {
console.log("Dragonroll backend started");

View File

@ -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 {
function ParseSchema(schema){
const typeTable = {
String: String,
Object: Object,
ObjectId: mongoose.Types.ObjectId,
Boolean: Boolean,
Date: Date,
};
let newSchema = structuredClone(schema);
save(){
// 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
}

View File

@ -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 = {

View File

@ -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

View File

@ -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 };
export { Main, Api };