#!/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 { gpp } from '../../node_modules/node-gpp/child.js'; import tools from '../../unify/tools.js'; //import parser from 'args-parser'; import fse from "fs-extra"; import filemanager from '../filemanager.js'; import fs from 'fs-extra'; import path from 'path'; import groupsFlat from '../themeGroups.js'; import moduleLoader from '../moduleLoader.js'; import core from '../core.js'; import simplePath from "../../unify/simplePath.js"; import objectParser from '../objectParser.js'; var commandLineArguments = process.argv; global.extendMap = new Array(); export default class cacheManager{ mode = "development"; serverAddress = "localhost"; serverPort = 3000; ssl = false; socketPort = 5000; allPlatformFiles = new Array(); themePaths = new Array(); moduleLoader = new moduleLoader(); core = new core(); objectParser = new objectParser(); gpp = new gpp(); initializeCache() { var cachePath = path.resolve( "./assets/cache/cache.json" ); var jsonString = JSON.stringify( {} ); fs.writeFileSync( cachePath, jsonString ); var jscachePath = path.resolve( "./assets/cache/cache.js" ); fs.writeFileSync( jscachePath, "export default `" + jsonString + "`;" ); } constructor() { this.pathToPlatforms = new simplePath(); this.pathToPlatforms.beginWithSlash = false; this.pathToPlatforms.endWithSlash = true; this.pathToPlatforms.add( "framework" ) this.pathToPlatforms.add( "cache" ) this.pathToPlatforms.add( "platforms" ) this.initializeCache(); } createImportRule( index, applicationFilePath ) { return "import bundle" + index + " from \"" + applicationFilePath + "\" \n"; } createExportRule( bundleDefinitions ) { return "export default [" + bundleDefinitions + "];\n"; } composeApplicationFilePath( cachePath, applicationFile ) { var applicationFilePath = new simplePath(); applicationFilePath.beginWithSlash = false; applicationFilePath.add( cachePath ); applicationFilePath.add( applicationFile.path ); applicationFilePath.add( applicationFile.name ); return applicationFilePath.resolve(); } createBundleDefinitions( applications, cachePath ) { var bundleDefinitions = new Array(); var importFileSource = ""; for ( var i = 0; i < applications.length; i++ ) { var applicationFile = applications[ i ]; var applicationFilePath = this.composeApplicationFilePath( cachePath, applicationFile ); importFileSource += this.createImportRule( i, applicationFilePath ); bundleDefinitions.push( "bundle" + i ); } importFileSource += this.createExportRule( bundleDefinitions.join(",") ) return importFileSource; } createImportFile( applications, cachePath, importFilePath ) { var importFileSource = this.createBundleDefinitions( applications, cachePath, importFileSource ); fs.writeFileSync( importFilePath, importFileSource ); } createPlatformCachePath() { var cachePath = new simplePath(); cachePath.beginWithSlash = false; cachePath.add( "../../framework/cache/platforms/" ); cachePath.add( this.os ); cachePath.add( this.device ); cachePath.add( this.tint ); return cachePath.resolve(); } writePathsToPlatformCache( applications, importFilePath ) { var cachePath = this.createPlatformCachePath(); var importFilePath = "./framework/client/import.js"; this.createImportFile( applications, cachePath, importFilePath ); } writePathsToServerCache( applications ) { var importFilePath = "./framework/server/imports.js"; var cachePath = "../../framework/cache/server/"; this.createImportFile( applications, cachePath, importFilePath ); } async writeApplicationPathToFile( applications, platform ) { this.writePathsToPlatformCache( applications ); this.writePathsToServerCache( applications ); } createApplicationFilePath( path ) { var fullPath = new simplePath(); fullPath.beginWithSlash = false; fullPath.add( "../../cache/server/" ) fullPath.add( path ); fullPath.add( "application.js?random=" + Math.random() ); return fullPath.resolve(); } async importApplication( path ) { var applicationPath = this.createApplicationFilePath( path ); var importObject = await import( applicationPath ); var initializer = importObject.default; var application = new initializer(); return application; } getApplicationProperties( application ) { if( application.mode == "production" ) { this.mode = "production"; } else { this.mode = "development"; } if( commandLineArguments.mode == "production" ) { this.mode = "production"; } if( application.serverAddress ) { this.serverAddress = application.serverAddress; } if( application.serverPort ) { this.serverPort = application.serverPort; } if( application.os ) { this.os = tools.CamelCase( application.os ); } else { this.os = tools.CamelCase( "WINDOWS" ); } if( application.device ) { this.device = tools.CamelCase( application.device ); } else { this.device = tools.CamelCase("PC"); } if( application.tint ) { this.tint = tools.CamelCase(application.tint); } else { this.tint = tools.CamelCase("LIGHT"); } if( application.port ) { this.serverPort = application.port; } if( application.maxClients ) { this.maxClients = application.maxClients; } if( application.cacheBuildSpeed ) { this.cacheBuildSpeed = application.cacheBuildSpeed; } if( application.ssl ) { this.ssl = application.ssl; } if( application.socketPort ) { this.socketPort = application.socketPort; } if( application.maxClusters ) { this.maxClusters = application.maxClusters; } if( application.useSyncServer ) { this.useSyncServer = application.useSyncServer; } if( application.syncClientID ) { this.syncClientID = application.syncClientID; } else { this.syncClientID = 0; } if( application.syncServerAddress ) { this.syncServerAddress = application.syncServerAddress; } if( typeof application.loadThemes ) { this.loadThemes = application.loadThemes; } else { this.loadThemes = true; } } createObjectFromProperties() { var info = new Object(); info.mode = this.mode; info.serverAddress = this.serverAddress; info.ssl = this.ssl; info.socketPort = this.socketPort; info.port = this.serverPort; info.maxClusters = this.maxClusters; info.os = this.os; info.device = this.device; info.tint = this.tint; info.useSyncServer = this.useSyncServer; info.syncClientID = this.syncClientID; info.syncServerAddress = this.syncServerAddress; info.platform = this.platform; info.loadThemes = this.loadThemes; return info; } createExportString( properties ) { var exportCode = "var a = " + JSON.stringify( properties ) + "; \n" exportCode += "export default a;"; return exportCode; } generatePropertyJSONFiles( properties ) { var json = JSON.stringify( properties ); fs.writeFileSync( "./framework/configs/config.json", json ); fs.writeFileSync( "./framework/server/config.json", json ); fs.writeFileSync( "./assets/configs/config.json", json ); } generatePropertyConfigFile( properties ) { var source = this.createExportString( properties ); fs.writeFileSync( "./framework/configs/config.js", source ); } async writeApplicationPropertiesToFile() { var properties = this.createObjectFromProperties(); this.generatePropertyJSONFiles( properties ); this.generatePropertyConfigFile( properties ); } async writeConfigFiles( applications ) { await this.writeApplicationPathToFile( applications ); this.writeApplicationPropertiesToFile( applications[0] ); } createClient() { this.client = new Object(); this.client.objects = new Array(); this.client.classObjects = new Array(); return this.client; } createPathToApplication( path ) { var pathToApplication = this.pathToPlatforms.clone(); pathToApplication.add( path ) return pathToApplication; } definePragmaTerms( files, path ) { var terms = path.split("/"); terms.shift(); for ( var i = 0; i < terms.length; i++ ) { files.definePragma( terms[i] ); } } addApplicationPathToGlobalArray( files, pathToApplication ) { var application = files.applications[0]; var themePath = pathToApplication.clone(); themePath.add( application.path ); themePath.add( application.name ); this.themePaths.push( themePath.resolve() ); } createTemporaryCachePath( path ) { var temporaryCachePath = this.pathToPlatforms.clone(); temporaryCachePath.add( "Original" ); temporaryCachePath.add( path ); return temporaryCachePath.resolve(); } async processPlatform( group ) { var path = group.path; var pathToApplication = this.createPathToApplication( path ); var files = new filemanager( pathToApplication.resolve() ); this.definePragmaTerms( files, path ); files.definePragma("CLIENT"); files.addCustomReplacements(); await files.findApplicationFiles( "./application"); this.addApplicationPathToGlobalArray( files, pathToApplication ); files.filterModified(); files.temporary_cache_directory = this.createTemporaryCachePath( path ); await files.createDirectories(); files.writeFiles("client"); this.collectPlatformPaths( files, path ); await this.createPlatformFolders( pathToApplication.resolve() ); } async createPlatformFolders( path ) { var folderCreator = new filemanager( path ); await folderCreator.findApplicationFiles( "./application"); await folderCreator.createDirectories(); return true; } writeControllerToCache( file ) { var cachePath = "./framework/server/cachedControllers/"; var source = file.source; var name = file.name; var filePath = cachePath + name; var customPrefixes = new Array("public"); fs.ensureDirSync( path.resolve( cachePath ) ); source = this.objectParser.compose( source, filePath, customPrefixes ); fs.writeFileSync( tools.slash( filePath ), source, "utf8" ); } writeControllersToCache( folderCreator ) { var files = folderCreator.files; for (var i = 0; i < files.length; i++) { var file = files[i]; this.writeControllerToCache( file ); } } async createControllerCache() { var folderCreator = new filemanager(); await folderCreator.findApplicationFiles( "./framework/server/controllers/"); this.writeControllersToCache( folderCreator ); return true; } async processPlatformGroups() { fs.ensureDirSync( tools.slash( "framework/cache/platforms/Original" ) ); for ( var i = 0; i < groupsFlat.length; i++ ) { var group = groupsFlat[i]; await this.processPlatform( group ); } } async createCacheDirectorytree( server_files, path ) { server_files.temporary_cache_directory = tools.slash( path ); await server_files.createDirectories(); await server_files.writeFiles(); } async createCacheDirectories( server_files ) { await this.createCacheDirectorytree( server_files, "framework/cache/platforms/Original/Server/" ) await this.createCacheDirectorytree( server_files, "framework/cache/platforms/Server/" ) await this.createCacheDirectorytree( server_files, "framework/cache/server/" ) } collectPlatformPath( file, path = false ) { if( file.type == "file" ) { var fullPath = this.pathToPlatforms.clone(); fullPath.beginWithSlash = true; fullPath.add( "Original" ) if( path ) { fullPath.add( path ) } else { fullPath.add( "Server" ) } fullPath.add( file.path ) fullPath.add( file.name ) this.allPlatformFiles.push( fullPath.resolve() ); } } collectPlatformPaths( files, path = false ) { var files = files.files; for (var i = 0; i < files.length; i++) { var file = files[ i ]; this.collectPlatformPath( file, path ); } } writePlaformPathsToJSON() { var jsonFiles = JSON.stringify( this.allPlatformFiles ); fs.writeFileSync( tools.slash("framework/cache/platforms/files.json"), jsonFiles, "utf8" ); } collectAndWritePathsToJSON( server_files ) { this.collectPlatformPaths( server_files ); this.writePlaformPathsToJSON(); } async prepareCacheServerFiles() { var cachePath = "./framework/cache/server/"; var server_files = new filemanager( cachePath ); server_files.addCustomReplacements(); server_files.definePragma("SERVER"); await server_files.findApplicationFiles( "./application"); this.collectAndWritePathsToJSON( server_files ); server_files.filterModified(); await this.createCacheDirectories( server_files ); return server_files; } async copyFilesToPlatformCache() { var server_from = path.resolve( "./framework/cache/platforms/Server/" ); var server_to = path.resolve( "./framework/cache/server/" ); await fs.copySync( server_from, server_to ); } async writeFilePathsToConfigAsJSON() { var fileList = new filemanager( ); fileList.storeSource = false; await fileList.findApplicationFiles( "./application"); fileList.writeFileListCache(); } createCacheServerDirectories( server_files ) { server_files.writeCacheHistory(); server_files.cache_directory = tools.slash( "framework/cache/platforms/Server/"); server_files.createDirectories(); } async parseApplication( application ) { var client = this.createClient(); if( !moduleLoader.core ) { await this.core.parse( application, client ); } } async prepareApplication( server_files, applications ) { this.application = await this.importApplication( applications[0].path ); this.getApplicationProperties( this.application ); await this.parseApplication( this.application ); } async start(){ console.log("start cachManager"); await this.processPlatformGroups(); var server_files = await this.prepareCacheServerFiles(); await this.gpp.convert_files(); await this.copyFilesToPlatformCache(); this.createCacheServerDirectories( server_files ); await this.writeFilePathsToConfigAsJSON(); var applications = server_files.applications; await this.prepareApplication( server_files, applications ); await this.writeUnparsedPathsToFile() await this.writeThemePathsToFile(); await this.writeApplicationPropertiesToFile( applications[0] ); await this.writeApplicationPathToFile( applications ); this.createControllerCache(); } createEmptyJSON( path ) { var importString = "export default {};\n"; fs.writeFileSync( tools.slash( path ), importString, "utf8" ); } createUnparsedPath( group, sourcePath ) { var fullPath = new simplePath(); fullPath.add( ".." ) fullPath.add( "cache" ) fullPath.add( "platforms" ) fullPath.add( group.path ); fullPath.add( sourcePath ); return fullPath.resolve(); } createUnparsedRule( group, sourcePath ) { var path = this.createUnparsedPath( group, sourcePath ); var importString = "import unparsed_" + this.exportID + " from '" + path + "';\n"; importString += "imports['" + path + "'] = unparsed_" + this.exportID + ";\n" this.exportID++; return importString; } unparsedFromFiles( group ) { var files = this.moduleLoader.files; var importString = ""; for ( var b = 0; b < files.length; b++ ) { var file = files[ b ] var sourcePath = file.__sourcePath; importString += this.createUnparsedRule( group, sourcePath ); } return importString; } async createUnparsedJson() { var hasImported = false; this.exportID = 0; var importString = "var imports = new Array(); \n\n"; for ( var i = 0; i < groupsFlat.length; i++ ) { var group = groupsFlat[i]; importString += this.unparsedFromFiles( group ); } importString += "export default imports;\n"; fs.writeFileSync( tools.slash("framework/client/unparsed.js"), importString, "utf8" ); } async importUnParsedObjects() { var group = groupsFlat[0]; this.moduleLoader.setDirectory( group.os, group.device, group.tint ); this.moduleLoader.parseNewFiles = false; this.moduleLoader.client = this.client; await this.moduleLoader.loadModulesFromFiles( "/", this.core, this.client ); } async writeUnparsedPathsToFile() { await this.importUnParsedObjects(); if( this.mode == "development" ) { this.createEmptyJSON( "framework/client/unparsed.js" ); } else { this.createUnparsedJson() } } getThemeImportPath( themePath ) { var path = new simplePath(); path.add( ".." ); path.add( ".." ); path.add( ".." ); path.add( themePath ); return path.resolve(); } createThemeImportRule( themePath, index ) { var path = this.getThemeImportPath( themePath ); var importString = "import unparsed_" + index + " from '" + path + "';\n"; importString += "imports['" + themePath + "'] = unparsed_" + index + ";\n" return importString; } getThemeImports() { var themePaths = this.themePaths; var importString = ""; for ( var index = 0; index < themePaths.length; index++ ) { var themePath = themePaths[ index ] importString += this.createThemeImportRule( themePath, index ); } return importString; } createThemeImportsFile() { var importString = "var imports = new Array(); \n\n"; if( this.loadThemes ) { importString += this.getThemeImports(); } importString += "export default imports;\n"; fs.writeFileSync( tools.slash("framework/client/imports/themeImports.js"), importString, "utf8" ); } writeThemePathsToFile() { if( this.mode == "development" ) { this.createEmptyJSON( "framework/client/imports/themeImports.js" ); } else { this.createThemeImportsFile(); } } } //export default cacheManager;