models/_UBCommonGlobals.js

/*
 Purpose of this file is to describe objects and functions added to both server-side JavaScript thread and command line
 (i.e. UB -f) JavaScript thread by UnityBase server.
 All described here is native UB objects imported to SpiderMonkey (i.e. realisation is in Pascal or C).
 This file provide correct syntax check, code insight and documentation if we edit models in IDE like JetBrains, eclipse e.t.c.
 Also server-side documentation generated based on this file.

 Author: pavel.mash
 Date: 10.08.13
*/

 /*
 * UnityBase global. Analog of window in browser. Each server thread have own global
 */
var global = {};

/* DECLARATION MOVED TO UB
 * Load a module. Acts like a <a href="http://nodejs.org/api/modules.html">Node JS</a> require, with 4 difference:
 *
 *   - **Core modules** list is: `["fs", "util", "path", "assert", "module", "console" and "events"]` - this modules always loaded from `bin\modules` folder
 *   - In case of `moduleName` is **RELATIVE** (not start from `./` `../` or `X:\` where X is drive letter) lookup order is:
 *      - `currentModulePath + \modules`
 *      - `currentModulePath + \node_modules`
 *      - `bin\modules`
 *      - `process.cwd()`
 *   - in case UnityBase run in production (`!process.isDebug`) and package.json contain `main_min` entry it value will be used as a module entry point<br>
 *       Placing minimized js into `main_min` help to prevent memory overflow;
 *   - It know about UnityBase **models**. In **server thread** context, in case `moduleName` start from `models/ModelName` require search for module inside `ModelName.path` folder:
 *
 *          require('models/UBS/public/UBReport');
 *
 *     will search in domain config (ubConfig.json) path for `UBS` model and perform request relative to this folder, i.e. load `D:\projects\UnityBase\models\UBS\public\UBReport.js` in my case.
 *
 *  *In case you need to debug from there module is loaded set OS Environment variable*
 *  `>SET NODE_DEBUG=modules` *and restart server - require will put to debug log all information about how module are loaded.* Do not do this on production, of course :)
 *
 * @param {String} moduleName
 * @returns {*}
 */
function require(moduleName) {}

/**
 * Use the internal <i><code>require()</code></i> machinery to look up the location of a module,
 * but rather than loading the module, just return the resolved filename.
 * @param {String} moduleName
 * @returns {String}
 */
require.resolve = function (moduleName) {
    return '';
};

/**
 * Modules are cached in this object when they are required.<p/>
 * By deleting a key value from this object, the next require will reload the module.
 * @type {Object}
 */
require.cache = {};

/**
 * Module object of a file that is run directly from Node.
 * You can determine whether a file has been run directly by testing
 * <i><code>require.main&nbsp;===&nbsp;module</code></i>
 * @type {Object}
 */
require.main = {};

/**
 * Instruct <i><code>require</code></i> on how to handle certain file extensions.
 * Process files with the extension <i><code>.sjs</code></i> as <i><code>.js</code></i>:
 * <pre><code>
 *   require.extensions['.sjs'] = require.extensions['.js'];
 * </code></pre>
 * @type {Array}
 */
require.extensions = [];

/**
 * An object which is shared between all instances of the current module and made accessible
 * through <i><code>require()</code></i>.<p/>
 * <i><code>exports</code></i> is the same as the <i><code>module.exports</code></i> object.
 * <i><code>exports</code></i> isn't actually a global but rather local to each module.
 * See <a href="http://nodejs.org/api/modules.html">http://nodejs.org/api/modules.html</a> for more information.
 * @type {Object}
 */
var exports = {};

/**
 * The filename of the code being executed.
 * This is the resolved absolute path of this code file.
 * For a main program this is not necessarily the same filename used in the command line.
 * The value inside a module is the path to that module file.
 * @type {String}
 */
var __filename = '';

/**
 * Full path to the folder that the currently executing script resides in.
 * @type {String}
 */
var __dirname = '';

/**
 * A reference to the current module
 * @type {RequiredModule}
 */
var module = {};

/**
 * Put something to server log (in case of GUI server - duplicate message to log panel)
 *
 *	console.debug('Value we got is', 12);
 *
 * @deprecated Deprecated since 1.8. Use console.[log|debug|warn|error] instead
 * @param {Number|String|Object} log if {Number} - this is log level and function wait additional args
 * @param {Object|String|Number} [format] place % inside format string to indicate where to put value
 * @param {Object|String|Number} [value]
 *
 */
function toLog(log, format, value){}

/**
 * Load file content to string. Only for non-binary files!
 *
 * Do not use directly. Use fs.readFileSync(path) instead.
 * @private
 * @param {String} fileName Full path to file
 * @return {String} File content. In case of error - raise exception
 */
function loadFile(fileName){}

/**
 * Create new Uint8Array and load file into it. Do not use directly. Use fs.readFileSync(path, {encoding: 'bin'})) instead
 *
 * @private
 * @param {String} fileName
 * @return {ArrayBuffer|null} Return Null in case file not exists
 */
function loadFileToBuffer(fileName){ return new ArrayBuffer(0)}

/**
 * Remove comments from JSON string (actually replace all comment content with ' ')
 * @param {String} JSONString String to remove comments from
 * @return {String} JSON string without comment's
 */
function removeCommentsFromJSON(JSONString){}
/**
 * @private
 * @param {String} fileName
 */
function fileExists(fileName){}
/**
 * @private
 * @param {String} pathToDir
 */
function directoryExists(pathToDir){}
/**
 * Read directory. Return array of file names. In case directory not exists - return null
 * if includeDirNames === true then directory names included with trailing slash. 'folder\' else no directory names included
 *
 * Do not use direclty. Use require('fs').readdirSync() instead.
 *
 * @param {String} pathToDir path to directory
 * @param {Boolean} [includeDirNames] Optional. default = false.
 * @returns {Array}
 * @private
 */
function readDir(pathToDir, includeDirNames){}
/**
 * ForceDirectories ensures that all the directories in a specific path exist.
 * Any portion that does not already exist will be created.  Function result
 * indicates success of the operation.  The function can fail if the current
 * user does not have sufficient file access rights to create directories in
 * the given path.
 * @param {String} pathToDir
 * @returns {boolean} success
 */
function forceDirectories(pathToDir){}
/**
 * Deletes an existing empty directory.
 * Call removeDir to remove the directory specified by the Dir parameter.
 * The return value is True if a new directory was successfully deleted, False if an error occurred.
 * The directory must be emptied before it can be successfully deleted
 * When working with symlinks, there are some special cases to consider because of how symlinks are implemented on different platforms.
 * On Windows, RemoveDir can only delete a symbolic link from a directory, regardless if the directory link is broken or not
 * @param {String} pathToDir
 * @returns {boolean} success
 */
function removeDir(pathToDir){}

/**
 * Check is fileName is relative path, and if true - transform it to absolute from baseDir
 * @param {String} baseDir
 * @param {String} fileName
 * @return {String}
 * @private
 */
function relToAbs(baseDir, fileName){}

/**
 * @private
 * @param fileName
 */
function fileStat(fileName){}
/**
 * Remove file. Do not use directly. Use require('fs').unlinkSync() instead.
 * @protected
 * @param {String} fileName
 * @private
 */
function deleteFile(fileName){}

/**
 * Move file. Do not use directly. Use require('fs').moveSync() instead.
 * @private
 * @param {String} fileNameFrom
 * @param {String} fileNameTo
 */
function moveFile(fileNameFrom, fileNameTo){}

/**
 * Create GUID
 * @returns {string} GUID
 */
function createGuid(){return ''}
/**
 * For test purpose only. Suspend thread for ms millisecond
 * @param {Number} ms millisecond to sleep
 * @protected
 */
function sleep(ms){}
/**
 * Run script in separate thread (experimental). Returns thread ID.
 *
 * Thread creates in suspended state. When we post new worker message thread resumes and call *onmessage* handler.
 * When thread terminates and Terminate handler assigned worker thread call *onterminate* handler.
 * In handlers you can use 2 methods:
 *
 * *postMessage(message)* for posting messages from worker thread. You can get this message by function getMessage of worker object
 *
 * *terminate()* for terminating current worker thread
 *
 * @param {Object} paramsObj parameters object
 * @param {String|Function} paramsObj.onmessage Message handler. Has 1 parameter - message. Before call
 * @param {String|Function} paramsObj.onterminate Terminate handler. Has no parameters
 * @returns {Number} threadID
 */
function worker(paramsObj){}
/**
 * Post message to worker thread. Worker call *onmessage* handler with parameter *message*
 * @param {Number} threadID
 * @param  {String} message
 */
function postWorkerMessage(threadID, message) {}

/**
 * Get message from worker thread. If worker thread didn't post any message then return undefined
 * @param {Number} threadID
 * @returns {String|undefuned}
 */
function getWorkerMessage(threadID) {}

/**
 * Terminate worker thread.
 * @param {Number} threadID
 */
function terminateWorkerThread(threadID){}

/**
 * Perform Garbage collection for current scripting context. Use it if you know WHAT you do!
 * @protected
 */
function gc(){}

/**
 * Write something to file. If isBynary == false in UTF8 encoding. Do not use directly, use require('fs').writeFileSync() instead
 * @private
 * @deprecated Use writeFileNew
 * @param {String} fileName
 * @param {String|Object|ArrayBuffer|ArrayBufferView} fileContent if {Object} passed it can be serialized to string first
 * @param {Boolean} [isBinary] If true - string not decoded to UTF8 and writed to file as is.
 * @return {Boolean} success or not
 */
function writeFile(fileName, fileContent, isBinary){return true;}

/**
 * Write content to file. Internally implement {@link UBWriter#write}
 * @private
 * @param {String} filePath
 * @param {String|Object|ArrayBuffer} fileContent
 * @param {String} [encoding="utf-8"] Optional encoding of source.
 *						        If 'bin' - return ArrayBuffer source representation without any conversion.
 *							  	If 'base64' - transform base64 encoded content of source to ArrayBuffer
 * @returns {ArrayBuffer|String} Return String in case no encoding passed or ArrayBuffer
 */
function writeFileNew(filePath, fileContent, encoding){}

/**
 * Native CRC32 implementation. Much (x100) faster compared to JS implemenattion
 * @param {Number} initialValue Must be 0 in case no initial value
 * @param {String|ArrayBuffer|ArrayBufferView} data Data to calculate CRC32. In case of string will be transformed to UFT8 before calculation
 * @returns {number}
 */
function ncrc32(initialValue, data){return 0;}


/**
 * Native SHA256 implementation. Much (x10) faster compared to JS implementation
 * @param {String|ArrayBuffer|ArrayBufferView} data Data to calculate SHA256. In case of string will be transformed to UFT8 before calculation
 * @returns {String} hexa string SHA256 representation
 */
function nsha256(data){return 'a0';}

// Classes definition. Must be AFTER global function definition for correct documentation generation

/**
 * Reader interface.
 * @interface
 */
function UBReader(){}
/**
 * Read from source
 * @param {String} [encoding] Optional encoding of source. Default to 'utf-8'.
 *          If 'bin' - return ArrayBuffer source representation without any conversion.
 *          If 'base64' - transform base64 encoded content of source to ArrayBuffer
 *          If 'bin2base64' - transform content to base64 encoded string
 * @returns {ArrayBuffer|String} Return String in case no encoding passed or ArrayBuffer
 */
UBReader.prototype.read = function(encoding) {};


/**
 * Writer interface.
 * @interface
 */
function UBWriter(){}
/**
 * Write to source.
 * @param {ArrayBuffer|Object|String} data Data to write. If Object - it stringify before write
 * @param {String} [encoding] Encode data to `encoding` before write. Default to `utf-8` in case data is String or `bin` in case data is ArrayBuffer.
 *          One of "utf-8"|"ucs2"|"bin"|"base64".
 */
UBWriter.prototype.write = function(data, encoding) {};

/**
 * @classdesc
 * Module, loaded vis `require()` call.
 * In particular <i><code>module.exports</code></i> is the same as the <i><code>exports</code></i> object.
* <i><code>module</code></i> isn't actually a global but rather local to each module.
* See <a href="http://nodejs.org/api/modules.html">http://nodejs.org/api/modules.html</a> for more information.
* @class RequiredModule
*/
function RequiredModule(){}
RequiredModule.prototype = {
    /**
     * The <i><code>exports</code></i> object is created by the Module system.
     */
    exports:exports,

    /**
     * Provides a way to load a module as if <i><code>require()</code></i> was called from the original module.
     *
     * @param {String} id required module name
     * @return {Object} <i><code>exports</code></i> object from the resolved module
     */
    require:function (id) {
        return exports;
    },

    /**
     * The identifier for the module. Typically this is the fully resolved filename.
     * @type {String}
     */
    id:'{module identifier}',

    /**
     * The fully resolved filename to the module.
     * @type {String}
     */
    filename:'{fully resolved filename}',

    /**
     * Whether or not the module is done loading, or is in the process of loading.
     * @type {Boolean}
     */
    loaded:true,

    /**
     * The module that required this one.
     * @type {Object}
     */
    parent:{},

    /**
     * The module objects required by this one.
     * @type {Array}
     */
    children:[]
};

/**
 * @classdesc
 *  Named collection of parameters.
 *
 *  Think of it as an pain JavaScript object with property values that are stored in the `native` code,
 *  not inside a JavaScript runtime
 * @extends {TubNamedCollection}
 * @class TubList
 */
function TubList(){}

/**
 * Delete all elements from list
 */
TubList.prototype.clear = function(){};

/**
 * Add parameter with name paramName, set it type to `Blob` and value to `data`. In case parameter with same name exists - replace it.
 *
 * After call content of JavaScript variable is copied to server memory, so to avoid memory overflow developer can
 * set JS variable to NULL to allow GC to free memory.
 *
 * Use this feature to pass BLOB's as database operation parameter value.
 * @example

 var
    store = new TubDataStore('tst_blob'),
    l = new TubList(),
    fs = require('fs'),
    arr;
 arr = fs.readFileSync(process.binPath + 'UB.exe', {encoding: 'bin'}); // get content of binary file as array buffer
 l.ID = store.generateID();
 l.description = 'test1';
 l.setBLOBValue('blb', arr); // set BLOB type parameter value.
 // in case we sure arr is === ArrayBuffer can be simplified to: l.blb = arr;
 arr = null; // give a GC chance to release array memory
 store.execSQL('insert into tst_blob(id, description, blb) values(:ID:, :description:, :blb:)', l);

 * @param {String} paramName Name of a parameter to add BLOB to
 * @param {ArrayBuffer|Object|String} data Data to write. If Object - it stringify before write
 * @param {String} [encoding] Encode data to `encoding` before write. Default to `utf-8` in case data is String or `bin` in case data is ArrayBuffer.
 *                              One of "utf-8"|"ucs2"|"bin"|"base64".
 */
TubList.prototype.setBLOBValue = function(paramName, data, encoding){};


/**
 * @classdesc Native realisation of HTTP client. Do not use it directly - instead use {@link http} module.
 * @class THTTPClient
 * @private
 * @param {String} Server
 * @param {String} aPort
 * @param {Boolean} aHttps
 * @param {Boolean} [enableCompression=false]
 * @param {String} [aProxyName=""]
 * @param {String} [aProxyByPass=""]
 * @param {Number} [sendTimeout=30000]
 * @param {Number} [receiveTimeout=30000]
 * @constructor
 */
function THTTPClient(Server, aPort, aHttps, enableCompression, aProxyName, aProxyByPass, sendTimeout, receiveTimeout){};
/**
 * @property {string} responseHeaders
 */
THTTPClient.prototype.responseHeaders = '';

/**
 * @classdesc Create buffer with size. In case size !==0 internally buffer is not initialized and contain random data!
 * @class TubBuffer
 * @private
 * @param {Number} size buffer size in bytes
 * @constructor
 * @deprecated Since UB 2.0 we will migrate to a netive buffer (UInt8Array and so on)
 */
function TubBuffer(size){}
/**
 * Current buffer size. R/W
 * @type {number}
 */
TubBuffer.prototype.size = 0;
/**
 * Current buffer position. R/W
 * @type {number}
 */
TubBuffer.prototype.position = 0;
/**
 * Perform conversion from specified codePage to {String}
 * If codePage is unknown - raise error
 * Transformation start from current buffer position
 * @param {Number} codePage
 * @param {Number} [byteCount] number of bytes to transform
 * @returns {string}
 */
TubBuffer.prototype.transformToString = function(codePage, byteCount){ return '';};
/**
 * Append specified file to buffer (starting from buffer position)
 * Increase buffer position by number of bytes written
 * @param {String} fileName
 * @returns {Boolean} success or not
 */
TubBuffer.prototype.writeFile = function(fileName){return true;};
/**
 * Save buffer to specified file (starting from position 0)
 * @param {String} fileName
 * @returns {Boolean} success or not
 */
TubBuffer.prototype.writeToFile = function(fileName){return true;};
/**
 * Append specified string to current buffer position. Perform optional string code page transformation
 * Increase current position by bytes written
 * @param {String} stringToWrite string to append to current buffer position
 * @param {Number} [transformToCodePage] Optional code page to transform string to while writing
 * @returns {Number} Actual number of bytes written (may differ from stringToWrite.length in case transformToCodePage <> UTF16)
 */
TubBuffer.prototype.writeString = function(stringToWrite, transformToCodePage){return 0;};

/**
 * @class TubZipReader
 * Class for read zip archives. Can read from file name or from TubBuffer
 * @param {String|TubBuffer} from fileName or TubBuffer object to read zip archive from
 * @constructor
 */
function TubZipReader(from){}
/**
 * Read only array of file names inside archive
 * @type {Array}
 */
TubZipReader.prototype.fileNames = [];
/**
 * Read only file count inside archive
 * @type {number}
 */
TubZipReader.prototype.fileCount = 0;
/**
 * Unzip specified file and append to existed TubBuffer.
 * @param {Number} fileIndex index of file to unzip
 * @param {TubBuffer} dest buffer to append unzipped data
 * @returns {number} Unzipped bytes count
 */
TubZipReader.prototype.unZipToBuffer = function(fileIndex, dest){return 0;};
/**
 * Unzip specified file to specified folder.
 * @param {Number} fileIndex index of file to unzip
 * @param {String} dirName directory name to unzip file to
 * @returns {Boolean} Success
 */
TubZipReader.prototype.unZipToDir = function (fileIndex, dirName){return true};
/**
 * Unzip all files to specified folder.
 * @param {String} dirName directory name to unzip files to
 * @returns {Boolean} Success
 */
TubZipReader.prototype.unZipAllToDir = function (dirName){return true};

/**
 * @class TubZipWriter
 * Create zip archive. After finish working with archive creator must call freeNative() method to close file handel
 * @param fileName name of zip archive file
 * @constructor
 */
function TubZipWriter(fileName){}
/**
 * Add byteCount bytes from source to archive as fleName
 * @param {String} fileName name of file inside archive
 * @param {Number} byteCount number of bytes to add starting from buffer position
 * @param {TubBuffer} source
 */
TubZipWriter.prototype.addBuffer = function(fileName, byteCount, source){};
/**
 * Add specified file to archive
 * @param fileName
 */
TubZipWriter.prototype.addFile = function(fileName){};
/**
 * Close writer
 */
TubZipWriter.prototype.freeNative = function(){};


/**
 * @classdesc Information about current executable. Do not create it directly - use a global variable `process`.
 * @todo Add a emitted events description
 * @class Process
 * @mixes EventEmitter
 */
function Process(){};
/**
 * Fires for the {process} instance when application stop working for each Working Thread
 *
 *      process.on('exit', function(){
 *          console.log('thread is terminated');
 *      });
 *
 * @event exit
 */

/**
 * Return current working directory for process (actually {@link Process#startupPath}
 * @return {String}
 */
Process.prototype.cwd = function(){}

/**
 * Just a hack for nodeJS compatribility (async emulation)
 * @param {function} cb
 */
Process.prototype.nextTick = function(cb){}

/**
 * Path to directory from which server executed (CWD)
 * @type {String}
 * @readonly
 */
Process.prototype.startupPath = '';

/**
 * The main executable full path (excluding .exe file name)
 * @type {String}
 * @readonly
 */
Process.prototype.binPath = '';

/**
 * Path to config file process started with
 * @type {String}
 * @readonly
 */
Process.prototype.configPath = '';

/**
 * Operation system environment variables
 * @type {Object<string, string>}
 * @readonly
 */
Process.prototype.env = {};

/**
 * Process `argv` list. You can use helper class `modules\cmd\argv.js` to work with this array.
 * @type {Array<string>}
 * @readonly
 */
Process.prototype.argv = [];

/**
 * In case this is server-side thread === 1 else (client theread) ===  0
 * @type {Number}
 * @readonly
 */
Process.prototype.isServer = 0;

/**
 * In case this is WebSocket server-side thread === 1 else not defined
 * @type {Number}
 * @readonly
 */
Process.prototype.isWebSocketServer = 0;

/**
 * When WebSockets are enabled === 1 else not defined
 * @type {Number}
 * @readonly
 */
Process.prototype.isWebSocketEnabled = 0;

/**
 * `true` if server executed with `-dev` command line switch.
 * @type {Number}
 * @readonly
 */
Process.prototype.isDebug = 0;

/**
 * The UB process startup mode. One of "Service", "Console", "GUI", "CmdLine"
 * @type {String}
 * @readonly
 */
Process.prototype.startupMode = "CmdLine"