2024-10-05 10:57:47 +00:00
|
|
|
const mongoose = require("mongoose");
|
|
|
|
const Schema = mongoose.Schema;
|
|
|
|
|
2024-10-14 13:50:47 +00:00
|
|
|
const express = require('express');
|
|
|
|
const router = express.Router();
|
|
|
|
|
2024-10-05 12:31:09 +00:00
|
|
|
/**
|
2024-10-05 17:27:28 +00:00
|
|
|
* Class for managing the backend api
|
|
|
|
* @hideconstructor
|
2024-10-05 12:31:09 +00:00
|
|
|
*/
|
2024-10-05 17:27:28 +00:00
|
|
|
class BackendApi {
|
|
|
|
#_plugin;
|
|
|
|
#_router;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This object is already created for you
|
|
|
|
* @param {plugin} Plugin instance
|
|
|
|
*/
|
|
|
|
constructor(plugin){
|
|
|
|
this.#_plugin = plugin;
|
2024-10-14 13:50:47 +00:00
|
|
|
this.#_router = new BackendRouter(`/plugin/${plugin.package}`);
|
2024-10-05 17:27:28 +00:00
|
|
|
}
|
2024-10-05 12:31:09 +00:00
|
|
|
|
2024-10-05 17:27:28 +00:00
|
|
|
/**
|
|
|
|
* Gets the router for your plugin
|
|
|
|
* @type {BackendRouter}
|
|
|
|
*/
|
|
|
|
get router(){
|
|
|
|
return this.#_router;
|
|
|
|
}
|
|
|
|
|
2024-10-14 13:50:47 +00:00
|
|
|
get _router(){
|
|
|
|
return router;
|
|
|
|
}
|
|
|
|
|
2024-10-05 17:27:28 +00:00
|
|
|
/**
|
|
|
|
* Returns a new database model for the plugin
|
|
|
|
* @param {String} name
|
|
|
|
* @param {Object} schema
|
2024-10-06 15:43:44 +00:00
|
|
|
* @returns {BackendModel}
|
|
|
|
* @example
|
|
|
|
* let itemModel = Api.createModel('Item', {
|
|
|
|
* name: {type: String, required: true, default: "New Item"},
|
|
|
|
* description: {type: String}
|
|
|
|
* type: {type: String, required: true, default: "Misc Item"},
|
|
|
|
* image: { type: String }
|
|
|
|
* });
|
2024-10-05 17:27:28 +00:00
|
|
|
*/
|
|
|
|
createModel(name, schema){
|
2024-10-14 13:50:47 +00:00
|
|
|
return new BackendModel(name, this.#_plugin.package, schema);
|
|
|
|
}
|
|
|
|
|
|
|
|
createModule(id){
|
|
|
|
return new BackendModule(this.#_plugin, id);
|
2024-10-05 17:27:28 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class registers routes to the backend that can be accessed from the frontend
|
|
|
|
* @hideconstructor
|
|
|
|
*/
|
|
|
|
class BackendRouter {
|
|
|
|
#_root;
|
|
|
|
|
|
|
|
constructor(path){
|
|
|
|
this.#_root = `plugins/${path}`;
|
2024-10-05 12:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hola
|
2024-10-05 17:27:28 +00:00
|
|
|
* @param {String} route
|
2024-10-05 12:31:09 +00:00
|
|
|
*/
|
2024-10-14 13:50:47 +00:00
|
|
|
get(route, callback){
|
|
|
|
router.get(this.#_root + route, callback);
|
2024-10-05 12:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {String} route
|
|
|
|
*
|
|
|
|
*/
|
2024-10-14 13:50:47 +00:00
|
|
|
post(route, callback){
|
|
|
|
router.post(this.#_root + route, callback);
|
2024-10-05 12:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {String} route
|
|
|
|
*
|
|
|
|
*/
|
2024-10-14 13:50:47 +00:00
|
|
|
put(route, callback){
|
|
|
|
router.put(this.#_root + route, callback);
|
2024-10-05 12:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {String} route
|
|
|
|
*
|
|
|
|
*/
|
2024-10-14 13:50:47 +00:00
|
|
|
delete(route, callback){
|
|
|
|
router.delete(this.#_root + route, callback);
|
2024-10-05 12:31:09 +00:00
|
|
|
}
|
2024-10-06 15:43:44 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates backend REST routes for the specified model. These routes are located
|
|
|
|
* relative to the plugin base route:
|
|
|
|
* - `/<plugin>/<model>` (POST) - Creates the element
|
|
|
|
* - `/<plugin>/<model>` (GET) - Gets a list with elements
|
|
|
|
* - `?id=<id>` return the document with that id
|
|
|
|
* - `?<paramName>=<paramValue>` returns all documents that match this criteria
|
|
|
|
* - `/<plugin>/<model>` (UPDATE) - Updates a element by id
|
|
|
|
* - `/<plugin>/<model>` (DELETE) - Deletes an element
|
|
|
|
* @param {BackendModel} model
|
|
|
|
*/
|
|
|
|
createModelRoutes(model, path){
|
|
|
|
|
|
|
|
}
|
2024-10-05 12:31:09 +00:00
|
|
|
}
|
|
|
|
|
2024-10-14 13:50:47 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-05 17:27:28 +00:00
|
|
|
/**
|
|
|
|
* @hideconstructor
|
|
|
|
*/
|
2024-10-05 23:36:18 +00:00
|
|
|
class BackendModel {
|
2024-10-05 17:27:28 +00:00
|
|
|
#_name;
|
2024-10-14 13:50:47 +00:00
|
|
|
#_prefix;
|
2024-10-05 17:27:28 +00:00
|
|
|
#_schema;
|
2024-10-14 13:50:47 +00:00
|
|
|
|
2024-10-06 15:43:44 +00:00
|
|
|
#_mongoSchema;
|
2024-10-05 10:57:47 +00:00
|
|
|
|
2024-10-14 13:50:47 +00:00
|
|
|
constructor(name, prefix, schema){
|
2024-10-05 17:27:28 +00:00
|
|
|
this.#_name = name;
|
2024-10-14 13:50:47 +00:00
|
|
|
this.#_prefix = prefix;
|
|
|
|
this.#_schema = ParseSchema(schema);
|
|
|
|
this.#_mongoSchema = mongoose.model(`${prefix}/${name}`, new Schema(schema));
|
2024-10-06 15:43:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds and returns a promise with the result of the query
|
|
|
|
* @param {Object} params
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*/
|
|
|
|
find(params){
|
|
|
|
return this.#_mongoSchema.find(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds one element and returns a promise with the result of the query
|
|
|
|
* @param {Object} params
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*/
|
|
|
|
findOne(params){
|
|
|
|
return this.#_mongoSchema.findOne(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds an element by id and returns a promise with the result of the query
|
|
|
|
* @param {String} id
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*/
|
|
|
|
findById(id){
|
|
|
|
return this.#_mongoSchema.findById(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an element given the data and returns a promise with the result of the operation
|
|
|
|
* @param {Object} data
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*/
|
|
|
|
create(data){
|
|
|
|
return this.#_mongoSchema.create(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates an element given the parameters with the given data and returns a promise with the result of the operation
|
|
|
|
* @param {Object} params
|
|
|
|
* @param {Object} data
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*/
|
|
|
|
updateOne(params, data){
|
|
|
|
return this.#_mongoSchema.updateOne(params, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates elements given the parameters with the given data and returns a promise with the result of the operation
|
|
|
|
* @param {Object} params
|
|
|
|
* @param {Object} data
|
|
|
|
* @returns {Promise<Object>}
|
|
|
|
*/
|
|
|
|
updateMany(params, data){
|
|
|
|
return this.#_mongoSchema.updateMany(params, data);
|
2024-10-05 10:57:47 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-10-14 13:50:47 +00:00
|
|
|
function ParseSchema(schema){
|
|
|
|
const typeTable = {
|
|
|
|
String: String,
|
|
|
|
Object: Object,
|
|
|
|
ObjectId: mongoose.Types.ObjectId,
|
|
|
|
Boolean: Boolean,
|
|
|
|
Date: Date,
|
|
|
|
};
|
|
|
|
|
|
|
|
let newSchema = structuredClone(schema);
|
2024-10-06 15:43:44 +00:00
|
|
|
|
2024-10-14 13:50:47 +00:00
|
|
|
// 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];
|
2024-10-06 15:43:44 +00:00
|
|
|
}
|
2024-10-14 13:50:47 +00:00
|
|
|
return newSchema;
|
2024-10-06 15:43:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-05 10:57:47 +00:00
|
|
|
module.exports = {
|
2024-10-05 17:27:28 +00:00
|
|
|
BackendApi
|
2024-10-05 10:57:47 +00:00
|
|
|
}
|