annotations
This commit is contained in:
+116
-1
@@ -2,7 +2,7 @@ import path, { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
/**
|
||||
* Main backend application
|
||||
* Main backend application class
|
||||
*/
|
||||
class App{
|
||||
constructor(){
|
||||
@@ -73,4 +73,119 @@ class App{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The following are pseudo in order to keep documentation aligned to the code */
|
||||
|
||||
/**
|
||||
* The core application plugins
|
||||
*/
|
||||
class AppCore{
|
||||
/**
|
||||
* The configuration plugin instance
|
||||
* @type Config
|
||||
*/
|
||||
config = undefined;
|
||||
|
||||
/**
|
||||
* The database plugin instance
|
||||
* @type Db
|
||||
*/
|
||||
db = undefined;
|
||||
|
||||
/**
|
||||
* The web server plugin instance
|
||||
* @type WebServer
|
||||
*/
|
||||
webServer = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main logical part application plugins
|
||||
*/
|
||||
class AppManagement {
|
||||
|
||||
/**
|
||||
* Game objects manager plugin instance
|
||||
* @type GameObjectsManager
|
||||
*/
|
||||
gameObject = undefined;
|
||||
|
||||
/**
|
||||
* Games manager plugin instance
|
||||
* @type GamesManager
|
||||
*/
|
||||
games = undefined;
|
||||
|
||||
/**
|
||||
* Rules manager plugin instance
|
||||
* @type RulesManager
|
||||
*/
|
||||
rules = undefined;
|
||||
|
||||
/**
|
||||
* Scenarios manager plugin instance
|
||||
* @type ScenariosManager
|
||||
*/
|
||||
scenarios = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main application controller plugin instances
|
||||
*/
|
||||
class AppControllerApi {
|
||||
|
||||
/**
|
||||
* Game objects controller plugin instance
|
||||
* @type GameObjectsController
|
||||
*/
|
||||
gameObjectsApi = undefined;
|
||||
|
||||
/**
|
||||
* Games controller plugin instance
|
||||
* @type GamesController
|
||||
*/
|
||||
gamesApi = undefined;
|
||||
|
||||
/**
|
||||
* Rules controller plugin instance
|
||||
* @type RulesController
|
||||
*/
|
||||
rulesApi = undefined;
|
||||
|
||||
/**
|
||||
* Scenarios controller plugin instance
|
||||
* @type ScenariosController
|
||||
*/
|
||||
scenariosApi = undefined;
|
||||
|
||||
/**
|
||||
* Asset controller plugin instance
|
||||
* @type AssetController
|
||||
*/
|
||||
assetApi = undefined;
|
||||
}
|
||||
|
||||
class AppConcrete {
|
||||
/**
|
||||
* Application core plugins
|
||||
* @type AppCore
|
||||
* @memberof App
|
||||
*/
|
||||
core = undefined;
|
||||
|
||||
/**
|
||||
* Application management plugins
|
||||
* @type AppManagement
|
||||
* @memberof App
|
||||
*/
|
||||
management = undefined;
|
||||
|
||||
/**
|
||||
* Application controller API plugins
|
||||
* @type AppControllerApi
|
||||
* @memberof App
|
||||
*/
|
||||
controller = undefined
|
||||
}
|
||||
|
||||
export default App;
|
||||
+86
-3
@@ -6,16 +6,40 @@ import path from 'path'
|
||||
class Config{
|
||||
name = 'config';
|
||||
|
||||
/**
|
||||
* @class File system options , repository setup
|
||||
* @alias FileSystemOptions
|
||||
* @memberof Config
|
||||
*/
|
||||
fs = {
|
||||
/** Repository path
|
||||
* @type {string}
|
||||
* @memberof FileSystemOptions
|
||||
*/
|
||||
repo: null
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Database options
|
||||
* @alias DatabaseOptions
|
||||
* @memberof Config
|
||||
*/
|
||||
db = {
|
||||
/** Database name
|
||||
* @type {string}
|
||||
* @memberof DatabaseOptions
|
||||
*/
|
||||
name:'pronature',
|
||||
|
||||
/** Database connection string
|
||||
* @type {string}
|
||||
* @memberof DatabaseOptions
|
||||
*/
|
||||
url: "mongodb://127.0.0.1:27017/pronature"
|
||||
}
|
||||
|
||||
/**
|
||||
* @class web site options
|
||||
* @class Web site endpoint options
|
||||
* @alias SiteOptions
|
||||
* @memberof Config
|
||||
*/
|
||||
@@ -25,38 +49,97 @@ class Config{
|
||||
* @memberof SiteOptions
|
||||
*/
|
||||
host:'https://localhost:5173',
|
||||
|
||||
/** Whether to use SSL
|
||||
* @type {boolean}
|
||||
* @memberof SiteOptions
|
||||
*/
|
||||
ssl: true,
|
||||
|
||||
/** Port to use
|
||||
* @type {Number}
|
||||
* @memberof SiteOptions
|
||||
*/
|
||||
port: 3000,
|
||||
|
||||
/**
|
||||
* @class certificate data
|
||||
* @class Certificate data
|
||||
* @alias CertificateOptions
|
||||
* @memberof SiteOptions
|
||||
*/
|
||||
certificate: {
|
||||
/**
|
||||
* Certificate key
|
||||
* Certificate private key
|
||||
* @type {string}
|
||||
* @memberof CertificateOptions
|
||||
*/
|
||||
key: './.cert/dev-key.pem',
|
||||
|
||||
/**
|
||||
* Certificate public key
|
||||
* @type {string}
|
||||
* @memberof CertificateOptions
|
||||
*/
|
||||
cert: './.cert/dev-cert.pem',
|
||||
|
||||
/**
|
||||
* PK Passphrase
|
||||
* @type {string}
|
||||
* @memberof CertificateOptions
|
||||
*/
|
||||
passphrase: 'parola'
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Access management options
|
||||
* @alias AccessManagementOptions
|
||||
* @memberof Config
|
||||
*/
|
||||
am = {
|
||||
/**
|
||||
* Salt, a string to be used in order to make a more complex password hash
|
||||
* @type {string}
|
||||
* @memberof AccessManagementOptions
|
||||
*/
|
||||
salt : 'P@ssSal7y!!',
|
||||
|
||||
/**
|
||||
* @class Cookie options
|
||||
* @alias CookieOptions
|
||||
* @memberof AccessManagementOptions
|
||||
*/
|
||||
cookie: {
|
||||
/**
|
||||
* Cookie secret
|
||||
* @type {string}
|
||||
* @memberof CookieOptions
|
||||
*/
|
||||
secret: 'S3cret4C00k!ie$',
|
||||
|
||||
/**
|
||||
* Cookie max age (in seconds)
|
||||
* @type {Number}
|
||||
* @memberof CookieOptions
|
||||
*/
|
||||
maxAge: 1000 * 60 * 60 * 24 * 7
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the configuration
|
||||
* @param {App} app The application
|
||||
*/
|
||||
async init(app){
|
||||
if (!this.fs.repo){
|
||||
this.fs.repo = path.resolve(`${app.root}/repo`) + '/';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the configuration plugin
|
||||
* @param {App} app the application instance
|
||||
*/
|
||||
async start(app){
|
||||
|
||||
}
|
||||
|
||||
+63
-21
@@ -8,10 +8,19 @@ let dbo;
|
||||
*/
|
||||
class Db {
|
||||
name = 'db';
|
||||
|
||||
/**
|
||||
* Initializes the database plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
init(app){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the database plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
async start(app){
|
||||
db = await MongoClient.connect(app.config.db.url, {maxPoolSize: 256});
|
||||
try {
|
||||
@@ -74,6 +83,12 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a database aggregation according to a given pipeline
|
||||
* @param {string} collection Database collection name
|
||||
* @param {Object} specs aggregation definition (the pipeline)
|
||||
* @returns {Object[]} Array of records
|
||||
*/
|
||||
async aggregate(collection, specs){
|
||||
try {
|
||||
let cursor = dbo.collection(collection);
|
||||
@@ -84,6 +99,13 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the distinct values for a specified field across a single collection
|
||||
* @param {string} collection Database collection name
|
||||
* @param {Object} key The target field for the distinction
|
||||
* @param {Object} query filter to be applied
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
async distinct(collection, key, query){
|
||||
try {
|
||||
return await dbo.collection(collection).distinct(key, query);
|
||||
@@ -91,6 +113,13 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a record in database by given key and value
|
||||
* @param {Object} collection DB collection
|
||||
* @param {Object} key The key/query which identifies the record to be updated
|
||||
* @param {Object} value The new value for the record
|
||||
* @returns {Object} The result from the update operation
|
||||
*/
|
||||
async update(collection, key, value){
|
||||
let r;
|
||||
try {
|
||||
@@ -101,6 +130,13 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs partial update on a record by given key and partial value
|
||||
* @param {Object} collection Database collection
|
||||
* @param {Object} key The key/query which identifies the record to be updated
|
||||
* @param {Object} value The partial value to be updated
|
||||
* @returns {Object} The result from the update operation
|
||||
*/
|
||||
async updateSet(collection, key, value){
|
||||
let r;
|
||||
try {
|
||||
@@ -110,6 +146,11 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a record from the database by given key
|
||||
* @param {Object} collection Database collection
|
||||
* @param {Object} key The key/query which identifies the record to be updated
|
||||
*/
|
||||
async remove(collection, key){
|
||||
try {
|
||||
await dbo.collection(collection).deleteMany(key);
|
||||
@@ -117,27 +158,28 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
convertToObjectId(object, key, recursive, result){
|
||||
if (object && object[key]){
|
||||
if (Array.isArray(object[key])){
|
||||
object[key].forEach((v, i, a)=>{
|
||||
a[i] = this.ObjectId(v);
|
||||
result && result.push(a[i]);
|
||||
})
|
||||
}else{
|
||||
let oid = this.ObjectId(object[key])
|
||||
object[key] = oid;
|
||||
result && result.push(oid);
|
||||
}
|
||||
}
|
||||
if (recursive){
|
||||
for (var k in object){
|
||||
if (typeof(object[k]) == 'object'){
|
||||
this.convertToObjectId(object[k], key, recursive, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convertToObjectId(object, key, recursive, result){
|
||||
// if (object && object[key]){
|
||||
// if (Array.isArray(object[key])){
|
||||
// object[key].forEach((v, i, a)=>{
|
||||
// a[i] = this.ObjectId(v);
|
||||
// result && result.push(a[i]);
|
||||
// })
|
||||
// }else{
|
||||
// let oid = this.ObjectId(object[key])
|
||||
// object[key] = oid;
|
||||
// result && result.push(oid);
|
||||
// }
|
||||
// }
|
||||
// if (recursive){
|
||||
// for (var k in object){
|
||||
// if (typeof(object[k]) == 'object'){
|
||||
// this.convertToObjectId(object[k], key, recursive, result);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
sanitizeQuery(q){
|
||||
if (!q) return;
|
||||
|
||||
@@ -8,9 +8,16 @@ import cookieParser from 'cookie-parser';
|
||||
import helmet from 'helmet';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
/**
|
||||
* The Web Server class, manages all request from the web pllatform, manages the APIs
|
||||
*/
|
||||
class WebServer {
|
||||
name = 'webServer';
|
||||
|
||||
/**
|
||||
* Initializes the web server plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
async init(app) {
|
||||
const xapp = express();
|
||||
this.xapp = xapp;
|
||||
@@ -61,6 +68,10 @@ class WebServer {
|
||||
app.config.am.helmet && xapp.use(helmet(app.config.am.helmet));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the web server plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
async start(app) {
|
||||
let indexFile = app.root + '/index.html';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import path from 'path';
|
||||
const collection = 'assets';
|
||||
|
||||
/**
|
||||
* Application layer manager
|
||||
* Game objects manager
|
||||
*/
|
||||
class GameObjectsManager{
|
||||
name = 'gameObject';
|
||||
@@ -157,7 +157,7 @@ class GameObjectsManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* GameObject entity
|
||||
* GameObject entity, can be: panorama picture, 3d environment, 3d object, 2d object (picture), a player (3d), audio or video asset
|
||||
*/
|
||||
class GameObject {
|
||||
/**
|
||||
@@ -166,9 +166,16 @@ class GameObject {
|
||||
*/
|
||||
name = null;
|
||||
|
||||
/**
|
||||
* Game object type
|
||||
* @type string
|
||||
*/
|
||||
type = null;
|
||||
|
||||
|
||||
/**
|
||||
* Associated file
|
||||
* @type File
|
||||
*/
|
||||
file = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,12 @@ class Rule {
|
||||
*/
|
||||
name = null;
|
||||
|
||||
/**
|
||||
* Rule definition
|
||||
* @type Object
|
||||
*/
|
||||
name = null;
|
||||
|
||||
}
|
||||
|
||||
export { RulesManager }
|
||||
@@ -1,14 +1,29 @@
|
||||
import express from 'express';
|
||||
|
||||
/**
|
||||
* Asset controller plugin
|
||||
*/
|
||||
class AssetController{
|
||||
|
||||
name = 'assetController'
|
||||
name = 'assetApi'
|
||||
route = '/asset'
|
||||
|
||||
/**
|
||||
* Initializes the AssetController plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
init(app){
|
||||
const router = express.Router();
|
||||
const {config} = app;
|
||||
|
||||
/**
|
||||
* API: GET /asset/:type/:id Retrieve asset by type and ID
|
||||
* @function read
|
||||
* @param {string} type Type can be "source", "default" or "thumb"
|
||||
* @param {string} id The name of the asset
|
||||
* @returns File
|
||||
* @memberof AssetController
|
||||
*/
|
||||
router.get('/:where/:id(*)', async (req, res)=>{
|
||||
res.sendFile(config.fs.repo + req.params.where + '/' + req.params.id, (err)=>{
|
||||
if (err){
|
||||
|
||||
@@ -2,17 +2,27 @@ import express from 'express';
|
||||
import multipart from 'connect-multiparty';
|
||||
|
||||
const multipartMiddleware = multipart();
|
||||
|
||||
/**
|
||||
* GameObjectsController. API for the game objects manager
|
||||
*/
|
||||
class GameObjectsController{
|
||||
|
||||
name = 'gameObjectsApi'
|
||||
route = '/api/game-object'
|
||||
|
||||
/**
|
||||
* Initializes the GameObjectsController plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
init(app){
|
||||
const { gameObject } = app;
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* Create & update
|
||||
* API: PUT /api/game-object/ Create or update game object
|
||||
* @function createOrUpdate
|
||||
* @memberof GameObjectsController
|
||||
*/
|
||||
router.put('/', multipartMiddleware, async (req, res)=>{
|
||||
try{
|
||||
@@ -26,22 +36,34 @@ class GameObjectsController{
|
||||
});
|
||||
|
||||
/**
|
||||
* List
|
||||
* API: POST /api/game-object/ List game objects by given criteria
|
||||
* @function list
|
||||
* @returns {GameObject[]}
|
||||
* @memberof GameObjectsController
|
||||
*/
|
||||
router.post('/', async (req, res)=>{
|
||||
let result = await gameObject.list(req.body);
|
||||
res.json(result);
|
||||
})
|
||||
|
||||
router.get('/', async (req, res)=>{
|
||||
|
||||
})
|
||||
|
||||
/**
|
||||
* API: GET /api/game-object/:id Retrieve game object by ID
|
||||
* @function read
|
||||
* @param {string} id The id of the game object
|
||||
* @returns {GameObject}
|
||||
* @memberof GameObjectsController
|
||||
*/
|
||||
router.get('/:id', async (req, res)=>{
|
||||
let object = await gameObject.read(parseInt(req.params.id));
|
||||
res.json(object);
|
||||
})
|
||||
|
||||
/**
|
||||
* API: DELETE /api/game-object/:id Delete game object by ID
|
||||
* @function remove
|
||||
* @param {string} id The id of the game object
|
||||
* @memberof GameObjectsController
|
||||
*/
|
||||
router.delete('/:id', async (req, res)=>{
|
||||
await gameObject.remove(req.params.id);
|
||||
res.json({status: 'OK'});
|
||||
|
||||
@@ -1,12 +1,59 @@
|
||||
import express from 'express';
|
||||
|
||||
/**
|
||||
* GamesController. API for the games manager
|
||||
*/
|
||||
class GamesController{
|
||||
|
||||
name = 'gamesApi'
|
||||
route = '/api/game'
|
||||
|
||||
/**
|
||||
* Initializes the GamesController plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
init(app){
|
||||
const router = express.Router();
|
||||
const { games } = app;
|
||||
|
||||
/**
|
||||
* API: PUT /api/game/ Create or update game
|
||||
* @function createOrUpdate
|
||||
* @memberof GamesController
|
||||
*/
|
||||
router.put('/', async (req, res)=>{
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* API: POST /api/game/ List games by given criteria
|
||||
* @function list
|
||||
* @returns {Game[]}
|
||||
* @memberof GamesController
|
||||
*/
|
||||
router.post('/', async (req, res)=>{
|
||||
})
|
||||
|
||||
/**
|
||||
* API: GET /api/game/:id Retrieve game by ID
|
||||
* @function read
|
||||
* @param {string} id The id of the game
|
||||
* @returns {Game}
|
||||
* @memberof GamesController
|
||||
*/
|
||||
router.get('/:id', async (req, res)=>{
|
||||
})
|
||||
|
||||
/**
|
||||
* API: DELETE /api/game/:id Delete game by ID
|
||||
* @function remove
|
||||
* @param {string} id The id of the game
|
||||
* @memberof GamesController
|
||||
*/
|
||||
router.delete('/:id', async (req, res)=>{
|
||||
})
|
||||
|
||||
app.webServer.xapp.use(this.route, router);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import express from 'express';
|
||||
|
||||
/**
|
||||
* RulesController. API for the game rules manager
|
||||
*/
|
||||
class RulesController{
|
||||
|
||||
name = 'rulesApi'
|
||||
route = '/api/rule'
|
||||
|
||||
/**
|
||||
* Initializes the RulesController plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
init(app){
|
||||
const router = express.Router();
|
||||
const { rules } = app;
|
||||
|
||||
/**
|
||||
* API: PUT /api/rule/ Create or update rule
|
||||
* @function createOrUpdate
|
||||
* @memberof RulesController
|
||||
*/
|
||||
router.put('/', async (req, res)=>{
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* API: POST /api/rule/ List rules by given criteria
|
||||
* @function list
|
||||
* @returns {Rule[]}
|
||||
* @memberof RulesController
|
||||
*/
|
||||
router.post('/', async (req, res)=>{
|
||||
})
|
||||
|
||||
/**
|
||||
* API: GET /api/rule/:id Retrieve rule by ID
|
||||
* @function read
|
||||
* @param {string} id The id of the rule
|
||||
* @returns {Rule}
|
||||
* @memberof RulesController
|
||||
*/
|
||||
router.get('/:id', async (req, res)=>{
|
||||
})
|
||||
|
||||
/**
|
||||
* API: DELETE /api/rule/:id Delete rule by ID
|
||||
* @function remove
|
||||
* @param {string} id The id of the rule
|
||||
* @memberof RulesController
|
||||
*/
|
||||
router.delete('/:id', async (req, res)=>{
|
||||
})
|
||||
|
||||
app.webServer.xapp.use(this.route, router);
|
||||
}
|
||||
}
|
||||
|
||||
export { RulesController }
|
||||
@@ -0,0 +1,60 @@
|
||||
import express from 'express';
|
||||
|
||||
/**
|
||||
* ScenariosController. API for the scenarios manager
|
||||
*/
|
||||
class ScenariosController{
|
||||
|
||||
name = 'scenariosApi'
|
||||
route = '/api/scenario'
|
||||
|
||||
/**
|
||||
* Initializes the ScenariosController plugin
|
||||
* @param {App} app The application instance
|
||||
*/
|
||||
init(app){
|
||||
const router = express.Router();
|
||||
const { scenarios } = app;
|
||||
|
||||
/**
|
||||
* API: PUT /api/scenario/ Create or update scenario
|
||||
* @function createOrUpdate
|
||||
* @memberof ScenariosController
|
||||
*/
|
||||
router.put('/', async (req, res)=>{
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* API: POST /api/scenario/ List scenarios by given criteria
|
||||
* @function list
|
||||
* @returns {Scenario[]}
|
||||
* @memberof ScenariosController
|
||||
*/
|
||||
router.post('/', async (req, res)=>{
|
||||
})
|
||||
|
||||
/**
|
||||
* API: GET /api/scenario/:id Retrieve scenario by ID
|
||||
* @function read
|
||||
* @param {string} id The id of the scenario
|
||||
* @returns {Scenario}
|
||||
* @memberof ScenariosController
|
||||
*/
|
||||
router.get('/:id', async (req, res)=>{
|
||||
})
|
||||
|
||||
/**
|
||||
* API: DELETE /api/scenario/:id Delete scenario by ID
|
||||
* @function remove
|
||||
* @param {string} id The id of the scenario
|
||||
* @memberof ScenariosController
|
||||
*/
|
||||
router.delete('/:id', async (req, res)=>{
|
||||
})
|
||||
|
||||
app.webServer.xapp.use(this.route, router);
|
||||
}
|
||||
}
|
||||
|
||||
export { ScenariosController }
|
||||
Reference in New Issue
Block a user