├── FAMECSE ├── AppliLib │ ├── Entities │ │ └── Aliment.class.js │ ├── FormBuilder │ │ └── AlimentFormBuilder.class.js │ ├── FormHeaders │ │ └── AlimentFormHeader.class.js │ ├── Models │ │ └── AlimentManager_OntGDB.class.js │ └── appConfig.xml ├── Applications │ └── Frontend │ │ ├── Config │ │ └── routes.xml │ │ ├── FrontendApplication.class.js │ │ ├── Modules │ │ └── Public │ │ │ ├── PublicController.class.js │ │ │ └── Views │ │ │ ├── index.view.js │ │ │ └── insert.view.js │ │ └── Templates │ │ └── layout.view.js ├── framework.js ├── package-lock.json ├── package.json ├── queries_test.txt └── uds-framework │ ├── Application.class.js │ ├── ApplicationComponent.class.js │ ├── ApplicationUtilitary.class.js │ ├── ArrayEntity.class.js │ ├── BackController.class.js │ ├── Dao │ ├── DAOFactory.class.js │ └── Queries │ │ ├── Entity_NEO4J.class.js │ │ └── Entity_ONTO.class.js │ ├── Entity.class.js │ ├── Field.class.js │ ├── FieldUtilitary.class.js │ ├── Fields │ └── StringField.class.js │ ├── Form.class.js │ ├── FormBuilder.class.js │ ├── FormHandler.class.js │ ├── FormHandlerFactory.class.js │ ├── FormHeader.class.js │ ├── FormHeaderFactory.class.js │ ├── HTTPRequest.class.js │ ├── HTTPResponse.class.js │ ├── Managers.class.js │ ├── Managers_NEO4JDB.class.js │ ├── Managers_OntGDB.class.js │ ├── Managers_api.class.js │ ├── PObject.class.js │ ├── Page.class.js │ ├── PageAction.class.js │ ├── Route.class.js │ ├── Router.class.js │ ├── ServeurComponents.class.js │ ├── Validator.class.js │ ├── Validators │ └── NotNullValidator.class.js │ ├── index.js │ └── tools.js ├── README.md ├── alphabox-workshop └── microservices-server │ ├── .editorconfig │ ├── .gitignore │ ├── .vscode │ └── launch.json │ ├── README.md │ ├── mixins │ └── db.mixin.js │ ├── moleculer.config.js │ ├── package.json │ ├── public │ └── index.html │ ├── services │ ├── api.service.js │ ├── greeter.service.js │ └── products.service.js │ └── test │ ├── integration │ └── products.service.spec.js │ └── unit │ ├── mixins │ └── db.mixin.spec.js │ └── services │ ├── greeter.spec.js │ └── products.spec.js └── mon_test.tar.xz /FAMECSE/AppliLib/Entities/Aliment.class.js: -------------------------------------------------------------------------------- 1 | const Entity = require('uds-framework/Entity.class'); 2 | /** 3 | * @class 4 | */ 5 | const Aliment = module.exports = function Aliment(donnees = {}) { 6 | Entity.call(this, donnees); 7 | this._$labelFr = null; 8 | this._$categorie = null; 9 | 10 | this.isValid = function () { 11 | return this._$categorie !== null && this._$labelFr !== null; 12 | } 13 | 14 | this.labelFr = function () { 15 | return this._$labelFr; 16 | } 17 | 18 | this.setLabelFr = function (labelFr) { 19 | this._$labelFr = labelFr; 20 | } 21 | 22 | this.categorie = function () { 23 | return this._$categorie; 24 | } 25 | 26 | this.setCategorie = function (categorie) { 27 | this._$categorie = categorie; 28 | } 29 | } -------------------------------------------------------------------------------- /FAMECSE/AppliLib/FormBuilder/AlimentFormBuilder.class.js: -------------------------------------------------------------------------------- 1 | const Managers = require("uds-framework/Managers.class"); 2 | const Entity = require("uds-framework/Entity.class"); 3 | const FormBuilder = require("uds-framework/FormBuilder.class"); 4 | const NotNullValidator = require("uds-framework/Validators/NotNullValidator.class"); 5 | const StringField = require("uds-framework/Fields/StringField.class"); 6 | /** 7 | * @class 8 | * @param {Managers} managers 9 | * @param {Entity} entity 10 | * @param {Array} options 11 | */ 12 | const AlimentFormBuilder = module.exports = function (managers, entity, options = {}) { 13 | FormBuilder.call(this, managers, entity, options); 14 | 15 | this.build = function () { 16 | this.form().add( 17 | new StringField({ 18 | 'name': "labelFr", 19 | 'placeholder': "NOM DE L'ALIMENT", 20 | 'validators': [ 21 | new NotNullValidator("Merci de spécifier une valeur") 22 | ] 23 | }) 24 | ).add( 25 | new StringField({ 26 | 'name': "categorie", 27 | 'placeholder': "CATEGORIE DE L'ALIMENT", 28 | 'validators': [ 29 | new NotNullValidator("Merci de spécifier une valeur") 30 | ] 31 | }) 32 | ); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /FAMECSE/AppliLib/FormHeaders/AlimentFormHeader.class.js: -------------------------------------------------------------------------------- 1 | const FormHeader = require("uds-framework/FormHeader.class"); 2 | const HTTPRequest = require("uds-framework/HTTPRequest.class"); 3 | /** 4 | * @class 5 | * @param {HTTPRequest} request 6 | */ 7 | const AlimentFormHeader = module.exports = function (request, aliment) { 8 | FormHeader.call(this, request, aliment); 9 | 10 | 11 | } -------------------------------------------------------------------------------- /FAMECSE/AppliLib/Models/AlimentManager_OntGDB.class.js: -------------------------------------------------------------------------------- 1 | const Managers_Gdb = require("uds-framework/Managers_OntGDB.class"); 2 | /** 3 | * @class AlimentManager_OntGDB 4 | */ 5 | module.exports = function AlimentManager_OntGDB(api, dao) { 6 | Managers_Gdb.call(this, api, dao); 7 | 8 | this.setApport = (substances) => { 9 | return substances.join(', '); 10 | }; 11 | 12 | this.insertAliment = async function (debut = -1, limit = -1) { 13 | const 14 | name = "rizA", 15 | labelFR = "riz", 16 | labelEN = "rize", 17 | comment = "riz à manger !", 18 | apports = "vitamineA, vitamineE"; 19 | 20 | try { 21 | let aliment = await this.dao().update( 22 | ` 23 | PREFIX entity: 24 | PREFIX atrib: 25 | PREFIX instance: 26 | INSERT DATA { instance:181360bd1bf rdf:type rdfs:Class.} 27 | `, 28 | { tranform: 'toJSON' } 29 | ); 30 | 31 | // console.log(aliment); 32 | 33 | return aliment; 34 | } catch (error) { 35 | console.log(error); 36 | return []; 37 | } 38 | } 39 | 40 | this.getAliments = async function (debut = -1, limit = -1) { 41 | try { 42 | let aliments = await this.dao() 43 | .query( 44 | `SELECT ?entity ?label ?comment ?value 45 | WHERE { 46 | { ?entity rdf:type food:Aliment } UNION {?entity rdf:type food:Legumes } UNION {?entity rdf:type food:ProduitLaitiers } UNION {?entity rdf:type food:MatiereGrasses } UNION {?entity rdf:type food:ViandeSeche } UNION {?entity rdf:type food:Cereales } UNION {?entity rdf:type food:ViandeBrousse } 47 | UNION {?entity rdf:type food:MatiereGrasses } UNION {?entity rdf:type food:ViandeBlanche } UNION {?entity rdf:type food:Cereales } 48 | OPTIONAL { 49 | ?entity rdfs:label ?label 50 | FILTER (lang(?label) = "fr") . 51 | } 52 | 53 | OPTIONAL { 54 | ?entity rdfs:label ?value 55 | FILTER (lang(?value) = "fr") . 56 | } 57 | } 58 | `, 59 | { transform: 'toJSON' } 60 | ); 61 | return aliments; 62 | } catch (error) { 63 | return []; 64 | } 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /FAMECSE/AppliLib/appConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | famecse 5 | famecse 6 | http://localhost:7200 7 | famecse 8 | no 9 | famecse 10 | http://localhost/ontologies/famecse# 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /FAMECSE/Applications/Frontend/Config/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FAMECSE/Applications/Frontend/FrontendApplication.class.js: -------------------------------------------------------------------------------- 1 | const Application = require('uds-framework/Application.class'); 2 | /** 3 | * @class 4 | */ 5 | const FrontendApplication = module.exports = function () { 6 | Application.call(this); 7 | this._$name = "Frontend"; 8 | } -------------------------------------------------------------------------------- /FAMECSE/Applications/Frontend/Modules/Public/PublicController.class.js: -------------------------------------------------------------------------------- 1 | const BackController = require('uds-framework/BackController.class'); 2 | const HTTPRequest = require('uds-framework/HTTPRequest.class'); 3 | //const Person = require('../../../../AppliLib/Entities/Person.class'); 4 | const Aliment = require('../../../../AppliLib/Entities/Aliment.class'); 5 | //const Conduit = require('../../../../AppliLib/Entities/Conduit.class'); 6 | /** 7 | * @class PublicController 8 | */ 9 | const PublicController = module.exports = function (app, module, action) { 10 | BackController.call(this, app, module, action); 11 | app.httpResponse().addHeaderAccess('http://localhost:8080'); 12 | 13 | this.executeInsertPlat = async function (httpRequest) { 14 | const formHandler = this.formHandler("Aliment", httpRequest); 15 | // var stats = await managers.getUnique(); 16 | // console.log(stats); 17 | if (await formHandler.process()) { 18 | // console.log(formHandler.form().entity()); 19 | // const idChauffeur = formHandler.form().entity().id(); 20 | // this.app().httpResponse().redirect("/insert/" + idChauffeur + "-conduit") 21 | } 22 | 23 | this.page().addVar("formulaire", formHandler.form().createView()); 24 | this.useViewM("insert"); 25 | } 26 | 27 | this.executeListInsert = async function (httpRequest) { 28 | var managers = this.getManagers().getManagerOf("Aliment"); 29 | // managers.save(aliment); 30 | var aliments = await managers.getList(); 31 | 32 | this.page().addVar("classes", aliments); 33 | this.useViewM("index"); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /FAMECSE/Applications/Frontend/Modules/Public/Views/index.view.js: -------------------------------------------------------------------------------- 1 | const PageAction = require("uds-framework/PageAction.class"); 2 | /** 3 | * @class index 4 | */ 5 | const index = module.exports = function (page) { 6 | PageAction.call(this, page); 7 | 8 | this.getActionView = function () { 9 | // console.log(this._$page.getVar("classes")); 10 | return JSON.stringify(this._$page.getVar("classes")); 11 | } 12 | } -------------------------------------------------------------------------------- /FAMECSE/Applications/Frontend/Modules/Public/Views/insert.view.js: -------------------------------------------------------------------------------- 1 | const PageAction = require("uds-framework/PageAction.class"); 2 | /** 3 | * @class index 4 | */ 5 | const index = module.exports = function (page) { 6 | PageAction.call(this, page); 7 | 8 | this.getActionView = function () { 9 | // console.log(this._$page.getVar("classes")); 10 | return this._$page.getVar("formulaire"); 11 | } 12 | } -------------------------------------------------------------------------------- /FAMECSE/Applications/Frontend/Templates/layout.view.js: -------------------------------------------------------------------------------- 1 | const PageAction = require("uds-framework/PageAction.class"); 2 | /** 3 | * @class layout 4 | */ 5 | const layout = module.exports = function (page) { 6 | PageAction.call(this, page); 7 | 8 | this.getActionView = function () { 9 | return this._$page.getVar("content-action-view"); 10 | } 11 | } -------------------------------------------------------------------------------- /FAMECSE/framework.js: -------------------------------------------------------------------------------- 1 | const ServeurComponents = require('uds-framework').ServeurComponents; 2 | const http = require('http'); 3 | const url = require('url'); 4 | 5 | var server = http.createServer(function (req, res) { 6 | var path = url.parse(req.url).pathname 7 | // res.end('{ "changed":' + count + '}'); 8 | if (path.indexOf(".") === -1) { 9 | const serveurComponents = new ServeurComponents(req, res, http); 10 | 11 | } 12 | }); 13 | 14 | server.listen(8086); -------------------------------------------------------------------------------- /FAMECSE/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodevues", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "serve": "node framework.js", 9 | "dev": "supervisor framework.js" 10 | }, 11 | "author": "cosi-sama", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@innotrade/enapso-graphdb-admin": "^1.4.1", 15 | "@innotrade/enapso-graphdb-client": "^1.8.5", 16 | "cookie-parser": "^1.4.6", 17 | "express": "^4.17.2", 18 | "express-session": "^1.17.2", 19 | "fs": "0.0.1-security", 20 | "lodash": "^4.17.21", 21 | "lodash.groupby": "^4.6.0", 22 | "lodash.omit": "^4.5.0", 23 | "neo4j-driver": "^4.4.3", 24 | "session-file-store": "^1.5.0", 25 | "supervisor": "^0.12.0", 26 | "vue": "^2.6.14", 27 | "vue-router": "^3.5.3", 28 | "xmldom-ts": "^0.3.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /FAMECSE/queries_test.txt: -------------------------------------------------------------------------------- 1 | PREFIX entity: 2 | PREFIX instance: 3 | PREFIX atrib: 4 | PREFIX rdfs: 5 | PREFIX rdf: 6 | 7 | select ?id ?a ?v 8 | where { 9 | ?id rdfs:domain entity:Aliment. 10 | ?id ?a ?v. 11 | FILTER(STRSTARTS(STR(?a), "http://example/framework/entity/atributs/")). 12 | } limit 100 13 | -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Application.class.js: -------------------------------------------------------------------------------- 1 | const HTTPRequest = require("uds-framework/HTTPRequest.class"); 2 | const HTTPResponse = require("uds-framework/HTTPResponse.class"); 3 | const PObject = require("uds-framework/PObject.class"); 4 | 5 | const Router = require("uds-framework/Router.class"); 6 | const Route = require("uds-framework/Route.class"); 7 | const xmldom = require('xmldom-ts'); 8 | const fs = require('fs'); 9 | 10 | /** 11 | * @abstract @class Application 12 | */ 13 | const Application = module.exports = function () { 14 | PObject.call(this); 15 | this._$httpRequest = new HTTPRequest(this); 16 | this._$httpResponse = new HTTPResponse(this); 17 | 18 | this._$filterChain = null; 19 | this._$currentRoute = null; 20 | this._$currentController = null; 21 | this._$name = ""; 22 | 23 | this._$currentDate = null; 24 | this._$config = null; 25 | this._$user = null; 26 | // this._$sessionController = ""; 27 | // this._$filigranne = ""; 28 | this._$forwardURI = ""; 29 | this._$appFileConfig = ""; 30 | 31 | this._$getInitRouter = function (contextURI = "") { 32 | var router = new Router(); 33 | var domParserImpl = new xmldom.DOMParserImpl(); 34 | 35 | var xslString = fs.readFileSync(__dirname + '/../../Applications/' + this._$name + '/Config/routes.xml').toString(); 36 | var dxml = domParserImpl.parseFromString(xslString); 37 | var routes = dxml.getElementsByTagName("route"); 38 | 39 | for (const key in routes) { 40 | if (Object.hasOwnProperty.call(routes, key) && routes[key].nodeName == "route") { 41 | const route = routes[key]; 42 | var vars = []; 43 | // console.log(); 44 | if (route.hasAttribute('vars')) { 45 | vars = route.getAttribute('vars').split(','); 46 | } 47 | 48 | router.addRoute(new Route( 49 | route.getAttribute('url'), 50 | route.getAttribute('module'), 51 | route.getAttribute('action'), 52 | vars 53 | )); 54 | } 55 | } 56 | 57 | return router; 58 | } 59 | 60 | /** 61 | * Instancier le controller de l'action 62 | * @param {Router} router 63 | * @param {String} url 64 | */ 65 | this._$getMatchRouteController = function (router, url) { 66 | // console.log(url); 67 | try { 68 | var matchedRoute = router.getRoute(url); 69 | // console.log(matchedRoute); 70 | // console.log(url); 71 | this._$currentRoute = matchedRoute; 72 | } catch (error) { 73 | console.log("NO ROUTE : " + url); 74 | } 75 | // $_GET = array_merge($_GET, $matchedRoute->vars()); 76 | var controlerClass = '../../Applications/' + this._$name + '/Modules/' + matchedRoute.module() + '/' + matchedRoute.module() + 'Controller.class'; 77 | var cClass = require(controlerClass); 78 | global._$params = matchedRoute.vars(); 79 | // $this->filigranne->actualise($matchedRoute); 80 | return new cClass(this, matchedRoute.module(), matchedRoute.action()); 81 | } 82 | 83 | /** 84 | * @returns BackController 85 | */ 86 | this.getController = function () { 87 | var router = this._$getInitRouter(); 88 | this._$currentController = this._$getMatchRouteController(router, this._$httpRequest.requestURI()); 89 | 90 | return this._$currentController; 91 | } 92 | 93 | this.run = async function () { 94 | var controller = this.getController(); 95 | await controller.execute(); 96 | 97 | this._$httpResponse.send(); 98 | } 99 | 100 | /** 101 | * @returns HTTPRequest 102 | */ 103 | this.httpRequest = function () { 104 | return this._$httpRequest; 105 | } 106 | 107 | /** 108 | * @returns HTTPResponse 109 | */ 110 | this.httpResponse = function () { 111 | return this._$httpResponse; 112 | } 113 | 114 | /** 115 | * @returns BackController 116 | */ 117 | this.currentController = function () { 118 | return this._$currentController; 119 | } 120 | 121 | /** 122 | * @returns Route 123 | */ 124 | this.currentRoute = function () { 125 | return this._$currentRoute; 126 | } 127 | 128 | /** 129 | * @returns String 130 | */ 131 | this.name = function () { 132 | return this._$name; 133 | } 134 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/ApplicationComponent.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require("uds-framework/PObject.class"); 2 | /** 3 | * @class ApplicationComponent 4 | * @param {Application} app 5 | */ 6 | const ApplicationComponent = module.exports = function (app) { 7 | PObject.call(this); 8 | this._$app = app; 9 | 10 | this.app = function () { 11 | return this._$app; 12 | } 13 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/ApplicationUtilitary.class.js: -------------------------------------------------------------------------------- 1 | const xmldom = require('xmldom-ts'); 2 | const fs = require('fs'); 3 | 4 | const ApplicationUtilitary = module.exports = { 5 | _$appFileConfig: null, 6 | 7 | loadAppConfig: function () { 8 | if (this._$appFileConfig == null) { 9 | var domParserImpl = new xmldom.DOMParserImpl(); 10 | var xslString = fs.readFileSync(__dirname + "/../../AppliLib/appConfig.xml").toString(); 11 | var dxml = domParserImpl.parseFromString(xslString); 12 | 13 | this._$appFileConfig = dxml; 14 | } 15 | 16 | return this._$appFileConfig; 17 | }, 18 | 19 | getAppConfigAttr: function (attrib, api) { 20 | var xmlConfig = this.loadAppConfig(); 21 | var daoConfigs = xmlConfig.getElementsByTagName("daoConfig"); 22 | var daoConfig = null; 23 | 24 | daoConfigs.forEach(dao => { 25 | if (dao.getAttribute("type") == api) { 26 | daoConfig = dao; 27 | } 28 | }); 29 | // console.log(attrib); 30 | // console.log(api); 31 | // console.log(daoConfig.getElementsByTagName(attrib)[0].firstChild.nodeValue); 32 | const child = daoConfig.getElementsByTagName(attrib)[0].firstChild; 33 | return child !== null ? child.nodeValue : ""; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /FAMECSE/uds-framework/ArrayEntity.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | /** 3 | * @class 4 | */ 5 | const ArrayEntity = module.exports = function (donnees = {}) { 6 | PObject.call(this); 7 | 8 | this._$erreurs = {}; 9 | this._$descriptions = {}; 10 | this._$dateModif = null; 11 | this._$dateInsert = null; 12 | 13 | this.erreurs = function () { 14 | return this._$erreurs; 15 | } 16 | 17 | this.dateInsert = function () { 18 | return this._$dateInsert; 19 | } 20 | 21 | this.arrayDescriptions = function () { 22 | return {}; 23 | } 24 | 25 | this.setDateInsert = function (dateInsert) { 26 | this._$dateInsert = dateInsert; 27 | } 28 | 29 | this.addDescription = function (attrib, valeur) { 30 | this._$descriptions[attrib] = valeur; 31 | } 32 | 33 | this.setDescriptions = function (data) { 34 | this._$descriptions = data; 35 | } 36 | 37 | this.dateModif = function (data) { 38 | return this._$dateModif; 39 | } 40 | 41 | this.getDescription = function (attrib) { 42 | return this._$descriptions[attrib]; 43 | } 44 | 45 | this.getDescriptions = function () { 46 | return this._$descriptions; 47 | } 48 | 49 | this.setDateModif = function (dateModif) { 50 | this._$dateModif = dateModif; 51 | } 52 | 53 | this.hydrate = function (donnees) { 54 | for (const attrib in donnees) { 55 | method = 'set' + attrib.charAt(0).toUpperCase() + attrib.slice(1); 56 | if (Object.hasOwnProperty.call(this, method)) { 57 | const valeur = donnees[attrib]; 58 | this[method](valeur); 59 | } 60 | else if (Object.hasOwnProperty.call(donnees, attrib)) { 61 | const valeur = donnees[attrib]; 62 | this.addDescription(attrib, valeur); 63 | // console.log(this[method]); 64 | } 65 | } 66 | } 67 | 68 | if (Object.keys(donnees).length > 0) { 69 | this.hydrate(donnees); 70 | } 71 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/BackController.class.js: -------------------------------------------------------------------------------- 1 | const ApplicationComponent = require("./ApplicationComponent.class"); 2 | const Managers = require("./Managers.class"); 3 | const Page = require("./Page.class"); 4 | const DAOFactory = require("./Dao/DAOFactory.class"); 5 | const FormHeaderFactory = require("./FormHeaderFactory.class"); 6 | const FormHandlerFactory = require("./FormHandlerFactory.class"); 7 | /** 8 | * @abstract @class BackController 9 | * @param {Application} app 10 | * @param {String} module 11 | * @param {String} action 12 | */ 13 | const BackController = module.exports = function (app, module, action) { 14 | ApplicationComponent.call(this, app); 15 | // console.log(DAOFactory.getConnexion("Gdb")); 16 | this.managers = new Managers("OntGDB", DAOFactory.getConnexion("OntGDB")); 17 | 18 | this._$module = ""; 19 | this._$action = ""; 20 | this._$page = null; 21 | this._$view = ""; 22 | 23 | this._$initContext = function (app, module, action, pageTitle) { 24 | this._$page = new Page(app); 25 | this._$page.addVar("title", pageTitle); 26 | this.setModule(module); 27 | this.setAction(action); 28 | } 29 | 30 | this._$initContextPage = function () { 31 | 32 | this.useViewM(this._$action); 33 | } 34 | 35 | this.formHandler = function (classeName, request, modified = false, options = {}) { 36 | const formHeaderFactory = new FormHeaderFactory(request); 37 | var classe = formHeaderFactory.get(classeName); 38 | // console.log(classe); 39 | if (modified !== false && request.method() != "POST") { 40 | classe = this.getManagers().getManagerOf(classeName).getUnique(modified); 41 | // $classe->prepareToModify(); 42 | } 43 | 44 | if (modified !== false && request.method() == "POST") { 45 | classe.setId(modified); 46 | } 47 | 48 | const formHandlerFactory = new FormHandlerFactory(this.getManagers().getManagerOf(classeName), classe, request, options); 49 | formHandlerFactory.build(); 50 | // $this->testVar($classe); 51 | // console.log(classe); 52 | return formHandlerFactory.formHandler(); 53 | } 54 | 55 | this.useViewM = function (model, mapping = "") { 56 | const app = this._$app.name(); 57 | const module = this._$module; 58 | 59 | const rep = "./../../Applications/" + app + "/Modules/" + module + "/Views/" + model + ".view"; 60 | this.page().setView(rep); 61 | } 62 | 63 | this.execute = async function () { 64 | // this.executeIndex(this.app.httpRequest); 65 | // console.log(this.action.slice(1)); 66 | await this["execute" + this._$action.charAt(0).toUpperCase() + this._$action.slice(1)](this.app().httpRequest()); 67 | // console.log(this.page()._$vars); 68 | this.app().httpResponse().setPage(this.page()); 69 | } 70 | 71 | this.initManagerNeo4j = function () { 72 | this.managers = new Managers("NEO4JDB", DAOFactory.getConnexion("NEO4JDB")); 73 | } 74 | 75 | this.getManagers = function () { 76 | return this.managers; 77 | } 78 | 79 | this.setModule = function (module) { 80 | this._$module = module; 81 | } 82 | 83 | this.setAction = function (action) { 84 | this._$action = action; 85 | } 86 | 87 | this.page = function () { 88 | return this._$page; 89 | } 90 | 91 | this._$initContext(app, module, action); 92 | this._$initContextPage(); 93 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Dao/DAOFactory.class.js: -------------------------------------------------------------------------------- 1 | // const { EnapsoGraphDBClient } = require("@innotrade/enapso-graphdb-client"); 2 | const { EnapsoGraphDBClient } = require('@innotrade/enapso-graphdb-client'); 3 | const { EnapsoGraphDBAdmin } = require('@innotrade/enapso-graphdb-admin'); 4 | const ApplicationUtilitary = require("uds-framework/ApplicationUtilitary.class"); 5 | const neo4j = require("neo4j-driver"); 6 | /** 7 | * @static @class DAOFactory 8 | */ 9 | const DAOFactory = module.exports = { 10 | _$dao: {}, 11 | _$api: "", 12 | 13 | _$establishConnexion_OntGDB: function () { 14 | const GRAPHDB_BASE_URL = ApplicationUtilitary.getAppConfigAttr("host", this._$api); 15 | const GRAPHDB_USERNAME = ApplicationUtilitary.getAppConfigAttr("user", this._$api); 16 | const GRAPHDB_REPOSITORY = ApplicationUtilitary.getAppConfigAttr("dbrepository", this._$api); 17 | const GRAPHDB_PASSWORD = ApplicationUtilitary.getAppConfigAttr("passWord", this._$api); 18 | const GRAPHDB_PREFIX = ApplicationUtilitary.getAppConfigAttr("dbprefix", this._$api); 19 | // var dbname = daoConfig.getElementsByTagName("dbname")[0].nodeValue; 20 | var ONTOLOGY_URI = ApplicationUtilitary.getAppConfigAttr("dbcontext", this._$api); 21 | // console.log(GRAPHDB_BASE_URL); 22 | // connection data to the run GraphDB instance 23 | // const GRAPHDB_BASE_URL = "http://localhost:7200", 24 | // GRAPHDB_REPOSITORY = "Test", 25 | // GRAPHDB_USERNAME = "Test", 26 | // GRAPHDB_PASSWORD = "Test", 27 | // GRAPHDB_CONTEXT_TEST = "http://ont.enapso.com/repo"; 28 | // console.log(GRAPHDB_REPOSITORY); 29 | const DEFAULT_PREFIXES = [ 30 | EnapsoGraphDBClient.PREFIX_OWL, 31 | EnapsoGraphDBClient.PREFIX_RDF, 32 | EnapsoGraphDBClient.PREFIX_RDFS, 33 | EnapsoGraphDBClient.PREFIX_XSD, 34 | EnapsoGraphDBClient.PREFIX_PROTONS, 35 | // EnapsoGraphDBClient.PREFIX_ENTEST, 36 | { 37 | prefix: GRAPHDB_PREFIX, 38 | iri: ONTOLOGY_URI, 39 | } 40 | ]; 41 | 42 | let graphDBEndpoint = new EnapsoGraphDBClient.Endpoint({ 43 | baseURL: GRAPHDB_BASE_URL, 44 | repository: GRAPHDB_REPOSITORY, 45 | prefixes: DEFAULT_PREFIXES, 46 | transform: 'JSON', 47 | }); 48 | 49 | // connect and authenticate 50 | graphDBEndpoint.login(GRAPHDB_USERNAME, GRAPHDB_PASSWORD) 51 | .then((result) => { 52 | console.log(result); 53 | }).catch((err) => { 54 | console.log(err); 55 | }); 56 | 57 | // graphDBEndpoint.getRepositories() 58 | // .then((result) => { 59 | // console.log(result); 60 | // }) 61 | // .catch((err) => { 62 | // console.log(err); 63 | // }); 64 | 65 | // graphDBEndpoint 66 | // .getContexts() 67 | // .then((result) => { 68 | // console.log(result); 69 | // }) 70 | // .catch((err) => { 71 | // console.log(err, 'process error here...'); 72 | // }); 73 | 74 | return graphDBEndpoint; 75 | }, 76 | 77 | _$establishConnexion_NEO4JDB: function () { 78 | const GRAPHDB_BASE_URL = ApplicationUtilitary.getAppConfigAttr("host", this._$api); 79 | const GRAPHDB_USERNAME = ApplicationUtilitary.getAppConfigAttr("user", this._$api); 80 | const GRAPHDB_PASSWORD = ApplicationUtilitary.getAppConfigAttr("passWord", this._$api); 81 | const GRAPHDB_DBNAME = ApplicationUtilitary.getAppConfigAttr("dbname", this._$api); 82 | 83 | // const driver = neo4j.driver(GRAPHDB_BASE_URL); 84 | const driver = neo4j.driver(GRAPHDB_BASE_URL, neo4j.auth.basic(GRAPHDB_USERNAME, GRAPHDB_PASSWORD)); 85 | return driver; 86 | // return session; 87 | }, 88 | 89 | getConnexion: function (api) { 90 | this._$api = api; 91 | if (this._$dao[api] === undefined) { 92 | 93 | this._$dao[api] = this["_$establishConnexion_" + api](); 94 | } 95 | // console.log(this._$dao); 96 | return this._$dao[api]; 97 | } 98 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Dao/Queries/Entity_NEO4J.class.js: -------------------------------------------------------------------------------- 1 | const Entity = require('uds-framework/Entity.class'); 2 | const PObject = require('uds-framework/PObject.class'); 3 | /** 4 | * @abstract @class 5 | * @param {Entity} entity 6 | */ 7 | const Entity_NEO4J = module.exports = function (entity) { 8 | PObject.call(this); 9 | this._$entity = entity; 10 | 11 | this.entityListqlSave = function () { 12 | var properties = this._$entity.properties(); 13 | var classeName = this._$entity.className(); 14 | 15 | var result = 'MERGE (a:' + classeName + '{'; 16 | 17 | for (const prop in properties) { 18 | if (Object.hasOwnProperty.call(properties, prop)) { 19 | const value = properties[prop]; 20 | result += prop.slice(2) + ':"' + value + '",'; 21 | } 22 | } 23 | const dateNow = this.currentStringDate(); 24 | result += 'dateInsert: "' + dateNow + '"}) ON CREATE SET a.id = ID(a) RETURN a.id AS id;'; 25 | return result; 26 | } 27 | 28 | this.entitiesqlAddAssociation = function (entityFrom, entityTo) { 29 | // var bodyQLFrom = this._$cypherBodyQL(entityFrom); 30 | // var bodyQLTo = this._$cypherBodyQL(entityTo); 31 | var bodyQLAssoc = this._$cypherBodyQLInner(this._$entity); 32 | 33 | // var classeName = this._$entity.className(); 34 | var classeNameFrom = entityFrom.className(); 35 | var classeNameTo = entityTo.className(); 36 | 37 | var result = "MERGE (j:" + classeNameFrom + " {id: '" + entityFrom.id() + "'})-[r:" + bodyQLAssoc + "]->(m:" + classeNameTo + " {id: '" + entityTo.id() + "'})"; 38 | return result; 39 | } 40 | 41 | 42 | this._$cypherBodyQL = function (entity) { 43 | var properties = entity.properties(); 44 | var classeName = entity.className(); 45 | 46 | var result = '(a:' + classeName + '{'; 47 | 48 | for (const prop in properties) { 49 | if (Object.hasOwnProperty.call(properties, prop)) { 50 | const value = properties[prop]; 51 | result += prop.slice(2) + ':"' + value + '",'; 52 | } 53 | } 54 | const dateNow = this.currentStringDate(); 55 | result += 'dateInsert: "' + dateNow + '"})'; 56 | return result; 57 | } 58 | 59 | this._$cypherBodyQLInner = function (entity) { 60 | var properties = entity.properties(); 61 | var classeName = entity.className(); 62 | 63 | var result = classeName + '{'; 64 | 65 | for (const prop in properties) { 66 | if (Object.hasOwnProperty.call(properties, prop)) { 67 | const value = properties[prop]; 68 | result += prop.slice(2) + ':"' + value + '",'; 69 | } 70 | } 71 | const dateNow = this.currentStringDate(); 72 | result += 'dateInsert: "' + dateNow + '"}'; 73 | return result; 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Dao/Queries/Entity_ONTO.class.js: -------------------------------------------------------------------------------- 1 | const Entity = require('uds-framework/Entity.class'); 2 | const PObject = require('uds-framework/PObject.class'); 3 | /** 4 | * @abstract @class 5 | * @param {Entity} entity 6 | */ 7 | const Entity_ONTO = module.exports = function (entity) { 8 | PObject.call(this); 9 | this._$entity = entity; 10 | 11 | this.entityListqlSave = function () { 12 | var properties = this._$entity.properties(); 13 | var classeName = this._$entity.className(); 14 | 15 | var result = 'MERGE (a:' + classeName + '{'; 16 | 17 | for (const prop in properties) { 18 | if (Object.hasOwnProperty.call(properties, prop)) { 19 | const value = properties[prop]; 20 | result += prop.slice(2) + ':"' + value + '",'; 21 | } 22 | } 23 | const dateNow = this.currentStringDate(); 24 | result += 'dateInsert: "' + dateNow + '"}) ON CREATE SET a.id = ID(a) RETURN a.id AS id;'; 25 | return result; 26 | } 27 | 28 | this.entityqlGetList = function () { 29 | var classeName = this._$entity.className(); 30 | 31 | var result = this.prefixHeader() + " "; 32 | result += "select ?id ?a ?v "; 33 | result += "where { "; 34 | result += "?id rdfs:domain entity:" + classeName + ". "; 35 | result += "?id ?a ?v. "; 36 | result += "FILTER(STRSTARTS(STR(?id), \"http://example/framework/entity/instance/\")). "; 37 | result += "FILTER(STRSTARTS(STR(?a), \"http://example/framework/entity/atributs/\")). "; 38 | result += "}"; 39 | 40 | return result; 41 | } 42 | 43 | this.entityqlGetUnique = function () { 44 | var classeName = this._$entity.className(); 45 | 46 | var result = this.prefixHeader() + " "; 47 | result += "select ?id ?a ?v "; 48 | result += "where { "; 49 | result += "?id rdfs:domain entity:" + classeName + ". "; 50 | result += "?id ?a ?v. "; 51 | result += "FILTER(STRSTARTS(STR(?id), \"http://example/framework/entity/instance/" + this._$entity.id() + "\")). "; 52 | result += "FILTER(STRSTARTS(STR(?a), \"http://example/framework/entity/atributs/\")). "; 53 | result += "}"; 54 | 55 | return result; 56 | } 57 | 58 | this.entityListqlSaveTab = function () { 59 | var properties = this._$entity.properties(); 60 | var classeName = this._$entity.className(); 61 | var uniq = (new Date()).getTime(); 62 | 63 | var result = [ 64 | this.prefixHeader() + " INSERT DATA { instance:" + uniq + " rdf:type rdfs:Class.}", 65 | this.prefixHeader() + " INSERT DATA { instance:" + uniq + " rdfs:domain entity:" + classeName + ".}", 66 | ]; 67 | 68 | for (const prop in properties) { 69 | if (Object.hasOwnProperty.call(properties, prop)) { 70 | const value = properties[prop]; 71 | result.push( 72 | this.prefixHeader() + " INSERT DATA { instance:" + uniq + " atrib:" + prop.slice(2) + " '" + value + "'. }" 73 | ) 74 | } 75 | } 76 | 77 | const dateNow = this.currentStringDate(); 78 | result.push( 79 | this.prefixHeader() + " INSERT DATA { instance:" + uniq + " atrib:dateInsert '" + dateNow + "'. }" 80 | ); 81 | 82 | this._$entity.setId(uniq); 83 | return result; 84 | } 85 | 86 | this.prefixHeader = function () { 87 | return ` 88 | PREFIX entity: 89 | PREFIX atrib: 90 | PREFIX instance: 91 | `; 92 | } 93 | 94 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Entity.class.js: -------------------------------------------------------------------------------- 1 | const ArrayEntity = require('uds-framework/ArrayEntity.class'); 2 | const PObject = require('uds-framework/PObject.class'); 3 | /** 4 | * @abstract @class 5 | */ 6 | const Entity = module.exports = function (donnees) { 7 | ArrayEntity.call(this, donnees); 8 | this._$id = null; 9 | 10 | this.id = function () { 11 | return this._$id; 12 | } 13 | 14 | this.setId = function (id) { 15 | return this._$id = id; 16 | } 17 | 18 | this.isNew = function () { 19 | // console.log(); 20 | return parseInt(this._$id) + "" == "NaN" || parseInt(this._$id) < 1; 21 | } 22 | 23 | this.arrayDescriptions = function () { 24 | 25 | } 26 | 27 | this.arrayDescriptions = function () { 28 | 29 | } 30 | 31 | this.propertiesNames = function () { 32 | var result = [], i = 0; 33 | const properties = Object.keys(this); 34 | 35 | for (const key in properties) { 36 | if (Object.hasOwnProperty.call(properties, key)) { 37 | const propertyName = properties[key]; 38 | if (!this.isFunction(this[propertyName]) && i++ > 4) { 39 | // console.log(typeof propertyName); 40 | result.push(propertyName); 41 | } 42 | } 43 | } 44 | 45 | return result; 46 | } 47 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Field.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | /** 3 | * @abstract @class 4 | * @param {Object} options 5 | */ 6 | const Field = module.exports = function (options = {}) { 7 | PObject.call(this); 8 | 9 | this._$errorMessage = ""; 10 | this._$label = ""; 11 | this._$placeholder = ""; 12 | this._$name; 13 | this._$validators = []; 14 | this._$value = ""; 15 | this._$length = ""; 16 | this._$icon = ""; 17 | this._$class = ""; 18 | this._$disable = ""; 19 | 20 | /** 21 | * @abstract @function 22 | */ 23 | this.buildWidget = function () { } 24 | 25 | this.hydrate = function (options) { 26 | for (const type in options) { 27 | const method = 'set' + type.charAt(0).toUpperCase() + type.slice(1); 28 | if (Object.hasOwnProperty.call(this, method)) { 29 | const value = options[type]; 30 | this[method](value); 31 | } 32 | } 33 | } 34 | 35 | this.isValid = function () { 36 | for (const key in this._$validators) { 37 | if (Object.hasOwnProperty.call(this._$validators, key)) { 38 | const validator = this._$validators[key]; 39 | if (!validator.isValid(this._$value)) { 40 | this._$errorMessage = validator.errorMessage(); 41 | return false; 42 | } 43 | } 44 | } 45 | return true; 46 | } 47 | 48 | this.errorBuildMessage = function () { 49 | var widget = ""; 50 | if (this._$errorMessage.toString().trim() != '') { 51 | widget += ''; 54 | } 55 | return widget; 56 | } 57 | 58 | this.label = function () { 59 | return this._$label; 60 | } 61 | 62 | this.length = function () { 63 | return this._$length; 64 | } 65 | 66 | this.name = function () { 67 | return this._$name; 68 | } 69 | 70 | this.validators = function () { 71 | return this._$validators; 72 | } 73 | 74 | this.value = function () { 75 | return typeof this._$value === "string" ? this._$value : ""; 76 | } 77 | 78 | this.getIcon = function () { 79 | return this._$value; 80 | } 81 | 82 | this.placeholder = function () { 83 | return this._$placeholder; 84 | } 85 | 86 | this.class = function () { 87 | return this._$class; 88 | } 89 | 90 | this.disable = function () { 91 | return this._$disable; 92 | } 93 | 94 | this.setLabel = function (label) { 95 | this._$label = label; 96 | } 97 | 98 | this.setLength = function (length) { 99 | length = parseInt(length); 100 | if (length > 0) { 101 | this; _$length = length; 102 | } 103 | } 104 | 105 | this.setName = function (name) { 106 | if (typeof name === 'string') { 107 | this._$name = name 108 | } 109 | } 110 | 111 | this.setValidators = function (validators) { 112 | for (let i = 0; i < validators.length; i++) { 113 | const validator = validators[i]; 114 | // console.log(); 115 | if (validator.constructor.name.indexOf("Validator") !== -1) { 116 | this._$validators.push(validator); 117 | } 118 | } 119 | } 120 | 121 | this.setValue = function (value) { 122 | this._$value = value; 123 | } 124 | 125 | this.setIcon = function (icon) { 126 | if (typeof icon === "string") { 127 | this._$icon = icon; 128 | } 129 | } 130 | 131 | this.setPlaceholder = function (placeholder) { 132 | if (typeof placeholder === "string") { 133 | this._$placeholder = placeholder; 134 | } 135 | } 136 | 137 | this.setClass = function (_class) { 138 | if (typeof _class === "string") { 139 | this._$class = _class; 140 | } 141 | } 142 | 143 | this.setDisable = function (disable) { 144 | if (typeof disable === "string") { 145 | this._$disable = disable; 146 | } 147 | } 148 | 149 | this.hydrate(options); 150 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/FieldUtilitary.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | /** 3 | * @class 4 | */ 5 | const FieldUtilitary = module.exports = function () { 6 | PObject.call(this); 7 | 8 | this._$$TYPE_TEXT = "text"; 9 | this._$$TYPE_PWD = "password"; 10 | this._$$TYPE_NUMBER = "number"; 11 | this._$$TYPE_CHECK = "checkbox"; 12 | this._$$TYPE_DATE = "date"; 13 | this._$$TYPE_EMAIL = "email"; 14 | this._$$TYPE_FILE = "file"; 15 | this._$$TYPE_TEL = "tel"; 16 | this._$$TYPE_TIME = "time"; 17 | this._$$CLASS_FORM = "form-control"; 18 | 19 | this._$motifInputBody = function (name, type, value = "", _class = "", label = "", placeholder = "", id = "", require = false) { 20 | var widget = ""; 21 | if (!this.emptyString(label)) { 22 | widget += ""; 23 | } 24 | 25 | var optClass = this.emptyString(_class) ? this._$$CLASS_FORM : _class; 26 | // throw new \Exception($optClass); 27 | 28 | widget += '"; 46 | } 47 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Fields/StringField.class.js: -------------------------------------------------------------------------------- 1 | const Field = require("uds-framework/Field.class"); 2 | const FieldUtilitary = require("uds-framework/FieldUtilitary.class"); 3 | /** 4 | * @class 5 | */ 6 | const StringField = module.exports = function (options = {}) { 7 | Field.call(this, options); 8 | this._$fieldUtilitary = new FieldUtilitary(); 9 | 10 | /** 11 | * @returns string 12 | */ 13 | this.buildWidget = function () { 14 | const widget = this.errorBuildMessage(); 15 | return widget + "" + this._$fieldUtilitary.motifInput(this.name(), this._$fieldUtilitary._$$TYPE_TEXT, this.value(), this.class(), this.label(), this.placeholder(), this.disable()); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Form.class.js: -------------------------------------------------------------------------------- 1 | const Field = require("uds-framework/Field.class"); 2 | const Entity = require("uds-framework/Entity.class"); 3 | /** 4 | * @abstract @class 5 | */ 6 | const Form = module.exports = function (entity, file_upload = "") { 7 | this._$entitty; 8 | this._$fields = []; 9 | this._$fileUpload; 10 | 11 | /** 12 | * @param {Field} field 13 | */ 14 | this.add = function (field) { 15 | var 16 | attrib = field.name(), 17 | value = null; 18 | 19 | if (this._$entitty[attrib] !== undefined) { 20 | value = this._$entitty[attrib](); 21 | } 22 | 23 | field.setValue(value); 24 | this._$fields.push(field); 25 | return this; 26 | } 27 | 28 | this.createView = function () { 29 | var view = ""; 30 | for (const key in this._$fields) { 31 | if (Object.hasOwnProperty.call(this._$fields, key)) { 32 | const field = this._$fields[key]; 33 | view += '
'; 34 | view += field.buildWidget(); 35 | view += '
'; 36 | } 37 | } 38 | return view; 39 | } 40 | 41 | this.isValid = function () { 42 | var valid = true; 43 | for (const key in this._$fields) { 44 | if (Object.hasOwnProperty.call(this._$fields, key)) { 45 | const field = this._$fields[key]; 46 | if (!field.isValid()) { 47 | valid = false; 48 | } 49 | } 50 | } 51 | return valid; 52 | } 53 | 54 | /** 55 | * @returns Entity 56 | */ 57 | this.entity = function () { 58 | return this._$entitty; 59 | } 60 | 61 | /** 62 | * 63 | * @param {Entity} entity 64 | */ 65 | this.setEntity = function (entity) { 66 | this._$entitty = entity; 67 | } 68 | 69 | this.setEntity(entity); 70 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/FormBuilder.class.js: -------------------------------------------------------------------------------- 1 | const Managers = require("uds-framework/Managers.class"); 2 | const Entity = require("uds-framework/Entity.class"); 3 | const Form = require("uds-framework/Form.class"); 4 | /** 5 | * @abstract @class 6 | * @param {Managers} managers 7 | * @param {Entity} entity 8 | * @param {Array} options 9 | */ 10 | const FormBuilder = module.exports = function (managers, entity, options = {}) { 11 | this._$form; 12 | this._$options = options; 13 | this._$managers = managers; 14 | 15 | /** 16 | * @abstract @function 17 | */ 18 | this.build = function () { } 19 | 20 | /** 21 | * @param {Form} form 22 | */ 23 | this.setForm = function (form) { 24 | this._$form = form; 25 | } 26 | 27 | /** 28 | * @returns Form 29 | */ 30 | this.form = function () { 31 | return this._$form; 32 | } 33 | 34 | this.setForm(new Form(entity)); 35 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/FormHandler.class.js: -------------------------------------------------------------------------------- 1 | const Form = require("uds-framework/Form.class"); 2 | const HTTPRequest = require("uds-framework/HTTPRequest.class"); 3 | const Managers_api = require("uds-framework/Managers_api.class"); 4 | /** 5 | * @abstract @class 6 | */ 7 | const FormHandler = module.exports = function (form, managers, httpRequest) { 8 | this._$form; 9 | this._$manager; 10 | this._$request; 11 | 12 | /** 13 | * @returns bool 14 | */ 15 | this.process = async function () { 16 | if (this._$request.method() == 'POST' && this._$form.isValid()) { 17 | // console.log("PROCESSSSSSSSSSS"); 18 | await this._$form.entity().setId(this._$manager.save(this._$form.entity())); 19 | return true; 20 | } 21 | 22 | return false; 23 | } 24 | 25 | this.setForm = function (form) { 26 | this._$form = form; 27 | } 28 | 29 | this.setManager = function (manager) { 30 | this._$manager = manager; 31 | } 32 | 33 | this.setRequest = function (request) { 34 | this._$request = request; 35 | } 36 | 37 | /** 38 | * 39 | * @returns @returns Form 40 | */ 41 | this.form = function () { 42 | return this._$form; 43 | } 44 | 45 | this.setManager(managers); 46 | this.setForm(form); 47 | this.setRequest(httpRequest); 48 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/FormHandlerFactory.class.js: -------------------------------------------------------------------------------- 1 | const FormHandler = require("uds-framework/FormHandler.class"); 2 | /** 3 | * @abstract @class 4 | */ 5 | const FormHandlerFactory = module.exports = function (managers, entity, request, options = {}) { 6 | this._$managers = managers; 7 | this._$request = request; 8 | this._$entity = entity; 9 | 10 | this._$options = options; 11 | this._$form = null; 12 | this._$formHandler = null; 13 | 14 | this.build = function () { 15 | const classeName = this._$entity.className().charAt(0).toUpperCase() + this._$entity.className().slice(1); 16 | var builder = '../../AppliLib/FormBuilder/' + classeName + 'FormBuilder.class'; 17 | var cClass = require(builder); 18 | 19 | const formBuilder = new cClass(this._$managers, this._$entity, this._$options); 20 | formBuilder.build(); 21 | 22 | this._$form = formBuilder.form(); 23 | this._$formHandler = new FormHandler(this._$form, this._$managers.getManagerOf(classeName), this._$request); 24 | } 25 | 26 | this.formHandler = function () { 27 | return this._$formHandler; 28 | } 29 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/FormHeader.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | /** 3 | * @abstract @class 4 | */ 5 | const FormHeader = module.exports = function (request, entity) { 6 | PObject.call(this); 7 | this._$request = request; 8 | this._$entity = entity; 9 | // console.log(entity); 10 | /** 11 | * @returns Array 12 | */ 13 | this.dataForm = function () { 14 | const properties = this._$entity.propertiesNames(); 15 | var data = {}; 16 | 17 | for (let i = 0; i < properties.length; i++) { 18 | const name = properties[i]; 19 | data[name.slice(2)] = request.getParam(name.slice(2)); 20 | // console.log(name.slice(2)); 21 | } 22 | // console.log(request.getParams()); 23 | // console.log(data); 24 | return data; 25 | } 26 | 27 | /** 28 | * @returns Entity 29 | */ 30 | this.entity = function () { 31 | this._$entity.hydrate(this.dataForm()); 32 | return this._$entity; 33 | } 34 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/FormHeaderFactory.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | const HTTPRequest = require('uds-framework/HTTPRequest.class'); 3 | /** 4 | * @abstract @class 5 | * @param {HTTPRequest} request 6 | */ 7 | const FormHeaderFactory = module.exports = function (request) { 8 | PObject.call(this); 9 | this._$request = request; 10 | 11 | this.get = function (classeName) { 12 | const build = "../../AppliLib/FormHeaders/" + classeName + "FormHeader.class"; 13 | const entity = "../../AppliLib/Entities/" + classeName + ".class"; 14 | 15 | const buildClass = require(build); 16 | const entityClass = require(entity); 17 | 18 | var formHeader = new buildClass(this._$request, new entityClass); 19 | // console.log(formHeader); 20 | return formHeader.entity(); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/HTTPRequest.class.js: -------------------------------------------------------------------------------- 1 | const ApplicationComponent = require("uds-framework/ApplicationComponent.class"); 2 | const url = require('url'); 3 | const querystring = require('querystring'); 4 | /** 5 | * @class HTTPRequest 6 | * @param {Application} app 7 | */ 8 | const HTTPRequest = module.exports = function (app) { 9 | ApplicationComponent.call(this, app); 10 | 11 | this.serveurComponents = global.serveurComponentsObject; 12 | 13 | this.cookieData = function (key) { 14 | return ""; 15 | } 16 | 17 | this.cookieExists = function (key) { return } 18 | this.setAttribute = function (key) { return } 19 | this.getAttribute = function (key) { return } 20 | 21 | this.getData = function (key) { 22 | var params = querystring.parse(url.parse(this.serveurComponents._$reqObject.url).query); 23 | params = this.mergeArrays(global._$params, params); 24 | 25 | return params[key] !== undefined ? params[key] : null; 26 | } 27 | 28 | this.method = function () { 29 | return this.serveurComponents._$reqObject.method; 30 | } 31 | 32 | this.postData = function (key) { 33 | var body = this.serveurComponents._$reqObject.postData; 34 | 35 | var post = querystring.parse(body); 36 | post = Object.keys(post).shift(); 37 | if (post !== undefined) { 38 | post = JSON.parse(post); 39 | } 40 | else post = []; 41 | 42 | return post[key] !== undefined ? post[key] : null; 43 | } 44 | 45 | this.postExists = function (key) { 46 | var body = this.serveurComponents._$reqObject.postData; 47 | 48 | var post = querystring.parse(body); 49 | return post[key] !== undefined; 50 | } 51 | 52 | this.getParam = function (key) { 53 | return this.getData(key) !== null ? this.getData(key) : this.postData(key); 54 | } 55 | 56 | this.getParams = function () { 57 | var params = querystring.parse(url.parse(this.serveurComponents._$reqObject.url).query); 58 | params = this.mergeArrays(global._$params, params); 59 | 60 | var body = this.serveurComponents._$reqObject.postData; 61 | var post = querystring.parse(body); 62 | post = Object.keys(post).shift(); 63 | if (post !== undefined) { 64 | // console.log(post); 65 | // console.log(JSON.parse(post)); 66 | params = this.mergeArrays(params, JSON.parse(post)); 67 | } 68 | // console.log(post); 69 | return params; 70 | } 71 | 72 | this.fileData = function (key) { return } 73 | this.fileExists = function (key) { return } 74 | this.getUpFile = function (key) { return } 75 | this.forward = function (key) { return } 76 | this.getParamNames = function (key) { return } 77 | this.postParamNames = function (key) { return } 78 | this.paramNames = function (key) { return } 79 | this.paramValues = function (key) { return } 80 | 81 | /** 82 | * @returns {String} 83 | */ 84 | this.requestURI = function () { 85 | return url.parse(this.serveurComponents._$reqObject.url).pathname; 86 | } 87 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/HTTPResponse.class.js: -------------------------------------------------------------------------------- 1 | const ApplicationComponent = require("uds-framework/ApplicationComponent.class"); 2 | /** 3 | * @class HTTPResponse 4 | * @param {Application} app 5 | */ 6 | const HTTPResponse = module.exports = function (app) { 7 | ApplicationComponent.call(this, app); 8 | this.serveurComponents = global.serveurComponentsObject; 9 | 10 | this._$page = null; 11 | 12 | this.addHeaderAccess = function (headerAccess) { 13 | this.serveurComponents._$respObject.setHeader('Access-Control-Allow-Origin', headerAccess); // update to match the domain you will make the request from 14 | this.serveurComponents._$respObject.setHeader( 15 | 'Access-Control-Allow-Headers', 16 | 'Origin, X-Requested-With, Content-Type, Accept' 17 | ); 18 | } 19 | 20 | this.addHeader = function (name, value) { 21 | this.serveurComponents._$respObject.setHeader(name, value); 22 | // update to match the domain you will make the request from 23 | } 24 | 25 | /** 26 | * @param {string} location 27 | */ 28 | this.redirect = function (location) { 29 | this.serveurComponents._$respObject.writeHead(200, { 'Location': location }); 30 | this.serveurComponents._$respObject.end(); 31 | } 32 | 33 | this.redirect404 = function () { 34 | 35 | } 36 | 37 | this.send = function () { 38 | this.serveurComponents._$respObject.writeHead(200, { "Content-Type": "text/html" }); 39 | this.serveurComponents._$respObject.end(this._$page.getGeneratedPage()); 40 | } 41 | 42 | this.setPage = function (page) { 43 | this._$page = page; 44 | } 45 | 46 | this.page = function () { 47 | return this._$page; 48 | } 49 | 50 | this.setCookie = function (name, value = '', expire = 0, path = null, domain = null, secure = false, httpOnly = true) { 51 | 52 | } 53 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Managers.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | /** 3 | * @class Managers 4 | * @param {String} api 5 | * @param {Application} api 6 | */ 7 | const Managers = module.exports = function (api, dao) { 8 | PObject.call(this); 9 | this._$api = api; 10 | this._$dao = dao; 11 | this._$table = ''; 12 | // console.log(dao); 13 | this._$classeTable = ''; 14 | this._$namespace = ''; 15 | this._$managers = new Map(); 16 | 17 | this.initTable = function () { 18 | var root = "Manager_" + this._$api; 19 | var className = this.className().replace(root, ""); 20 | console.log(className); 21 | this._$classeTable = className; 22 | } 23 | 24 | this.getManagerOf = function (module) { 25 | if (!this._$managers.has(module)) { 26 | var cManager = require("../../AppliLib/Models/" + module + "Manager_" + this._$api + ".class"); 27 | this._$managers.set(module, new cManager(this._$api, this._$dao)); 28 | } 29 | 30 | return this._$managers.get(module); 31 | } 32 | 33 | this.dao = function () { 34 | return this._$dao; 35 | } 36 | 37 | this.classeTable = function () { 38 | // this.initTable(); 39 | return this._$classeTable; 40 | } 41 | 42 | this.initTable(); 43 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Managers_NEO4JDB.class.js: -------------------------------------------------------------------------------- 1 | const Managers_api = require("uds-framework/Managers_api.class"); 2 | const Entity_NEO4J = require("uds-framework/Dao/Queries/Entity_NEO4J.class"); 3 | // const neo4j = require("neo4j-driver"); 4 | /** 5 | * @abstract @class Managers_api 6 | * @param {String} api 7 | * @param {*} dao 8 | */ 9 | const Managers_NEO4JDB = module.exports = function (api, dao) { 10 | Managers_api.call(this, api, dao); 11 | 12 | this.getUnique = async function (id) { 13 | return await this.$query( 14 | 'MERGE (a:Greeting) ON CREATE SET a.message = $message RETURN a.message + ", from node " + id(a)', 15 | { message: 'hello, world' } 16 | ); 17 | } 18 | 19 | this._$add = async function (entity) { 20 | const entity_PDO = new Entity_NEO4J(entity); 21 | // console.log(entity_PDO.entityListqlSave()); 22 | const id = await this.$query(entity_PDO.entityListqlSave()); 23 | // console.log(Object.values(id[0])); 24 | return id[0].id.low; 25 | } 26 | 27 | this.addEntityAssociation = async function (entityFrom, entityAssoc, entityTo) { 28 | const entity_PDO = new Entity_NEO4J(entityAssoc); 29 | // console.log(entity_PDO.entitiesqlAddAssociation(entityFrom, entityTo)); 30 | const id = await this.$query(entity_PDO.entitiesqlAddAssociation(entityFrom, entityTo)); 31 | return id; 32 | } 33 | 34 | this.$query = async function (query, data = {}) { 35 | var result = null, resultSend = []; 36 | const session = this.dao().session(); 37 | try { 38 | result = await session.writeTransaction( 39 | tx => 40 | tx.run(query, data) 41 | ); 42 | for (let i = 0; i < result.records.length; i++) { 43 | const re = result.records[i]; 44 | // console.log(re.get('id')); 45 | // console.log(re.toObject()); 46 | resultSend.push(re.toObject()); 47 | } 48 | // const singleRecord = result.records[0]; 49 | // greeting = singleRecord.get(0); 50 | // console.log(greeting); 51 | } finally { 52 | await session.close(); 53 | } 54 | 55 | // on application exit: 56 | // await driver.close(); 57 | return resultSend; 58 | } 59 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Managers_OntGDB.class.js: -------------------------------------------------------------------------------- 1 | const Managers_api = require("uds-framework/Managers_api.class"); 2 | const Entity_ONTO = require("uds-framework/Dao/Queries/Entity_ONTO.class"); 3 | const groupBy = require('lodash.groupby'); 4 | const omit = require('lodash.omit'); 5 | /** 6 | * @abstract @class Managers_api 7 | * @param {String} api 8 | * @param {*} dao 9 | */ 10 | const Managers_OntGDB = module.exports = function (api, dao) { 11 | Managers_api.call(this, api, dao); 12 | 13 | /** 14 | * @protected @function 15 | * Méthode permettant d'ajouter une entité 16 | * @param {Entity} entity L'entité à ajouter 17 | * @returns Int 18 | */ 19 | this._$add = async function (entity) { 20 | const entity_PDO = new Entity_ONTO(entity); 21 | // console.log(entity_PDO.entityListqlSave()); 22 | const queries = entity_PDO.entityListqlSaveTab(); 23 | 24 | for (var i = 0; i < queries.length; i++) { 25 | const result = await this.$update(queries[i]); 26 | 27 | } 28 | 29 | // console.log(Object.values(id[0])); 30 | return entity.id(); 31 | } 32 | 33 | /** 34 | * @abstract @function 35 | * Méthode retournant une liste d'entités demandée 36 | * @param {Int} id La première enité à selectionner 37 | * @returns array La liste des entités. chaque entrée est une instance de Entity 38 | */ 39 | this.getUnique = async function (id) { 40 | const cEntity = require('../../AppliLib/Entities/' + this.classeTable() + '.class'); 41 | const entity = new cEntity(); 42 | entity.setId(id); 43 | // console.log(this.classeTable()); 44 | const entity_PDO = new Entity_ONTO(entity); 45 | const result = await this.$query(entity_PDO.entityqlGetUnique()); 46 | // console.log(this.$bindArrayEntity(result)); 47 | entity.hydrate(this.$bindArrayEntity(result)); 48 | // console.log(entity); 49 | return entity; 50 | // return 1; 51 | } 52 | 53 | /** 54 | * @abstract @function 55 | * Méthode retournant une liste d'entités demandée 56 | * @param {Int} debut La première enité à selectionner 57 | * @param {Int} limit Le nombre d'entité à selectionner 58 | * @returns array La liste des entités. chaque entrée est une instance de Entity 59 | */ 60 | this.getList = async function (debut = -1, limit = -1) { 61 | const cEntity = require('../../AppliLib/Entities/' + this.classeTable() + '.class'); 62 | var entity = new cEntity(); 63 | // entity.setId(id); 64 | // console.log(this.classeTable()); 65 | const entity_PDO = new Entity_ONTO(entity); 66 | var result = await this.$query(entity_PDO.entityqlGetList()); 67 | // console.log(this.$bindArrayEntities(result)); 68 | result = this.$bindArrayEntities(result); 69 | // entity.hydrate(this.$bindArrayEntities(result)); 70 | // console.log(entity); 71 | var entities = []; 72 | for (const id in result) { 73 | if (Object.hasOwnProperty.call(result, id)) { 74 | // const obj = result[id]; 75 | const entity = new cEntity(); 76 | // console.log(result[id]); 77 | entity.hydrate(result[id]); 78 | entities.push(entity); 79 | } 80 | } 81 | return entities; 82 | } 83 | 84 | /** 85 | * @protected @function 86 | * Méthode perméttant de modifier une entité 87 | * @param {Entity} entity L'entité à modifier 88 | * @returns Int 89 | */ 90 | this._$modify = async function (entity) { 91 | // console.log("jdksj"); 92 | } 93 | 94 | this.$query = async function (message) { 95 | try { 96 | let result = await this.dao() 97 | .query(message, 98 | { transform: 'toJSON' } 99 | ); 100 | // console.log(result); 101 | return result; 102 | } catch (error) { 103 | console.log(error); 104 | return []; 105 | } 106 | } 107 | 108 | this.$update = async function (message) { 109 | // console.log(message); 110 | try { 111 | let result = await this.dao() 112 | .update(message, 113 | { transform: 'toJSON' }); 114 | return result; 115 | } catch (error) { 116 | console.log(error); 117 | return []; 118 | } 119 | } 120 | 121 | this.$bindArrayEntity = function (dataQuery) { 122 | var 123 | records = dataQuery.records, 124 | result = {}; 125 | 126 | for (var i = 0; i < records.length; i++) { 127 | var 128 | attribName = records[i].a.replace("http://example/framework/entity/atributs/", ""), 129 | attribValue = records[i].v; 130 | // console.log(attribName); 131 | result[attribName] = attribValue; 132 | result["id"] = records[i].id.replace("http://example/framework/entity/instance/", ""); 133 | } 134 | 135 | return result; 136 | } 137 | 138 | this.$bindArrayEntities = function (dataQuery) { 139 | var 140 | records = dataQuery.records, 141 | result = {}; 142 | 143 | for (var i = 0; i < records.length; i++) { 144 | var 145 | id_ = records[i].id.replace("http://example/framework/entity/instance/", ""), 146 | attribName = records[i].a.replace("http://example/framework/entity/atributs/", ""), 147 | attribValue = records[i].v; 148 | // console.log(attribName); 149 | if (result[id_] === undefined) { 150 | result[id_] = { id: id_ }; 151 | } 152 | result[id_][attribName] = attribValue 153 | } 154 | 155 | return result; 156 | } 157 | 158 | this._$normalizeSparqlResults = (results) => 159 | omit( 160 | groupBy(results, (x) => x.predicat.split('#')[1]), 161 | [ 162 | 'topObjectProperty', 163 | 'first', 164 | 'someValuesFrom', 165 | 'allValuesFrom', 166 | 'topDataProperty', 167 | ] 168 | ); 169 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Managers_api.class.js: -------------------------------------------------------------------------------- 1 | const Entity = require('uds-framework/Entity.class'); 2 | const Managers = require('uds-framework/Managers.class'); 3 | /** 4 | * @abstract @class Managers_api 5 | * @param {String} api 6 | * @param {Application} api 7 | */ 8 | const Managers_api = module.exports = function (api, dao) { 9 | Managers.call(this, api, dao); 10 | /** 11 | * @abstract @protected @function 12 | * Méthode permettant d'ajouter une entité 13 | * @param {Entity} entity L'entité à ajouter 14 | * @returns Int 15 | */ 16 | this._$add = async function (entity) { } 17 | /** 18 | * @abstract @protected @function 19 | * Méthode perméttant de modifier une entité 20 | * @param {Entity} entity L'entité à modifier 21 | * @returns Int 22 | */ 23 | this._$modify = async function (entity) { } 24 | /** 25 | * Méthode permettant d'enrégistrer une intité. 26 | * @param {Entity} entity L'entité à enrégistrer 27 | * @returns Int 28 | */ 29 | this.save = async function (entity) { 30 | // console.log(entity.isNew()); 31 | if (entity.isValid()) { 32 | var id = 0; 33 | entity.isNew() ? id = await this._$add(entity) : id = await this._$modify(entity); 34 | entity.setId(id); 35 | return id; 36 | } else { 37 | new Error("L'entité doit être validée avant l'enrégistrement ou isValid() n'est pas defini !"); 38 | } 39 | } 40 | /** 41 | * @abstract @function 42 | * Méthode retournant une liste d'entités demandée 43 | * @param {Entity} entityFrom 44 | * @param {Entity} entityBy 45 | * @param {Entity} entityTo 46 | * @returns id Entity Association 47 | */ 48 | this.addEntityAssociation = function (entityFrom, enityBy, entityTo) { } 49 | 50 | /** 51 | * @abstract @function 52 | * Méthode retournant une liste d'entités demandée 53 | * @param {Int} debut La première enité à selectionner 54 | * @param {Int} limit Le nombre d'entité à selectionner 55 | * @returns array La liste des entités. chaque entrée est une instance de Entity 56 | */ 57 | this.getList = function (debut = -1, limit = -1) { } 58 | /** 59 | * @abstract @function 60 | * Méthode retournant une liste d'entités demandée 61 | * @param {Int} id La première enité à selectionner 62 | * @returns array La liste des entités. chaque entrée est une instance de Entity 63 | */ 64 | this.getUnique = function (id) { } 65 | /** 66 | * @abstract @function 67 | * Méthode permettant de supprimer une entité 68 | * @param {Int} id La première enité à selectionner 69 | * @returns void 70 | */ 71 | this.delete = function (id) { } 72 | /** 73 | * Méthode renvoyant le nombre d'entité total 74 | * @returns int 75 | */ 76 | this.count = function (id) { } 77 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/PObject.class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @abstract @class 3 | */ 4 | const PObject = module.exports = function () { 5 | 6 | /** 7 | * @param {string} value 8 | * @returns bool 9 | */ 10 | this.emptyString = function (value) { 11 | if (typeof value === "string") { 12 | // console.log(value); 13 | return value.trim() == ''; 14 | } 15 | return false; 16 | } 17 | 18 | this.className = function () { 19 | return this.constructor.name; 20 | } 21 | 22 | this.propertiesNames = function () { 23 | var result = []; 24 | const properties = Object.keys(this); 25 | 26 | for (const key in properties) { 27 | if (Object.hasOwnProperty.call(properties, key)) { 28 | const propertyName = properties[key]; 29 | if (!this.isFunction(this[propertyName])) { 30 | // console.log(typeof propertyName); 31 | result.push(propertyName); 32 | } 33 | } 34 | } 35 | 36 | return result; 37 | } 38 | this.properties = function () { 39 | var result = {}; 40 | const properties = this.propertiesNames(); 41 | 42 | for (let i = 0; i < properties.length; i++) { 43 | const propertyName = properties[i]; 44 | result[propertyName] = this[propertyName]; 45 | } 46 | 47 | return result; 48 | } 49 | 50 | this.escapeHtml = function (text) { 51 | if (text == null || text === undefined) { 52 | text = ""; 53 | } 54 | 55 | var map = { 56 | '&': '&', 57 | '<': '<', 58 | '>': '>', 59 | '"': '"', 60 | "'": ''' 61 | }; 62 | 63 | return text.replace(/[&<>"']/g, function (m) { return map[m]; }); 64 | } 65 | 66 | this.mergeArrays = function (tab1, tab2) { 67 | var result = {}; 68 | for (const key in tab1) { 69 | if (Object.hasOwnProperty.call(tab1, key)) { 70 | const elt = tab1[key]; 71 | result[key] = elt; 72 | } 73 | } 74 | 75 | for (const key in tab2) { 76 | if (Object.hasOwnProperty.call(tab2, key)) { 77 | const elt = tab2[key]; 78 | result[key] = elt; 79 | } 80 | } 81 | 82 | return result; 83 | } 84 | 85 | this.isFunction = function (tFunction) { 86 | return tFunction && {}.toString.call(tFunction) === '[object Function]'; 87 | } 88 | 89 | this.currentStringDate = function () { 90 | // const monthNames = ["January", "February", "March", "April", "May", "June", 91 | // "July", "August", "September", "October", "November", "December"]; 92 | // const dateObj = new Date(); 93 | // const month = monthNames[dateObj.getMonth()]; 94 | // const day = String(dateObj.getDate()).padStart(2, '0'); 95 | // const year = dateObj.getFullYear(); 96 | // const output = month + '\n' + day + ',' + year; 97 | 98 | return new Date(Date.now()).toLocaleString(); 99 | } 100 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Page.class.js: -------------------------------------------------------------------------------- 1 | const ApplicationComponent = require("uds-framework/ApplicationComponent.class"); 2 | const PageAction = require("uds-framework/PageAction.class"); 3 | /** 4 | * @class Page 5 | * @param {Application} app 6 | */ 7 | const Page = module.exports = function (app) { 8 | ApplicationComponent.call(this, app); 9 | 10 | this._$vars = new Map(); 11 | this._$viewContent = ""; 12 | this._$viewPath = ""; 13 | this._$onlyViewAction = false; 14 | 15 | this.initPageVars = function () { 16 | this._$vars = new Map(); 17 | } 18 | 19 | this.addVar = function (varName, value) { 20 | // console.log(varName); 21 | // console.log(value); 22 | this._$vars.set(varName, value); 23 | // console.log(this._$vars); 24 | } 25 | 26 | this.getVar = function (varName) { 27 | return this._$vars.get(varName); 28 | } 29 | 30 | /** 31 | * @returns String 32 | */ 33 | this.getGeneratedPage = function () { 34 | var action_view = this.getControllerView(); 35 | if (this._$onlyViewAction) { 36 | return action_view; 37 | } 38 | 39 | const cPage = require("./../../Applications/" + this._$app.name() + "/Templates/layout.view"); 40 | this._$vars.set("content-action-view", action_view); 41 | 42 | const view = new cPage(this); 43 | return view.getActionView(); 44 | } 45 | 46 | /** 47 | * @returns String 48 | */ 49 | this.getControllerView = function () { 50 | if (this._$viewContent == "") { 51 | this._$viewContent = this._$getControllerViewActu(); 52 | } 53 | return this._$viewContent; 54 | } 55 | 56 | /** 57 | * @returns String 58 | */ 59 | this._$getControllerViewActu = function () { 60 | /** 61 | * @var {PageAction} 62 | */ 63 | const cPageAction = require(this._$viewPath); 64 | const view = new cPageAction(this); 65 | return view.getActionView(); 66 | } 67 | 68 | this.setView = function (path) { 69 | this._$viewPath = path; 70 | } 71 | 72 | this.setOnlyViewAction = function (onlyViewAction = true) { 73 | this._$onlyViewAction = onlyViewAction; 74 | } 75 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/PageAction.class.js: -------------------------------------------------------------------------------- 1 | const Page = require("uds-framework/Page.class"); 2 | /** 3 | * @abstract @class PageAction 4 | * @param {Page} page 5 | */ 6 | const PageAction = module.exports = function (page) { 7 | this._$page = page; 8 | 9 | this.getActionView = function () { 10 | return ""; 11 | } 12 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Route.class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class Route 3 | */ 4 | const Route = module.exports = function (url, module, action, varsNames, vars = []) { 5 | this._$url = url; 6 | this._$module = module; 7 | this._$action = action; 8 | this._$varsNames = varsNames; 9 | this._$vars = vars; 10 | 11 | this.match = function (url) { 12 | var regex = new RegExp("^" + this._$url.replace(/\//g, '\\\/') + "$"); 13 | // var regexO = new RegExp("^\/$"); 14 | // console.log(this._$url.replace(/\//g, '\\\/')); 15 | // console.log(this._$url); 16 | if (regex.test(url)) { 17 | // console.log(regex.exec(url)); 18 | return regex.exec(url); 19 | } 20 | return false; 21 | } 22 | 23 | this.hasVars = function () { 24 | return this._$varsNames.length > 0; 25 | } 26 | 27 | this.url = function () { 28 | return this._$url; 29 | } 30 | 31 | this.module = function () { 32 | return this._$module; 33 | } 34 | 35 | this.action = function () { 36 | return this._$action; 37 | } 38 | 39 | this.vars = function () { 40 | return this._$vars; 41 | } 42 | 43 | this.varsNames = function () { 44 | return this._$varsNames; 45 | } 46 | 47 | this.setVars = function (vars) { 48 | this._$vars = vars; 49 | } 50 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Router.class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class Router 3 | */ 4 | const Router = module.exports = function () { 5 | this.routes = new Map(); 6 | 7 | this.addRoute = function (route) { 8 | if (!this.routes.has(route.url())) { 9 | this.routes.set(route.url(), route); 10 | } 11 | } 12 | 13 | this.getRoute = function (url) { 14 | for (const route of this.routes.values()) { 15 | // console.log(url); 16 | var varsValues = true; 17 | if ((varsValues = route.match(url)) !== false) { 18 | 19 | if (route.hasVars()) { 20 | // console.log(varsValues); 21 | var varsNames = route.varsNames(); 22 | var listVars = []; 23 | // console.log(varsNames); 24 | for (const key in varsValues) { 25 | if (Object.hasOwnProperty.call(varsValues, key)) { 26 | const match = varsValues[key]; 27 | // console.log("/////"); 28 | // console.log(key); 29 | // console.log(match); 30 | // console.log(varsNames[key - 1] !== undefined); 31 | // console.log("/////"); 32 | if (key !== 0 && varsNames[key - 1] !== undefined) { 33 | listVars[varsNames[key - 1]] = match; 34 | } 35 | } 36 | } 37 | route.setVars(listVars); 38 | } 39 | // console.log(route); 40 | return route; 41 | } 42 | } 43 | 44 | new Error("ROUTE NO VALIDE"); 45 | } 46 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/ServeurComponents.class.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | /** 3 | * @class ServeurComponents 4 | * @param {http.IncomingMessage} _req 5 | * @param {http.ServerResponse} _resp 6 | * @param {http} _http 7 | */ 8 | const ServeurComponents = module.exports = function (_req, _resp, _http) { 9 | this._$reqObject = _req; 10 | this._$respObject = _resp; 11 | this._$httpObject = _http; 12 | // res.writeHead(200, { "Content-Type": "text/json" }); 13 | this._$reqObject.postData = ""; 14 | global.serveurComponentsObject = this; 15 | this._$reqObject.on('data', function (data) { 16 | global.serveurComponentsObject._$reqObject.postData += data; 17 | // console.log(data); 18 | // Too much POST data, kill the connection! 19 | // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB 20 | if (global.serveurComponentsObject._$reqObject.postData.length > 1e6) 21 | global.serveurComponentsObject.serveurComponents._$reqObject.connection.destroy(); 22 | }); 23 | // res.end('{ "changed":' + count + '}'); 24 | this._$reqObject.on('end', function () { 25 | const Frontend = require('../../Applications/Frontend/FrontendApplication.class'); 26 | var frontend = new Frontend(); 27 | const run = async () => { 28 | await frontend.run(); 29 | }; 30 | 31 | (async () => { 32 | await run(); 33 | })(); 34 | }); 35 | // res.end("outXmlString Me"); 36 | // res.end(manager.readFile("./vues-test/index.xml")); 37 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Validator.class.js: -------------------------------------------------------------------------------- 1 | const PObject = require('uds-framework/PObject.class'); 2 | /** 3 | * @abstract @class 4 | */ 5 | const Validator = module.exports = function Validator(errorMessage) { 6 | PObject.call(this); 7 | this._$errorMessage; 8 | 9 | /** 10 | * @abstract 11 | * @param {String} value 12 | */ 13 | this.isValid = function (value) { } 14 | 15 | this.setErrorMessage = function (errorMessage) { 16 | this._$errorMessage = errorMessage.toString(); 17 | } 18 | 19 | this.errorMessage = function () { 20 | return this._$errorMessage; 21 | } 22 | 23 | this.setErrorMessage(errorMessage); 24 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/Validators/NotNullValidator.class.js: -------------------------------------------------------------------------------- 1 | const Validator = require('uds-framework/Validator.class'); 2 | /** 3 | * @class 4 | */ 5 | const NotNullValidator = module.exports = function NotNullValidator(errorMessage) { 6 | Validator.call(this, errorMessage); 7 | this._$id = null; 8 | 9 | this.isValid = function (value) { 10 | // console.log(value); 11 | // console.log(!this.emptyString(value)); 12 | return !this.emptyString(value); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /FAMECSE/uds-framework/index.js: -------------------------------------------------------------------------------- 1 | const ServeurComponents = require("./ServeurComponents.class"); 2 | 3 | const HTTPResponse = module.exports = { 4 | ServeurComponents: ServeurComponents 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # info205 2 | Association rule project in level 2, university of Yaounde I, department of computer science 3 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = tab 11 | indent_size = 4 12 | space_after_anon_function = true 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | indent_style = space 23 | indent_size = 4 24 | 25 | [{package,bower}.json] 26 | indent_style = space 27 | indent_size = 2 28 | 29 | [*.{yml,yaml}] 30 | trim_trailing_whitespace = false 31 | indent_style = space 32 | indent_size = 2 33 | 34 | [*.js] 35 | quote_type = "double" 36 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # JetBrains IDE 64 | .idea 65 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "type": "node", 10 | "request": "launch", 11 | "name": "Debug", 12 | "program": "${workspaceRoot}/node_modules/moleculer/bin/moleculer-runner.js", 13 | "cwd": "${workspaceRoot}", 14 | "args": [ 15 | "services" 16 | ] 17 | }, 18 | { 19 | "type": "node", 20 | "request": "launch", 21 | "name": "Jest", 22 | "program": "${workspaceRoot}/node_modules/jest-cli/bin/jest.js", 23 | "args": ["--runInBand"], 24 | "cwd": "${workspaceRoot}", 25 | "runtimeArgs": [ 26 | "--nolazy" 27 | ] 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/README.md: -------------------------------------------------------------------------------- 1 | [![Moleculer](https://badgen.net/badge/Powered%20by/Moleculer/0e83cd)](https://moleculer.services) 2 | 3 | # alphabox-workshop 4 | This is a [Moleculer](https://moleculer.services/)-based microservices project. Generated with the [Moleculer CLI](https://moleculer.services/docs/0.14/moleculer-cli.html). 5 | 6 | ## Usage 7 | Start the project with `npm run dev` command. 8 | After starting, open the http://localhost:3000/ URL in your browser. 9 | On the welcome page you can test the generated services via API Gateway and check the nodes & services. 10 | 11 | In the terminal, try the following commands: 12 | - `nodes` - List all connected nodes. 13 | - `actions` - List all registered service actions. 14 | - `call greeter.hello` - Call the `greeter.hello` action. 15 | - `call greeter.welcome --name John` - Call the `greeter.welcome` action with the `name` parameter. 16 | - `call products.list` - List the products (call the `products.list` action). 17 | 18 | 19 | ## Services 20 | - **api**: API Gateway services 21 | - **greeter**: Sample service with `hello` and `welcome` actions. 22 | - **products**: Sample DB service. To use with MongoDB, set `MONGO_URI` environment variables and install MongoDB adapter with `npm i moleculer-db-adapter-mongo`. 23 | 24 | ## Mixins 25 | - **db.mixin**: Database access mixin for services. Based on [moleculer-db](https://github.com/moleculerjs/moleculer-db#readme) 26 | 27 | 28 | ## Useful links 29 | 30 | * Moleculer website: https://moleculer.services/ 31 | * Moleculer Documentation: https://moleculer.services/docs/0.14/ 32 | 33 | ## NPM scripts 34 | 35 | - `npm run dev`: Start development mode (load all services locally with hot-reload & REPL) 36 | - `npm run start`: Start production mode (set `SERVICES` env variable to load certain services) 37 | - `npm run cli`: Start a CLI and connect to production. Don't forget to set production namespace with `--ns` argument in script 38 | - `npm run ci`: Run continuous test mode with watching 39 | - `npm test`: Run tests & generate coverage report 40 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/mixins/db.mixin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const fs = require("fs"); 4 | const DbService = require("moleculer-db"); 5 | 6 | /** 7 | * @typedef {import('moleculer').Context} Context Moleculer's Context 8 | */ 9 | 10 | module.exports = function(collection) { 11 | const cacheCleanEventName = `cache.clean.${collection}`; 12 | 13 | const schema = { 14 | mixins: [DbService], 15 | 16 | events: { 17 | /** 18 | * Subscribe to the cache clean event. If it's triggered 19 | * clean the cache entries for this service. 20 | * 21 | * @param {Context} ctx 22 | */ 23 | async [cacheCleanEventName]() { 24 | if (this.broker.cacher) { 25 | await this.broker.cacher.clean(`${this.fullName}.*`); 26 | } 27 | } 28 | }, 29 | 30 | methods: { 31 | /** 32 | * Send a cache clearing event when an entity changed. 33 | * 34 | * @param {String} type 35 | * @param {any} json 36 | * @param {Context} ctx 37 | */ 38 | async entityChanged(type, json, ctx) { 39 | ctx.broadcast(cacheCleanEventName); 40 | } 41 | }, 42 | 43 | async started() { 44 | // Check the count of items in the DB. If it's empty, 45 | // call the `seedDB` method of the service. 46 | if (this.seedDB) { 47 | const count = await this.adapter.count(); 48 | if (count == 0) { 49 | this.logger.info(`The '${collection}' collection is empty. Seeding the collection...`); 50 | await this.seedDB(); 51 | this.logger.info("Seeding is done. Number of records:", await this.adapter.count()); 52 | } 53 | } 54 | } 55 | }; 56 | 57 | if (process.env.MONGO_URI) { 58 | // Mongo adapter 59 | const MongoAdapter = require("moleculer-db-adapter-mongo"); 60 | 61 | schema.adapter = new MongoAdapter(process.env.MONGO_URI); 62 | schema.collection = collection; 63 | } else if (process.env.NODE_ENV === 'test') { 64 | // NeDB memory adapter for testing 65 | schema.adapter = new DbService.MemoryAdapter(); 66 | } else { 67 | // NeDB file DB adapter 68 | 69 | // Create data folder 70 | if (!fs.existsSync("./data")) { 71 | fs.mkdirSync("./data"); 72 | } 73 | 74 | schema.adapter = new DbService.MemoryAdapter({ filename: `./data/${collection}.db` }); 75 | } 76 | 77 | return schema; 78 | }; 79 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/moleculer.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Moleculer ServiceBroker configuration file 5 | * 6 | * More info about options: 7 | * https://moleculer.services/docs/0.14/configuration.html 8 | * 9 | * 10 | * Overwriting options in production: 11 | * ================================ 12 | * You can overwrite any option with environment variables. 13 | * For example to overwrite the "logLevel" value, use `LOGLEVEL=warn` env var. 14 | * To overwrite a nested parameter, e.g. retryPolicy.retries, use `RETRYPOLICY_RETRIES=10` env var. 15 | * 16 | * To overwrite broker’s deeply nested default options, which are not presented in "moleculer.config.js", 17 | * use the `MOL_` prefix and double underscore `__` for nested properties in .env file. 18 | * For example, to set the cacher prefix to `MYCACHE`, you should declare an env var as `MOL_CACHER__OPTIONS__PREFIX=mycache`. 19 | * It will set this: 20 | * { 21 | * cacher: { 22 | * options: { 23 | * prefix: "mycache" 24 | * } 25 | * } 26 | * } 27 | */ 28 | module.exports = { 29 | // Namespace of nodes to segment your nodes on the same network. 30 | namespace: "", 31 | // Unique node identifier. Must be unique in a namespace. 32 | nodeID: null, 33 | // Custom metadata store. Store here what you want. Accessing: `this.broker.metadata` 34 | metadata: {}, 35 | 36 | // Enable/disable logging or use custom logger. More info: https://moleculer.services/docs/0.14/logging.html 37 | // Available logger types: "Console", "File", "Pino", "Winston", "Bunyan", "debug", "Log4js", "Datadog" 38 | logger: { 39 | type: "Console", 40 | options: { 41 | // Using colors on the output 42 | colors: true, 43 | // Print module names with different colors (like docker-compose for containers) 44 | moduleColors: false, 45 | // Line formatter. It can be "json", "short", "simple", "full", a `Function` or a template string like "{timestamp} {level} {nodeID}/{mod}: {msg}" 46 | formatter: "full", 47 | // Custom object printer. If not defined, it uses the `util.inspect` method. 48 | objectPrinter: null, 49 | // Auto-padding the module name in order to messages begin at the same column. 50 | autoPadding: false 51 | } 52 | }, 53 | // Default log level for built-in console logger. It can be overwritten in logger options above. 54 | // Available values: trace, debug, info, warn, error, fatal 55 | logLevel: "info", 56 | 57 | // Define transporter. 58 | // More info: https://moleculer.services/docs/0.14/networking.html 59 | // Note: During the development, you don't need to define it because all services will be loaded locally. 60 | // In production you can set it via `TRANSPORTER=nats://localhost:4222` environment variable. 61 | transporter: null, //"TCP" 62 | 63 | // Define a cacher. 64 | // More info: https://moleculer.services/docs/0.14/caching.html 65 | cacher: null, 66 | 67 | // Define a serializer. 68 | // Available values: "JSON", "Avro", "ProtoBuf", "MsgPack", "Notepack", "Thrift". 69 | // More info: https://moleculer.services/docs/0.14/networking.html#Serialization 70 | serializer: "JSON", 71 | 72 | // Number of milliseconds to wait before reject a request with a RequestTimeout error. Disabled: 0 73 | requestTimeout: 10 * 1000, 74 | 75 | // Retry policy settings. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Retry 76 | retryPolicy: { 77 | // Enable feature 78 | enabled: false, 79 | // Count of retries 80 | retries: 5, 81 | // First delay in milliseconds. 82 | delay: 100, 83 | // Maximum delay in milliseconds. 84 | maxDelay: 1000, 85 | // Backoff factor for delay. 2 means exponential backoff. 86 | factor: 2, 87 | // A function to check failed requests. 88 | check: err => err && !!err.retryable 89 | }, 90 | 91 | // Limit of calling level. If it reaches the limit, broker will throw an MaxCallLevelError error. (Infinite loop protection) 92 | maxCallLevel: 100, 93 | 94 | // Number of seconds to send heartbeat packet to other nodes. 95 | heartbeatInterval: 10, 96 | // Number of seconds to wait before setting node to unavailable status. 97 | heartbeatTimeout: 30, 98 | 99 | // Cloning the params of context if enabled. High performance impact, use it with caution! 100 | contextParamsCloning: false, 101 | 102 | // Tracking requests and waiting for running requests before shuting down. More info: https://moleculer.services/docs/0.14/context.html#Context-tracking 103 | tracking: { 104 | // Enable feature 105 | enabled: false, 106 | // Number of milliseconds to wait before shuting down the process. 107 | shutdownTimeout: 5000, 108 | }, 109 | 110 | // Disable built-in request & emit balancer. (Transporter must support it, as well.). More info: https://moleculer.services/docs/0.14/networking.html#Disabled-balancer 111 | disableBalancer: false, 112 | 113 | // Settings of Service Registry. More info: https://moleculer.services/docs/0.14/registry.html 114 | registry: { 115 | // Define balancing strategy. More info: https://moleculer.services/docs/0.14/balancing.html 116 | // Available values: "RoundRobin", "Random", "CpuUsage", "Latency", "Shard" 117 | strategy: "RoundRobin", 118 | // Enable local action call preferring. Always call the local action instance if available. 119 | preferLocal: true 120 | }, 121 | 122 | // Settings of Circuit Breaker. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Circuit-Breaker 123 | circuitBreaker: { 124 | // Enable feature 125 | enabled: false, 126 | // Threshold value. 0.5 means that 50% should be failed for tripping. 127 | threshold: 0.5, 128 | // Minimum request count. Below it, CB does not trip. 129 | minRequestCount: 20, 130 | // Number of seconds for time window. 131 | windowTime: 60, 132 | // Number of milliseconds to switch from open to half-open state 133 | halfOpenTime: 10 * 1000, 134 | // A function to check failed requests. 135 | check: err => err && err.code >= 500 136 | }, 137 | 138 | // Settings of bulkhead feature. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Bulkhead 139 | bulkhead: { 140 | // Enable feature. 141 | enabled: false, 142 | // Maximum concurrent executions. 143 | concurrency: 10, 144 | // Maximum size of queue 145 | maxQueueSize: 100, 146 | }, 147 | 148 | // Enable action & event parameter validation. More info: https://moleculer.services/docs/0.14/validating.html 149 | validator: true, 150 | 151 | errorHandler: null, 152 | 153 | // Enable/disable built-in metrics function. More info: https://moleculer.services/docs/0.14/metrics.html 154 | metrics: { 155 | enabled: false, 156 | // Available built-in reporters: "Console", "CSV", "Event", "Prometheus", "Datadog", "StatsD" 157 | reporter: { 158 | type: "Prometheus", 159 | options: { 160 | // HTTP port 161 | port: 3030, 162 | // HTTP URL path 163 | path: "/metrics", 164 | // Default labels which are appended to all metrics labels 165 | defaultLabels: registry => ({ 166 | namespace: registry.broker.namespace, 167 | nodeID: registry.broker.nodeID 168 | }) 169 | } 170 | } 171 | }, 172 | 173 | // Enable built-in tracing function. More info: https://moleculer.services/docs/0.14/tracing.html 174 | tracing: { 175 | enabled: false, 176 | // Available built-in exporters: "Console", "Datadog", "Event", "EventLegacy", "Jaeger", "Zipkin" 177 | exporter: { 178 | type: "Console", // Console exporter is only for development! 179 | options: { 180 | // Custom logger 181 | logger: null, 182 | // Using colors 183 | colors: true, 184 | // Width of row 185 | width: 100, 186 | // Gauge width in the row 187 | gaugeWidth: 40 188 | } 189 | } 190 | }, 191 | 192 | // Register custom middlewares 193 | middlewares: [], 194 | 195 | // Register custom REPL commands. 196 | replCommands: null, 197 | 198 | // Called after broker created. 199 | created(broker) { 200 | 201 | }, 202 | 203 | // Called after broker started. 204 | async started(broker) { 205 | 206 | }, 207 | 208 | // Called after broker stopped. 209 | async stopped(broker) { 210 | 211 | } 212 | }; 213 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alphabox-workshop", 3 | "version": "1.0.0", 4 | "description": "My Moleculer-based microservices project", 5 | "scripts": { 6 | "dev": "moleculer-runner --repl --hot services/**/*.service.js", 7 | "start": "moleculer-runner", 8 | "cli": "moleculer connect TCP", 9 | "ci": "jest --watch", 10 | "test": "jest --coverage" 11 | }, 12 | "keywords": [ 13 | "microservices", 14 | "moleculer" 15 | ], 16 | "author": "", 17 | "devDependencies": { 18 | "jest": "^26.6.3", 19 | "jest-cli": "^26.6.3", 20 | "moleculer-repl": "^0.6.4" 21 | }, 22 | "dependencies": { 23 | "moleculer-web": "^0.9.1", 24 | "moleculer-db": "^0.8.4", 25 | "moleculer-db-adapter-mongo": "^0.4.7", 26 | "moleculer": "^0.14.13" 27 | }, 28 | "engines": { 29 | "node": ">= 10.x.x" 30 | }, 31 | "jest": { 32 | "coverageDirectory": "../coverage", 33 | "testEnvironment": "node", 34 | "rootDir": "./services", 35 | "roots": [ 36 | "../test" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | alphabox-workshop - Moleculer Microservices Project 8 | 9 | 10 | 11 | 12 | 322 | 323 | 324 |
325 |
326 | 327 | 332 |
333 | 334 |
335 |
336 |
337 |

Welcome to your Moleculer microservices project!

338 |

Check out the Moleculer documentation to learn how to customize this project.

339 | 340 | 387 |
388 |
389 | 390 | 423 | 424 |
425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 448 | 449 | 450 |
Node IDTypeVersionIPHostnameStatusCPU
{{ node.id }}{{ node.client.type }}{{ node.client.version }}{{ node.ipList[0] }}{{ node.hostname }}
{{ node.available ? "Online": "Offline" }}
445 |
446 | {{ node.cpu != null ? Number(node.cpu).toFixed(0) + '%' : '-' }} 447 |
451 |
452 |
453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 496 | 497 |
Service/Action nameRESTParametersInstancesStatus
498 |
499 |
500 | 501 | 512 |
513 | 753 | 754 | 755 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/services/api.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const ApiGateway = require("moleculer-web"); 4 | 5 | /** 6 | * @typedef {import('moleculer').Context} Context Moleculer's Context 7 | * @typedef {import('http').IncomingMessage} IncomingRequest Incoming HTTP Request 8 | * @typedef {import('http').ServerResponse} ServerResponse HTTP Server Response 9 | */ 10 | 11 | module.exports = { 12 | name: "api", 13 | mixins: [ApiGateway], 14 | 15 | // More info about settings: https://moleculer.services/docs/0.14/moleculer-web.html 16 | settings: { 17 | // Exposed port 18 | port: process.env.PORT || 3000, 19 | 20 | // Exposed IP 21 | ip: "0.0.0.0", 22 | 23 | // Global Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares 24 | use: [], 25 | 26 | routes: [ 27 | { 28 | path: "/api", 29 | 30 | whitelist: [ 31 | "**" 32 | ], 33 | 34 | // Route-level Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares 35 | use: [], 36 | 37 | // Enable/disable parameter merging method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Disable-merging 38 | mergeParams: true, 39 | 40 | // Enable authentication. Implement the logic into `authenticate` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authentication 41 | authentication: false, 42 | 43 | // Enable authorization. Implement the logic into `authorize` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authorization 44 | authorization: false, 45 | 46 | // The auto-alias feature allows you to declare your route alias directly in your services. 47 | // The gateway will dynamically build the full routes from service schema. 48 | autoAliases: true, 49 | 50 | aliases: { 51 | 52 | }, 53 | 54 | /** 55 | * Before call hook. You can check the request. 56 | * @param {Context} ctx 57 | * @param {Object} route 58 | * @param {IncomingRequest} req 59 | * @param {ServerResponse} res 60 | * @param {Object} data 61 | * 62 | onBeforeCall(ctx, route, req, res) { 63 | // Set request headers to context meta 64 | ctx.meta.userAgent = req.headers["user-agent"]; 65 | }, */ 66 | 67 | /** 68 | * After call hook. You can modify the data. 69 | * @param {Context} ctx 70 | * @param {Object} route 71 | * @param {IncomingRequest} req 72 | * @param {ServerResponse} res 73 | * @param {Object} data 74 | onAfterCall(ctx, route, req, res, data) { 75 | // Async function which return with Promise 76 | return doSomething(ctx, res, data); 77 | }, */ 78 | 79 | // Calling options. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Calling-options 80 | callingOptions: {}, 81 | 82 | bodyParsers: { 83 | json: { 84 | strict: false, 85 | limit: "1MB" 86 | }, 87 | urlencoded: { 88 | extended: true, 89 | limit: "1MB" 90 | } 91 | }, 92 | 93 | // Mapping policy setting. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Mapping-policy 94 | mappingPolicy: "all", // Available values: "all", "restrict" 95 | 96 | // Enable/disable logging 97 | logging: true 98 | } 99 | ], 100 | 101 | // Do not log client side errors (does not log an error response when the error.code is 400<=X<500) 102 | log4XXResponses: false, 103 | // Logging the request parameters. Set to any log level to enable it. E.g. "info" 104 | logRequestParams: null, 105 | // Logging the response data. Set to any log level to enable it. E.g. "info" 106 | logResponseData: null, 107 | 108 | 109 | // Serve assets from "public" folder. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Serve-static-files 110 | assets: { 111 | folder: "public", 112 | 113 | // Options to `server-static` module 114 | options: {} 115 | } 116 | }, 117 | 118 | methods: { 119 | 120 | /** 121 | * Authenticate the request. It check the `Authorization` token value in the request header. 122 | * Check the token value & resolve the user by the token. 123 | * The resolved user will be available in `ctx.meta.user` 124 | * 125 | * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! 126 | * 127 | * @param {Context} ctx 128 | * @param {Object} route 129 | * @param {IncomingRequest} req 130 | * @returns {Promise} 131 | */ 132 | async authenticate(ctx, route, req) { 133 | // Read the token from header 134 | const auth = req.headers["authorization"]; 135 | 136 | if (auth && auth.startsWith("Bearer")) { 137 | const token = auth.slice(7); 138 | 139 | // Check the token. Tip: call a service which verify the token. E.g. `accounts.resolveToken` 140 | if (token == "123456") { 141 | // Returns the resolved user. It will be set to the `ctx.meta.user` 142 | return { id: 1, name: "John Doe" }; 143 | 144 | } else { 145 | // Invalid token 146 | throw new ApiGateway.Errors.UnAuthorizedError(ApiGateway.Errors.ERR_INVALID_TOKEN); 147 | } 148 | 149 | } else { 150 | // No token. Throw an error or do nothing if anonymous access is allowed. 151 | // throw new E.UnAuthorizedError(E.ERR_NO_TOKEN); 152 | return null; 153 | } 154 | }, 155 | 156 | /** 157 | * Authorize the request. Check that the authenticated user has right to access the resource. 158 | * 159 | * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! 160 | * 161 | * @param {Context} ctx 162 | * @param {Object} route 163 | * @param {IncomingRequest} req 164 | * @returns {Promise} 165 | */ 166 | async authorize(ctx, route, req) { 167 | // Get the authenticated user. 168 | const user = ctx.meta.user; 169 | 170 | // It check the `auth` property in action schema. 171 | if (req.$action.auth == "required" && !user) { 172 | throw new ApiGateway.Errors.UnAuthorizedError("NO_RIGHTS"); 173 | } 174 | } 175 | 176 | } 177 | }; 178 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/services/greeter.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import('moleculer').Context} Context Moleculer's Context 5 | */ 6 | 7 | module.exports = { 8 | name: "greeter", 9 | 10 | /** 11 | * Settings 12 | */ 13 | settings: { 14 | 15 | }, 16 | 17 | /** 18 | * Dependencies 19 | */ 20 | dependencies: [], 21 | 22 | /** 23 | * Actions 24 | */ 25 | actions: { 26 | 27 | /** 28 | * Say a 'Hello' action. 29 | * 30 | * @returns 31 | */ 32 | hello: { 33 | rest: { 34 | method: "GET", 35 | path: "/hello" 36 | }, 37 | async handler() { 38 | return "Hello Moleculer"; 39 | } 40 | }, 41 | 42 | /** 43 | * Welcome, a username 44 | * 45 | * @param {String} name - User name 46 | */ 47 | welcome: { 48 | rest: "/welcome", 49 | params: { 50 | name: "string" 51 | }, 52 | /** @param {Context} ctx */ 53 | async handler(ctx) { 54 | return `Welcome, ${ctx.params.name}`; 55 | } 56 | } 57 | }, 58 | 59 | /** 60 | * Events 61 | */ 62 | events: { 63 | 64 | }, 65 | 66 | /** 67 | * Methods 68 | */ 69 | methods: { 70 | 71 | }, 72 | 73 | /** 74 | * Service created lifecycle event handler 75 | */ 76 | created() { 77 | 78 | }, 79 | 80 | /** 81 | * Service started lifecycle event handler 82 | */ 83 | async started() { 84 | 85 | }, 86 | 87 | /** 88 | * Service stopped lifecycle event handler 89 | */ 90 | async stopped() { 91 | 92 | } 93 | }; 94 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/services/products.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const DbMixin = require("../mixins/db.mixin"); 4 | 5 | /** 6 | * @typedef {import('moleculer').Context} Context Moleculer's Context 7 | */ 8 | 9 | module.exports = { 10 | name: "products", 11 | // version: 1 12 | 13 | /** 14 | * Mixins 15 | */ 16 | mixins: [DbMixin("products")], 17 | 18 | /** 19 | * Settings 20 | */ 21 | settings: { 22 | // Available fields in the responses 23 | fields: [ 24 | "_id", 25 | "name", 26 | "quantity", 27 | "price" 28 | ], 29 | 30 | // Validator for the `create` & `insert` actions. 31 | entityValidator: { 32 | name: "string|min:3", 33 | price: "number|positive" 34 | } 35 | }, 36 | 37 | /** 38 | * Action Hooks 39 | */ 40 | hooks: { 41 | before: { 42 | /** 43 | * Register a before hook for the `create` action. 44 | * It sets a default value for the quantity field. 45 | * 46 | * @param {Context} ctx 47 | */ 48 | create(ctx) { 49 | ctx.params.quantity = 0; 50 | } 51 | } 52 | }, 53 | 54 | /** 55 | * Actions 56 | */ 57 | actions: { 58 | /** 59 | * The "moleculer-db" mixin registers the following actions: 60 | * - list 61 | * - find 62 | * - count 63 | * - create 64 | * - insert 65 | * - update 66 | * - remove 67 | */ 68 | 69 | // --- ADDITIONAL ACTIONS --- 70 | 71 | /** 72 | * Increase the quantity of the product item. 73 | */ 74 | increaseQuantity: { 75 | rest: "PUT /:id/quantity/increase", 76 | params: { 77 | id: "string", 78 | value: "number|integer|positive" 79 | }, 80 | async handler(ctx) { 81 | const doc = await this.adapter.updateById(ctx.params.id, { $inc: { quantity: ctx.params.value } }); 82 | const json = await this.transformDocuments(ctx, ctx.params, doc); 83 | await this.entityChanged("updated", json, ctx); 84 | 85 | return json; 86 | } 87 | }, 88 | 89 | /** 90 | * Decrease the quantity of the product item. 91 | */ 92 | decreaseQuantity: { 93 | rest: "PUT /:id/quantity/decrease", 94 | params: { 95 | id: "string", 96 | value: "number|integer|positive" 97 | }, 98 | /** @param {Context} ctx */ 99 | async handler(ctx) { 100 | const doc = await this.adapter.updateById(ctx.params.id, { $inc: { quantity: -ctx.params.value } }); 101 | const json = await this.transformDocuments(ctx, ctx.params, doc); 102 | await this.entityChanged("updated", json, ctx); 103 | 104 | return json; 105 | } 106 | } 107 | }, 108 | 109 | /** 110 | * Methods 111 | */ 112 | methods: { 113 | /** 114 | * Loading sample data to the collection. 115 | * It is called in the DB.mixin after the database 116 | * connection establishing & the collection is empty. 117 | */ 118 | async seedDB() { 119 | await this.adapter.insertMany([ 120 | { name: "Samsung Galaxy S10 Plus", quantity: 10, price: 704 }, 121 | { name: "iPhone 11 Pro", quantity: 25, price: 999 }, 122 | { name: "Huawei P30 Pro", quantity: 15, price: 679 }, 123 | ]); 124 | } 125 | }, 126 | 127 | /** 128 | * Fired after database connection establishing. 129 | */ 130 | async afterConnected() { 131 | // await this.adapter.collection.createIndex({ name: 1 }); 132 | } 133 | }; 134 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/test/integration/products.service.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ServiceBroker, Context } = require("moleculer"); 4 | const { ValidationError } = require("moleculer").Errors; 5 | const TestService = require("../../services/products.service"); 6 | 7 | describe("Test 'products' service", () => { 8 | 9 | describe("Test actions", () => { 10 | const broker = new ServiceBroker({ logger: false }); 11 | const service = broker.createService(TestService); 12 | service.seedDB = null; // Disable seeding 13 | 14 | beforeAll(() => broker.start()); 15 | afterAll(() => broker.stop()); 16 | 17 | const record = { 18 | name: "Awesome item", 19 | price: 999 20 | }; 21 | let newID; 22 | 23 | it("should contains the seeded items", async () => { 24 | const res = await broker.call("products.list"); 25 | expect(res).toEqual({ page: 1, pageSize: 10, rows: [], total: 0, totalPages: 0 }); 26 | }); 27 | 28 | it("should add the new item", async () => { 29 | const res = await broker.call("products.create", record); 30 | expect(res).toEqual({ 31 | _id: expect.any(String), 32 | name: "Awesome item", 33 | price: 999, 34 | quantity: 0 35 | }); 36 | newID = res._id; 37 | 38 | const res2 = await broker.call("products.count"); 39 | expect(res2).toBe(1); 40 | }); 41 | 42 | it("should get the saved item", async () => { 43 | const res = await broker.call("products.get", { id: newID }); 44 | expect(res).toEqual({ 45 | _id: expect.any(String), 46 | name: "Awesome item", 47 | price: 999, 48 | quantity: 0 49 | }); 50 | 51 | const res2 = await broker.call("products.list"); 52 | expect(res2).toEqual({ 53 | page: 1, 54 | pageSize: 10, 55 | rows: [{ _id: newID, name: "Awesome item", price: 999, quantity: 0 }], 56 | total: 1, 57 | totalPages: 1 58 | }); 59 | }); 60 | 61 | it("should update an item", async () => { 62 | const res = await broker.call("products.update", { id: newID, price: 499 }); 63 | expect(res).toEqual({ 64 | _id: expect.any(String), 65 | name: "Awesome item", 66 | price: 499, 67 | quantity: 0 68 | }); 69 | }); 70 | 71 | it("should get the updated item", async () => { 72 | const res = await broker.call("products.get", { id: newID }); 73 | expect(res).toEqual({ 74 | _id: expect.any(String), 75 | name: "Awesome item", 76 | price: 499, 77 | quantity: 0 78 | }); 79 | }); 80 | 81 | it("should increase the quantity", async () => { 82 | const res = await broker.call("products.increaseQuantity", { id: newID, value: 5 }); 83 | expect(res).toEqual({ 84 | _id: expect.any(String), 85 | name: "Awesome item", 86 | price: 499, 87 | quantity: 5 88 | }); 89 | }); 90 | 91 | it("should decrease the quantity", async () => { 92 | const res = await broker.call("products.decreaseQuantity", { id: newID, value: 2 }); 93 | expect(res).toEqual({ 94 | _id: expect.any(String), 95 | name: "Awesome item", 96 | price: 499, 97 | quantity: 3 98 | }); 99 | }); 100 | 101 | it("should remove the updated item", async () => { 102 | const res = await broker.call("products.remove", { id: newID }); 103 | expect(res).toBe(1); 104 | 105 | const res2 = await broker.call("products.count"); 106 | expect(res2).toBe(0); 107 | 108 | const res3 = await broker.call("products.list"); 109 | expect(res3).toEqual({ page: 1, pageSize: 10, rows: [], total: 0, totalPages: 0 }); 110 | }); 111 | 112 | }); 113 | 114 | }); 115 | 116 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/test/unit/mixins/db.mixin.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ServiceBroker } = require("moleculer"); 4 | const DbService = require("moleculer-db"); 5 | const DbMixin = require("../../../mixins/db.mixin"); 6 | 7 | describe("Test DB mixin", () => { 8 | 9 | describe("Test schema generator", () => { 10 | const broker = new ServiceBroker({ logger: false, cacher: "Memory" }); 11 | 12 | beforeAll(() => broker.start()); 13 | afterAll(() => broker.stop()); 14 | 15 | it("check schema properties", async () => { 16 | const schema = DbMixin("my-collection"); 17 | 18 | expect(schema.mixins).toEqual([DbService]); 19 | expect(schema.adapter).toBeInstanceOf(DbService.MemoryAdapter); 20 | expect(schema.started).toBeDefined(); 21 | expect(schema.events["cache.clean.my-collection"]).toBeInstanceOf(Function); 22 | }); 23 | 24 | it("check cache event handler", async () => { 25 | jest.spyOn(broker.cacher, "clean"); 26 | 27 | const schema = DbMixin("my-collection"); 28 | 29 | await schema.events["cache.clean.my-collection"].call({ broker, fullName: "my-service" }); 30 | 31 | expect(broker.cacher.clean).toBeCalledTimes(1); 32 | expect(broker.cacher.clean).toBeCalledWith("my-service.*"); 33 | }); 34 | 35 | describe("Check service started handler", () => { 36 | 37 | it("should not call seedDB method", async () => { 38 | const schema = DbMixin("my-collection"); 39 | 40 | schema.adapter.count = jest.fn(async () => 10); 41 | const seedDBFn = jest.fn(); 42 | 43 | await schema.started.call({ broker, logger: broker.logger, adapter: schema.adapter, seedDB: seedDBFn }); 44 | 45 | expect(schema.adapter.count).toBeCalledTimes(1); 46 | expect(schema.adapter.count).toBeCalledWith(); 47 | 48 | expect(seedDBFn).toBeCalledTimes(0); 49 | }); 50 | 51 | it("should call seedDB method", async () => { 52 | const schema = DbMixin("my-collection"); 53 | 54 | schema.adapter.count = jest.fn(async () => 0); 55 | const seedDBFn = jest.fn(); 56 | 57 | await schema.started.call({ broker, logger: broker.logger, adapter: schema.adapter, seedDB: seedDBFn }); 58 | 59 | expect(schema.adapter.count).toBeCalledTimes(2); 60 | expect(schema.adapter.count).toBeCalledWith(); 61 | 62 | expect(seedDBFn).toBeCalledTimes(1); 63 | expect(seedDBFn).toBeCalledWith(); 64 | }); 65 | }); 66 | 67 | it("should broadcast a cache clear event", async () => { 68 | const schema = DbMixin("my-collection"); 69 | 70 | const ctx = { 71 | broadcast: jest.fn() 72 | }; 73 | 74 | await schema.methods.entityChanged(null, null, ctx); 75 | 76 | expect(ctx.broadcast).toBeCalledTimes(1); 77 | expect(ctx.broadcast).toBeCalledWith("cache.clean.my-collection"); 78 | }); 79 | }); 80 | 81 | }); 82 | 83 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/test/unit/services/greeter.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ServiceBroker } = require("moleculer"); 4 | const { ValidationError } = require("moleculer").Errors; 5 | const TestService = require("../../../services/greeter.service"); 6 | 7 | describe("Test 'greeter' service", () => { 8 | let broker = new ServiceBroker({ logger: false }); 9 | broker.createService(TestService); 10 | 11 | beforeAll(() => broker.start()); 12 | afterAll(() => broker.stop()); 13 | 14 | describe("Test 'greeter.hello' action", () => { 15 | 16 | it("should return with 'Hello Moleculer'", async () => { 17 | const res = await broker.call("greeter.hello"); 18 | expect(res).toBe("Hello Moleculer"); 19 | }); 20 | 21 | }); 22 | 23 | describe("Test 'greeter.welcome' action", () => { 24 | 25 | it("should return with 'Welcome'", async () => { 26 | const res = await broker.call("greeter.welcome", { name: "Adam" }); 27 | expect(res).toBe("Welcome, Adam"); 28 | }); 29 | 30 | it("should reject an ValidationError", async () => { 31 | expect.assertions(1); 32 | try { 33 | await broker.call("greeter.welcome"); 34 | } catch(err) { 35 | expect(err).toBeInstanceOf(ValidationError); 36 | } 37 | }); 38 | 39 | }); 40 | 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /alphabox-workshop/microservices-server/test/unit/services/products.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { ServiceBroker, Context } = require("moleculer"); 4 | const { ValidationError } = require("moleculer").Errors; 5 | const TestService = require("../../../services/products.service"); 6 | 7 | describe("Test 'products' service", () => { 8 | 9 | describe("Test actions", () => { 10 | const broker = new ServiceBroker({ logger: false }); 11 | const service = broker.createService(TestService); 12 | 13 | jest.spyOn(service.adapter, "updateById"); 14 | jest.spyOn(service, "transformDocuments"); 15 | jest.spyOn(service, "entityChanged"); 16 | 17 | beforeAll(() => broker.start()); 18 | afterAll(() => broker.stop()); 19 | 20 | const record = { 21 | _id: "123", 22 | name: "Awesome thing", 23 | price: 999, 24 | quantity: 25, 25 | createdAt: Date.now() 26 | }; 27 | 28 | describe("Test 'products.increaseQuantity'", () => { 29 | 30 | it("should call the adapter updateById method & transform result", async () => { 31 | service.adapter.updateById.mockImplementation(async () => record); 32 | service.transformDocuments.mockClear(); 33 | service.entityChanged.mockClear(); 34 | 35 | const res = await broker.call("products.increaseQuantity", { 36 | id: "123", 37 | value: 10 38 | }); 39 | expect(res).toEqual({ 40 | _id: "123", 41 | name: "Awesome thing", 42 | price: 999, 43 | quantity: 25, 44 | }); 45 | 46 | expect(service.adapter.updateById).toBeCalledTimes(1); 47 | expect(service.adapter.updateById).toBeCalledWith("123", { $inc: { quantity: 10 } } ); 48 | 49 | expect(service.transformDocuments).toBeCalledTimes(1); 50 | expect(service.transformDocuments).toBeCalledWith(expect.any(Context), { id: "123", value: 10 }, record); 51 | 52 | expect(service.entityChanged).toBeCalledTimes(1); 53 | expect(service.entityChanged).toBeCalledWith("updated", { _id: "123", name: "Awesome thing", price: 999, quantity: 25 }, expect.any(Context)); 54 | }); 55 | 56 | }); 57 | 58 | describe("Test 'products.decreaseQuantity'", () => { 59 | 60 | it("should call the adapter updateById method & transform result", async () => { 61 | service.adapter.updateById.mockClear(); 62 | service.transformDocuments.mockClear(); 63 | service.entityChanged.mockClear(); 64 | 65 | const res = await broker.call("products.decreaseQuantity", { 66 | id: "123", 67 | value: 10 68 | }); 69 | expect(res).toEqual({ 70 | _id: "123", 71 | name: "Awesome thing", 72 | price: 999, 73 | quantity: 25, 74 | }); 75 | 76 | expect(service.adapter.updateById).toBeCalledTimes(1); 77 | expect(service.adapter.updateById).toBeCalledWith("123", { $inc: { quantity: -10 } } ); 78 | 79 | expect(service.transformDocuments).toBeCalledTimes(1); 80 | expect(service.transformDocuments).toBeCalledWith(expect.any(Context), { id: "123", value: 10 }, record); 81 | 82 | expect(service.entityChanged).toBeCalledTimes(1); 83 | expect(service.entityChanged).toBeCalledWith("updated", { _id: "123", name: "Awesome thing", price: 999, quantity: 25 }, expect.any(Context)); 84 | }); 85 | 86 | it("should throw error if params is not valid", async () => { 87 | service.adapter.updateById.mockClear(); 88 | service.transformDocuments.mockClear(); 89 | service.entityChanged.mockClear(); 90 | 91 | expect.assertions(2); 92 | try { 93 | await broker.call("products.decreaseQuantity", { 94 | id: "123", 95 | value: -5 96 | }); 97 | } catch(err) { 98 | expect(err).toBeInstanceOf(ValidationError); 99 | expect(err.data).toEqual([{ 100 | action: "products.decreaseQuantity", 101 | actual: -5, 102 | field: "value", 103 | message: "The 'value' field must be a positive number.", 104 | nodeID: broker.nodeID, 105 | type: "numberPositive" 106 | }]); 107 | } 108 | }); 109 | 110 | }); 111 | 112 | }); 113 | 114 | describe("Test methods", () => { 115 | const broker = new ServiceBroker({ logger: false }); 116 | const service = broker.createService(TestService); 117 | 118 | jest.spyOn(service.adapter, "insertMany"); 119 | jest.spyOn(service, "seedDB"); 120 | 121 | beforeAll(() => broker.start()); 122 | afterAll(() => broker.stop()); 123 | 124 | describe("Test 'seedDB'", () => { 125 | 126 | it("should be called after service started & DB connected", async () => { 127 | expect(service.seedDB).toBeCalledTimes(1); 128 | expect(service.seedDB).toBeCalledWith(); 129 | }); 130 | 131 | it("should insert 3 documents", async () => { 132 | expect(service.adapter.insertMany).toBeCalledTimes(1); 133 | expect(service.adapter.insertMany).toBeCalledWith([ 134 | { name: "Samsung Galaxy S10 Plus", quantity: 10, price: 704 }, 135 | { name: "iPhone 11 Pro", quantity: 25, price: 999 }, 136 | { name: "Huawei P30 Pro", quantity: 15, price: 679 }, 137 | ]); 138 | }); 139 | 140 | }); 141 | 142 | }); 143 | 144 | describe("Test hooks", () => { 145 | const broker = new ServiceBroker({ logger: false }); 146 | const createActionFn = jest.fn(); 147 | broker.createService(TestService, { 148 | actions: { 149 | create: { 150 | handler: createActionFn 151 | } 152 | } 153 | }); 154 | 155 | beforeAll(() => broker.start()); 156 | afterAll(() => broker.stop()); 157 | 158 | describe("Test before 'create' hook", () => { 159 | 160 | it("should add quantity with zero", async () => { 161 | await broker.call("products.create", { 162 | id: "111", 163 | name: "Test product", 164 | price: 100 165 | }); 166 | 167 | expect(createActionFn).toBeCalledTimes(1); 168 | expect(createActionFn.mock.calls[0][0].params).toEqual({ 169 | id: "111", 170 | name: "Test product", 171 | price: 100, 172 | quantity: 0 173 | }); 174 | }); 175 | 176 | }); 177 | 178 | }); 179 | 180 | }); 181 | 182 | -------------------------------------------------------------------------------- /mon_test.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiofidelus/codingparty/25c280379ced952a22beb898db3bc39cf56d9e4c/mon_test.tar.xz --------------------------------------------------------------------------------