First commit
This commit is contained in:
307
framework/server/applicationManager.js
Normal file
307
framework/server/applicationManager.js
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org - The Unified Company
|
||||
|
||||
*/
|
||||
|
||||
import file from './file.js';
|
||||
|
||||
import socketManager from './socketManagerServer.js';
|
||||
|
||||
import core from './core.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import defaultObject from '../unify/defaultObject.js';
|
||||
|
||||
import moduleLoader from '../server/moduleLoader.js';
|
||||
|
||||
import Console from '../server/console.js';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import process from 'process';
|
||||
|
||||
import imports from './imports.js';
|
||||
|
||||
import simplePath from "../unify/simplePath.js";
|
||||
|
||||
import { inspect } from 'util'
|
||||
|
||||
import deepclone from '../unify/clonedeep.js';
|
||||
|
||||
|
||||
|
||||
export default class applicationManager{
|
||||
|
||||
defaultSocketPort = 5002;
|
||||
|
||||
runExampleApplications = true;
|
||||
|
||||
defaultObject = new defaultObject();
|
||||
|
||||
moduleLoader = new moduleLoader();
|
||||
|
||||
serverAddress = "localhost";
|
||||
|
||||
serverPort = false;
|
||||
|
||||
httpsServer;
|
||||
|
||||
serverManager;
|
||||
|
||||
|
||||
|
||||
|
||||
groomApplicationObject( application ) {
|
||||
|
||||
//console.log("before groom: ", tools.sizeOf( application ) )
|
||||
|
||||
//tools.groomApplicationObject( application );
|
||||
|
||||
//console.log("after groom: ", tools.sizeOf( application ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
importApplication( applicationID ) {
|
||||
|
||||
var app = new imports[ applicationID ]();
|
||||
|
||||
this.groomApplicationObject( app );
|
||||
|
||||
this.defaultObject.agregateDefaultObject( app );
|
||||
|
||||
app.setApplicationID( applicationID );
|
||||
|
||||
return app;
|
||||
|
||||
}
|
||||
|
||||
setupCore( socket, applicationID ) {
|
||||
|
||||
var unifyCore = new core();
|
||||
|
||||
if( applicationID == 0 ) {
|
||||
|
||||
global.core = unifyCore;
|
||||
|
||||
}
|
||||
|
||||
unifyCore.socket = socket;
|
||||
|
||||
return unifyCore;
|
||||
|
||||
}
|
||||
|
||||
parseApplication( unifyCore, app, client ) {
|
||||
|
||||
unifyCore.parse( app, client );
|
||||
|
||||
unifyCore.createDependencyMap( client );
|
||||
|
||||
}
|
||||
|
||||
setGlobals( client, application ) {
|
||||
|
||||
global.objects = client.objects;
|
||||
|
||||
global.classObjects = client.classObjects;
|
||||
|
||||
global.dependencieMap = client.dependencieMap;
|
||||
|
||||
global.maxClients = application.maxClients;
|
||||
|
||||
global.cacheBuildSpeed = application.cacheBuildSpeed;
|
||||
|
||||
}
|
||||
|
||||
loadUnloadedFiles( client, unifyCore ) {
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
this.moduleLoader.client = client;
|
||||
|
||||
this.moduleLoader.loadModulesFromFiles( "/", unifyCore, client );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createTables( unifyCore ) {
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
unifyCore.tableManager.createTables();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createDummyClient() {
|
||||
|
||||
var client = new Object();
|
||||
|
||||
client.objects = new Array();
|
||||
|
||||
client.classObjects = new Array();
|
||||
|
||||
return client;
|
||||
|
||||
}
|
||||
|
||||
setApplicationGlobals( applicationID, unifyCore, socket ) {
|
||||
|
||||
global.cores[ applicationID ] = unifyCore;
|
||||
|
||||
global.sockets[ applicationID ] = socket;
|
||||
|
||||
}
|
||||
|
||||
prepareApplication( unifyCore, app, applicationID ) {
|
||||
|
||||
if( applicationID == 0 ) {
|
||||
|
||||
var client = this.createDummyClient();
|
||||
|
||||
|
||||
|
||||
this.parseApplication( unifyCore, app, client );
|
||||
|
||||
this.loadUnloadedFiles( client, unifyCore );
|
||||
|
||||
this.setGlobals( client, app );
|
||||
|
||||
this.createTables( unifyCore );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
instantiateSocket( applicationID, app ) {
|
||||
|
||||
var socket = new socketManager( this.defaultSocketPort + applicationID );
|
||||
|
||||
socket.serverManager = this.serverManager;
|
||||
|
||||
socket.httpsServer = this.httpsServer;
|
||||
|
||||
socket.applicationURLArray = this.applicationURLArray;
|
||||
|
||||
|
||||
var unifyCore = new core();
|
||||
|
||||
//unifyCore.prepareClone( app );
|
||||
|
||||
socket.setApplication( deepclone( app ) );
|
||||
|
||||
socket.setApplicationID( applicationID );
|
||||
|
||||
//socket.setApplication( app );
|
||||
|
||||
return socket;
|
||||
|
||||
}
|
||||
|
||||
setupSocketConnection( socket, unifyCore ) {
|
||||
|
||||
socket.create();
|
||||
|
||||
socket.core = unifyCore;
|
||||
|
||||
}
|
||||
|
||||
async runApplication( applicationThree, applicationID ) {
|
||||
|
||||
var app = this.importApplication( applicationID );
|
||||
|
||||
|
||||
var socket = this.instantiateSocket( applicationID, app );
|
||||
|
||||
var unifyCore = this.setupCore( socket, applicationID );
|
||||
|
||||
|
||||
this.prepareApplication( unifyCore, app, applicationID );
|
||||
|
||||
this.setupSocketConnection( socket, unifyCore );
|
||||
|
||||
this.setApplicationGlobals( applicationID, unifyCore, socket );
|
||||
|
||||
|
||||
await unifyCore.findDuplicates( app );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
setApplicationURL( applications ) {
|
||||
|
||||
if( this.runExampleApplications ) {
|
||||
|
||||
this.applicationURLArray = applications;
|
||||
|
||||
} else {
|
||||
|
||||
this.applicationURLArray = new Array( applications[0] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createGlobals() {
|
||||
|
||||
global.applications = new Object();
|
||||
|
||||
global.cores = new Array();
|
||||
|
||||
}
|
||||
|
||||
getNumberOfApplication() {
|
||||
|
||||
if( this.runExampleApplications ) {
|
||||
|
||||
var number_applications = this.applications.length;
|
||||
|
||||
} else {
|
||||
|
||||
var number_applications = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
async runApplications( applications ) {
|
||||
|
||||
this.createGlobals();
|
||||
|
||||
this.setApplicationURL( applications );
|
||||
|
||||
// remove later
|
||||
this.applications = applications;
|
||||
|
||||
var n = this.getNumberOfApplication();
|
||||
|
||||
for( var c = 0; c < 1; c++ ) {
|
||||
|
||||
var applicationThree = this.applications[ c ];
|
||||
|
||||
|
||||
await this.runApplication( applicationThree, c );
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
145
framework/server/cacheDisabler.js
Normal file
145
framework/server/cacheDisabler.js
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
export default class cacheDisabler{
|
||||
|
||||
randomString = String( Math.floor(Math.random() * 1000 )).padStart(4, '0');
|
||||
|
||||
trimParts( parts ) {
|
||||
|
||||
return parts.filter( function( entry ) { return entry.trim() != ''; });
|
||||
|
||||
}
|
||||
|
||||
removePreviousRandomNumber( parts, overrideSplit ) {
|
||||
|
||||
var overrideSplit = parts[3].split("?");
|
||||
|
||||
|
||||
|
||||
if( overrideSplit[1] ) {
|
||||
|
||||
// ';
|
||||
if( parts[3].includes(";") ) {
|
||||
|
||||
var lastPart = overrideSplit[1].slice( overrideSplit[1].length-2, overrideSplit[1].length );
|
||||
|
||||
|
||||
// '
|
||||
} else {
|
||||
|
||||
var lastPart = overrideSplit[1].slice( overrideSplit[1].length-1, overrideSplit[1].length );
|
||||
|
||||
}
|
||||
|
||||
|
||||
overrideSplit[1] = lastPart;
|
||||
|
||||
parts[3] = overrideSplit.join("")
|
||||
|
||||
|
||||
}
|
||||
|
||||
return parts;
|
||||
|
||||
}
|
||||
|
||||
injectWithoutSemicolon( parts, index, random, part ) {
|
||||
|
||||
var l = part.length;
|
||||
|
||||
parts[ index ] = part.slice( 0, l - 1 ) + random + part.slice( l - 1, l );
|
||||
|
||||
}
|
||||
|
||||
injectWithSemicolon( parts, index, random, part ) {
|
||||
|
||||
var l = part.length;
|
||||
|
||||
parts[ index ] = part.slice( 0, l - 2 ) + random + part.slice( l - 2, l );
|
||||
|
||||
}
|
||||
|
||||
injectRandomNumber( parts ) {
|
||||
|
||||
var randomString = "?disableCache=" + this.randomString;
|
||||
|
||||
var urlPartIndex = parts.length - 1;
|
||||
|
||||
var urlPart = parts[ urlPartIndex ];
|
||||
|
||||
if( urlPart.includes(";") ) {
|
||||
|
||||
this.injectWithSemicolon( parts, urlPartIndex, randomString, urlPart );
|
||||
|
||||
} else {
|
||||
|
||||
this.injectWithoutSemicolon( parts, urlPartIndex, randomString, urlPart );
|
||||
|
||||
}
|
||||
|
||||
return parts;
|
||||
|
||||
}
|
||||
|
||||
parseImportLine( lineWords ) {
|
||||
|
||||
lineWords = this.trimParts( lineWords );
|
||||
|
||||
lineWords = this.removePreviousRandomNumber( lineWords );
|
||||
|
||||
lineWords = this.injectRandomNumber( lineWords );
|
||||
|
||||
return lineWords;
|
||||
|
||||
}
|
||||
|
||||
parseLine( lines, i ) {
|
||||
|
||||
var stripped = lines[i].replaceAll("\t", " ");
|
||||
|
||||
var parts = stripped.split(" ");
|
||||
|
||||
if( parts.includes("import") ) {
|
||||
|
||||
parts = this.parseImportLine( parts );
|
||||
|
||||
}
|
||||
|
||||
lines[i] = parts.join(" ");
|
||||
|
||||
}
|
||||
|
||||
parseSource( source, path ) {
|
||||
|
||||
source = source.replaceAll("\r", "\n");
|
||||
|
||||
var lines = source.split("\n");
|
||||
|
||||
for ( var i = 0; i < lines.length; i++ ) {
|
||||
|
||||
this.parseLine( lines, i );
|
||||
|
||||
|
||||
}
|
||||
|
||||
var body = lines.join("\n");
|
||||
|
||||
return body;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
365
framework/server/cachedControllers/columnController.js
Normal file
365
framework/server/cachedControllers/columnController.js
Normal file
@@ -0,0 +1,365 @@
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
|
||||
as published by the ESA.
|
||||
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
|
||||
|
||||
import deepclone from '../../unify/clonedeep.js';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default class columnController{
|
||||
|
||||
__className = "columnController";
|
||||
|
||||
__sourcePath = "./framework/server/cachedControllers/columnController.js";
|
||||
|
||||
__publicMethods = "update";
|
||||
|
||||
|
||||
|
||||
|
||||
prepareQuery() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
deleteByParentID( tableName, parent_id, storageCollection ) {
|
||||
|
||||
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
|
||||
|
||||
query.type = "delete";
|
||||
|
||||
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
|
||||
|
||||
query.find( storageCollection.getLeft() + "_id", parent_id );
|
||||
|
||||
|
||||
|
||||
database.query( query );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateRow( row, clientValue ) {
|
||||
|
||||
|
||||
|
||||
if( clientValue == "" ) {
|
||||
|
||||
|
||||
|
||||
clientValue = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
var validated = true;
|
||||
|
||||
|
||||
|
||||
if( object.validate ) {
|
||||
|
||||
|
||||
|
||||
validated = object.validate( row, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( clientValue == true && validated ) {
|
||||
|
||||
|
||||
|
||||
var row_id = row.id;
|
||||
|
||||
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
|
||||
|
||||
query.type = "insert";
|
||||
|
||||
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
|
||||
|
||||
query.setColumn( storageCollection.getLeft() + "_id", parent_id );
|
||||
|
||||
|
||||
|
||||
query.setColumn( storageCollection.getRight() + "_id", row_id );
|
||||
|
||||
|
||||
|
||||
database.query( query );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateRenderCollection( object ) {
|
||||
|
||||
|
||||
|
||||
var clientObject = deepclone( object );
|
||||
|
||||
|
||||
|
||||
var storageCollection = object.storageCollection;
|
||||
|
||||
|
||||
|
||||
var leftTableName = storageCollection.parentName;
|
||||
|
||||
var rightTableName = storageCollection.parent.propertyName;
|
||||
|
||||
|
||||
|
||||
var tableName = leftTableName + "_" + rightTableName;
|
||||
|
||||
var parent_id = object.parent.id;
|
||||
|
||||
|
||||
|
||||
this.deleteByParentID( tableName, parent_id, storageCollection );
|
||||
|
||||
|
||||
|
||||
object.get( client );
|
||||
|
||||
|
||||
|
||||
for( var c = 0; c < object.rows.length; c++ ) {
|
||||
|
||||
|
||||
|
||||
var row = object.rows[c];
|
||||
|
||||
|
||||
|
||||
var clientValue = clientObject.rows[c].value;
|
||||
|
||||
|
||||
|
||||
this.updateRow( row, clientValue );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
findParentTable( object ) {
|
||||
|
||||
|
||||
|
||||
if( object.type == "table" ) {
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
return this.findParentTable( object.parent );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateColumn( object ) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var table = this.findParentTable( object );
|
||||
|
||||
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
|
||||
|
||||
query.type = "update";
|
||||
|
||||
|
||||
|
||||
//console.log( table );
|
||||
|
||||
|
||||
|
||||
query.addObject( table );
|
||||
|
||||
|
||||
|
||||
database.query( query );
|
||||
|
||||
|
||||
|
||||
//this.objectManager.updateClient( object, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
update( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
if( !object.isAllowed( client.user, "WRITE" ) ) {
|
||||
|
||||
|
||||
|
||||
object.deserialize();
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( object.type == "renderCollection" ) {
|
||||
|
||||
|
||||
|
||||
// For storageCollection selects and check buttons
|
||||
|
||||
this.updateRenderCollection( object );
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
this.updateColumn( object );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
71
framework/server/cachedControllers/nodeEditorController.js
Normal file
71
framework/server/cachedControllers/nodeEditorController.js
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import files from "../launcher.js";
|
||||
|
||||
|
||||
|
||||
var fileManager = new files();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default class nodeEditor{
|
||||
|
||||
__className = "nodeEditor";
|
||||
|
||||
__sourcePath = "./framework/server/cachedControllers/nodeEditorController.js";
|
||||
|
||||
__public = "";
|
||||
|
||||
|
||||
|
||||
|
||||
getProject( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
console.log("get project");
|
||||
|
||||
|
||||
|
||||
console.log("readdir");
|
||||
|
||||
|
||||
|
||||
fileManager.findApplicationFiles("./application/test_project/");
|
||||
|
||||
|
||||
|
||||
var output = new Object();
|
||||
|
||||
|
||||
|
||||
output.files = fileManager.applicationURLArray;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return fileManager.applicationURLArray;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
199
framework/server/cachedControllers/objectController.js
Normal file
199
framework/server/cachedControllers/objectController.js
Normal file
@@ -0,0 +1,199 @@
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
|
||||
as published by the ESA.
|
||||
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
|
||||
|
||||
import deepclone from '../../unify/clonedeep.js';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default class objectController{
|
||||
|
||||
__className = "objectController";
|
||||
|
||||
__sourcePath = "./framework/server/cachedControllers/objectController.js";
|
||||
|
||||
__publicMethods = "callNodeMethod";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async callNodeMethod( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
console.log("called method", object.nodeMethodName, eventName);
|
||||
|
||||
|
||||
|
||||
var args = JSON.parse( object.nodeMethodArguments );
|
||||
|
||||
|
||||
|
||||
object.client = client;
|
||||
|
||||
|
||||
|
||||
var output = object[ eventName ]( args[0], args[1], args[2], args[3], args[4], args[5] );
|
||||
|
||||
|
||||
|
||||
delete object.client;
|
||||
|
||||
|
||||
|
||||
var out = await output;
|
||||
|
||||
|
||||
|
||||
if( !typeof out ) {
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
//console.log("output", out);
|
||||
|
||||
|
||||
|
||||
return out;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Deprecated, Unsafe.
|
||||
|
||||
add( json, client, eventName ) {
|
||||
|
||||
/*
|
||||
|
||||
// todo : this is not save
|
||||
|
||||
|
||||
|
||||
var properties = JSON.parse( json );
|
||||
|
||||
|
||||
|
||||
var parentObject = tools.getObjectByPath( client.application, properties.parentApplicationPath );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var classObjects = client.classObjects;
|
||||
|
||||
|
||||
|
||||
var object = client.classObjects[ properties.className ];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var objectClone = deepclone( object );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
parentObject[ properties.propertyName ] = objectClone;
|
||||
|
||||
|
||||
|
||||
objectClone.parent = parentObject;
|
||||
|
||||
|
||||
|
||||
objectClone.propertyName = properties.propertyName;
|
||||
|
||||
|
||||
|
||||
objectClone.id = properties.id;
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
375
framework/server/cachedControllers/settingsController.js
Normal file
375
framework/server/cachedControllers/settingsController.js
Normal file
@@ -0,0 +1,375 @@
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
|
||||
as published by the ESA.
|
||||
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
|
||||
|
||||
import userManager from '../userManager.js';
|
||||
|
||||
|
||||
|
||||
import filemanager from '../filemanager.js';
|
||||
|
||||
|
||||
|
||||
import path from 'path';
|
||||
|
||||
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var __dirname = path.resolve();
|
||||
|
||||
|
||||
|
||||
var files = new filemanager();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default class settingsController{
|
||||
|
||||
__className = "settingsController";
|
||||
|
||||
__sourcePath = "./framework/server/cachedControllers/settingsController.js";
|
||||
|
||||
__publicMethods = "setType,getCacheDateTime,recreateCache,setVisibleElements,setTheme,signOut,signIn";
|
||||
|
||||
|
||||
|
||||
|
||||
setType( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
//console.log("set type", object);
|
||||
|
||||
|
||||
|
||||
switch( object ) {
|
||||
|
||||
|
||||
|
||||
case "debug":
|
||||
|
||||
|
||||
|
||||
client.type = "debug";
|
||||
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
removeClient( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
//client.destroy();
|
||||
|
||||
|
||||
|
||||
//console.log( "removed client", client.id );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getCacheDateTime() {
|
||||
|
||||
|
||||
|
||||
return fs.statSync( "./assets/cache/cache.js" ).mtime
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
recreateCache( object ) {
|
||||
|
||||
|
||||
|
||||
console.log("object.performCacheUpdate = true;", object.getClassName());
|
||||
|
||||
|
||||
|
||||
object.performCacheUpdate = true;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
setVisibleElements( elements, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
//console.log("setVisibleElements", elements);
|
||||
|
||||
|
||||
|
||||
global.visibleElements = elements.split(",");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
setTheme( themeProfileJSON ) {
|
||||
|
||||
|
||||
|
||||
var themeProfile = JSON.parse( themeProfileJSON );
|
||||
|
||||
|
||||
|
||||
console.log("setTheme", themeProfile );
|
||||
|
||||
|
||||
|
||||
global.os = tools.CamelCase( themeProfile.os );
|
||||
|
||||
|
||||
|
||||
global.device = tools.CamelCase( themeProfile.device );
|
||||
|
||||
|
||||
|
||||
global.tint = tools.CamelCase( themeProfile.tint );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
debugObject( path, client, eventName ){
|
||||
|
||||
|
||||
|
||||
//Console.enableLog( path );
|
||||
|
||||
console.log( "enable debug object", path );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
signOut( cookieUser, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
return userManager.signOut( cookieUser, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
signIn( cookieUser, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
return userManager.signin( cookieUser, client );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
deleteFile( file ) {
|
||||
|
||||
|
||||
|
||||
files.removeFile( __dirname + "/application/" + file.path + "/" + file.name );
|
||||
|
||||
|
||||
|
||||
files.removeFile( __dirname + "/framework/cache/" + file.path + "/" + file.name );
|
||||
|
||||
|
||||
|
||||
this.updateCache();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
removeDirectory( file ) {
|
||||
|
||||
|
||||
|
||||
files.removeDir( __dirname + "/application/" + file.path + "/" );
|
||||
|
||||
|
||||
|
||||
files.removeDir( __dirname + "/framework/cache/" + file.path + "/" );
|
||||
|
||||
|
||||
|
||||
this.updateCache();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async updateCache() {
|
||||
|
||||
|
||||
|
||||
//await files.findApplicationFiles( "./application");
|
||||
|
||||
|
||||
|
||||
//global.applicationManager.applications = files.applications;
|
||||
|
||||
|
||||
|
||||
//console.log("updated applications", files.applications);
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
await files.removeFiles( "./framework/cache/");
|
||||
|
||||
|
||||
|
||||
await files.removeDirectories( "./framework/cache/" );
|
||||
|
||||
|
||||
|
||||
await files.createDirectories();
|
||||
|
||||
|
||||
|
||||
await files.writeFiles();
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
saveFile( file ) {
|
||||
|
||||
|
||||
|
||||
fs.writeFileSync( __dirname + "/application/" + file.path + "/" + file.name, file.source );
|
||||
|
||||
|
||||
|
||||
fs.writeFileSync( __dirname + "/framework/cache/" + file.path + "/" + file.name, files.parseSource( file.source) );
|
||||
|
||||
|
||||
|
||||
this.updateCache();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
createDirectory( file ) {
|
||||
|
||||
|
||||
|
||||
console.log( "create directory", file );
|
||||
|
||||
|
||||
|
||||
files.createDir( __dirname + "/application/" + file.path );
|
||||
|
||||
|
||||
|
||||
files.createDir( __dirname + "/framework/cache/" + file.path );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
608
framework/server/cachedControllers/tableController.js
Normal file
608
framework/server/cachedControllers/tableController.js
Normal file
@@ -0,0 +1,608 @@
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
|
||||
as published by the ESA.
|
||||
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
|
||||
|
||||
import shared from '../../unify/shared.js';
|
||||
|
||||
|
||||
|
||||
import userManager from '../userManager.js';
|
||||
|
||||
|
||||
|
||||
import defaultObject from '../../unify/defaultObject.js';
|
||||
|
||||
|
||||
|
||||
import consoleColors from '../../unify/consoleColors.js';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default class tableController {
|
||||
|
||||
__className = "tableController";
|
||||
|
||||
__sourcePath = "./framework/server/cachedControllers/tableController.js";
|
||||
|
||||
__publicMethods = "save,delete,get,create,count";
|
||||
|
||||
|
||||
|
||||
|
||||
id = 3;
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
|
||||
|
||||
Console.setFilename("tableController.js");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getLastID() {
|
||||
|
||||
|
||||
|
||||
return ++this.id;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getParentObject( object ) {
|
||||
|
||||
|
||||
|
||||
if( object.type == "table" ) {
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
return object.parent;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async save( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
var parentObject = this.getParentObject( object );
|
||||
|
||||
|
||||
|
||||
if( !parentObject.isAllowed( client.user, "WRITE" ) ) {
|
||||
|
||||
|
||||
|
||||
parentObject = parentObject.deserialize();
|
||||
|
||||
|
||||
|
||||
return parentObject;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
parentObject.signed.value = true;
|
||||
|
||||
|
||||
|
||||
if( parentObject.id == 0 || !parentObject.id ) {
|
||||
|
||||
|
||||
|
||||
var parentObject = this.create( parentObject, client, eventName );
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
parentObject.save();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//this.updateBidirectionalCollection( parentObject, collection, client, eventName );
|
||||
|
||||
|
||||
|
||||
return parentObject;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateBidirectionalCollection( object, collection, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
if( object.parent.getCollection ) {
|
||||
|
||||
|
||||
|
||||
var collection = object.parent.getCollection();
|
||||
|
||||
|
||||
|
||||
if( collection ) {
|
||||
|
||||
|
||||
|
||||
this.objectManager.updateClient( collection, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateBidirectionalObject( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
if( eventName ) {
|
||||
|
||||
|
||||
|
||||
this.objectManager.updateClient( object, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
registerBidirectionalObject( object ) {
|
||||
|
||||
|
||||
|
||||
this.objectManager.registerObject( object, client );
|
||||
|
||||
|
||||
|
||||
var collection = object.getCollection();
|
||||
|
||||
|
||||
|
||||
if( collection ) {
|
||||
|
||||
|
||||
|
||||
this.objectManager.registerObject( collection, client );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
delete( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
if( !object.isAllowed( client.user, "DELETE" ) ) {
|
||||
|
||||
|
||||
|
||||
object = object.deserialize();
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
var result = object.delete();
|
||||
|
||||
|
||||
|
||||
//this.updateBidirectionalCollection( object );
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getObject( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
if( object.preprocess ) {
|
||||
|
||||
|
||||
|
||||
object.preprocess( object, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//console.log("object.get");
|
||||
|
||||
|
||||
|
||||
object.get( client );
|
||||
|
||||
|
||||
|
||||
//console.log("//object.get");
|
||||
|
||||
|
||||
|
||||
if( object.process ) {
|
||||
|
||||
|
||||
|
||||
object.process( object, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
get( object, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
object.updated = false;
|
||||
|
||||
|
||||
|
||||
if( !object.isAllowed( client.user, "READ" ) ) {
|
||||
|
||||
|
||||
|
||||
object.deserialize();
|
||||
|
||||
|
||||
|
||||
object.updateChildrenPermissions( object, client.user );
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if( object.get ) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if( object.type == "renderCollection" ) {
|
||||
|
||||
|
||||
|
||||
//console.log("clearCollection");
|
||||
|
||||
|
||||
|
||||
//object.removeChildren( );
|
||||
|
||||
|
||||
|
||||
//object.getChildrenRenderCollections( client );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.getObject( object, client, eventName );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//this.registerBidirectionalObject( object );
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
insertObject( object, client ) {
|
||||
|
||||
|
||||
|
||||
var last_id = database.insertRow( object );
|
||||
|
||||
|
||||
|
||||
object.permissions = userManager.computePermissions( object, client.user );
|
||||
|
||||
|
||||
|
||||
object.id = last_id;
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
insertCollection( object, last_insert_id ) {
|
||||
|
||||
|
||||
|
||||
var collection = object.getCollection();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if( collection ) {
|
||||
|
||||
|
||||
|
||||
collection.addObject( object );
|
||||
|
||||
|
||||
|
||||
//if( !collection.id ) {
|
||||
|
||||
|
||||
|
||||
console.log("");
|
||||
|
||||
|
||||
|
||||
console.log(consoleColors.green( "create->insertCollection(" ), collection.id, last_insert_id, consoleColors.green(")") );
|
||||
|
||||
|
||||
|
||||
var parent_id = collection.parent.id;
|
||||
|
||||
|
||||
|
||||
var insert = collection.queryInsert( parent_id, last_insert_id );
|
||||
|
||||
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return insert;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
create( object, client, eventName ){
|
||||
|
||||
|
||||
|
||||
if( !object.isAllowed( client.user, "WRITE" ) ) {
|
||||
|
||||
|
||||
|
||||
object = object.deserialize();
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
object = this.insertObject( object, client );
|
||||
|
||||
|
||||
|
||||
//this.objectManager.registerObject( object, client );
|
||||
|
||||
|
||||
|
||||
this.insertCollection( object, object.id );
|
||||
|
||||
|
||||
|
||||
//console.log("return object", object);
|
||||
|
||||
|
||||
|
||||
return object;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
count( collection, client, eventName ) {
|
||||
|
||||
|
||||
|
||||
collection.count = collection.countRows();
|
||||
|
||||
|
||||
|
||||
if( collection.count == 0 ) {
|
||||
|
||||
|
||||
|
||||
collection.count = 0;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return collection;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
612
framework/server/collection/collection.js
Normal file
612
framework/server/collection/collection.js
Normal file
@@ -0,0 +1,612 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import joinSQL from '../../unify/joinSQL.js';
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
import unify from '../../unify/unify.js';
|
||||
|
||||
|
||||
import queryChildren from "./collection.queryChildren.js";
|
||||
|
||||
import queryRoot from "./collection.queryRoot.js";
|
||||
|
||||
import queryCount from "./collection.queryCount.js";
|
||||
|
||||
|
||||
|
||||
import searchable from '../../unify/sql/searchable.js';
|
||||
|
||||
import placeholder from '../../unify/placeholder.js';
|
||||
|
||||
|
||||
|
||||
export default class collection {
|
||||
|
||||
__className = "collection";
|
||||
|
||||
|
||||
queryChildren = new queryChildren();
|
||||
|
||||
queryRoot = new queryRoot();
|
||||
|
||||
queryCount = new queryCount();
|
||||
|
||||
|
||||
query = new querySQL();
|
||||
|
||||
filterObject;
|
||||
|
||||
|
||||
|
||||
find( ...values ) {
|
||||
|
||||
this.query.find( ...values );
|
||||
|
||||
}
|
||||
|
||||
createFilterObject() {
|
||||
|
||||
if( !this.filterObject ) {
|
||||
|
||||
this.filterObject = new placeholder();
|
||||
}
|
||||
|
||||
|
||||
this.filterObject.__className = "placeholder";
|
||||
|
||||
unify.extend( this.filterObject );
|
||||
|
||||
}
|
||||
|
||||
getCollectionObject() {
|
||||
|
||||
//var collection = this.getCollection();
|
||||
|
||||
var realObject = new this.object();
|
||||
|
||||
unify.extend( realObject );
|
||||
|
||||
return realObject;
|
||||
|
||||
}
|
||||
|
||||
createCollectionSearchable( collection, child ) {
|
||||
|
||||
var tableName = collection.createInstance().getClassName();
|
||||
//tableName
|
||||
var search = new searchable( "./" + collection.propertyName + "/" + child.propertyName );
|
||||
|
||||
this.filterObject[ collection.propertyName ][ child.propertyName ] = search;
|
||||
|
||||
}
|
||||
|
||||
handleFilterCollectionChildren( collectionObject, collection ) {
|
||||
|
||||
var collectionChildren = collectionObject.getChildren();
|
||||
|
||||
for( var b = 0; b < collectionChildren.length; b++ ) {
|
||||
|
||||
var child = collectionChildren[b];
|
||||
|
||||
this.createCollectionSearchable( collection, child );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleCollectionSearchables( child ) {
|
||||
|
||||
if( child.type == "collection") {
|
||||
|
||||
var collectionObject = child.createInstance();
|
||||
|
||||
unify.extend( collectionObject );
|
||||
|
||||
//console.log("get selectedUser from this", child);
|
||||
|
||||
this.filterObject[ child.propertyName ].tableName = collectionObject.getClassName()
|
||||
|
||||
this.filterObject[ child.propertyName ].type = "collection";
|
||||
|
||||
this.handleFilterCollectionChildren( collectionObject, child )
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createSearchable( child, parent ) {
|
||||
|
||||
//console.log("get news from this", parent);
|
||||
|
||||
var search = new searchable( parent.getClassName() + "/" + child.propertyName );
|
||||
|
||||
this.filterObject[ child.propertyName ] = search;
|
||||
|
||||
}
|
||||
|
||||
createSearchables( object ) {
|
||||
|
||||
var children = object.getChildren();
|
||||
|
||||
for( var c = 0; c < children.length; c++ ) {
|
||||
|
||||
var child = children[c];
|
||||
|
||||
this.createSearchable( child, object );
|
||||
|
||||
this.handleCollectionSearchables( child );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createSearchableID() {
|
||||
|
||||
var search = new searchable( "./id" );
|
||||
|
||||
this.filterObject[ "id" ] = search;
|
||||
|
||||
}
|
||||
|
||||
getFilter() {
|
||||
|
||||
this.createFilterObject();
|
||||
|
||||
this.createSearchableID();
|
||||
|
||||
var object = this.getCollectionObject();
|
||||
|
||||
this.createSearchables( object );
|
||||
|
||||
//console.log("this.filterObject", this.filterObject);
|
||||
|
||||
return this.filterObject;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sync() {
|
||||
|
||||
|
||||
/*
|
||||
var object = this.createInstance();
|
||||
|
||||
var tableName = tools.getTableName( object );
|
||||
|
||||
this.query.type = "select";
|
||||
this.query.table = tableName;
|
||||
|
||||
var rows = global.database.query( this.query );
|
||||
*/
|
||||
|
||||
|
||||
var rows = this.querySelect( false, this.filterObject, false );
|
||||
|
||||
|
||||
//console.log("rows", rows);
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
|
||||
var row = rows[i];
|
||||
|
||||
var object = this.createInstance();
|
||||
|
||||
object.serialize( row );
|
||||
|
||||
this.rows[i] = object;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//console.log(this.query);
|
||||
|
||||
//console.log(rows);
|
||||
|
||||
return this.rows;
|
||||
|
||||
}
|
||||
|
||||
length() {
|
||||
|
||||
return this.rows.length;
|
||||
|
||||
}
|
||||
|
||||
get( index ) {
|
||||
|
||||
if( index ) {
|
||||
|
||||
return this.rows[index];
|
||||
|
||||
} else {
|
||||
|
||||
return this.rows[0];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pop() {
|
||||
|
||||
return this.rows.pop();
|
||||
|
||||
}
|
||||
|
||||
shift() {
|
||||
|
||||
return this.rows.shift();
|
||||
|
||||
}
|
||||
|
||||
getRows() {
|
||||
|
||||
return this.rows;
|
||||
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
this.queryChildren.collection = this;
|
||||
|
||||
this.queryRoot.collection = this;
|
||||
|
||||
this.queryCount.collection = this;
|
||||
|
||||
|
||||
}
|
||||
|
||||
querySelect( userQuery, filterObject, client ) {
|
||||
|
||||
if( !userQuery ) {
|
||||
|
||||
userQuery = new querySQL();
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( this.parent ) {
|
||||
|
||||
this.queryChildren.queryType = "select"
|
||||
|
||||
return this.queryChildren.query( userQuery, filterObject );
|
||||
|
||||
} else {
|
||||
|
||||
this.queryRoot.queryType = "select"
|
||||
|
||||
return this.queryRoot.query( userQuery, filterObject, client );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
countRows() {
|
||||
|
||||
return this.queryCount.query();
|
||||
|
||||
}
|
||||
|
||||
filterQuery( query, filterObject ) {
|
||||
|
||||
this.prepareOrder( query, filterObject );
|
||||
|
||||
//console.log("filterQuery", filterObject);
|
||||
|
||||
if( filterObject.direction ) {
|
||||
|
||||
if( filterObject.direction.toLowerCase() == "asc" || filterObject.direction.toLowerCase() == "desc" ) {
|
||||
|
||||
query.direction = tools.htmlEntities( filterObject.direction );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( filterObject.limit && typeof filterObject.limit == "number" ) {
|
||||
|
||||
query.limit = parseInt( filterObject.limit );
|
||||
|
||||
}
|
||||
|
||||
if( filterObject.from && typeof filterObject.from == "number" ) {
|
||||
|
||||
query.offset = parseInt( filterObject.from );
|
||||
|
||||
}
|
||||
|
||||
if( filterObject.offset && typeof filterObject.offset == "number" ) {
|
||||
|
||||
query.offset = parseInt( filterObject.offset );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
prepareOrder( unionQuery, filterObject ) {
|
||||
|
||||
if( filterObject.order ) {
|
||||
|
||||
var searchable = filterObject.order;
|
||||
|
||||
//console.log("search order . ", filterObject.order, searchable.getColumnName());
|
||||
|
||||
if( searchable ) {
|
||||
|
||||
var columnName = searchable.path.replace("/", ".");
|
||||
|
||||
unionQuery.orderBy( columnName );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
searchQuery( query, filterObject ) {
|
||||
|
||||
if( filterObject ) {
|
||||
|
||||
|
||||
if( filterObject.search) {
|
||||
|
||||
filterObject.search.path = "./"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
query.filter = filterObject;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
if( filterObject.search ) {
|
||||
|
||||
var searchables = filterObject.search.findPath( "." );
|
||||
|
||||
for ( var i = 0; i < searchables.length; i++ ) {
|
||||
|
||||
var currentSearchable = searchables[i];
|
||||
|
||||
var columnName = currentSearchable.getColumnName();
|
||||
|
||||
var searchValue = currentSearchable.getValue();
|
||||
|
||||
var operator = currentSearchable.getOperator();
|
||||
|
||||
if( !searchValue ) {
|
||||
|
||||
var searchValue = "";
|
||||
|
||||
}
|
||||
|
||||
query.find( columnName, searchValue, operator, true, true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
getID( object ) {
|
||||
|
||||
var id = object.id;
|
||||
|
||||
if( !id ) {
|
||||
|
||||
id = object.parent.id;
|
||||
|
||||
}
|
||||
|
||||
if( !id ) {
|
||||
|
||||
id = this.id;
|
||||
|
||||
}
|
||||
|
||||
return id;
|
||||
|
||||
}
|
||||
|
||||
rowExists( id ) {
|
||||
|
||||
var rows = this.rows;
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
|
||||
var currentChild = rows[i];
|
||||
|
||||
if( id == currentChild.id ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
getRowByID( id ) {
|
||||
|
||||
var rows = this.rows;
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
|
||||
var currentChild = rows[i];
|
||||
|
||||
if( id == currentChild.id ) {
|
||||
|
||||
return currentChild;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
findID( rows, id ) {
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
|
||||
var currentChild = rows[i];
|
||||
|
||||
console.log("find id", id, currentChild.id);
|
||||
|
||||
if( id == currentChild.id ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
delete( object ) {
|
||||
|
||||
this.remove( object );
|
||||
|
||||
}
|
||||
|
||||
remove( object ) {
|
||||
|
||||
var row_id = object.id;
|
||||
|
||||
//var joinTable = this.tableName + "_" + this.propertyName;
|
||||
var joinTable = this.parentName + "_" + this.propertyName;
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "delete";
|
||||
|
||||
query.table = joinTable;
|
||||
|
||||
query.find( this.getLeft() + "_id", this.parent.id );
|
||||
|
||||
query.find( this.getRight() + "_id", row_id ); //row.tableName
|
||||
|
||||
|
||||
global.database.query( query );
|
||||
|
||||
}
|
||||
|
||||
add( object ) {
|
||||
|
||||
var row_id = object.id;
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
var parentName = this.getParentName();
|
||||
|
||||
var joinTable = parentName + "_" + this.propertyName;
|
||||
|
||||
|
||||
query.type = "insert";
|
||||
|
||||
query.table = joinTable;
|
||||
|
||||
query.setColumn( this.getLeft() + "_id", this.parent.id );
|
||||
|
||||
query.setColumn( this.getRight() + "_id", row_id ); //row.tableName
|
||||
|
||||
|
||||
global.database.query( query );
|
||||
|
||||
}
|
||||
|
||||
getObject() {
|
||||
|
||||
if( this.propertyName == "storageCollection" ) {
|
||||
|
||||
return this.parent;
|
||||
|
||||
} else {
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
queryInsert( parent_id, last_insert_id ) {
|
||||
|
||||
var joinTable = this.parentName + "_" + this.propertyName;
|
||||
|
||||
var left = this.getLeft();
|
||||
|
||||
var right = this.getRight();
|
||||
|
||||
|
||||
var query = new querySQL( );
|
||||
|
||||
query.type = "insert";
|
||||
|
||||
query.table = joinTable;
|
||||
|
||||
query.setValue( right + "_id", last_insert_id );
|
||||
|
||||
query.setValue( left + "_id", parent_id );
|
||||
|
||||
console.log( query );
|
||||
|
||||
|
||||
return global.database.query( query );
|
||||
|
||||
}
|
||||
|
||||
|
||||
count() {
|
||||
|
||||
var userQuery = new querySQL();
|
||||
|
||||
var filterObject = new Object();
|
||||
|
||||
var client = false;
|
||||
|
||||
unify.extend( filterObject );
|
||||
|
||||
if( this.parent ) {
|
||||
|
||||
this.queryChildren.queryType = "count"
|
||||
|
||||
return this.queryChildren.query( userQuery, filterObject );
|
||||
|
||||
} else {
|
||||
|
||||
this.queryRoot.queryType = "count"
|
||||
|
||||
return this.queryRoot.query( userQuery, filterObject, client );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
123
framework/server/collection/collection.queryChildren.js
Normal file
123
framework/server/collection/collection.queryChildren.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import joinSQL from '../../unify/joinSQL.js';
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
export default class queryChildren{
|
||||
|
||||
queryType = "select";
|
||||
|
||||
type = "collectionQuery"
|
||||
|
||||
__className = "queryChildren"
|
||||
|
||||
createQuery( joinTableName, joinQuery, id ) {
|
||||
|
||||
var query = new querySQL( );
|
||||
|
||||
query.type = this.queryType;
|
||||
|
||||
query.table = joinTableName;
|
||||
|
||||
query.debug = joinQuery.debug;
|
||||
|
||||
query.find( this.collection.getLeft() + "_id", id );
|
||||
|
||||
|
||||
return query;
|
||||
|
||||
}
|
||||
|
||||
createJoin( joinQuery ) {
|
||||
|
||||
var join = new joinSQL( joinQuery );
|
||||
|
||||
join.table = this.collection.tableName;
|
||||
|
||||
join.name = join.table;
|
||||
|
||||
join.left.table = join.name;
|
||||
|
||||
join.right.column = this.collection.getRight() + "_id";
|
||||
|
||||
join.find( "signed", true );
|
||||
|
||||
return join;
|
||||
|
||||
}
|
||||
|
||||
query( joinQuery, filterObject ) {
|
||||
|
||||
|
||||
var object = this.collection.getObject();
|
||||
|
||||
|
||||
var leftTable = this.collection.getParentName();
|
||||
|
||||
var rightTable = object.propertyName;
|
||||
|
||||
|
||||
var id = this.collection.getID( object );
|
||||
|
||||
if( !id ) {
|
||||
|
||||
if( this.collection.parent ) {
|
||||
|
||||
var id = this.collection.parent.id;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var joinTableName = leftTable + "_" + rightTable;
|
||||
|
||||
var query = this.createQuery( joinTableName, joinQuery, id );
|
||||
|
||||
var join = this.createJoin( joinQuery, join );
|
||||
|
||||
|
||||
if( filterObject ) {
|
||||
|
||||
this.collection.filterQuery( join, filterObject )
|
||||
|
||||
|
||||
|
||||
if( filterObject.search ) {
|
||||
|
||||
//console.log("searchQuery", join, filterObject);
|
||||
|
||||
this.collection.searchQuery( join, filterObject );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
join.setFilterAddress("./");
|
||||
|
||||
query.addJoin( join );
|
||||
|
||||
var result = global.database.query( query );
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
82
framework/server/collection/collection.queryCount.js
Normal file
82
framework/server/collection/collection.queryCount.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import joinSQL from '../../unify/joinSQL.js';
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
export default class queryCount{
|
||||
|
||||
createJoin() {
|
||||
|
||||
var join = new joinSQL();
|
||||
|
||||
join.table = this.tableName;
|
||||
|
||||
join.name = "children";
|
||||
|
||||
join.left.table = join.name;
|
||||
|
||||
join.right.column = this.getRight() + "_id";
|
||||
|
||||
join.find( "signed", "true" );
|
||||
//join.find( this.tableName + ".joined", "true" ); // please fix
|
||||
|
||||
return join;
|
||||
|
||||
}
|
||||
|
||||
createQuery() {
|
||||
|
||||
var object = this.getObject();
|
||||
|
||||
|
||||
var leftTable = this.parentName;
|
||||
|
||||
var rightTable = object.propertyName;
|
||||
|
||||
var id = this.collection.getID();
|
||||
|
||||
var joinTableName = leftTable + "_" + rightTable;
|
||||
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.table = joinTableName;
|
||||
|
||||
query.find( this.getLeft() + "_id", id );
|
||||
|
||||
|
||||
return query;
|
||||
|
||||
}
|
||||
|
||||
query() {
|
||||
|
||||
var query = this.createQuery();
|
||||
|
||||
var join = this.createJoin();
|
||||
|
||||
query.addJoin( join );
|
||||
|
||||
// bug : todo : count not length
|
||||
return global.database.query( query ).length;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
321
framework/server/collection/collection.queryRoot.js
Normal file
321
framework/server/collection/collection.queryRoot.js
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import joinSQL from '../../unify/joinSQL.js';
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
|
||||
export default class queryRoot{
|
||||
|
||||
queryType = "select";
|
||||
|
||||
type = "collectionQuery"
|
||||
|
||||
__className = "queryRoot"
|
||||
|
||||
prepareSelectQuery( query, object, userQuery ) {
|
||||
|
||||
query.table = this.collection.getTableName();
|
||||
|
||||
query.type = this.queryType;
|
||||
|
||||
query.setFilterAddress( query.table + "/" );
|
||||
|
||||
query.extractColumns( object, query.table );
|
||||
|
||||
query.find( "signed", true );
|
||||
|
||||
query.find( "joined", false );
|
||||
|
||||
query.debug = userQuery.debug;
|
||||
|
||||
|
||||
return query;
|
||||
|
||||
}
|
||||
|
||||
createChildrenJoin( joinTableName, collectionObject, object ) {
|
||||
|
||||
var childObject = new collectionObject.object()
|
||||
|
||||
var childObjectName = tools.getClassName( childObject );
|
||||
|
||||
|
||||
var childrenJoin = new joinSQL( );
|
||||
|
||||
childrenJoin.table = childObjectName;
|
||||
|
||||
childrenJoin.setFilterAddress( "./" + collectionObject.propertyName + "/" )
|
||||
|
||||
childrenJoin.joinType = "LEFT";
|
||||
|
||||
childrenJoin.name = collectionObject.propertyName;
|
||||
|
||||
childrenJoin.left.table = joinTableName;
|
||||
|
||||
childrenJoin.left.column = collectionObject.getRight() + "_id";
|
||||
|
||||
|
||||
childrenJoin.right.table = childrenJoin.name;
|
||||
|
||||
childrenJoin.right.column = "id";
|
||||
|
||||
|
||||
//childrenJoin.find( "signed", true );
|
||||
|
||||
//childrenJoin.find( "joined", true );
|
||||
|
||||
|
||||
return childrenJoin;
|
||||
|
||||
}
|
||||
|
||||
createParentJoin( joinTableName, collectionObject ) {
|
||||
|
||||
var parentJoin = new joinSQL( );
|
||||
|
||||
parentJoin.table = this.collection.getTableName();
|
||||
|
||||
parentJoin.joinType = "INNER";
|
||||
|
||||
parentJoin.name = "parentJoin";
|
||||
|
||||
|
||||
|
||||
parentJoin.left.table = joinTableName;
|
||||
|
||||
parentJoin.left.column = collectionObject.getLeft() + "_id";
|
||||
|
||||
parentJoin.right.table = parentJoin.name;
|
||||
|
||||
parentJoin.right.column = "id";
|
||||
|
||||
|
||||
|
||||
|
||||
return parentJoin;
|
||||
|
||||
}
|
||||
|
||||
createJoinQuery( joinTableName, object, collectionObject ) {
|
||||
|
||||
var query = new joinSQL( );
|
||||
|
||||
query.table = joinTableName;
|
||||
|
||||
query.joinType = "LEFT";
|
||||
|
||||
|
||||
query.name = joinTableName;
|
||||
|
||||
|
||||
|
||||
query.left.table = joinTableName;
|
||||
|
||||
query.left.column = collectionObject.getLeft() + "_id";
|
||||
|
||||
query.right.table = this.collection.getTableName();
|
||||
|
||||
query.right.column = "id";
|
||||
|
||||
query.extractColumns( object, "parentJoin" );
|
||||
|
||||
|
||||
return query;
|
||||
|
||||
}
|
||||
|
||||
searchChildrenJoin( child, childrenJoin, filterObject ) {
|
||||
|
||||
if( filterObject.search ) {
|
||||
|
||||
var searchables = filterObject.search.findPath( "./" + child.propertyName );
|
||||
|
||||
|
||||
for ( var i = 0; i < searchables.length; i++ ) {
|
||||
|
||||
var currentSearchable = searchables[i];
|
||||
|
||||
var columnName = currentSearchable.getColumnName();
|
||||
|
||||
var searchValue = currentSearchable.getValue();
|
||||
|
||||
var operator = currentSearchable.getOperator();
|
||||
|
||||
|
||||
if( !searchValue ) {
|
||||
|
||||
var searchValue = "";
|
||||
|
||||
}
|
||||
|
||||
childrenJoin.find( columnName, searchValue, operator, true, true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
composeJoinQuery( query, collectionObject, childrenJoin, parentJoin ) {
|
||||
|
||||
query.addGroup( collectionObject.getLeft() + "_id" );
|
||||
|
||||
//childrenJoin.addJoin( );
|
||||
|
||||
query.addJoin( childrenJoin );
|
||||
|
||||
//query.addJoin( parentJoin );
|
||||
|
||||
}
|
||||
|
||||
createJoinTableName( collectionObject ) {
|
||||
|
||||
var leftTable = this.collection.getTableName();
|
||||
|
||||
var rightTable = collectionObject.propertyName;
|
||||
|
||||
var joinTableName = leftTable + "_" + rightTable;
|
||||
|
||||
|
||||
return joinTableName;
|
||||
|
||||
}
|
||||
|
||||
queryFilterChild( query, object, child, filterObject ) {
|
||||
|
||||
var collectionObject = object[ child.propertyName ];
|
||||
|
||||
var tableName = collectionObject.tableName;
|
||||
|
||||
|
||||
var joinTableName = this.createJoinTableName( collectionObject );
|
||||
|
||||
var joinQuery = this.createJoinQuery( joinTableName, object, collectionObject );
|
||||
|
||||
var childrenJoin = this.createChildrenJoin( joinTableName, collectionObject, object );
|
||||
|
||||
//var parentJoin = this.createParentJoin( joinTableName, collectionObject );
|
||||
|
||||
|
||||
|
||||
|
||||
this.composeJoinQuery( joinQuery, collectionObject, childrenJoin );
|
||||
|
||||
//this.searchChildrenJoin( child, childrenJoin, filterObject );
|
||||
|
||||
|
||||
query.addJoin( joinQuery );
|
||||
|
||||
//unionQuery.addUnion( joinQuery );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
queryChildren( filterObject, query, client ) {
|
||||
|
||||
var children = filterObject.getChildren();
|
||||
|
||||
var joined = false;
|
||||
|
||||
|
||||
|
||||
|
||||
for( var c = 0; c < children.length; c++ ) {
|
||||
|
||||
var child = children[c];
|
||||
|
||||
if( child.type == "collection" ) {
|
||||
|
||||
var object = new this.collection.object();
|
||||
|
||||
core.parse( object, client );
|
||||
|
||||
//console.log("child.propertyName", child);
|
||||
|
||||
//console.log("filterObject.search", filterObject.search);
|
||||
|
||||
var tableName = filterObject.getClassName();
|
||||
|
||||
//console.log("filterObject.search.findPath", "./" + child.tableName );
|
||||
|
||||
//if( filterObject.search && filterObject.search.findPath( "./" + child.tableName ) ) {
|
||||
|
||||
if( filterObject.search && filterObject.search.findPath( "./" + child.propertyName ) ) {
|
||||
|
||||
this.queryFilterChild( query, object, child, filterObject );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
searchQuery( query, filterObject ) {
|
||||
|
||||
if( filterObject ) {
|
||||
|
||||
|
||||
if( filterObject.search) {
|
||||
|
||||
filterObject.search.path = query.tableName + "/"
|
||||
|
||||
}
|
||||
|
||||
query.filter = filterObject;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
query( userQuery, filterObject, client ) {
|
||||
|
||||
var core = this.collection.getCore();
|
||||
|
||||
var object = new this.collection.object();
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
|
||||
//console.log("the good ")
|
||||
|
||||
this.prepareSelectQuery( query, object, userQuery );
|
||||
|
||||
this.searchQuery( query, filterObject );
|
||||
|
||||
this.collection.filterQuery( query, filterObject );
|
||||
|
||||
this.queryChildren( filterObject, query, client );
|
||||
|
||||
|
||||
query.debug = userQuery.debug;
|
||||
|
||||
|
||||
|
||||
var parentResult = global.database.query( query );
|
||||
|
||||
|
||||
return parentResult;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
2
framework/server/config.js
Normal file
2
framework/server/config.js
Normal file
@@ -0,0 +1,2 @@
|
||||
var a = {"mode":"development","serverAddress":"localhost","ssl":false,"socketPort":5000,"port":3000,"maxClusters":1,"os":"Windows","device":"PC","theme":"LIGHT","syncClientID":0};
|
||||
export default a;
|
||||
1
framework/server/config.json
Normal file
1
framework/server/config.json
Normal file
@@ -0,0 +1 @@
|
||||
{"mode":"development","serverAddress":"localhost","ssl":false,"socketPort":5000,"port":3000,"maxClusters":1,"os":"Windows","device":"Pc","tint":"Dark","syncClientID":0,"loadThemes":true}
|
||||
302
framework/server/console.js
Normal file
302
framework/server/console.js
Normal file
@@ -0,0 +1,302 @@
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import document from '../unify/document.js';
|
||||
|
||||
import deepclone from '../unify/clonedeep.js';
|
||||
|
||||
class Console{
|
||||
|
||||
objects = new Array();
|
||||
|
||||
currentObject = false;
|
||||
|
||||
filename = false;
|
||||
|
||||
enabled = false;
|
||||
|
||||
enabledPaths = new Array();
|
||||
|
||||
rows = new Array();
|
||||
|
||||
tableName = false;
|
||||
|
||||
maxChars = new Array( 0,0,0,0,0,0 );
|
||||
|
||||
padding = 4;
|
||||
|
||||
|
||||
setFilename( filename ){
|
||||
|
||||
this.filename = filename;
|
||||
|
||||
}
|
||||
|
||||
createNameObject( parameter ) {
|
||||
|
||||
if( !parameter ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if( typeof parameter == "string") {
|
||||
|
||||
return parameter;
|
||||
|
||||
}
|
||||
|
||||
|
||||
var object = {};
|
||||
|
||||
object[ tools.getClassName( parameter ) ] = parameter;
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
getObjectByPath( objectA ) {
|
||||
|
||||
var objects = this.objects;
|
||||
|
||||
for( var c = 0; c<objects.length; c++ ) {
|
||||
|
||||
var objectB = objects[c];
|
||||
|
||||
if( objectA.applicationPathString == objectB.applicationPathString ) {
|
||||
|
||||
return objectB;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
enableLog( path ) {
|
||||
|
||||
this.enabledPaths.push( path );
|
||||
|
||||
}
|
||||
|
||||
register( object ) {
|
||||
|
||||
//this.enabled = true;
|
||||
/*
|
||||
var paths = this.enabledPaths;
|
||||
|
||||
for(var c = 0; c<paths.length;c++) {
|
||||
|
||||
var path = paths[c];
|
||||
|
||||
if( path == object.applicationPathString ) {
|
||||
|
||||
this.enabled = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( !this.getObjectByPath( object ) ) {
|
||||
|
||||
this.objects.push( object );
|
||||
|
||||
console.log("add");
|
||||
|
||||
this.sendObjectToDebugger( object );
|
||||
|
||||
}
|
||||
|
||||
this.currentObject = object;
|
||||
*/
|
||||
|
||||
//this.log("clear_console");
|
||||
this.log("--------------------------", object.getClassName() );
|
||||
|
||||
}
|
||||
|
||||
sendObjectToDebugger( object ) {
|
||||
|
||||
var parameters = {};
|
||||
|
||||
parameters.action = "addObject";
|
||||
|
||||
parameters.object = cycle.decycle( object );
|
||||
|
||||
var socketManager = global.socketManager;
|
||||
|
||||
var clients = socketManager.clients;
|
||||
|
||||
for( var c = 0; c < clients.length; c++ ) {
|
||||
|
||||
var client = clients[c];
|
||||
|
||||
if( this.enabled ) {
|
||||
|
||||
client.debugMessage( parameters );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
table( parameter1 ) {
|
||||
|
||||
if( global.clusterID == 1 ) {
|
||||
|
||||
console.table( parameter1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
warning( parameter1, parameter2, parameter3 ) {
|
||||
|
||||
if( global.clusterID == 1 ) {
|
||||
|
||||
if( parameter3 ) {
|
||||
|
||||
console.log( parameter1, parameter2, parameter3 );
|
||||
|
||||
} else if( parameter2 ) {
|
||||
|
||||
console.log( parameter1, parameter2 );
|
||||
|
||||
} else if( parameter1 ) {
|
||||
|
||||
console.log( tools.consoleColors().green( parameter1 ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
valid( parameter1, parameter2, parameter3 ) {
|
||||
|
||||
if( global.clusterID == 1 ) {
|
||||
|
||||
if( parameter3 ) {
|
||||
|
||||
console.log( parameter1, parameter2, parameter3 );
|
||||
|
||||
} else if( parameter2 ) {
|
||||
|
||||
console.log( tools.consoleColors().cyan( parameter1), tools.consoleColors().cyan(parameter2) );
|
||||
|
||||
} else if( parameter1 ) {
|
||||
|
||||
console.log( tools.consoleColors().green( parameter1 ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
log( parameter1, parameter2, parameter3 ) {
|
||||
|
||||
if( parameter3 ) {
|
||||
|
||||
console.log( parameter1, parameter2, parameter3 );
|
||||
|
||||
} else if( parameter2 ) {
|
||||
|
||||
console.log( parameter1, parameter2 );
|
||||
|
||||
} else if( parameter1 ) {
|
||||
|
||||
var parameter1 = deepclone( parameter1 );
|
||||
|
||||
tools.cleanObject(parameter1);
|
||||
|
||||
console.log( parameter1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setWidth( width ) {
|
||||
|
||||
this.maxChars = width;
|
||||
|
||||
}
|
||||
|
||||
addColumn( a, b, c, d ) {
|
||||
|
||||
var row = new Array();
|
||||
|
||||
if( a ) {
|
||||
|
||||
row.push( a );
|
||||
|
||||
this.maxChars[0] = Math.max( this.maxChars[0], a.length );
|
||||
|
||||
|
||||
|
||||
if( b ) {
|
||||
|
||||
row.push( b );
|
||||
|
||||
this.maxChars[1] = Math.max( this.maxChars[1], b.length );
|
||||
|
||||
}
|
||||
|
||||
if( c ) {
|
||||
|
||||
row.push( c );
|
||||
|
||||
this.maxChars[2] = Math.max( this.maxChars[2], c.length );
|
||||
|
||||
}
|
||||
|
||||
if( d ) {
|
||||
|
||||
row.push( d );
|
||||
|
||||
this.maxChars[3] = Math.max( this.maxChars[3], d.length );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.rows.push( row );
|
||||
|
||||
}
|
||||
|
||||
logTable() {
|
||||
|
||||
//if( global.clusterID == 1 ) {
|
||||
|
||||
for (var i = 0; i < this.rows.length; i++) {
|
||||
|
||||
var row = this.rows[i];
|
||||
|
||||
if( row[0] ) {
|
||||
|
||||
console.log( " ", row[0].padEnd( this.maxChars[0] + this.padding ), row[1] );
|
||||
|
||||
} else if( row[0] ) {
|
||||
|
||||
//console.log( row[0] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log("\n");
|
||||
|
||||
this.rows = new Array();
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new Console();
|
||||
|
||||
|
||||
66
framework/server/contract.js
Normal file
66
framework/server/contract.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
|
||||
Deprecated.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import rule from '../unify/contractRule.js';
|
||||
|
||||
export default class contract{
|
||||
|
||||
object = false;
|
||||
|
||||
rules = [];
|
||||
|
||||
constructor( object ) {
|
||||
|
||||
this.object = tools.serialize( object );
|
||||
|
||||
}
|
||||
|
||||
allow( right, object ){
|
||||
|
||||
var newRule = new rule();
|
||||
|
||||
newRule.type = "allow";
|
||||
|
||||
newRule.right = right;
|
||||
|
||||
newRule.object = tools.serialize( object );
|
||||
|
||||
this.rules.push( newRule );
|
||||
|
||||
}
|
||||
|
||||
deny() {
|
||||
|
||||
var newRule = new rule();
|
||||
|
||||
newRule.type = "deny";
|
||||
|
||||
newRule.right = right;
|
||||
|
||||
newRule.object = tools.serialize( object );
|
||||
|
||||
this.rules.push( newRule );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
178
framework/server/controllers/columnController.js
Normal file
178
framework/server/controllers/columnController.js
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
import deepclone from '../../unify/clonedeep.js';
|
||||
|
||||
|
||||
|
||||
|
||||
export default class columnController{
|
||||
|
||||
prepareQuery() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
deleteByParentID( tableName, parent_id, storageCollection ) {
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "delete";
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
query.find( storageCollection.getLeft() + "_id", parent_id );
|
||||
|
||||
database.query( query );
|
||||
|
||||
}
|
||||
|
||||
updateRow( row, clientValue ) {
|
||||
|
||||
if( clientValue == "" ) {
|
||||
|
||||
clientValue = false;
|
||||
}
|
||||
|
||||
var validated = true;
|
||||
|
||||
if( object.validate ) {
|
||||
|
||||
validated = object.validate( row, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
if( clientValue == true && validated ) {
|
||||
|
||||
var row_id = row.id;
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "insert";
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
query.setColumn( storageCollection.getLeft() + "_id", parent_id );
|
||||
|
||||
query.setColumn( storageCollection.getRight() + "_id", row_id );
|
||||
|
||||
database.query( query );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateRenderCollection( object ) {
|
||||
|
||||
var clientObject = deepclone( object );
|
||||
|
||||
var storageCollection = object.storageCollection;
|
||||
|
||||
var leftTableName = storageCollection.parentName;
|
||||
var rightTableName = storageCollection.parent.propertyName;
|
||||
|
||||
var tableName = leftTableName + "_" + rightTableName;
|
||||
var parent_id = object.parent.id;
|
||||
|
||||
this.deleteByParentID( tableName, parent_id, storageCollection );
|
||||
|
||||
object.get( client );
|
||||
|
||||
for( var c = 0; c < object.rows.length; c++ ) {
|
||||
|
||||
var row = object.rows[c];
|
||||
|
||||
var clientValue = clientObject.rows[c].value;
|
||||
|
||||
this.updateRow( row, clientValue );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
findParentTable( object ) {
|
||||
|
||||
if( object.type == "table" ) {
|
||||
|
||||
return object;
|
||||
|
||||
} else {
|
||||
|
||||
return this.findParentTable( object.parent );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateColumn( object ) {
|
||||
|
||||
|
||||
|
||||
var table = this.findParentTable( object );
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "update";
|
||||
|
||||
//console.log( table );
|
||||
|
||||
query.addObject( table );
|
||||
|
||||
database.query( query );
|
||||
|
||||
//this.objectManager.updateClient( object, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
public update( object, client, eventName ) {
|
||||
|
||||
if( !object.isAllowed( client.user, "WRITE" ) ) {
|
||||
|
||||
object.deserialize();
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if( object.type == "renderCollection" ) {
|
||||
|
||||
// For storageCollection selects and check buttons
|
||||
this.updateRenderCollection( object );
|
||||
|
||||
} else {
|
||||
|
||||
this.updateColumn( object );
|
||||
|
||||
}
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
95
framework/server/controllers/objectController.js
Normal file
95
framework/server/controllers/objectController.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
import deepclone from '../../unify/clonedeep.js';
|
||||
|
||||
|
||||
|
||||
|
||||
export default class objectController{
|
||||
|
||||
|
||||
public async callNodeMethod( object, client, eventName ) {
|
||||
|
||||
console.log("called method", object.nodeMethodName, eventName);
|
||||
|
||||
var args = JSON.parse( object.nodeMethodArguments );
|
||||
|
||||
object.client = client;
|
||||
|
||||
var output = object[ eventName ]( args[0], args[1], args[2], args[3], args[4], args[5] );
|
||||
|
||||
delete object.client;
|
||||
|
||||
var out = await output;
|
||||
|
||||
if( !typeof out ) {
|
||||
|
||||
return object;
|
||||
|
||||
} else {
|
||||
|
||||
//console.log("output", out);
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Deprecated, Unsafe.
|
||||
add( json, client, eventName ) {
|
||||
/*
|
||||
// todo : this is not save
|
||||
|
||||
var properties = JSON.parse( json );
|
||||
|
||||
var parentObject = tools.getObjectByPath( client.application, properties.parentApplicationPath );
|
||||
|
||||
|
||||
var classObjects = client.classObjects;
|
||||
|
||||
var object = client.classObjects[ properties.className ];
|
||||
|
||||
|
||||
var objectClone = deepclone( object );
|
||||
|
||||
|
||||
parentObject[ properties.propertyName ] = objectClone;
|
||||
|
||||
objectClone.parent = parentObject;
|
||||
|
||||
objectClone.propertyName = properties.propertyName;
|
||||
|
||||
objectClone.id = properties.id;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
183
framework/server/controllers/settingsController.js
Normal file
183
framework/server/controllers/settingsController.js
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
import querySQL from '../../unify/querySQL.js';
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
import userManager from '../userManager.js';
|
||||
|
||||
import filemanager from '../filemanager.js';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
|
||||
var __dirname = path.resolve();
|
||||
|
||||
var files = new filemanager();
|
||||
|
||||
|
||||
export default class settingsController{
|
||||
|
||||
public setType( object, client, eventName ) {
|
||||
|
||||
//console.log("set type", object);
|
||||
|
||||
switch( object ) {
|
||||
|
||||
case "debug":
|
||||
|
||||
client.type = "debug";
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
removeClient( object, client, eventName ) {
|
||||
|
||||
//client.destroy();
|
||||
|
||||
//console.log( "removed client", client.id );
|
||||
|
||||
}
|
||||
|
||||
public getCacheDateTime() {
|
||||
|
||||
return fs.statSync( "./assets/cache/cache.js" ).mtime
|
||||
|
||||
}
|
||||
|
||||
public recreateCache( object ) {
|
||||
|
||||
console.log("object.performCacheUpdate = true;", object.getClassName());
|
||||
|
||||
object.performCacheUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
public setVisibleElements( elements, client, eventName ) {
|
||||
|
||||
//console.log("setVisibleElements", elements);
|
||||
|
||||
global.visibleElements = elements.split(",");
|
||||
|
||||
}
|
||||
|
||||
public setTheme( themeProfileJSON ) {
|
||||
|
||||
var themeProfile = JSON.parse( themeProfileJSON );
|
||||
|
||||
console.log("setTheme", themeProfile );
|
||||
|
||||
global.os = tools.CamelCase( themeProfile.os );
|
||||
|
||||
global.device = tools.CamelCase( themeProfile.device );
|
||||
|
||||
global.tint = tools.CamelCase( themeProfile.tint );
|
||||
|
||||
}
|
||||
|
||||
debugObject( path, client, eventName ){
|
||||
|
||||
//Console.enableLog( path );
|
||||
console.log( "enable debug object", path );
|
||||
|
||||
}
|
||||
|
||||
public signOut( cookieUser, client, eventName ) {
|
||||
|
||||
return userManager.signOut( cookieUser, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
public signIn( cookieUser, client, eventName ) {
|
||||
|
||||
return userManager.signin( cookieUser, client );
|
||||
|
||||
}
|
||||
|
||||
deleteFile( file ) {
|
||||
|
||||
files.removeFile( __dirname + "/application/" + file.path + "/" + file.name );
|
||||
|
||||
files.removeFile( __dirname + "/framework/cache/" + file.path + "/" + file.name );
|
||||
|
||||
this.updateCache();
|
||||
|
||||
}
|
||||
|
||||
removeDirectory( file ) {
|
||||
|
||||
files.removeDir( __dirname + "/application/" + file.path + "/" );
|
||||
|
||||
files.removeDir( __dirname + "/framework/cache/" + file.path + "/" );
|
||||
|
||||
this.updateCache();
|
||||
|
||||
}
|
||||
|
||||
|
||||
async updateCache() {
|
||||
|
||||
//await files.findApplicationFiles( "./application");
|
||||
|
||||
//global.applicationManager.applications = files.applications;
|
||||
|
||||
//console.log("updated applications", files.applications);
|
||||
/*
|
||||
|
||||
await files.removeFiles( "./framework/cache/");
|
||||
|
||||
await files.removeDirectories( "./framework/cache/" );
|
||||
|
||||
await files.createDirectories();
|
||||
|
||||
await files.writeFiles();
|
||||
*/
|
||||
}
|
||||
|
||||
saveFile( file ) {
|
||||
|
||||
fs.writeFileSync( __dirname + "/application/" + file.path + "/" + file.name, file.source );
|
||||
|
||||
fs.writeFileSync( __dirname + "/framework/cache/" + file.path + "/" + file.name, files.parseSource( file.source) );
|
||||
|
||||
this.updateCache();
|
||||
|
||||
}
|
||||
|
||||
createDirectory( file ) {
|
||||
|
||||
console.log( "create directory", file );
|
||||
|
||||
files.createDir( __dirname + "/application/" + file.path );
|
||||
|
||||
files.createDir( __dirname + "/framework/cache/" + file.path );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
300
framework/server/controllers/tableController.js
Normal file
300
framework/server/controllers/tableController.js
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
import Console from '../console.js';
|
||||
|
||||
import tools from '../../unify/tools.js';
|
||||
|
||||
import database from '../database.js';
|
||||
|
||||
import shared from '../../unify/shared.js';
|
||||
|
||||
import userManager from '../userManager.js';
|
||||
|
||||
import defaultObject from '../../unify/defaultObject.js';
|
||||
|
||||
import consoleColors from '../../unify/consoleColors.js';
|
||||
|
||||
|
||||
|
||||
export default class tableController {
|
||||
|
||||
id = 3;
|
||||
|
||||
constructor() {
|
||||
|
||||
Console.setFilename("tableController.js");
|
||||
|
||||
}
|
||||
|
||||
getLastID() {
|
||||
|
||||
return ++this.id;
|
||||
|
||||
}
|
||||
|
||||
getParentObject( object ) {
|
||||
|
||||
if( object.type == "table" ) {
|
||||
|
||||
return object;
|
||||
|
||||
} else {
|
||||
|
||||
return object.parent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async save( object, client, eventName ) {
|
||||
|
||||
var parentObject = this.getParentObject( object );
|
||||
|
||||
if( !parentObject.isAllowed( client.user, "WRITE" ) ) {
|
||||
|
||||
parentObject = parentObject.deserialize();
|
||||
|
||||
return parentObject;
|
||||
|
||||
}
|
||||
|
||||
parentObject.signed.value = true;
|
||||
|
||||
if( parentObject.id == 0 || !parentObject.id ) {
|
||||
|
||||
var parentObject = this.create( parentObject, client, eventName );
|
||||
|
||||
} else {
|
||||
|
||||
parentObject.save();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//this.updateBidirectionalCollection( parentObject, collection, client, eventName );
|
||||
|
||||
return parentObject;
|
||||
|
||||
}
|
||||
|
||||
updateBidirectionalCollection( object, collection, client, eventName ) {
|
||||
|
||||
if( object.parent.getCollection ) {
|
||||
|
||||
var collection = object.parent.getCollection();
|
||||
|
||||
if( collection ) {
|
||||
|
||||
this.objectManager.updateClient( collection, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateBidirectionalObject( object, client, eventName ) {
|
||||
|
||||
if( eventName ) {
|
||||
|
||||
this.objectManager.updateClient( object, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerBidirectionalObject( object ) {
|
||||
|
||||
this.objectManager.registerObject( object, client );
|
||||
|
||||
var collection = object.getCollection();
|
||||
|
||||
if( collection ) {
|
||||
|
||||
this.objectManager.registerObject( collection, client );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public delete( object, client, eventName ) {
|
||||
|
||||
if( !object.isAllowed( client.user, "DELETE" ) ) {
|
||||
|
||||
object = object.deserialize();
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
var result = object.delete();
|
||||
|
||||
//this.updateBidirectionalCollection( object );
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
getObject( object, client, eventName ) {
|
||||
|
||||
if( object.preprocess ) {
|
||||
|
||||
object.preprocess( object, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
//console.log("object.get");
|
||||
|
||||
object.get( client );
|
||||
|
||||
//console.log("//object.get");
|
||||
|
||||
if( object.process ) {
|
||||
|
||||
object.process( object, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public get( object, client, eventName ) {
|
||||
|
||||
|
||||
object.updated = false;
|
||||
|
||||
if( !object.isAllowed( client.user, "READ" ) ) {
|
||||
|
||||
object.deserialize();
|
||||
|
||||
object.updateChildrenPermissions( object, client.user );
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( object.get ) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if( object.type == "renderCollection" ) {
|
||||
|
||||
//console.log("clearCollection");
|
||||
|
||||
//object.removeChildren( );
|
||||
|
||||
//object.getChildrenRenderCollections( client );
|
||||
|
||||
}
|
||||
|
||||
this.getObject( object, client, eventName );
|
||||
|
||||
}
|
||||
|
||||
//this.registerBidirectionalObject( object );
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
insertObject( object, client ) {
|
||||
|
||||
var last_id = database.insertRow( object );
|
||||
|
||||
object.permissions = userManager.computePermissions( object, client.user );
|
||||
|
||||
object.id = last_id;
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
insertCollection( object, last_insert_id ) {
|
||||
|
||||
var collection = object.getCollection();
|
||||
|
||||
|
||||
|
||||
if( collection ) {
|
||||
|
||||
collection.addObject( object );
|
||||
|
||||
//if( !collection.id ) {
|
||||
|
||||
console.log("");
|
||||
|
||||
console.log(consoleColors.green( "create->insertCollection(" ), collection.id, last_insert_id, consoleColors.green(")") );
|
||||
|
||||
var parent_id = collection.parent.id;
|
||||
|
||||
var insert = collection.queryInsert( parent_id, last_insert_id );
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return insert;
|
||||
|
||||
}
|
||||
|
||||
public create( object, client, eventName ){
|
||||
|
||||
if( !object.isAllowed( client.user, "WRITE" ) ) {
|
||||
|
||||
object = object.deserialize();
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
object = this.insertObject( object, client );
|
||||
|
||||
//this.objectManager.registerObject( object, client );
|
||||
|
||||
this.insertCollection( object, object.id );
|
||||
|
||||
//console.log("return object", object);
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
public count( collection, client, eventName ) {
|
||||
|
||||
collection.count = collection.countRows();
|
||||
|
||||
if( collection.count == 0 ) {
|
||||
|
||||
collection.count = 0;
|
||||
|
||||
}
|
||||
|
||||
return collection;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
1014
framework/server/core.js
Normal file
1014
framework/server/core.js
Normal file
File diff suppressed because it is too large
Load Diff
1617
framework/server/database.js
Normal file
1617
framework/server/database.js
Normal file
File diff suppressed because it is too large
Load Diff
28
framework/server/file.js
Normal file
28
framework/server/file.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
export default class file{
|
||||
|
||||
files = new Array();
|
||||
|
||||
type = "file";
|
||||
|
||||
add( currentFile ){
|
||||
|
||||
this.files.push( currentFile );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
678
framework/server/filemanager.js
Normal file
678
framework/server/filemanager.js
Normal file
@@ -0,0 +1,678 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import file from './file.js';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import fse from "fs-extra";
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import multiExtender from './multiExtender.js';
|
||||
|
||||
import objectParser from './objectParser.js';
|
||||
|
||||
import cacheDisabler from './cacheDisabler.js';
|
||||
|
||||
|
||||
export default class filemanager{
|
||||
|
||||
applications = new Array();
|
||||
|
||||
files = new Array();
|
||||
|
||||
directories = new Array();
|
||||
|
||||
replacements = new Array();
|
||||
|
||||
cores = new Array();
|
||||
|
||||
pragmas = new Array();
|
||||
|
||||
allFiles = new Array();
|
||||
|
||||
|
||||
storeSource = true;
|
||||
|
||||
cache_folder_depth = 0;
|
||||
|
||||
|
||||
multiExtender = new multiExtender();
|
||||
|
||||
objectParser = new objectParser();
|
||||
|
||||
cacheDisabler = new cacheDisabler();
|
||||
|
||||
|
||||
crossPlatformPath( path ) {
|
||||
|
||||
return tools.slash( path );
|
||||
|
||||
}
|
||||
|
||||
constructor( cache_directory ) {
|
||||
|
||||
if( !cache_directory ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
this.cache_directory = this.crossPlatformPath( cache_directory );
|
||||
|
||||
this.writeRandomString()
|
||||
|
||||
}
|
||||
|
||||
async writeRandomString() {
|
||||
|
||||
this.randomString = String(Math.floor(Math.random() * 1000 )).padStart(4, '0');
|
||||
|
||||
this.cacheDisabler.randomString = this.randomString;
|
||||
|
||||
await fs.writeFileSync( "./framework/configs/randomString.json", this.randomString );
|
||||
|
||||
}
|
||||
|
||||
routeDirectory( directory, relativeDirectory ) {
|
||||
|
||||
var path = "framework";
|
||||
|
||||
var subPath = "unify";
|
||||
|
||||
var files = fs.readdirSync( directory );
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
|
||||
var fileName = files[i];
|
||||
|
||||
var fileLocation = relativeDirectory + fileName;
|
||||
|
||||
this.replace( fileLocation );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addCustomReplacements() {
|
||||
|
||||
this.addReplacement( "/elements/", "/"+this.cache_directory+"elements/");
|
||||
|
||||
this.addReplacement( "/user/", "/"+this.cache_directory+"user/" );
|
||||
|
||||
this.replace( "/engine/");
|
||||
|
||||
this.replace( "/3rdparty/");
|
||||
|
||||
this.routeDirectory( "framework/unify", "/unify/" );
|
||||
|
||||
this.routeDirectory( "framework/server", "/server/" );
|
||||
|
||||
this.routeDirectory( "framework/client", "/client/" );
|
||||
|
||||
this.routeDirectory( "framework/unify/sql", "/unify/sql/" );
|
||||
|
||||
this.routeDirectory( "framework/unify/math", "/unify/math/" );
|
||||
|
||||
}
|
||||
|
||||
replace( source ) {
|
||||
|
||||
var target = "/framework" + source;
|
||||
|
||||
this.addReplacement(source, target);
|
||||
|
||||
}
|
||||
|
||||
addReplacement( source, target ) {
|
||||
|
||||
var replacement = new Object();
|
||||
|
||||
replacement.source = source;
|
||||
|
||||
replacement.target = target;
|
||||
|
||||
this.replacements.push( replacement );
|
||||
|
||||
}
|
||||
|
||||
readFileListCache( filesJson ) {
|
||||
|
||||
this.files = filesJson;
|
||||
|
||||
}
|
||||
|
||||
getFiles() {
|
||||
|
||||
return this.files;
|
||||
|
||||
}
|
||||
|
||||
writeFileListCache() {
|
||||
|
||||
var json = "export default " + JSON.stringify( this.files ) + ";";
|
||||
|
||||
fs.writeFileSync( "./framework/configs/files.js", json );
|
||||
|
||||
|
||||
var json = "export default " + JSON.stringify( this.applications ) + ";";
|
||||
|
||||
fs.writeFileSync( "./framework/configs/applications.js", json );
|
||||
|
||||
}
|
||||
|
||||
async updateCache() {
|
||||
|
||||
await this.findApplicationFiles( "./application");
|
||||
|
||||
await this.emptyCacheDirectory();
|
||||
|
||||
await this.createDirectories();
|
||||
|
||||
await this.writeFiles();
|
||||
|
||||
}
|
||||
|
||||
addReplacement( source, target ) {
|
||||
|
||||
var replacement = new Object();
|
||||
|
||||
replacement.source = source;
|
||||
|
||||
replacement.target = target;
|
||||
|
||||
this.replacements.push( replacement );
|
||||
|
||||
}
|
||||
|
||||
async createDir( path ) {
|
||||
|
||||
fse.ensureDirSync( path );
|
||||
|
||||
}
|
||||
|
||||
async emptyCacheDirectory() {
|
||||
|
||||
fs.emptyDirSync( this.cache_directory );
|
||||
|
||||
}
|
||||
|
||||
async createDirectory( directory ) {
|
||||
|
||||
if( this.temporary_cache_directory ) {
|
||||
|
||||
//console.log(path.resolve( this.temporary_cache_directory + directory ));
|
||||
|
||||
fs.ensureDirSync( path.resolve( this.temporary_cache_directory + directory ) );
|
||||
|
||||
} else {
|
||||
|
||||
fs.ensureDirSync( path.resolve( this.cache_directory + directory ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async createDirectories() {
|
||||
|
||||
var directories = this.directories.reverse();
|
||||
|
||||
for( var c = 0; c < directories.length; c++ ) {
|
||||
|
||||
var directory = directories[c];
|
||||
|
||||
this.createDirectory( directory );
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
definePragma( pragma ) {
|
||||
|
||||
this.pragmas.push( pragma );
|
||||
|
||||
}
|
||||
|
||||
cleanURL( source ) {
|
||||
|
||||
var token = "//";
|
||||
|
||||
for ( var i = 0; i < 4; i++ ) {
|
||||
|
||||
token += "/";
|
||||
|
||||
source = source.replaceAll( token, "/" );
|
||||
|
||||
}
|
||||
|
||||
source = source.replaceAll('..//', '../');
|
||||
|
||||
return source;
|
||||
|
||||
}
|
||||
|
||||
definePragmas( source ) {
|
||||
|
||||
for ( var i = 0; i < this.pragmas.length; i++ ) {
|
||||
|
||||
var pragma = this.pragmas[i];
|
||||
|
||||
source = "\n\n#define " + pragma.toUpperCase() + " \n\n" + source;
|
||||
|
||||
}
|
||||
|
||||
return source;
|
||||
|
||||
}
|
||||
|
||||
writeFileToDisk( source, path, filename ) {
|
||||
|
||||
if( this.temporary_cache_directory ) {
|
||||
|
||||
fs.writeFileSync( this.temporary_cache_directory + path + "/" + filename, source );
|
||||
|
||||
} else {
|
||||
|
||||
fs.writeFileSync( this.cache_directory + path + "/" + filename, source );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
composeFile( file, side ) {
|
||||
|
||||
var path = file.path;
|
||||
|
||||
var filename = file.name;
|
||||
|
||||
var source = file.parsedSource;
|
||||
|
||||
var customMethodPreFixes = new Array("node", "state");
|
||||
|
||||
if( source ) {
|
||||
|
||||
source = this.cleanURL( source );
|
||||
|
||||
source = this.objectParser.compose( source, path + "/" + filename, customMethodPreFixes );
|
||||
|
||||
if( side == "client" ) {
|
||||
|
||||
source = this.cacheDisabler.parseSource( source, path + "/" + filename );
|
||||
|
||||
}
|
||||
|
||||
source = this.multiExtender.enableMultiExtend( source, file.depth );
|
||||
|
||||
source = this.definePragmas( source );
|
||||
|
||||
this.writeFileToDisk( source, path, filename );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async writeFiles( side ) {
|
||||
|
||||
var files = this.files;
|
||||
|
||||
for( var c = 0; c < files.length; c++ ) {
|
||||
|
||||
var file = files[c];
|
||||
|
||||
this.composeFile( file, side );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async renewCache( directory, files ) {
|
||||
|
||||
for( var c = 0; c < files.length; c++ ) {
|
||||
|
||||
var filename = files[c];
|
||||
|
||||
var filePath = this.cache_directory + "/" + filename;
|
||||
|
||||
console.log( "Refresh cache:", directory, filename );
|
||||
|
||||
filePath = path.resolve( filePath )
|
||||
|
||||
var source = await fs.readFileSync( filePath, 'utf8');
|
||||
|
||||
source = this.cacheDisabler.parseSource( source );
|
||||
|
||||
await fs.writeFileSync( filePath, source );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async findApplicationFiles( directory, depth = 0, parentFile ) {
|
||||
|
||||
var files = await fs.readdirSync( directory );
|
||||
|
||||
for( var c = 0; c<files.length; c++ ) {
|
||||
|
||||
var filename = files[c];
|
||||
|
||||
if( filename != ".DS_Store" ) {
|
||||
|
||||
var newFile = await this.processFile( filename, directory, depth, parentFile );
|
||||
|
||||
if( parentFile ) {
|
||||
|
||||
parentFile.add( newFile );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return parentFile;
|
||||
|
||||
}
|
||||
|
||||
normalizePath( directory ) {
|
||||
|
||||
if( process.platform == "win32" ) {
|
||||
|
||||
var separator = "\\";
|
||||
|
||||
} else {
|
||||
|
||||
var separator = "/";
|
||||
|
||||
}
|
||||
|
||||
var dirParts = directory.split( separator );
|
||||
|
||||
dirParts.shift();
|
||||
|
||||
return dirParts.join( separator );
|
||||
|
||||
}
|
||||
|
||||
writeCacheHistory() {
|
||||
|
||||
fs.writeFileSync( path.resolve("./framework/cache/platforms/cachedFiles.json"), JSON.stringify( this.allFiles ) );
|
||||
|
||||
}
|
||||
|
||||
filterFile( file, previousFiles, index ) {
|
||||
|
||||
var name = file.name;
|
||||
|
||||
var searchIndex = previousFiles.findIndex( ( file ) => file.name == name );
|
||||
|
||||
if( searchIndex != -1 ) {
|
||||
|
||||
var previousFile = previousFiles[ searchIndex ];
|
||||
|
||||
if( previousFile.dateModified.toString() == file.dateModified.toString() ) {
|
||||
|
||||
delete this.files[ index ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
filterFiles( source ) {
|
||||
|
||||
var previousFiles = JSON.parse( source );
|
||||
|
||||
var files = this.files;
|
||||
|
||||
for ( var index = 0; index < files.length; index++ ) {
|
||||
|
||||
var file = files[ index ];
|
||||
|
||||
this.filterFile( file, previousFiles, index )
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
filterModified() {
|
||||
|
||||
if( !fs.existsSync( path.resolve("./framework/cache/platforms/cachedFiles.json") ) ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var source = fs.readFileSync( path.resolve("./framework/cache/platforms/cachedFiles.json"), "utf8" );
|
||||
|
||||
if( !source ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
this.filterFiles( source );
|
||||
|
||||
this.files = this.files.filter( n => n );
|
||||
|
||||
}
|
||||
|
||||
getFileType( stats ) {
|
||||
|
||||
if( stats.isDirectory() ) {
|
||||
|
||||
return "directory";
|
||||
|
||||
}
|
||||
|
||||
if( stats.isFile() ) {
|
||||
|
||||
return "file";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createFileObject( directory, filename, depth ) {
|
||||
|
||||
var filePath = path.join( directory, filename );
|
||||
|
||||
var stats = fs.statSync( filePath );
|
||||
|
||||
|
||||
var newFile = new file();
|
||||
|
||||
newFile.name = filename;
|
||||
|
||||
newFile.path = this.normalizePath( directory );
|
||||
|
||||
newFile.filePath = filePath;
|
||||
|
||||
newFile.depth = depth;
|
||||
|
||||
newFile.dateModified = stats.ctime.toString();
|
||||
|
||||
newFile.type = this.getFileType( stats );
|
||||
|
||||
|
||||
return newFile;
|
||||
|
||||
}
|
||||
|
||||
async processDirectory( newFile, parentFile ) {
|
||||
|
||||
const excludeDirectorys = new Array("assets", ".DS_Store");
|
||||
|
||||
if( !excludeDirectorys.includes( newFile.name ) ) {
|
||||
|
||||
if( parentFile ) {
|
||||
|
||||
await this.findApplicationFiles( newFile.filePath, newFile.depth + 1, newFile );
|
||||
|
||||
} else {
|
||||
|
||||
await this.findApplicationFiles( newFile.filePath, newFile.depth + 1 );
|
||||
|
||||
this.directories.push( this.normalizePath( newFile.filePath ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async processNormalFile( newFile, directory, parentFile ) {
|
||||
|
||||
if( newFile.name == "application.js" ) {
|
||||
|
||||
if( !parentFile ) {
|
||||
|
||||
var fileThree = await this.findApplicationFiles( directory, newFile.depth + 1, newFile );
|
||||
|
||||
this.applications.push( fileThree );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( this.storeSource ) {
|
||||
|
||||
this.processSource( newFile, newFile.filePath, newFile.depth );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async handleFile( newFile, parentFile, directory ) {
|
||||
|
||||
var fileParts = newFile.name.split(".");
|
||||
|
||||
if( newFile.type == "directory" ) {
|
||||
|
||||
await this.processDirectory( newFile, parentFile );
|
||||
|
||||
} else {
|
||||
|
||||
await this.processNormalFile( newFile, directory, parentFile );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async processFile( filename, directory, depth, parentFile = false ) {
|
||||
|
||||
var newFile = this.createFileObject( directory, filename, depth );
|
||||
|
||||
await this.handleFile( newFile, parentFile, directory, depth );
|
||||
|
||||
|
||||
if( !parentFile ) {
|
||||
|
||||
this.files.push( newFile );
|
||||
|
||||
this.allFiles.push( newFile )
|
||||
|
||||
}
|
||||
|
||||
return newFile;
|
||||
|
||||
}
|
||||
|
||||
async processSource( newFile, filePath, depth ) {
|
||||
|
||||
newFile.source = await fs.readFileSync( filePath, 'utf8' );
|
||||
|
||||
var source = this.cleanURL( newFile.source );
|
||||
|
||||
newFile.source = source;
|
||||
|
||||
newFile.parsedSource = this.parseSource( source , depth );
|
||||
|
||||
return file;
|
||||
|
||||
}
|
||||
|
||||
parseSourceLine( code, replacement, depth ) {
|
||||
|
||||
var source = replacement.source;
|
||||
|
||||
var target = replacement.target;
|
||||
|
||||
|
||||
var relativeTarget = this.computeRelativePath( depth ) + target;
|
||||
|
||||
|
||||
code = code.replaceAll( '"' + source, '"' + relativeTarget );
|
||||
|
||||
code = code.replaceAll( "'" + source, "'" + relativeTarget );
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
parseSource( code, depth ) {
|
||||
|
||||
code = "\n\nimport extender from '/unify/extender.js';\n\n " + code;
|
||||
|
||||
var replacements = this.replacements;
|
||||
|
||||
for( var c = 0; c < replacements.length;c++ ) {
|
||||
|
||||
var replacement = replacements[c];
|
||||
|
||||
|
||||
code = this.parseSourceLine( code, replacement, depth );
|
||||
|
||||
}
|
||||
|
||||
code = this.cleanURL( code );
|
||||
|
||||
return code;
|
||||
|
||||
}
|
||||
|
||||
computeRelativePath( depth ){
|
||||
|
||||
var backString = "";
|
||||
|
||||
var path = this.cache_directory;
|
||||
|
||||
var parts = path.split("/")
|
||||
|
||||
parts = parts.filter(n => n)
|
||||
|
||||
|
||||
if( parts[0] == "." ) {
|
||||
|
||||
parts.shift();
|
||||
|
||||
}
|
||||
|
||||
var totalDepth = parts.length + depth;
|
||||
|
||||
for (var i = 0; i < totalDepth; i++) {
|
||||
|
||||
backString += "../";
|
||||
|
||||
}
|
||||
|
||||
return backString;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
828
framework/server/hotSwapping.js
Normal file
828
framework/server/hotSwapping.js
Normal file
@@ -0,0 +1,828 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import { spawn } from 'child_process';
|
||||
|
||||
import filemanager from './filemanager.js';
|
||||
|
||||
import unify from '../unify/unify.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import colors from '../unify/consoleColors.js';
|
||||
|
||||
import groupsFlat from './themeGroups.js';
|
||||
|
||||
import cacheManager from "./scripts/cacheManager.js";
|
||||
|
||||
import { gpp } from '../node_modules/node-gpp/child.js';
|
||||
|
||||
import simplePath from '../unify/simplePath.js';
|
||||
|
||||
|
||||
|
||||
export default class hotSwap{
|
||||
|
||||
|
||||
allPlatformFiles = new Array();
|
||||
|
||||
cache = new cacheManager();
|
||||
|
||||
gpp = new gpp();
|
||||
|
||||
|
||||
constructor( clients ) {
|
||||
|
||||
this.clients = clients;
|
||||
|
||||
this.create();
|
||||
|
||||
this.createPlatformCachePath();
|
||||
|
||||
this.createGlobals();
|
||||
|
||||
}
|
||||
|
||||
createGlobals() {
|
||||
|
||||
if( !global.visibleElements ) {
|
||||
|
||||
global.visibleElements = new Array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createPlatformCachePath() {
|
||||
|
||||
this.pathToPlatforms = new simplePath();
|
||||
|
||||
this.pathToPlatforms.beginWithSlash = false;
|
||||
|
||||
this.pathToPlatforms.endWithSlash = true;
|
||||
|
||||
this.pathToPlatforms.add( "framework" )
|
||||
|
||||
this.pathToPlatforms.add( "cache" )
|
||||
|
||||
this.pathToPlatforms.add( "platforms" )
|
||||
|
||||
}
|
||||
|
||||
setSocketManager( socketManager ) {
|
||||
|
||||
this.socketManager = socketManager;
|
||||
|
||||
}
|
||||
|
||||
createInheritenceCache() {
|
||||
|
||||
}
|
||||
|
||||
async spawnNodemonInstance() {
|
||||
|
||||
|
||||
var files = new filemanager( "./application/" );
|
||||
|
||||
await files.findApplicationFiles( "./application");
|
||||
|
||||
|
||||
var directories = files.directories;
|
||||
|
||||
var that = this;
|
||||
|
||||
for (var i = 0; i < directories.length; i++) {
|
||||
|
||||
var directory = directories[ i ];
|
||||
|
||||
var pathToFile = new simplePath();
|
||||
|
||||
pathToFile.beginWithSlash = false;
|
||||
|
||||
pathToFile.endWithSlash = true;
|
||||
|
||||
pathToFile.add( "application" )
|
||||
|
||||
pathToFile.add( directory )
|
||||
|
||||
|
||||
let directoryPath = path.resolve( pathToFile.resolve() );
|
||||
|
||||
//console.log("Watch directory:", i, colors.green( directoryPath ) );
|
||||
|
||||
|
||||
var callback = function( eventType, filename ) {
|
||||
|
||||
var filePath = directoryPath + "/" + filename;
|
||||
|
||||
console.log("file changed ", eventType, filePath );
|
||||
|
||||
that.message( eventType, filePath );
|
||||
|
||||
};
|
||||
|
||||
if ( fs.existsSync( directoryPath ) ) {
|
||||
|
||||
fs.watch( directoryPath, callback )
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
spawnNodemon() {
|
||||
|
||||
this.createInheritenceCache();
|
||||
|
||||
try {
|
||||
|
||||
this.spawnNodemonInstance();
|
||||
|
||||
} catch ( error ) {
|
||||
|
||||
//console.error("Nodemon Crashed, Instantiating a new instance of nodemon..", error);
|
||||
|
||||
this.spawnNodemonInstance();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
create() {
|
||||
|
||||
//if( global.clusterID == 1 ) {
|
||||
|
||||
var app = this.spawnNodemon();
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
async message( event, file ) {
|
||||
|
||||
if( event == "change" ) {
|
||||
|
||||
//var files = event.data;
|
||||
|
||||
this.updateFiles( file );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getPlatformCachePath() {
|
||||
|
||||
var cachePath = new simplePath();
|
||||
|
||||
cachePath.beginWithSlash = false;
|
||||
|
||||
cachePath.add( "framework" );
|
||||
|
||||
cachePath.add( "cache" );
|
||||
|
||||
cachePath.add( "platforms" );
|
||||
|
||||
cachePath.add( global.os );
|
||||
|
||||
cachePath.add( global.device );
|
||||
|
||||
cachePath.add( global.tint );
|
||||
|
||||
|
||||
return cachePath.resolve();
|
||||
|
||||
}
|
||||
|
||||
getPathParts( file ) {
|
||||
|
||||
var rootDir = tools.slash( path.resolve("./") ).replace("C:/", "c:/");
|
||||
|
||||
var fullPath = file.replace( rootDir, "" );
|
||||
|
||||
var pathParts = fullPath.split("/");
|
||||
|
||||
return pathParts;
|
||||
|
||||
}
|
||||
|
||||
async processSource( fileObject, filePath ) {
|
||||
|
||||
var clientFiles = new filemanager();
|
||||
|
||||
clientFiles.cache_directory = this.getPlatformCachePath();
|
||||
|
||||
clientFiles.addCustomReplacements();
|
||||
|
||||
await clientFiles.processSource( fileObject, filePath, fileObject.depth - 2 )
|
||||
|
||||
}
|
||||
|
||||
getRelativePath( pathParts ) {
|
||||
|
||||
var relativeApplicationPath = pathParts.join("/").replace("/application/", "");
|
||||
|
||||
return tools.slash( relativeApplicationPath );
|
||||
|
||||
}
|
||||
|
||||
async createFileObject( filePath ) {
|
||||
|
||||
var slashedFilePath = tools.slash( filePath );
|
||||
|
||||
var pathParts = this.getPathParts( slashedFilePath );
|
||||
|
||||
|
||||
var fileObject = new Object();
|
||||
|
||||
fileObject.name = pathParts.pop();
|
||||
|
||||
fileObject.depth = pathParts.length;
|
||||
|
||||
fileObject.path = this.getRelativePath( pathParts );
|
||||
|
||||
fileObject.type = "file";
|
||||
|
||||
fileObject.files = new Array();
|
||||
|
||||
|
||||
await this.processSource( fileObject, slashedFilePath );
|
||||
|
||||
|
||||
return fileObject;
|
||||
|
||||
}
|
||||
|
||||
updateClientObjects( newInstance, clientObject ) {
|
||||
|
||||
//console.log( "nodeMethods", clientObject );
|
||||
|
||||
var nodeMethods = newInstance.__nodeMethods.split(",");
|
||||
|
||||
|
||||
|
||||
for ( var j = 0; j < nodeMethods.length; j++ ) {
|
||||
|
||||
var nodeMethodName = nodeMethods[j];
|
||||
|
||||
clientObject[ nodeMethodName ] = newInstance[nodeMethodName];
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateMethodByClient( newInstance, client, className ) {
|
||||
|
||||
var classObjects = client.classObjects;
|
||||
|
||||
var clientObject = classObjects[ className ];
|
||||
|
||||
|
||||
if( clientObject ) {
|
||||
|
||||
this.updateClientObjects( newInstance, clientObject );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateClients( newInstance, clients, className ) {
|
||||
|
||||
//for ( var i = 0; i < clients.length; i++ ) {
|
||||
|
||||
for ( const [ key, client ] of Object.entries( clients ) ) {
|
||||
|
||||
//var client = clients[ i ];
|
||||
|
||||
this.updateMethodByClient( newInstance, client, className );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async updateMethods( newInstance, clients ) {
|
||||
|
||||
var className = newInstance.getClassName();
|
||||
|
||||
if( global.mode == "development") {
|
||||
|
||||
this.updateClients( newInstance, clients, className );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getAllExtendedObjects( extendObjects, pathsArray ) {
|
||||
|
||||
//console.log("extendObjects", extendObjects, pathsArray);
|
||||
|
||||
for ( var c = 0; c < extendObjects.length - 1; c++ ) {
|
||||
|
||||
var objectName = extendObjects[c];
|
||||
|
||||
var extendedObject = global.classObjects[ objectName ]
|
||||
|
||||
if( extendedObject ) {
|
||||
|
||||
pathsArray.push( extendedObject.__sourcePath );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( "Class not found in core.classObjects.", objectName );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getExtendedDependencyPathsOfObject( object, pathsArray ) {
|
||||
|
||||
//var visible = global.visibleElements.includes( object.getClassName() );
|
||||
|
||||
//if( visible ) {
|
||||
|
||||
pathsArray.push( object.__sourcePath );
|
||||
|
||||
var extendObjects = object.getExtends();
|
||||
|
||||
extendObjects = tools.removeDuplicates( extendObjects );
|
||||
|
||||
this.getAllExtendedObjects( extendObjects, pathsArray );
|
||||
|
||||
//console.log("extendObjects", extendObjects);
|
||||
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
getExtendedDependencyPaths( objects ) {
|
||||
|
||||
var pathsArray = new Array();
|
||||
|
||||
for ( var i = 0; i < objects.length; i++ ) {
|
||||
|
||||
var object = objects[i];
|
||||
|
||||
//console.log("getExtendedDependencyPaths", object.__sourcePath );
|
||||
|
||||
this.getExtendedDependencyPathsOfObject( object, pathsArray );
|
||||
|
||||
}
|
||||
|
||||
pathsArray = tools.removeDuplicates( pathsArray );
|
||||
|
||||
return pathsArray;
|
||||
|
||||
}
|
||||
|
||||
reloadPathCache( paths, group ) {
|
||||
|
||||
for ( var c = 0; c < paths.length; c++ ) {
|
||||
|
||||
var cachePath = this.pathToPlatforms.clone();
|
||||
|
||||
cachePath.beginWithSlash = true;
|
||||
|
||||
cachePath.add( "Original" );
|
||||
|
||||
cachePath.add( group.path );
|
||||
|
||||
cachePath.add( paths[ c ] );
|
||||
|
||||
this.allPlatformFiles.push( cachePath.resolve() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async reloadAllThemeCache( groups, paths ) {
|
||||
|
||||
for ( var i = 0; i < groups.length; i++ ) {
|
||||
|
||||
var group = groups[i];
|
||||
|
||||
this.reloadPathCache( paths, group );
|
||||
|
||||
await this.renewPlatform( group.name, group.path, paths );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createApplicationPath( path, filename ) {
|
||||
|
||||
var fullPath = this.pathToPlatforms.clone();
|
||||
|
||||
fullPath.absolute = true;
|
||||
|
||||
fullPath.add( global.os )
|
||||
|
||||
fullPath.add( global.device )
|
||||
|
||||
fullPath.add( global.tint )
|
||||
|
||||
fullPath.add( path )
|
||||
|
||||
fullPath.add( filename + "?disableCache=" + Math.random() )
|
||||
|
||||
|
||||
return fullPath.resolve();
|
||||
}
|
||||
|
||||
async processDependencies( fileObject, groupsFlatSelection ) {
|
||||
|
||||
var path = this.createApplicationPath( fileObject.path, fileObject.name );
|
||||
|
||||
var importPromise = import( "file://" + path );
|
||||
|
||||
var that = this;
|
||||
|
||||
importPromise.catch( error => {
|
||||
|
||||
console.log("Error loading dynamic import. Your code contains an error.", error)
|
||||
|
||||
} ).then( async function( module ) {
|
||||
|
||||
if( !module ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
var newInstance = new module.default();
|
||||
|
||||
await that.updateInstance( newInstance, groupsFlatSelection );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async prepareInstance( newInstance ) {
|
||||
|
||||
if( !newInstance ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
unify.extend( newInstance );
|
||||
|
||||
if( !newInstance.getClassName ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
await this.updateMethods( newInstance, this.clients );
|
||||
|
||||
return newInstance;
|
||||
|
||||
}
|
||||
|
||||
getDependencieObjects( newInstance ) {
|
||||
|
||||
var className = newInstance.getClassName();
|
||||
|
||||
//console.log("dependencieMap", className, Object.keys( global.dependencieMap ) ) ;
|
||||
|
||||
var dependencyObjects = global.dependencieMap[ className ];
|
||||
|
||||
if( dependencyObjects ) {
|
||||
|
||||
return dependencyObjects;
|
||||
|
||||
} else {
|
||||
|
||||
return new Array();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
async updateInstance( newInstance, groupsFlatSelection ) {
|
||||
|
||||
var newInstance = await this.prepareInstance( newInstance );
|
||||
|
||||
if( !newInstance ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
var dependencyObjects = this.getDependencieObjects( newInstance )
|
||||
|
||||
var pathsArray = this.getExtendedDependencyPaths( dependencyObjects );
|
||||
|
||||
await this.reloadAllThemeCache( groupsFlatSelection, pathsArray )
|
||||
|
||||
}
|
||||
|
||||
getAbsolutePathByFile( file, customPath ) {
|
||||
|
||||
var absolutePath = this.pathToPlatforms.clone();
|
||||
|
||||
absolutePath.beginWithSlash = true;
|
||||
|
||||
absolutePath.add( "Original" );
|
||||
|
||||
if( customPath ) {
|
||||
|
||||
absolutePath.add( customPath );
|
||||
|
||||
} else {
|
||||
|
||||
absolutePath.add( "Server" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
absolutePath.add( file.path );
|
||||
|
||||
absolutePath.add( file.name );
|
||||
|
||||
return absolutePath.resolve();
|
||||
|
||||
}
|
||||
|
||||
addPlatformPaths( files, customPath = false ) {
|
||||
|
||||
for ( var i = 0; i < files.length; i++ ) {
|
||||
|
||||
var file = files[i];
|
||||
|
||||
var absolutePath = this.getAbsolutePathByFile( file, customPath );
|
||||
|
||||
if( file.type == "file" ) {
|
||||
|
||||
this.allPlatformFiles.push( absolutePath );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async processServerFiles( filesArray ) {
|
||||
|
||||
var cachePath = tools.slash( "framework/cache/platforms/Original/Server/" );
|
||||
|
||||
var server_files = new filemanager( cachePath );
|
||||
|
||||
server_files.definePragma("SERVER");
|
||||
|
||||
server_files.definePragma("server_cache");
|
||||
|
||||
server_files.addCustomReplacements();
|
||||
|
||||
server_files.files = filesArray;
|
||||
|
||||
this.addPlatformPaths( filesArray );
|
||||
|
||||
await server_files.writeFiles();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
async updateConfig() {
|
||||
|
||||
var cachePath = tools.slash( "framework/server_cache/" );
|
||||
|
||||
var server_files = new filemanager( cachePath );
|
||||
|
||||
await server_files.findApplicationFiles( "./application");
|
||||
|
||||
var applications = server_files.applications;
|
||||
|
||||
var application = await this.cache.importApplication( applications[0].path );
|
||||
|
||||
|
||||
this.cache.getApplicationProperties( application )
|
||||
|
||||
await this.cache.writeApplicationPropertiesToFile();
|
||||
|
||||
}
|
||||
|
||||
createGroupPath() {
|
||||
|
||||
var groupPath = new simplePath();
|
||||
|
||||
groupPath.endWithSlash = false;
|
||||
|
||||
|
||||
groupPath.add( global.os )
|
||||
|
||||
groupPath.add( global.device )
|
||||
|
||||
groupPath.add( global.tint )
|
||||
|
||||
return groupPath.resolve();
|
||||
|
||||
}
|
||||
|
||||
createGroup() {
|
||||
|
||||
var groups = new Array( groupsFlat[5] );
|
||||
|
||||
//group.path = this.createGroupPath();
|
||||
|
||||
groups[0].path = this.createGroupPath();
|
||||
|
||||
return groups;
|
||||
|
||||
}
|
||||
|
||||
async processThemeGroups( groups, filesArray ) {
|
||||
|
||||
for ( var i = 0; i < groups.length; i++ ) {
|
||||
|
||||
var group = groups[i];
|
||||
|
||||
await this.processPlatform( group.name, group.path, filesArray );//filesArray );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async writeCachePathsToJSON() {
|
||||
|
||||
var jsonFiles = JSON.stringify( this.allPlatformFiles );
|
||||
|
||||
var path = tools.slash("framework/cache/platforms/files.json");
|
||||
|
||||
await fs.writeFileSync( path, jsonFiles, "utf8" );
|
||||
|
||||
}
|
||||
|
||||
async updateFile( file ) {
|
||||
|
||||
var fileObject = await this.createFileObject( file ) ;
|
||||
|
||||
var themeGroups = this.createGroup();
|
||||
|
||||
var filesArray = new Array( fileObject );
|
||||
|
||||
|
||||
await this.processThemeGroups( themeGroups, filesArray );
|
||||
|
||||
await this.processServerFiles( filesArray );
|
||||
|
||||
await this.updateConfig();
|
||||
|
||||
await this.writeCachePathsToJSON();
|
||||
|
||||
await this.gpp.convert_files();
|
||||
|
||||
//console.log("themeGroups", themeGroups);
|
||||
|
||||
await this.processDependencies( fileObject, themeGroups );
|
||||
|
||||
console.log( colors.green( "Updated file:" ), colors.green( file ) );
|
||||
|
||||
this.sendFileToClient( fileObject );
|
||||
|
||||
}
|
||||
|
||||
async updateFiles( file ) {
|
||||
|
||||
//for (var i = 0; i < files.length; i++) {
|
||||
|
||||
// var file = files[i];
|
||||
|
||||
await this.updateFile( file );
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
sendFileToClient( fileObject ) {
|
||||
|
||||
var clients = this.clients;
|
||||
|
||||
var parameters = new Object();
|
||||
|
||||
parameters.file = fileObject;
|
||||
|
||||
parameters.action = "updateFile";
|
||||
|
||||
console.log( "send updated file to client", clients.length );
|
||||
|
||||
for ( const [ key, client ] of Object.entries( clients ) ) {
|
||||
|
||||
|
||||
|
||||
client.debugMessage( parameters )
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reloadPathCache( paths, group ) {
|
||||
|
||||
for ( var c = 0; c < paths.length; c++ ) {
|
||||
|
||||
var cachePath = this.pathToPlatforms.clone();
|
||||
|
||||
cachePath.beginWithSlash = true;
|
||||
|
||||
cachePath.add( "Original" );
|
||||
|
||||
cachePath.add( group.path );
|
||||
|
||||
cachePath.add( paths[ c ] );
|
||||
|
||||
this.allPlatformFiles.push( cachePath.resolve() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
definePragmas( files, path ) {
|
||||
|
||||
var terms = path.split("/");
|
||||
|
||||
terms.shift();
|
||||
|
||||
for ( var i = 0; i < terms.length; i++ ) {
|
||||
|
||||
files.definePragma( terms[i] );
|
||||
|
||||
}
|
||||
|
||||
files.definePragma("CLIENT");
|
||||
|
||||
}
|
||||
|
||||
getThemePath( path, isOriginal = false ) {
|
||||
|
||||
var fullPath = this.pathToPlatforms.clone();
|
||||
|
||||
if( isOriginal ) {
|
||||
|
||||
fullPath.add( "Original" );
|
||||
|
||||
}
|
||||
|
||||
fullPath.add( path );
|
||||
|
||||
return fullPath.resolve();
|
||||
|
||||
}
|
||||
|
||||
async processPlatform( name, path, filesArray ) {
|
||||
|
||||
var themePath = this.getThemePath( path );
|
||||
|
||||
var files = new filemanager( themePath );
|
||||
|
||||
files.addCustomReplacements();
|
||||
|
||||
this.definePragmas( files, path );
|
||||
|
||||
files.files = filesArray;
|
||||
|
||||
files.temporary_cache_directory = this.getThemePath( path, true );
|
||||
|
||||
await files.writeFiles("client");
|
||||
|
||||
this.addPlatformPaths( files.files, path )
|
||||
|
||||
}
|
||||
|
||||
async renewPlatform( name, path, filesArray ) {
|
||||
|
||||
var themePath = this.getThemePath( path, true );
|
||||
|
||||
//console.log("getThemePath", path);
|
||||
|
||||
var files = new filemanager( themePath );
|
||||
|
||||
await files.renewCache( path, filesArray );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
2
framework/server/imports.js
Normal file
2
framework/server/imports.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import bundle0 from "../../framework/cache/server/demo/application.js"
|
||||
export default [bundle0];
|
||||
323
framework/server/index.js
Executable file
323
framework/server/index.js
Executable file
@@ -0,0 +1,323 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import cluster from 'cluster';
|
||||
|
||||
import os from 'os';
|
||||
|
||||
//import express from 'express';
|
||||
|
||||
import https from 'https';
|
||||
|
||||
import util from 'util';
|
||||
|
||||
import serverManager from './serverManager.js';
|
||||
|
||||
import applicationManager from './applicationManager.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import moduleLoader from '../server/moduleLoader.js';
|
||||
|
||||
//import syncClient from '../sync/syncClient.js';
|
||||
|
||||
import user from '../cache/server/user/user.js';
|
||||
|
||||
import sqlite3 from '../node_modules/better-sqlite3/lib/index.js';
|
||||
|
||||
import fileList from '../configs/files.js';
|
||||
|
||||
import database from '../server/database.js';
|
||||
|
||||
import serverOptions from '../configs/config.js';
|
||||
|
||||
import colors from '../unify/consoleColors.js';
|
||||
|
||||
//import objectSizeof from "object-sizeof";
|
||||
|
||||
//import cacheManager from './scripts/cacheManager.js';
|
||||
|
||||
class unifyServer{
|
||||
|
||||
workers = new Array();
|
||||
|
||||
defineGlobals( clusterID ) {
|
||||
|
||||
if( clusterID ){
|
||||
|
||||
global.clusterID = cluster.worker.id;
|
||||
|
||||
}
|
||||
|
||||
global.maxSocketBufferSize = 3000;
|
||||
|
||||
global.mode = serverOptions.mode;
|
||||
|
||||
global.socketPort = serverOptions.socketPort;
|
||||
|
||||
global.ssl = serverOptions.ssl;
|
||||
|
||||
global.useSyncServer = serverOptions.useSyncServer;
|
||||
|
||||
global.os = tools.CamelCase( serverOptions.os );
|
||||
|
||||
global.device = tools.CamelCase( serverOptions.device );
|
||||
|
||||
global.tint = tools.CamelCase( serverOptions.tint );
|
||||
|
||||
global.database = database;
|
||||
|
||||
global.path = path;
|
||||
|
||||
global.user = user;
|
||||
|
||||
global.util = util;
|
||||
|
||||
global.sockets = new Array();
|
||||
|
||||
global.path = path;
|
||||
|
||||
//global.objectSizeof = objectSizeof;
|
||||
|
||||
|
||||
if( !global.__dirname ) {
|
||||
|
||||
global.__dirname = path.resolve();
|
||||
|
||||
}
|
||||
|
||||
if( !global.extendMap ) {
|
||||
|
||||
global.extendMap = new Array();
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( serverOptions.useSyncServer ) {
|
||||
|
||||
global.syncClient = new syncClient();
|
||||
|
||||
global.syncClient.clusterClientID = serverOptions.syncClientID;
|
||||
|
||||
global.syncClient.syncServerAddress = serverOptions.syncServerAddress;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createServer() {
|
||||
|
||||
var server = new serverManager();
|
||||
|
||||
if( process.platform != "android" ) {
|
||||
|
||||
server.port = serverOptions.port;
|
||||
|
||||
server.ssl = serverOptions.ssl;
|
||||
|
||||
server.mode = serverOptions.mode;
|
||||
|
||||
server.serverAddress = serverOptions.serverAddress;
|
||||
|
||||
|
||||
//server.createExpressApp();
|
||||
|
||||
server.setupServer();
|
||||
|
||||
server.createHttpsServer();
|
||||
|
||||
server.createListener();
|
||||
|
||||
}
|
||||
|
||||
return server.httpsServer;
|
||||
|
||||
}
|
||||
|
||||
createProcessListeners() {
|
||||
|
||||
process.on("SIGTERM", (signal) => {
|
||||
|
||||
console.log(`Process ${process.pid} received a SIGTERM signal`);
|
||||
|
||||
if( global.syncClient ) {
|
||||
|
||||
global.syncClient.emptyTable();
|
||||
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
|
||||
});
|
||||
|
||||
process.on("SIGINT", (signal) => {
|
||||
|
||||
console.log(`Process ${process.pid} has been interrupted`);
|
||||
|
||||
if( global.useSyncServer && global.syncClient ) {
|
||||
|
||||
global.syncClient.emptyTable();
|
||||
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
|
||||
});
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
|
||||
console.error( err );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
logServer( serverOptions ) {
|
||||
|
||||
if( global.clusterID == 1 ) {
|
||||
|
||||
if( serverOptions.ssl ) {
|
||||
|
||||
console.log( "\nHttps WebServer started on port: 443" );
|
||||
|
||||
} else {
|
||||
|
||||
console.log( "\nHttps WebServer started on port: ", serverOptions.port );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async start( clusterID ) {
|
||||
|
||||
this.defineGlobals( clusterID );
|
||||
|
||||
this.createProcessListeners();
|
||||
|
||||
|
||||
var httpsServer = this.createServer();
|
||||
|
||||
var applications = new applicationManager();
|
||||
|
||||
applications.defaultSocketPort = serverOptions.socketPort;
|
||||
|
||||
applications.httpsServer = httpsServer;
|
||||
|
||||
|
||||
await applications.runApplications( fileList ); //files.applications
|
||||
|
||||
this.logServer( serverOptions );
|
||||
|
||||
}
|
||||
|
||||
async processFiles() {
|
||||
|
||||
var numCPUS = os.cpus().length;
|
||||
|
||||
console.log("cpu cores detected: ", os.cpus().length );
|
||||
|
||||
if( serverOptions.maxClusters ) {
|
||||
|
||||
console.log( "but max number of clusters set to: ", serverOptions.maxClusters );
|
||||
|
||||
var numberOfClusters = serverOptions.maxClusters;
|
||||
|
||||
} else {
|
||||
|
||||
console.log( "maxClusters is not set." );
|
||||
|
||||
var numberOfClusters = numCPUS;
|
||||
|
||||
}
|
||||
|
||||
console.log("Sync client loaded");
|
||||
|
||||
console.log("Loading ", numberOfClusters, "Cluster(s).");
|
||||
|
||||
console.log("");
|
||||
|
||||
console.log("platform detected: ", process.platform);
|
||||
|
||||
|
||||
if( process.platform == "android" ) {
|
||||
|
||||
this.start( 0 );
|
||||
|
||||
} else {
|
||||
|
||||
for (var i = 0; i < numberOfClusters; i++) {
|
||||
|
||||
this.spawnCluster();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
spawnCluster() {
|
||||
|
||||
var newCluster = cluster.fork();
|
||||
|
||||
this.workers.push( newCluster );
|
||||
|
||||
}
|
||||
|
||||
setupClusters() {
|
||||
|
||||
if( cluster.isMaster ) {
|
||||
|
||||
var that = this;
|
||||
|
||||
cluster.on("disconnect", function( worker ) {
|
||||
|
||||
console.log("Cluster disconnected, start new cluster.");
|
||||
|
||||
that.spawnCluster();
|
||||
|
||||
});
|
||||
|
||||
this.processFiles();
|
||||
|
||||
} else {
|
||||
|
||||
console.log( "starting cluster: ", cluster.worker.id );
|
||||
|
||||
this.start( cluster.worker.id );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//var cache = new cacheManager();
|
||||
|
||||
//await cache.start();
|
||||
|
||||
var server = new unifyServer();
|
||||
|
||||
server.setupClusters();
|
||||
|
||||
|
||||
export default {};
|
||||
224
framework/server/moduleLoader.js
Normal file
224
framework/server/moduleLoader.js
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import Console from '../server/console.js';
|
||||
|
||||
import simplePath from '../unify/simplePath.js';
|
||||
|
||||
|
||||
var __dirname = path.resolve();
|
||||
|
||||
global.path = path;
|
||||
|
||||
|
||||
|
||||
export default class moduleLoader{
|
||||
|
||||
parseNewFiles = true;
|
||||
|
||||
files = new Array();
|
||||
|
||||
constructor( os, device, tint ) {
|
||||
|
||||
this.createPlatformCachePath();
|
||||
|
||||
this.setDirectory( os, device, tint );
|
||||
|
||||
}
|
||||
|
||||
createPlatformCachePath() {
|
||||
|
||||
this.pathToPlatforms = new simplePath();
|
||||
|
||||
this.pathToPlatforms.beginWithSlash = false;
|
||||
|
||||
this.pathToPlatforms.endWithSlash = true;
|
||||
|
||||
this.pathToPlatforms.add( "framework" )
|
||||
|
||||
this.pathToPlatforms.add( "cache" )
|
||||
|
||||
this.pathToPlatforms.add( "platforms" )
|
||||
|
||||
}
|
||||
|
||||
setDirectory( os, device, tint ) {
|
||||
|
||||
if( tint ) {
|
||||
|
||||
this.absolutePath = this.pathToPlatforms.clone();
|
||||
|
||||
this.absolutePath.add( os );
|
||||
|
||||
this.absolutePath.add( device );
|
||||
|
||||
this.absolutePath.add( tint );
|
||||
|
||||
} else {
|
||||
|
||||
this.absolutePath = this.pathToPlatforms.clone();
|
||||
|
||||
this.absolutePath.add( global.os );
|
||||
|
||||
this.absolutePath.add( global.device );
|
||||
|
||||
this.absolutePath.add( global.tint );
|
||||
|
||||
}
|
||||
|
||||
this.absolutePath.endWithSlash = true;
|
||||
|
||||
this.absolutePath.absolute = true;
|
||||
|
||||
}
|
||||
|
||||
async loadModulesFromFiles( directory, core, client ) {
|
||||
|
||||
this.client = client;
|
||||
|
||||
this.core = core;
|
||||
|
||||
var path = this.absolutePath.clone();
|
||||
|
||||
path.add( directory );
|
||||
|
||||
|
||||
var files = await fs.readdirSync( path.resolve() + "/" );
|
||||
|
||||
for(var c = 0; c<files.length; c++) {
|
||||
|
||||
var filename = files[c];
|
||||
|
||||
await this.parseFileDirectory( filename, directory );
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
async parseFileDirectory( filename, directory ) {
|
||||
|
||||
var join = path.join;
|
||||
|
||||
var exclude = new Array();
|
||||
|
||||
|
||||
var fileParts = filename.split(".");
|
||||
|
||||
var filePath = join( directory, filename );
|
||||
|
||||
|
||||
if( fileParts.length == 1 ) {
|
||||
|
||||
await this.parseDirectory( filePath );
|
||||
|
||||
} else {
|
||||
|
||||
await this.parseFile( filePath, fileParts );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async parseFile( filePath, fileParts ) {
|
||||
|
||||
var extension = fileParts.pop();
|
||||
|
||||
if( extension == "js" ) {
|
||||
|
||||
await this.loadModule( filePath );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async loadModule( filePath ) {
|
||||
|
||||
var excludeFiles = new Array("config.js");
|
||||
|
||||
if( !excludeFiles.includes( filePath ) ) {
|
||||
|
||||
var absolutePath = this.absolutePath.clone();
|
||||
|
||||
absolutePath.add( filePath );
|
||||
|
||||
var importObject = await import( tools.slash( "file://" + absolutePath.resolve() ) );
|
||||
|
||||
var contructor = importObject.default;
|
||||
|
||||
if( contructor && contructor.prototype ) {
|
||||
|
||||
await this.initializeModule( contructor, filePath );
|
||||
|
||||
} else {
|
||||
|
||||
Console.warning( "\n Warning: " + filePath + " does not contain a default extended class.\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async initializeModule( initializer, path ) {
|
||||
|
||||
var object = new initializer();
|
||||
|
||||
var className = tools.getClassName( object );
|
||||
|
||||
var exists = this.core.getObjectByclassName( className, this.client );
|
||||
|
||||
if( !exists ) {
|
||||
|
||||
//console.log( "Module loader import unify object", tools.getClassName( object ) );
|
||||
|
||||
this.files.push( object );
|
||||
|
||||
if( this.parseNewFiles ){
|
||||
|
||||
await this.core.parse( object, this.client );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async parseDirectory( filePath ) {
|
||||
|
||||
var excludeDirectorys = new Array("assets");
|
||||
|
||||
var filePathParts = filePath.split("/");
|
||||
|
||||
var directoryName = filePathParts[ filePathParts.length - 1 ];
|
||||
|
||||
|
||||
if( !excludeDirectorys.includes( directoryName ) ) {
|
||||
|
||||
await this.loadModulesFromFiles( "./" + filePath, this.core, this.client );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
82
framework/server/multiExtender.js
Normal file
82
framework/server/multiExtender.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
export default class multiExtender{
|
||||
|
||||
processExtendLine( stripped, extendsIndex, lines, i ) {
|
||||
|
||||
var bodyOpenIndex = stripped.indexOf("{")
|
||||
|
||||
if( bodyOpenIndex == -1 ) {
|
||||
|
||||
var extendArgumentsString = stripped.slice( extendsIndex + 7 )
|
||||
|
||||
} else {
|
||||
|
||||
var extendArgumentsString = stripped.slice( extendsIndex + 7, bodyOpenIndex )
|
||||
|
||||
}
|
||||
|
||||
var extendArguments = extendArgumentsString.split(",");
|
||||
|
||||
extendArguments = extendArguments.map( str => str.replace(/\s/g, '') );
|
||||
|
||||
var newArguments = " extender(" + extendArguments.join(",") + ")";
|
||||
|
||||
if( extendArguments.length > 1 ) {
|
||||
|
||||
lines[i] = lines[i].replace(extendArgumentsString, newArguments)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
processLine( lines, i ) {
|
||||
|
||||
var stripped = lines[i].replaceAll("\t", " ");
|
||||
|
||||
var extendsIndex = stripped.indexOf("extends")
|
||||
|
||||
var lineWidth = stripped.length;
|
||||
|
||||
if( extendsIndex != -1 ) {
|
||||
|
||||
this.processExtendLine( stripped, extendsIndex, lines, i );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enableMultiExtend( source, depth ) {
|
||||
|
||||
source = source.replaceAll("\r", "\n");
|
||||
|
||||
var lines = source.split("\n");
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
|
||||
this.processLine( lines, i );
|
||||
|
||||
}
|
||||
|
||||
var body = "\n\n";
|
||||
|
||||
body += lines.join("\n");
|
||||
|
||||
return body;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
195
framework/server/objectCacheManager.js
Normal file
195
framework/server/objectCacheManager.js
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import unify from '../unify/unify.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
|
||||
export default class objectCacheManager{
|
||||
|
||||
|
||||
objects = new Array();
|
||||
|
||||
|
||||
removeObjectsByClientID( userID ) {
|
||||
|
||||
var objects = this.objects;
|
||||
|
||||
var entries = Object.entries( objects );
|
||||
|
||||
var count = 0;
|
||||
|
||||
var total = 0;
|
||||
|
||||
for( var b = 0; b < entries.length; b++ ) {
|
||||
|
||||
var entry = entries[b];
|
||||
|
||||
var objectsByID = Object.entries( tools.getObjectByEntry( entry ) );
|
||||
|
||||
var path = tools.getClassNameByEntry( entry );
|
||||
|
||||
var empty = true;
|
||||
|
||||
for ( var c = 0; c < objectsByID.length; c++ ) {
|
||||
|
||||
var objectsByUserID = tools.getObjectByEntry( objectsByID[c] );
|
||||
|
||||
var objectID = tools.getClassNameByEntry( objectsByID[c] );
|
||||
|
||||
total++;
|
||||
|
||||
|
||||
if( objectsByUserID[ userID ] ) {
|
||||
|
||||
delete this.objects[path][objectID][userID];
|
||||
|
||||
this.objects[path][objectID].splice( userID, 1 );
|
||||
|
||||
count++;
|
||||
|
||||
} else {
|
||||
|
||||
empty = false;
|
||||
|
||||
}
|
||||
|
||||
this.objects[path][objectID] = this.objects[path][objectID].filter(Boolean);
|
||||
|
||||
if( this.objects[path][objectID].length == 0 ) {
|
||||
|
||||
this.objects[path][objectID] = undefined;
|
||||
|
||||
empty = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( empty ) {
|
||||
|
||||
delete delete this.objects[path][objectID];
|
||||
|
||||
}
|
||||
|
||||
this.objects[path] = this.objects[path].filter(Boolean);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// console.log("removed ", count, "objects");
|
||||
|
||||
// console.log("total ", total, "objects");
|
||||
|
||||
}
|
||||
|
||||
addClientObjectByPathID( clientObject, id, applicationPathString, userID ) {
|
||||
|
||||
var arrayWithObjects = this.objects[ applicationPathString ];
|
||||
|
||||
if( arrayWithObjects ) {
|
||||
|
||||
var arrayWithObjectByID = arrayWithObjects[ id ];
|
||||
|
||||
if( arrayWithObjectByID ) {
|
||||
|
||||
var arrayByUserID = arrayWithObjectByID[ userID ];
|
||||
|
||||
if( arrayByUserID ) {
|
||||
|
||||
return arrayByUserID;
|
||||
|
||||
} else {
|
||||
|
||||
arrayWithObjectByID[ userID ] = clientObject;
|
||||
|
||||
// this.objects[ applicationPathString ][ id ][ userID ]
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.objects[ applicationPathString ][ id ] = new Array();
|
||||
|
||||
return this.addClientObjectByPathID( clientObject, id, applicationPathString, userID );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.objects[ applicationPathString ] = new Array();
|
||||
|
||||
return this.addClientObjectByPathID( clientObject, id, applicationPathString, userID );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getClientObjects( applicationPathString, id ) {
|
||||
|
||||
var arrayWithObjects = this.objects[ applicationPathString ];
|
||||
|
||||
if( arrayWithObjects ) {
|
||||
|
||||
var arrayWithObjectByID = arrayWithObjects[ id ];
|
||||
|
||||
if( arrayWithObjectByID ) {
|
||||
|
||||
return arrayWithObjectByID;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
addClientObject( clientObject, userID ) {
|
||||
|
||||
var object = clientObject.object;
|
||||
|
||||
unify.extend(object);
|
||||
|
||||
if(object.getApplicationPathString) {
|
||||
|
||||
var applicationPathString = object.getApplicationPathString();
|
||||
var id = object.id;
|
||||
|
||||
if( !id ) {
|
||||
|
||||
id = 0;
|
||||
|
||||
}
|
||||
|
||||
var userID = userID;
|
||||
|
||||
if( object.bidirectional ) {
|
||||
|
||||
this.addClientObjectByPathID( clientObject, id, applicationPathString, userID );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
101
framework/server/objectManager.js
Normal file
101
framework/server/objectManager.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import unify from '../unify/unify.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import Console from './console.js';
|
||||
|
||||
import cacheManager from "./objectCacheManager.js";
|
||||
|
||||
|
||||
export default class objectManager{
|
||||
|
||||
clientObjects = new Array(); // clientObjects[ className ] [ id ] --> [ clientObjects ]
|
||||
|
||||
cacheManager = new cacheManager();
|
||||
|
||||
registerObject( object, socketClient ) {
|
||||
|
||||
this.registerChildren( object, socketClient );
|
||||
|
||||
}
|
||||
|
||||
removeObjectsByClientID( userID ) {
|
||||
|
||||
this.cacheManager.removeObjectsByClientID( userID );
|
||||
|
||||
// todo : delete object when client disconnects
|
||||
|
||||
}
|
||||
|
||||
registerChildren( object, socketClient ) {
|
||||
|
||||
var clientObject = new Object();
|
||||
|
||||
clientObject.socketClient = socketClient;
|
||||
|
||||
clientObject.object = object;
|
||||
|
||||
this.cacheManager.addClientObject( clientObject, socketClient.userID );
|
||||
|
||||
if( object.getChildren ) {
|
||||
|
||||
var children = object.getChildren();
|
||||
|
||||
for( var c = 0; c< children.length;c++ ) {
|
||||
|
||||
var child = children[c];
|
||||
|
||||
this.registerChildren( child, socketClient );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateClient( object, clientA, eventName ) {
|
||||
|
||||
var clientObjects = this.cacheManager.getClientObjects( object.getApplicationPathString(), object.id );
|
||||
|
||||
if( clientObjects ) {
|
||||
|
||||
for( var c = 0; c < clientObjects.length; c++ ) {
|
||||
|
||||
var clientObject = clientObjects[c];
|
||||
|
||||
if( clientObject ) {
|
||||
|
||||
var clientB = clientObject.socketClient;
|
||||
|
||||
if( clientB.userID != clientA.userID || object.getClassName() == "collection" ) {
|
||||
|
||||
clientB.updateMessage( 10, object, eventName ); //registeredObject.object
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
294
framework/server/objectParser.js
Normal file
294
framework/server/objectParser.js
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
export default class objectParser{
|
||||
|
||||
parseAsyncMethod( parts, nodeMethods ) {
|
||||
|
||||
delete parts[0];
|
||||
|
||||
var methodDefinitionParts = parts[2].split("(");
|
||||
|
||||
if( methodDefinitionParts.length > 0 ) {
|
||||
|
||||
delete parts[0];
|
||||
|
||||
parts = parts.filter(n => n)
|
||||
|
||||
nodeMethods.push( methodDefinitionParts[0] );
|
||||
|
||||
parts[1] = methodDefinitionParts.join("(")
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parseMethod( parts, nodeMethods ) {
|
||||
|
||||
var methodDefinitionParts = parts[1].split("(");
|
||||
|
||||
if( parts.includes("=") ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if( methodDefinitionParts.length > 0 ) {
|
||||
|
||||
delete parts[0];
|
||||
|
||||
nodeMethods.push( methodDefinitionParts[0] );
|
||||
|
||||
parts[1] = methodDefinitionParts.join("(");
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parseNodeMethodLine( parts, nodeMethods, term ) {
|
||||
|
||||
if( parts[0] == term ) {
|
||||
|
||||
if( parts[1] == "async" ) {
|
||||
|
||||
return this.parseAsyncMethod( parts, nodeMethods );
|
||||
|
||||
} else {
|
||||
|
||||
return this.parseMethod( parts, nodeMethods );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
recomposeLine( isNodeMethod, lines, i, parts ) {
|
||||
|
||||
if( isNodeMethod ) {
|
||||
|
||||
lines[i] = parts.join(" ");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parseLine( lines, i, nodeMethods, term ) {
|
||||
|
||||
var stripped = lines[i].replaceAll("\t", " ");
|
||||
|
||||
var parts = stripped.split(" ");
|
||||
|
||||
parts = parts.filter( n => n );
|
||||
|
||||
|
||||
var isNodeMethod = this.parseNodeMethodLine( parts, nodeMethods, term );
|
||||
|
||||
this.recomposeLine( isNodeMethod, lines, i, parts );
|
||||
|
||||
}
|
||||
|
||||
getLines( source ) {
|
||||
|
||||
source = source.replaceAll("\r", "\n");
|
||||
|
||||
var lines = source.split("\n");
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
createOutput( lines, nodeMethods, term ) {
|
||||
|
||||
var body = "\n\n";
|
||||
|
||||
body += lines.join("\n");
|
||||
|
||||
|
||||
var output = new Object();
|
||||
|
||||
output.source = body;
|
||||
|
||||
output.nodeMethods = nodeMethods;
|
||||
|
||||
output.term = term;
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
parseNodeMethods( source, term ) {
|
||||
|
||||
var lines = this.getLines( source );
|
||||
|
||||
var nodeMethods = new Array();
|
||||
|
||||
for ( var i = 0; i < lines.length; i++ ) {
|
||||
|
||||
this.parseLine( lines, i, nodeMethods, term );
|
||||
|
||||
}
|
||||
|
||||
var output = this.createOutput( lines, nodeMethods, term );
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
|
||||
getClassIndices( source ) {
|
||||
|
||||
var regex = /\bclass /gi
|
||||
|
||||
var result;
|
||||
|
||||
var indices = new Array();
|
||||
|
||||
while ( ( result = regex.exec( source ) ) ) {
|
||||
|
||||
indices.push( result.index );
|
||||
|
||||
}
|
||||
|
||||
return indices;
|
||||
|
||||
}
|
||||
|
||||
defineClassName( classname ) {
|
||||
|
||||
return "\n\n\t__className\t\t\t= \""+ classname +"\"; ";
|
||||
|
||||
}
|
||||
|
||||
defineSourcePath( path ) {
|
||||
|
||||
return "\n\n\t__sourcePath\t\t\t= \""+ tools.slash( path ) +"\"; ";
|
||||
|
||||
}
|
||||
|
||||
defineMethods( output ) {
|
||||
|
||||
return "\n\n\t" + "__" + output.term + "Methods\t\t\t= \""+ output.nodeMethods.join() +"\"; ";
|
||||
|
||||
}
|
||||
|
||||
defineCustomProperties( classname, path, customPrefixes ) {
|
||||
|
||||
var classNameDefinition = this.defineClassName( classname );
|
||||
|
||||
var pathDefinition = this.defineSourcePath( path );
|
||||
|
||||
|
||||
var prefixArrayString = "";
|
||||
|
||||
for ( var i = 0; i < customPrefixes.length; i++ ) {
|
||||
|
||||
var customPrefix = customPrefixes[i];
|
||||
|
||||
prefixArrayString += this.defineMethods( customPrefix ) + "\n";
|
||||
|
||||
}
|
||||
|
||||
//var nodeMethodDefinition = this.defineMethods( "__nodeMethods", nodeMethods );
|
||||
|
||||
//var stateMethodDefinition = this.defineMethods( "__stateMethods", stateMethods );
|
||||
|
||||
return classNameDefinition + pathDefinition + prefixArrayString;
|
||||
}
|
||||
|
||||
composeLine( source, path, customPrefixes, afterClassIndex ) {
|
||||
|
||||
var afterClassString = source.substr( afterClassIndex, source.length );
|
||||
|
||||
var words = afterClassString.split(" ")
|
||||
|
||||
var classname = words[1].split("{")[0];
|
||||
|
||||
var beginBodyIndex = afterClassIndex + afterClassString.indexOf("{") + 1;
|
||||
|
||||
var beginBody = source.substr( 0, beginBodyIndex );
|
||||
|
||||
var endBody = source.substr( beginBodyIndex, source.length );
|
||||
|
||||
|
||||
if( afterClassString.indexOf("{") == -1 ) {
|
||||
|
||||
return source;
|
||||
|
||||
}
|
||||
|
||||
var customDefinitions = this.defineCustomProperties( classname, path, customPrefixes );
|
||||
|
||||
|
||||
return beginBody + customDefinitions + endBody;
|
||||
|
||||
}
|
||||
|
||||
compose( source, path, customMethodPreFixes ) {
|
||||
|
||||
var customPrefixes = new Array();
|
||||
|
||||
for (var i = 0; i < customMethodPreFixes.length; i++) {
|
||||
|
||||
var methodPrefix = customMethodPreFixes[i];
|
||||
|
||||
var nodeMethods = this.parseNodeMethods( source, methodPrefix );
|
||||
|
||||
source = nodeMethods.source;
|
||||
|
||||
customPrefixes.push( nodeMethods );
|
||||
|
||||
}
|
||||
/*
|
||||
var nodeMethods = this.parseNodeMethods( source, "node" );
|
||||
|
||||
source = nodeMethods.source;
|
||||
|
||||
var stateMethods = this.parseNodeMethods( source, "state" );
|
||||
|
||||
source = stateMethods.source;
|
||||
*/
|
||||
|
||||
var classIndices = this.getClassIndices( source );
|
||||
|
||||
|
||||
for ( var i = classIndices.length - 1; i >= 0; i-- ) {
|
||||
|
||||
var afterClassIndex = classIndices[ i ];
|
||||
|
||||
source = this.composeLine( source, path, customPrefixes, afterClassIndex );
|
||||
|
||||
}
|
||||
|
||||
return source;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
201
framework/server/renderCollection.js
Normal file
201
framework/server/renderCollection.js
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import Console from '../server/console.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import unify from '../unify/unify.js';
|
||||
|
||||
import querySQL from '../unify/querySQL.js';
|
||||
|
||||
import coll from '../unify/collection.js';
|
||||
|
||||
import clientRenderCollection from '../client/renderCollection.js';
|
||||
|
||||
import shared from '../unify/shared.js';
|
||||
|
||||
|
||||
export default class renderCollection extends clientRenderCollection{
|
||||
|
||||
__className = "renderCollection";
|
||||
|
||||
updatedCache = false;
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
}
|
||||
|
||||
deleteRows() {
|
||||
|
||||
/*
|
||||
var rows = this.rows;
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
|
||||
var row = rows[i];
|
||||
|
||||
console.log("delete row", row.propertyName);
|
||||
|
||||
delete this[ row.propertyName ];
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
getStoredRows( customQuery ) {
|
||||
|
||||
var customQuery = this.createQuery();
|
||||
|
||||
customQuery.debug = this.debug;
|
||||
|
||||
var storedRows = this.storageCollection.querySelect( customQuery );
|
||||
|
||||
return storedRows;
|
||||
|
||||
}
|
||||
|
||||
addCurrentRow( row, client, c ) {
|
||||
|
||||
//var object = collection.createInstance();
|
||||
|
||||
var parsedObject = this.addRow( row, client );
|
||||
|
||||
parsedObject.rowID = c;
|
||||
|
||||
this.rows.push( parsedObject );
|
||||
|
||||
}
|
||||
|
||||
addRows( rows, client, collection ) {
|
||||
|
||||
for( var c = 0; c < rows.length; c++ ) {
|
||||
|
||||
var row = rows[ c ];
|
||||
|
||||
this.addCurrentRow( row, client, c );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getFromCollection( collection, client ) {
|
||||
|
||||
//console.log("get parent that is table", collection);
|
||||
|
||||
if( collection.parent ) {
|
||||
|
||||
collection.id = collection.parent.id;
|
||||
|
||||
} else {
|
||||
|
||||
collection.id = this.id;
|
||||
|
||||
}
|
||||
|
||||
var customQuery = this.createQuery();
|
||||
|
||||
customQuery.debug = this.debug;
|
||||
|
||||
//console.log("this is renderCollection get from collection", this.getClassName(), this.getApplicationPath() );
|
||||
|
||||
// returns array directly from better-sqlite3
|
||||
var rows = collection.querySelect( customQuery, this.filterObject, client );
|
||||
|
||||
//if( this.storageCollection.enabled ) {
|
||||
|
||||
// var storedRows = this.getStoredRows( customQuery );
|
||||
|
||||
//}
|
||||
|
||||
this.addRows( rows, client, collection );
|
||||
|
||||
collection.rows = this.rows;
|
||||
|
||||
}
|
||||
|
||||
get( client ) {
|
||||
|
||||
//this.deleteRows();
|
||||
|
||||
this.rows = new Array();
|
||||
|
||||
var collection = this.getCollection();
|
||||
|
||||
if( collection ) {
|
||||
|
||||
this.getFromCollection( collection, client );
|
||||
|
||||
} else {
|
||||
|
||||
console.log("This renderCollection has no collection.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createQuery() {
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
var filter = this.filterObject;
|
||||
|
||||
unify.extend( filter );
|
||||
|
||||
return query;
|
||||
|
||||
}
|
||||
|
||||
createQueryChildCollection( child, query ) {
|
||||
|
||||
var collectionChildren = child.getChildren(); // this are the object properties of collection.object...
|
||||
|
||||
for( var b = 0; b< collectionChildren.length; b++ ) {
|
||||
|
||||
var collectionChild = collectionChildren[b];
|
||||
|
||||
if( collectionChild.like ) {
|
||||
|
||||
query.find( collectionChild.propertyName, collectionChild.like, "LIKE" );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
findRow( storedRows, id ) {
|
||||
|
||||
for( var c = 0 ;c < storedRows.length; c++ ) {
|
||||
|
||||
var storedRow = storedRows[c];
|
||||
|
||||
if( storedRow.id == id ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1011
framework/server/scripts/cacheManager.js
Executable file
1011
framework/server/scripts/cacheManager.js
Executable file
File diff suppressed because it is too large
Load Diff
560
framework/server/serverManager.js
Normal file
560
framework/server/serverManager.js
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
//import compression from 'compression';
|
||||
|
||||
//import express from 'express';
|
||||
|
||||
//import nocache from 'nocache';
|
||||
|
||||
//import cors from "cors";
|
||||
|
||||
//import bodyParser from 'body-parser';
|
||||
|
||||
//import { RateLimiterMemory } from 'rate-limiter-flexible';
|
||||
|
||||
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import https from 'https';
|
||||
|
||||
import http from 'http';
|
||||
|
||||
import fs from "fs";
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import Console from './console.js';
|
||||
|
||||
import database from './database.js';
|
||||
|
||||
import querySQL from '../unify/querySQL.js';
|
||||
|
||||
import mimeLookup from "../../assets/json/mimeTypes.json" assert { type: "json" };
|
||||
|
||||
|
||||
|
||||
export default class serverManager{
|
||||
|
||||
__className = "serverManager";
|
||||
|
||||
mode;
|
||||
|
||||
port = 8070;
|
||||
|
||||
ssl = false;
|
||||
|
||||
httpsServer = false;
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
//this.initializeRateLimiter();
|
||||
|
||||
}
|
||||
|
||||
createExpressApp() {
|
||||
|
||||
//this.app = express();
|
||||
|
||||
}
|
||||
|
||||
createHttpsServer( ) {
|
||||
|
||||
if( this.ssl ) {
|
||||
|
||||
var privateKey = fs.readFileSync('./sslCertificates/privkey.pem', 'utf8');
|
||||
|
||||
var certificate = fs.readFileSync('./sslCertificates/fullchain.pem', 'utf8');
|
||||
|
||||
this.httpsServer = https.createServer({ key: privateKey, cert: certificate }, this.app );
|
||||
|
||||
} else {
|
||||
|
||||
this.httpsServer = http.createServer( this.app );
|
||||
|
||||
}
|
||||
|
||||
return this.httpsServer;
|
||||
|
||||
}
|
||||
|
||||
createListener( ) {
|
||||
|
||||
if( this.ssl ) {
|
||||
|
||||
if( !this.port ) {
|
||||
|
||||
this.port = 443;
|
||||
|
||||
}
|
||||
|
||||
this.httpsServer.listen( this.port );
|
||||
|
||||
console.log("\nHttps WebServer started on port: ", this.port);
|
||||
|
||||
} else {
|
||||
|
||||
this.httpsServer.listen( this.port );
|
||||
|
||||
console.log("\nHttps WebServer started on port: ", 443);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
initializeRateLimiter() {
|
||||
|
||||
this.rateLimiter = new RateLimiterMemory({
|
||||
|
||||
points: 1000,
|
||||
duration: 1,
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
restrictDirectories( app ) {
|
||||
|
||||
app.all('/sslCertificates/*', function (req,res, next) {
|
||||
|
||||
res.status(403).send({
|
||||
|
||||
message: 'Access Forbidden'
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
app.all('/storage/*', function (req,res, next) {
|
||||
|
||||
res.status(403).send({
|
||||
|
||||
message: 'Access Forbidden'
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
exposeDirectories( app ) {
|
||||
|
||||
app.use( express.static( path.resolve("") ) );
|
||||
|
||||
|
||||
if( global.mode == "production" ) {
|
||||
|
||||
app.use( express.static( path.resolve( 'assets/production/') ) );
|
||||
|
||||
} else {
|
||||
|
||||
app.use( express.static( path.resolve( 'assets/development/') ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
app.use( express.static( path.resolve('application/') ) );
|
||||
|
||||
app.use( express.static( path.resolve('admin/') ) );
|
||||
|
||||
app.use( express.static( path.resolve('framework/') , { maxAge: 99999999999 } ) );
|
||||
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
app.use( "/*.html", function ( req, res ) {
|
||||
|
||||
res.sendFile( path.resolve('assets/development/index.html') );//
|
||||
|
||||
} );
|
||||
|
||||
} else {
|
||||
|
||||
app.use( "/*.html", function ( req, res ) {
|
||||
|
||||
res.sendFile( path.resolve( 'assets/production/index.html') );
|
||||
|
||||
});
|
||||
|
||||
app.use( "/*.json", function ( req, res ) {
|
||||
|
||||
res.sendFile( path.resolve( 'assets/production/index.json') );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async rateLimiterCallback( req, res, next ) {
|
||||
|
||||
var rate = await this.rateLimiter.consume( this.userID, 2 )
|
||||
.then( () => {
|
||||
|
||||
return true;
|
||||
|
||||
})
|
||||
.catch( () => {
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
|
||||
if( !rate ) {
|
||||
|
||||
res.writeHead( 429 );
|
||||
|
||||
res.end();
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if( next ) {
|
||||
|
||||
next();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
usePlugins( app ) {
|
||||
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
app.use( nocache() );
|
||||
|
||||
}
|
||||
|
||||
app.use( cors() );
|
||||
|
||||
app.use( bodyParser.json() );
|
||||
|
||||
app.use( compression() );
|
||||
|
||||
app.use( async ( req, res, next ) => {
|
||||
|
||||
this.rateLimiterCallback( req, res, next );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getExtension(filename) {
|
||||
|
||||
var ext = path.extname( filename || '' ).split('.');
|
||||
|
||||
return "." + ext[ext.length - 1];
|
||||
|
||||
}
|
||||
|
||||
setupServer() {
|
||||
|
||||
//var app = this.app;
|
||||
|
||||
|
||||
//this.usePlugins( app );
|
||||
|
||||
//this.restrictDirectories( app );
|
||||
|
||||
//this.exposeDirectories( app );
|
||||
|
||||
|
||||
//https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||
/*
|
||||
const mimeLookup = {
|
||||
|
||||
'.js': 'application/javascript',
|
||||
|
||||
'.html': 'text/html',
|
||||
|
||||
'.css':'text/css',
|
||||
|
||||
'.woff':'font/woff',
|
||||
|
||||
'.woff2':'font/woff2',
|
||||
|
||||
'.ttf':'font/ttf',
|
||||
|
||||
'.png':'png'
|
||||
};
|
||||
*/
|
||||
|
||||
function send404(response){
|
||||
|
||||
response.writeHead(404, {'Content-Type': 'text/plain'});
|
||||
|
||||
response.write('Error 404: Resource not found.');
|
||||
|
||||
response.end();
|
||||
|
||||
}
|
||||
|
||||
var that = this;
|
||||
|
||||
/*
|
||||
|
||||
http.createServer( function( req, res ) {
|
||||
|
||||
if( req.method == 'GET' ) {
|
||||
|
||||
let fileurl;
|
||||
|
||||
var cleanUrl = req.url.split("?")[0];
|
||||
|
||||
var fileExt = that.getExtension( cleanUrl );
|
||||
|
||||
var mimeType = mimeLookup[ fileExt ];
|
||||
|
||||
//console.log("req.url", req.url);
|
||||
|
||||
//console.log("fileExt", fileExt);
|
||||
|
||||
|
||||
|
||||
if( mimeType == 'text/html' || fileExt == '.' ) {
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
fileurl = '/assets/development/index.html';
|
||||
|
||||
} else {
|
||||
|
||||
fileurl = '/assets/production/index.html';
|
||||
|
||||
}
|
||||
|
||||
mimeType = "text/html";
|
||||
|
||||
} else {
|
||||
|
||||
if( !mimeType ) {
|
||||
|
||||
send404(res);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
fileurl = cleanUrl;
|
||||
|
||||
}
|
||||
|
||||
var filepath = path.resolve('./' + fileurl);
|
||||
|
||||
fs.exists( filepath, ( exists ) => {
|
||||
|
||||
if( !exists ) {
|
||||
|
||||
send404(res);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
res.writeHead( 200, {'Content-Type': mimeType } );
|
||||
|
||||
fs.createReadStream( filepath ).pipe( res );
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}).listen( 3000 );
|
||||
*/
|
||||
|
||||
var reject = new Array();
|
||||
|
||||
|
||||
reject.push( "/framework/cache/platforms/Original/" );
|
||||
|
||||
reject.push( "/framework/cache/platforms/Server/" );
|
||||
|
||||
reject.push( "/framework/cache/server/" );
|
||||
|
||||
reject.push( "/storage/" );
|
||||
|
||||
reject.push( "/application/" );
|
||||
|
||||
reject.push( "package.json" );
|
||||
|
||||
var server = this;
|
||||
|
||||
|
||||
this.app = function( req, res ) {
|
||||
|
||||
//res.setHeader("Content-Security-Policy", "default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests");
|
||||
|
||||
//res.setHeader("Content-Security-Policy", "default-src 'self' ws: wss: " + server.serverAddress + " *." + server.serverAddress + "style-src 'self' 'unsafe-inline';" );
|
||||
|
||||
if( req.method == 'GET' ) {
|
||||
|
||||
let fileurl;
|
||||
|
||||
var cleanUrl = req.url.split("?")[0];
|
||||
|
||||
var fileExt = that.getExtension( cleanUrl );
|
||||
|
||||
var mimeType = mimeLookup[ fileExt ];
|
||||
|
||||
|
||||
if( mimeType == 'text/html' || fileExt == '.' || fileExt == '.html' || fileExt == '.htm' ) {
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
fileurl = '/assets/development/index.html';
|
||||
|
||||
} else {
|
||||
|
||||
fileurl = '/assets/production/index.html';
|
||||
|
||||
}
|
||||
|
||||
mimeType = "text/html";
|
||||
|
||||
} else {
|
||||
|
||||
//if( !mimeType ) {
|
||||
|
||||
// send404(res);
|
||||
|
||||
// return;
|
||||
|
||||
//}
|
||||
|
||||
fileurl = cleanUrl;
|
||||
|
||||
}
|
||||
|
||||
//console.log(fileurl);
|
||||
|
||||
for (var i = 0; i < reject.length; i++) {
|
||||
|
||||
var rejectURl = reject[i];
|
||||
|
||||
|
||||
if( fileurl.includes( rejectURl ) ) {
|
||||
|
||||
console.log("Access forbidden, reject url.");
|
||||
|
||||
send404( res );
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var filepath = path.resolve('./' + fileurl);
|
||||
|
||||
fs.exists( filepath, ( exists ) => {
|
||||
|
||||
if( !exists ) {
|
||||
|
||||
send404(res);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//console.log(fileurl, mimeType);
|
||||
|
||||
res.writeHead( 200, {'Content-Type': mimeType } );
|
||||
|
||||
fs.createReadStream( filepath ).pipe( res );
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//.listen( 3000 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
secureStatic( secure ) {
|
||||
|
||||
return function ( req, res, next ) {
|
||||
|
||||
var result = req.url.match(/^\/framework\/db\/.+$/);
|
||||
|
||||
if ( result ) {
|
||||
|
||||
return res.status(403).end('403 Forbidden')
|
||||
|
||||
} else {
|
||||
|
||||
next();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
runAPIServer() {
|
||||
|
||||
/*
|
||||
var app = this.app;
|
||||
|
||||
var that = this;
|
||||
|
||||
|
||||
app.use( "/api/", function ( req, res ) {
|
||||
|
||||
const body = JSON.stringify( req.body );
|
||||
|
||||
class ajaxSocket{
|
||||
|
||||
send( content ) {
|
||||
|
||||
|
||||
res.json( content );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( req.body.eventName == "connect" ) {
|
||||
|
||||
that.socketManager.connection( new ajaxSocket() );
|
||||
|
||||
} else {
|
||||
|
||||
var object = JSON.parse( body );
|
||||
|
||||
var clients = that.socketManager.sessionClients;
|
||||
|
||||
var client = clients[object.sessionKey];
|
||||
|
||||
client.socket.send = function( content ) {
|
||||
|
||||
res.json( content );
|
||||
|
||||
}
|
||||
|
||||
client.message( body );
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
1064
framework/server/socketClient.js
Normal file
1064
framework/server/socketClient.js
Normal file
File diff suppressed because it is too large
Load Diff
1118
framework/server/socketManagerServer.js
Normal file
1118
framework/server/socketManagerServer.js
Normal file
File diff suppressed because it is too large
Load Diff
20
framework/server/sqlReplacement.js
Normal file
20
framework/server/sqlReplacement.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
export default class replacement{
|
||||
|
||||
|
||||
}
|
||||
85
framework/server/sqlite.js
Normal file
85
framework/server/sqlite.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import sqlite3 from '../node_modules/better-sqlite3/lib/index.js';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
|
||||
export default class sqlite{
|
||||
|
||||
|
||||
file = path.resolve( './storage/index.sqlite' );
|
||||
|
||||
db;
|
||||
|
||||
queryID = 0;
|
||||
|
||||
type = "file";
|
||||
|
||||
constructor() {
|
||||
|
||||
//this.setup();
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
if( global.sqlite == undefined ) {
|
||||
|
||||
if( this.type == "file") {
|
||||
|
||||
if( process.platform == "android" ) {
|
||||
|
||||
this.db = sqlite3( __dirname + "/storage/index.sqlite" );
|
||||
|
||||
} else {
|
||||
|
||||
this.db = sqlite3( this.file );
|
||||
|
||||
}
|
||||
|
||||
//console.log("Loading database: ", this.file);
|
||||
|
||||
} else {
|
||||
|
||||
this.db = sqlite3( ":memory:" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
this.db = global.sqlite;
|
||||
|
||||
}
|
||||
|
||||
this.db.pragma('journal_mode = WAL');
|
||||
|
||||
}
|
||||
|
||||
onConnect( err ) {
|
||||
|
||||
if ( err ) {
|
||||
|
||||
console.error("Database error:", err.message);
|
||||
|
||||
}
|
||||
|
||||
console.log('Connected to the database.');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
319
framework/server/table.js
Normal file
319
framework/server/table.js
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import clientTable from '../client/table.js';
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import document from '../unify/document.js';
|
||||
|
||||
import querySQL from '../unify/querySQL.js';
|
||||
|
||||
import Console from './console.js';
|
||||
|
||||
import collection from '../unify/collection.js';
|
||||
|
||||
import permissionManager from '../unify/permissionManager.js';
|
||||
|
||||
import userManager from '../server/userManager.js';
|
||||
|
||||
|
||||
|
||||
export default class table extends clientTable{
|
||||
|
||||
__className = "table";
|
||||
|
||||
permissionManager = new permissionManager();
|
||||
|
||||
type = "table";
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
Console.setFilename("table.js");
|
||||
|
||||
}
|
||||
|
||||
setCollectionObject( collectionObject ) {
|
||||
|
||||
var newCollection = new collection( collectionObject );
|
||||
|
||||
this.setCollection( newCollection );
|
||||
|
||||
}
|
||||
|
||||
setCollection( collection ) {
|
||||
|
||||
if( collection ) {
|
||||
|
||||
this.collections = [ collection ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parseObject( object, propertyName) {
|
||||
|
||||
if( tools.objectIsRenderCollection( object ) )
|
||||
{
|
||||
|
||||
// hasMany collection render join
|
||||
this.parseRenderCollection( object );
|
||||
|
||||
} else if( tools.objectIsTable( object ) ) {
|
||||
|
||||
// hasOne
|
||||
if( propertyName != "table" ) {
|
||||
|
||||
this.joinObject( object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getProperties( parent, child ) {
|
||||
|
||||
var entries = Object.entries( parent );
|
||||
|
||||
for( var c = 0; c < entries.length; c++ ) {
|
||||
|
||||
var entry = entries[ c ];
|
||||
|
||||
var object = tools.getObjectByEntry( entry );
|
||||
|
||||
var propertyName = tools.getClassNameByEntry( entry );
|
||||
|
||||
this.parseObject( object, propertyName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
joinObject( object ) {
|
||||
|
||||
var tableName = tools.getClassName( object );
|
||||
|
||||
var parentName = tools.getClassName( tools.getTableFromObject( object.parent ) );
|
||||
|
||||
var columnName = object.propertyName;
|
||||
|
||||
// ?? doesn't do anything.
|
||||
|
||||
//Console.log( "Select * From " + tableName + " where " + parentName + "." + columnName +"_id = " + tableName + ".id" );
|
||||
|
||||
}
|
||||
|
||||
parseRenderCollection( renderCollection ) {
|
||||
|
||||
var collections = renderCollection.collections;
|
||||
|
||||
for(var b = 0; b < collections.length;b++) {
|
||||
|
||||
var currentCollection = collections[b];
|
||||
|
||||
var join = currentCollection.createJoin( renderCollection.propertyName );
|
||||
|
||||
}
|
||||
|
||||
var renderCollectionObject = renderCollection.getObject();
|
||||
|
||||
this.getProperties( renderCollectionObject, renderCollection );
|
||||
|
||||
}
|
||||
|
||||
|
||||
getRow() {
|
||||
|
||||
this.getProperties( this.constructor );
|
||||
|
||||
//console.log("get table from this object", this);
|
||||
|
||||
var table = tools.getTableFromObject( this );
|
||||
|
||||
|
||||
|
||||
var tableName = tools.getClassName( table );
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "select";
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
query.find( "id", this.id );
|
||||
|
||||
var output = global.database.query( query );
|
||||
|
||||
if( output[0] ) {
|
||||
|
||||
return output[0];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// For server side, When being instantiated
|
||||
create() {
|
||||
|
||||
if( typeof document == "undefined" ) {
|
||||
|
||||
this.createInstance();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createInstance( inherit_id = true ) {
|
||||
|
||||
this.signed.value = true;
|
||||
|
||||
var new_inser_id = global.database.insertRow( this );
|
||||
|
||||
if( inherit_id ) {
|
||||
|
||||
this.id = new_inser_id;
|
||||
|
||||
}
|
||||
|
||||
return new_inser_id;
|
||||
|
||||
}
|
||||
|
||||
updateChildrenPermissions( object, user ) {
|
||||
|
||||
if( object.permission ) {
|
||||
|
||||
object.permissions = userManager.computePermissions( object, user );
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( object.getChildren ) {
|
||||
|
||||
var children = object.getChildren();
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
|
||||
var child = children[i]
|
||||
|
||||
this.updateChildrenPermissions( child, user );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get( client ) {
|
||||
|
||||
var sqlRow = this.getRow();
|
||||
|
||||
if( sqlRow ) {
|
||||
|
||||
//console.log("get", this.getClassName(), sqlRow);
|
||||
|
||||
this.serialize( sqlRow );
|
||||
|
||||
this.updated = true;
|
||||
|
||||
}
|
||||
|
||||
if( client ) {
|
||||
|
||||
//this.computePermissions( client );
|
||||
|
||||
var user = client.user;
|
||||
|
||||
this.updateChildrenPermissions( this, user );
|
||||
|
||||
//this.permissions = userManager.computePermissions( this, user );
|
||||
|
||||
//this.computePermissions( this, user );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete() {
|
||||
|
||||
var table = this.table;
|
||||
|
||||
var tableName = table.getClassName();
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "delete";
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
query.find( "id", this.id );
|
||||
|
||||
var output = global.database.query( query );
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
save() {
|
||||
|
||||
if( !this.table ) {
|
||||
|
||||
this.getCore().tableManager.parse( this )
|
||||
|
||||
}
|
||||
|
||||
var table = this.table;
|
||||
|
||||
var tableName = table.getClassName();
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "update";
|
||||
|
||||
query.table = tableName;
|
||||
|
||||
query.debug = this.debug;
|
||||
|
||||
query.addObject( this );
|
||||
|
||||
var query = global.database.query( query );
|
||||
|
||||
}
|
||||
|
||||
find( column, value ) {
|
||||
|
||||
var tableName = tools.getTableName( this );
|
||||
|
||||
var query = new querySQL();
|
||||
|
||||
query.type = "select";
|
||||
query.table = tableName;
|
||||
|
||||
query.find( column, value );
|
||||
|
||||
return global.database.query( query );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
109
framework/server/tableLogger.js
Normal file
109
framework/server/tableLogger.js
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
export default class tableLogger{
|
||||
|
||||
rows = new Array();
|
||||
|
||||
tableName = false;
|
||||
|
||||
maxChars = new Array(0,0,0,0,0,0);
|
||||
|
||||
padding = 4;
|
||||
|
||||
setTable( tableName, maxChars ) {
|
||||
|
||||
this.maxChars = maxChars;
|
||||
|
||||
this.tableName = tableName;
|
||||
|
||||
}
|
||||
|
||||
addColumn( a, b, c, d ) {
|
||||
|
||||
var row = new Array();
|
||||
|
||||
if( a ) {
|
||||
|
||||
row.push( a );
|
||||
|
||||
this.maxChars[0] = Math.max( this.maxChars[0], a.length );
|
||||
|
||||
|
||||
|
||||
if( b ) {
|
||||
|
||||
row.push( b );
|
||||
|
||||
this.maxChars[1] = Math.max( this.maxChars[1], b.length );
|
||||
|
||||
}
|
||||
|
||||
if( c ) {
|
||||
|
||||
row.push( c );
|
||||
|
||||
this.maxChars[2] = Math.max( this.maxChars[2], c.length );
|
||||
|
||||
}
|
||||
|
||||
if( d ) {
|
||||
|
||||
row.push( d );
|
||||
|
||||
this.maxChars[3] = Math.max( this.maxChars[3], d.length );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.rows.push( row );
|
||||
|
||||
}
|
||||
|
||||
log() {
|
||||
|
||||
if( global.clusterID == 1 ) {
|
||||
|
||||
//Console.log("\n__________________________________________ \n");
|
||||
|
||||
console.log( "\nTable name:", this.tableName, "\n" );
|
||||
|
||||
for (var i = 0; i < this.rows.length; i++) {
|
||||
|
||||
var row = this.rows[i];
|
||||
|
||||
if( row[0] ) {
|
||||
|
||||
console.log( " ", row[0].padEnd( this.maxChars[0] + this.padding ), row[1] );
|
||||
|
||||
} else if( row[0] ) {
|
||||
|
||||
//console.log( "row[0]:", row[0] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log("\n");
|
||||
|
||||
this.rows = new Array();
|
||||
//this.maxChars = new Array(0,0,0,0,0,0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
294
framework/server/tableManager.js
Normal file
294
framework/server/tableManager.js
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import Console from './console.js';
|
||||
|
||||
import database from './database.js';
|
||||
|
||||
import datatype from '../unify/datatype.js';
|
||||
|
||||
import collection from '../unify/collection.js';
|
||||
|
||||
import querySQL from '../unify/querySQL.js';
|
||||
|
||||
import tableLogger from './tableLogger.js';
|
||||
|
||||
|
||||
export default class databaseManager{
|
||||
|
||||
tables = new Array();
|
||||
|
||||
parse( object ) {
|
||||
|
||||
if( object.type == "table" ) {
|
||||
|
||||
if( !object.table ) {
|
||||
|
||||
var objectName = object.getClassName();
|
||||
|
||||
var tableObject = tools.getTableFromObject( object );
|
||||
|
||||
|
||||
object.table = tableObject;
|
||||
|
||||
} else {
|
||||
|
||||
var tableObject = object.table;
|
||||
|
||||
}
|
||||
|
||||
this.addTable( tableObject )
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addTable( tableObject ) {
|
||||
|
||||
var className = tools.getClassName( tableObject );
|
||||
|
||||
if ( !this.getTableByName( className ) ) {
|
||||
|
||||
this.tables.push( tableObject );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
getTableByName( name ){
|
||||
|
||||
for( var c = 0; c<this.tables.length; c++ ) {
|
||||
|
||||
var table = this.tables[c];
|
||||
|
||||
if( tools.getClassName( table ) == name ) {
|
||||
|
||||
return table;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
ensureTableColumsTable() {
|
||||
|
||||
var tableExists = database.tableExists("tableColumns")
|
||||
|
||||
|
||||
if( !tableExists ) {
|
||||
|
||||
console.log("New database detected, Creating tableColumns table and columns.");
|
||||
|
||||
this.setup();
|
||||
|
||||
}
|
||||
|
||||
//database
|
||||
//setup
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
createTables() {
|
||||
|
||||
this.ensureTableColumsTable();
|
||||
|
||||
var tables = this.tables;
|
||||
|
||||
for( var c = 0; c < tables.length; c++ ) {
|
||||
|
||||
var table = tables[c];
|
||||
|
||||
this.createTable( table );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getObjectByclassName( className ) {
|
||||
|
||||
var objectCollection = new collection();
|
||||
|
||||
objectCollection.set( this.tables );
|
||||
|
||||
objectCollection.filter( "class", className );
|
||||
|
||||
|
||||
return objectCollection.getFirstRow();
|
||||
|
||||
}
|
||||
|
||||
logTable( tableName, children ) {
|
||||
|
||||
var tableLog = new tableLogger();
|
||||
|
||||
tableLog.setTable( tableName, [18, 18] );
|
||||
|
||||
for ( var c = 0; c < children.length; c++ ) {
|
||||
|
||||
var child = children[c];
|
||||
|
||||
var column = this.parseColumn( child, tableName );
|
||||
|
||||
tableLog.addColumn( column, datatype.TEXT );
|
||||
|
||||
}
|
||||
|
||||
tableLog.log();
|
||||
|
||||
}
|
||||
|
||||
createTable( object ) {
|
||||
|
||||
var tableName = tools.getClassName( object );
|
||||
|
||||
database.createTable( tableName );
|
||||
|
||||
database.cleanTable( tableName );
|
||||
|
||||
database.addColumn( "joined", datatype.TEXT, tableName );
|
||||
|
||||
|
||||
var children = object.getChildren();
|
||||
|
||||
this.logTable( tableName, children );
|
||||
|
||||
}
|
||||
|
||||
parseColumnObject( object, tableName, columnName ) {
|
||||
|
||||
if( tools.objectIsTable( object ) ) {
|
||||
|
||||
// hasOne
|
||||
database.addColumn( columnName + "_id", "INTEGER", tableName );
|
||||
|
||||
} else {
|
||||
|
||||
// regular column
|
||||
database.addColumn( columnName, object.datatype, tableName );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parseColumn( object, tableName ) {
|
||||
|
||||
var objectName = tools.getClassName( object.parent );
|
||||
|
||||
var columnName = object.propertyName;
|
||||
|
||||
if( tools.isUnifyObject( columnName, object ) ) {
|
||||
|
||||
if( tools.getClassName( object ) == "collection" ) {
|
||||
|
||||
// collection join
|
||||
var column = this.createJoinTable( object, object.datatype );
|
||||
|
||||
} else {
|
||||
|
||||
this.parseColumnObject( object, tableName, columnName );
|
||||
|
||||
var column = columnName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return column;
|
||||
|
||||
}
|
||||
|
||||
createJoinTable( object ) {
|
||||
|
||||
object.update();
|
||||
|
||||
var parentTableName = object.getLeft();
|
||||
|
||||
var objectName = object.getRight();
|
||||
|
||||
var propertyName = object.propertyName;
|
||||
|
||||
var tableName = object.parentName + "_" + propertyName;
|
||||
|
||||
|
||||
database.createTable( tableName );
|
||||
|
||||
database.addColumn( "joint", datatype.TEXT, tableName );
|
||||
|
||||
database.addColumn( parentTableName + "_id", "INTEGER", tableName );
|
||||
|
||||
database.addColumn( objectName + "_id", "INTEGER", tableName );
|
||||
|
||||
|
||||
var tableLog = new tableLogger();
|
||||
|
||||
tableLog.setTable( tableName, new Array( 18, 18 ) );
|
||||
|
||||
tableLog.addColumn( parentTableName + "_id", "INTEGER" );
|
||||
|
||||
tableLog.addColumn( objectName + "_id", "INTEGER" );
|
||||
|
||||
tableLog.log();
|
||||
|
||||
}
|
||||
|
||||
|
||||
createColumn( column_name, type, columns_array ) {
|
||||
|
||||
var column = new Object();
|
||||
|
||||
column.name = column_name;
|
||||
|
||||
column.type = type;
|
||||
|
||||
if( columns_array ) {
|
||||
|
||||
columns_array.push( column );
|
||||
|
||||
}
|
||||
|
||||
return column;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
var tableName = "tableColumns";
|
||||
|
||||
database.createTable( tableName );
|
||||
|
||||
|
||||
|
||||
database.addColumnSimple( "tableName", datatype.TEXT, tableName );
|
||||
|
||||
database.addColumnSimple( "columnName", datatype.TEXT, tableName );
|
||||
|
||||
database.addColumnSimple( "datatype", datatype.TEXT, tableName );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
76
framework/server/themeGroups.js
Normal file
76
framework/server/themeGroups.js
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
class themeGroup{
|
||||
|
||||
name;
|
||||
|
||||
items = new Array();
|
||||
|
||||
add( group ) {
|
||||
|
||||
this.items.push( group );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var platforms = new Array("Windows", "Android", "Linux", "Ios", "Macos");
|
||||
|
||||
var devices = new Array("Mobile", "Tablet", "Pc");
|
||||
|
||||
var tints = new Array("Light", "Dark");
|
||||
|
||||
|
||||
var groupsFlat = new Array();
|
||||
|
||||
|
||||
for (var i = 0; i < platforms.length; i++) {
|
||||
|
||||
var os = platforms[i];
|
||||
|
||||
for (var j = 0; j < devices.length; j++) {
|
||||
|
||||
var device = devices[j]
|
||||
|
||||
for (var k = 0; k < tints.length; k++) {
|
||||
|
||||
var tint = tints[k]
|
||||
|
||||
|
||||
var currentGroup = new themeGroup();
|
||||
|
||||
|
||||
currentGroup.level = 3;
|
||||
|
||||
currentGroup.os = os;
|
||||
|
||||
currentGroup.device = device;
|
||||
|
||||
currentGroup.tint = tint;
|
||||
|
||||
|
||||
currentGroup.path = "/" + os + "/" + device + "/" + tint;
|
||||
|
||||
groupsFlat.push( currentGroup );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default groupsFlat;
|
||||
6
framework/server/updater.js
Normal file
6
framework/server/updater.js
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
global.runMode = "updater";
|
||||
|
||||
|
||||
import index from './index.js';
|
||||
397
framework/server/userManager.js
Normal file
397
framework/server/userManager.js
Normal file
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
|
||||
import unify from '../unify/unify.js';
|
||||
|
||||
class visitor{
|
||||
|
||||
value = 2.0;
|
||||
|
||||
label = "Member";
|
||||
|
||||
color = "black";
|
||||
|
||||
type = "userGroup";
|
||||
|
||||
|
||||
}
|
||||
|
||||
class userManager{
|
||||
|
||||
computePermissions( object, user ) {
|
||||
|
||||
var permissions = new Object();
|
||||
|
||||
if( object.isAllowed( user, "WRITE" ) ) {
|
||||
|
||||
permissions.WRITE = true;
|
||||
|
||||
} else {
|
||||
|
||||
permissions.WRITE = false;
|
||||
|
||||
}
|
||||
|
||||
if( object.isAllowed( user, "DELETE" ) ) {
|
||||
|
||||
permissions.DELETE = true;
|
||||
|
||||
} else {
|
||||
|
||||
permissions.DELETE = false;
|
||||
|
||||
}
|
||||
|
||||
if( object.isAllowed( user, "READ" ) ) {
|
||||
|
||||
permissions.READ = true;
|
||||
|
||||
} else {
|
||||
|
||||
permissions.READ = false;
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
getPermissions( user, client ) {
|
||||
|
||||
var root = client.application;
|
||||
|
||||
client.permissionObjects = [];
|
||||
|
||||
this.getPermissionsChildren( user, client, root );
|
||||
|
||||
return client.permissionObjects;
|
||||
|
||||
}
|
||||
|
||||
createToken() {
|
||||
|
||||
var token = "";
|
||||
|
||||
for (var i = 0; i < 40; i++) {
|
||||
|
||||
token += Math.floor(Math.random() * 10);
|
||||
|
||||
}
|
||||
|
||||
return token;
|
||||
|
||||
}
|
||||
|
||||
getPermissionsRenderCollection( object, client, user ) {
|
||||
|
||||
var rows = object.rows;
|
||||
|
||||
for( var b = 0; b < rows.length; b++) {
|
||||
|
||||
var rowObject = rows[b];
|
||||
|
||||
var permission = this.getPermissionFromObject( rowObject, user );
|
||||
|
||||
if( permission ) {
|
||||
|
||||
client.permissionObjects.push( permission );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getPermissionsChildrenObjects( objects, client, user ) {
|
||||
|
||||
for( var c = 0; c < objects.length; c++) {
|
||||
|
||||
var object = objects[c];
|
||||
|
||||
var permission = this.getPermissionFromObject( object, user );
|
||||
|
||||
if( permission ) {
|
||||
|
||||
client.permissionObjects.push( permission );
|
||||
|
||||
}
|
||||
|
||||
if( object.type == "renderCollection" ) {
|
||||
|
||||
this.getPermissionsRenderCollection( object, client, user );
|
||||
|
||||
}
|
||||
|
||||
this.getPermissionsChildren( user, client, object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getPermissionsChildren( user, client, object ) {
|
||||
|
||||
unify.extend( object );
|
||||
|
||||
if( object.getChildren ) {
|
||||
|
||||
var objects = object.getChildren();
|
||||
|
||||
var permissionObjects = new Array();
|
||||
|
||||
this.getPermissionsChildrenObjects( objects, client, user );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getPermissionFromObject( object, user ) {
|
||||
|
||||
var permissionManager = object.permissionManager;
|
||||
|
||||
if( permissionManager && permissionManager.permissions.length > 0 && object.parent ) {
|
||||
|
||||
var objectPermission = {};
|
||||
|
||||
object.updated = true;
|
||||
|
||||
objectPermission.path = object.getApplicationPath().join("/")
|
||||
|
||||
objectPermission.permission = this.computePermissions( object, user );
|
||||
|
||||
return objectPermission;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
createVisitor( client ) {
|
||||
|
||||
var table = new global.user();
|
||||
|
||||
table.username.value = "Visitor";
|
||||
|
||||
table.id = 0;
|
||||
|
||||
table.groups = new visitor();
|
||||
|
||||
table.permissionObjects = this.getPermissions( table, client );
|
||||
|
||||
return table;
|
||||
|
||||
}
|
||||
|
||||
signOut( cookieUser, client, eventName ) {
|
||||
|
||||
if( client.user ) {
|
||||
|
||||
client.user.get();
|
||||
|
||||
client.user.sessionKey.value = "";
|
||||
|
||||
client.user.save();
|
||||
|
||||
}
|
||||
|
||||
var table = this.createVisitor( client );
|
||||
|
||||
client.user = table;
|
||||
|
||||
global.core.setUserObjects( false, client );
|
||||
|
||||
return table;
|
||||
|
||||
}
|
||||
|
||||
|
||||
signin( object, client, force = false ) {
|
||||
|
||||
console.log("try to sign in");
|
||||
|
||||
var visitor = this.createVisitor( client );
|
||||
|
||||
if( object.table ) {
|
||||
|
||||
table = object;
|
||||
|
||||
} else {
|
||||
|
||||
var table = new global.user();
|
||||
|
||||
}
|
||||
|
||||
client.user = visitor;
|
||||
|
||||
client.user.error = false;
|
||||
|
||||
unify.extend( table );
|
||||
|
||||
if( object.username && object.username.value != "Visitor" ) {
|
||||
|
||||
var username = object.username.value;
|
||||
|
||||
var users = table.find( "username", username );
|
||||
|
||||
console.log("try to sign in users", users);
|
||||
|
||||
if( users.length > 0 ) {
|
||||
|
||||
var fetchedUser = users[ 0 ];
|
||||
|
||||
var hash = fetchedUser.hash;
|
||||
|
||||
console.log("try to sign in hash", hash);
|
||||
|
||||
|
||||
var password = object.password.value;
|
||||
|
||||
|
||||
if( object.sessionKey.value != "" ) {
|
||||
|
||||
console.log("try to signin with sessionKey")
|
||||
|
||||
var sign = ( object.sessionKey.value == fetchedUser.sessionKey );
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if( !object.password ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( !sign ) {
|
||||
|
||||
var sign = global.bcrypt.compareSync( password, hash );
|
||||
|
||||
}
|
||||
|
||||
console.log("sign in with password", sign);
|
||||
|
||||
if( !password ) {
|
||||
|
||||
client.user.error = "password required";
|
||||
|
||||
}
|
||||
|
||||
if( !hash ) {
|
||||
|
||||
client.user.error = "user does not have an hash";
|
||||
|
||||
}
|
||||
|
||||
if( sign || force ) {
|
||||
|
||||
table.id = fetchedUser.id;
|
||||
|
||||
console.log("fetchedUser", fetchedUser);
|
||||
|
||||
if( fetchedUser.activation == "true" ) {
|
||||
|
||||
table.get( );
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
console.log("not activated");
|
||||
|
||||
table.activation.value = false;
|
||||
|
||||
}
|
||||
|
||||
table.group.value = fetchedUser.group;
|
||||
|
||||
table.permissionObjects = this.getPermissions( table, client );
|
||||
|
||||
table.username.value = username;
|
||||
|
||||
//console.log("store session key", table.hash.value);
|
||||
|
||||
if( fetchedUser.activation == "true" ) {
|
||||
|
||||
if( table.sessionKey.value == "" ) {
|
||||
|
||||
table.sessionKey.value = this.createToken();
|
||||
|
||||
if( fetchedUser.activation == "true" ) {
|
||||
|
||||
table.save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//table.save();
|
||||
|
||||
table.error = false;
|
||||
|
||||
client.user = table;
|
||||
|
||||
client.user.status = "success";
|
||||
|
||||
} else {
|
||||
|
||||
client.user.status = "failed";
|
||||
client.user.error = "password";
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
client.user.status = "failed";
|
||||
client.user.error = "username";
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
client.user.error = "password";
|
||||
|
||||
}
|
||||
|
||||
if( client.user.status == "success" ) {
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
|
||||
global.core.setUserObjects( client.user, client );
|
||||
|
||||
global.core.parse( client.user, client );
|
||||
|
||||
if( client.user.error ) {
|
||||
|
||||
client.user.error = "Wrong Password or Username";
|
||||
|
||||
}
|
||||
|
||||
return client.user;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default new userManager();
|
||||
Reference in New Issue
Block a user