total.js
Version:
MVC framework for Node.js
1,691 lines (1,452 loc) • 497 kB
JavaScript
// Copyright 2012-2021 (c) Peter Širka <petersirka@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
/**
* @module Framework
* @version 3.4.13
*/
'use strict';
const Qs = require('querystring');
const Os = require('os');
const Fs = require('fs');
const Zlib = require('zlib');
const Path = require('path');
const Crypto = require('crypto');
const Parser = require('url');
const Child = require('child_process');
const Util = require('util');
const http = require('http');
const ENCODING = 'utf8';
const HEADER_CACHE = 'Cache-Control';
const HEADER_TYPE = 'Content-Type';
const HEADER_LENGTH = 'Content-Length';
const CT_TEXT = 'text/plain';
const CT_HTML = 'text/html';
const CT_JSON = 'application/json';
const COMPRESSION = { 'text/plain': true, 'text/javascript': true, 'text/css': true, 'text/jsx': true, 'application/javascript': true, 'application/x-javascript': true, 'application/json': true, 'text/xml': true, 'image/svg+xml': true, 'text/x-markdown': true, 'text/html': true };
const COMPRESSIONSPECIAL = { js: 1, css: 1, mjs: 1 };
const RESPONSENOCACHE = { zip: 1, rar: 1 };
const REG_TEMPORARY = /\//g;
const REG_MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|Tablet/i;
const REG_ROBOT = /search|agent|bot|crawler|spider/i;
const REG_VERSIONS = /(href|src)="[a-zA-Z0-9/:\-._]+\.(jpg|js|css|png|apng|gif|svg|html|ico|json|less|sass|scss|swf|txt|webp|heif|heic|jpeg|woff|woff2|xls|xlsx|xml|xsl|xslt|zip|rar|csv|doc|docx|eps|gzip|jpe|jpeg|manifest|mov|mp3|flac|mp4|ogg|package|pdf)"/gi;
const REG_COMPILECSS = /url\(.*?\)/g;
const REG_ROUTESTATIC = /^(\/\/|https:|http:)+/;
const REG_NEWIMPL = /^(async\s)?function(\s)?([a-zA-Z$][a-zA-Z0-9$]+)?(\s)?\([a-zA-Z0-9$]+\)|^function anonymous\(\$/;
const REG_RANGE = /bytes=/;
const REG_EMPTY = /\s/g;
const REG_ACCEPTCLEANER = /\s|\./g;
const REG_SANITIZE_BACKSLASH = /\/\//g;
const REG_WEBSOCKET_ERROR = /ECONNRESET|EHOSTUNREACH|EPIPE|is closed/i;
const REG_WINDOWSPATH = /\\/g;
const REG_SCRIPTCONTENT = /<|>|;/;
const REG_HTTPHTTPS = /^(\/)?(http|https):\/\//i;
const REG_NOCOMPRESS = /[.|-]+min(@[a-z0-9]*)?\.(css|js)$/i;
const REG_WWW = /^www\./i;
const REG_TEXTAPPLICATION = /text|application/;
const REG_ENCODINGCLEANER = /[;\s]charset=utf-8/g;
const REG_SKIPERROR = /epipe|invalid\sdistance/i;
const REG_OLDCONF = /-/g;
const REG_UTF8 = /[^\x20-\x7E]+/;
const REG_ENCODEDSPACE = /\+/g;
const FLAGS_INSTALL = ['get'];
const FLAGS_DOWNLOAD = ['get', 'dnscache'];
const QUERYPARSEROPTIONS = { maxKeys: 33 };
const EMPTYARRAY = [];
const EMPTYOBJECT = {};
const EMPTYREQUEST = { uri: {} };
const SINGLETONS = {};
const REPOSITORY_HEAD = '$head';
const REPOSITORY_META_TITLE = '$title';
const REPOSITORY_META_DESCRIPTION = '$description';
const REPOSITORY_META_KEYWORDS = '$keywords';
const REPOSITORY_META_AUTHOR = '$author';
const REPOSITORY_META_IMAGE = '$image';
const REPOSITORY_PLACE = '$place';
const REPOSITORY_SITEMAP = '$sitemap';
const REPOSITORY_COMPONENTS = '$components';
const ATTR_END = '"';
const ETAG = '858';
const CONCAT = [null, null];
const CLUSTER_CACHE_SET = { TYPE: 'cache', method: 'set' };
const CLUSTER_CACHE_REMOVE = { TYPE: 'cache', method: 'remove' };
const CLUSTER_CACHE_REMOVEALL = { TYPE: 'cache', method: 'removeAll' };
const CLUSTER_CACHE_CLEAR = { TYPE: 'cache', method: 'clear' };
const CLUSTER_SNAPSHOT = { TYPE: 'snapshot' };
const GZIPFILE = { memLevel: 9 };
const GZIPSTREAM = { memLevel: 1 };
const MODELERROR = {};
const IMAGES = { jpg: 1, png: 1, gif: 1, apng: 1, jpeg: 1, heif: 1, heic: 1, webp: 1 };
const KEYSLOCALIZE = { html: 1, htm: 1 };
const PROXYOPTIONS = { end: true };
const PROXYKEEPALIVE = new http.Agent({ keepAlive: true, timeout: 60000 });
const JSFILES = { js: 1, mjs: 1 };
var PREFFILE = 'preferences.json';
var PATHMODULES = require.resolve('./index');
PATHMODULES = PATHMODULES.substring(0, PATHMODULES.length - 8);
Object.freeze(EMPTYOBJECT);
Object.freeze(EMPTYARRAY);
Object.freeze(EMPTYREQUEST);
global.EMPTYOBJECT = EMPTYOBJECT;
global.EMPTYARRAY = EMPTYARRAY;
global.NOW = new Date();
global.THREAD = '';
global.isWORKER = false;
global.REQUIRE = function(path) {
return require(F.directory + '/' + path);
};
function flowwrapper(name) {
if (!name)
name = 'default';
if (F.flows[name])
return F.flows[name];
var flow = new framework_flow.make(name);
return F.flows[name] = flow;
}
global.FLOWSTREAM = function(name) {
global.framework_flow = require('./flow');
global.FLOW = flowwrapper;
return flowwrapper(name);
};
var DEF = global.DEF = {};
DEF.currencies = {};
var PROTORES, PROTOREQ;
var RANGE = { start: 0, end: 0 };
var HEADERS = {};
var SUCCESSHELPER = { success: true };
// Cached headers for repeated usage
HEADERS.responseCode = {};
HEADERS.responseCode[HEADER_TYPE] = CT_TEXT;
HEADERS.redirect = {};
HEADERS.redirect[HEADER_TYPE] = CT_HTML + '; charset=utf-8';
HEADERS.redirect[HEADER_LENGTH] = '0';
HEADERS.sse = {};
HEADERS.sse[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.sse['Pragma'] = 'no-cache';
HEADERS.sse['Expires'] = '-1';
HEADERS.sse[HEADER_TYPE] = 'text/event-stream';
HEADERS.sse['X-Powered-By'] = 'Total.js';
HEADERS.file_lastmodified = {};
HEADERS.file_lastmodified['Access-Control-Allow-Origin'] = '*';
HEADERS.file_lastmodified[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.file_lastmodified['X-Powered-By'] = 'Total.js';
HEADERS.file_release_compress = {};
HEADERS.file_release_compress[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.file_release_compress['Vary'] = 'Accept-Encoding';
HEADERS.file_release_compress['Access-Control-Allow-Origin'] = '*';
HEADERS.file_release_compress['Last-Modified'] = 'Mon, 01 Jan 2001 08:00:00 GMT';
HEADERS.file_release_compress['Content-Encoding'] = 'gzip';
HEADERS.file_release_compress['X-Powered-By'] = 'Total.js';
HEADERS.file_release_compress_range = {};
HEADERS.file_release_compress_range['Accept-Ranges'] = 'bytes';
HEADERS.file_release_compress_range[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.file_release_compress_range['Vary'] = 'Accept-Encoding';
HEADERS.file_release_compress_range['Access-Control-Allow-Origin'] = '*';
HEADERS.file_release_compress_range['Last-Modified'] = 'Mon, 01 Jan 2001 08:00:00 GMT';
HEADERS.file_release_compress_range['Content-Encoding'] = 'gzip';
HEADERS.file_release_compress_range[HEADER_LENGTH] = '0';
HEADERS.file_release_compress_range['Content-Range'] = '';
HEADERS.file_release_compress_range['X-Powered-By'] = 'Total.js';
HEADERS.file_release = {};
HEADERS.file_release[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.file_release['Vary'] = 'Accept-Encoding';
HEADERS.file_release['Access-Control-Allow-Origin'] = '*';
HEADERS.file_release['Last-Modified'] = 'Mon, 01 Jan 2001 08:00:00 GMT';
HEADERS.file_release['X-Powered-By'] = 'Total.js';
HEADERS.file_release_range = {};
HEADERS.file_release_range['Accept-Ranges'] = 'bytes';
HEADERS.file_release_range[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.file_release_range['Vary'] = 'Accept-Encoding';
HEADERS.file_release_range['Access-Control-Allow-Origin'] = '*';
HEADERS.file_release_range['Last-Modified'] = 'Mon, 01 Jan 2001 08:00:00 GMT';
HEADERS.file_release_range[HEADER_LENGTH] = '0';
HEADERS.file_release_range['Content-Range'] = '';
HEADERS.file_release_range['X-Powered-By'] = 'Total.js';
HEADERS.file_debug_compress = {};
HEADERS.file_debug_compress[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.file_debug_compress['Vary'] = 'Accept-Encoding';
HEADERS.file_debug_compress['Access-Control-Allow-Origin'] = '*';
HEADERS.file_debug_compress['Pragma'] = 'no-cache';
HEADERS.file_debug_compress['Expires'] = '-1';
HEADERS.file_debug_compress['Content-Encoding'] = 'gzip';
HEADERS.file_debug_compress['X-Powered-By'] = 'Total.js';
HEADERS.file_debug_compress_range = {};
HEADERS.file_debug_compress_range['Accept-Ranges'] = 'bytes';
HEADERS.file_debug_compress_range[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.file_debug_compress_range['Vary'] = 'Accept-Encoding';
HEADERS.file_debug_compress_range['Access-Control-Allow-Origin'] = '*';
HEADERS.file_debug_compress_range['Content-Encoding'] = 'gzip';
HEADERS.file_debug_compress_range['Pragma'] = 'no-cache';
HEADERS.file_debug_compress_range['Expires'] = '-1';
HEADERS.file_debug_compress_range[HEADER_LENGTH] = '0';
HEADERS.file_debug_compress_range['Content-Range'] = '';
HEADERS.file_debug_compress_range['X-Powered-By'] = 'Total.js';
HEADERS.file_debug = {};
HEADERS.file_debug[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.file_debug['Vary'] = 'Accept-Encoding';
HEADERS.file_debug['Pragma'] = 'no-cache';
HEADERS.file_debug['Expires'] = '-1';
HEADERS.file_debug['Access-Control-Allow-Origin'] = '*';
HEADERS.file_debug['X-Powered-By'] = 'Total.js';
HEADERS.file_debug_range = {};
HEADERS.file_debug_range['Accept-Ranges'] = 'bytes';
HEADERS.file_debug_range[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.file_debug_range['Vary'] = 'Accept-Encoding';
HEADERS.file_debug_range['Access-Control-Allow-Origin'] = '*';
HEADERS.file_debug_range['Pragma'] = 'no-cache';
HEADERS.file_debug_range['Expires'] = '-1';
HEADERS.file_debug_range[HEADER_LENGTH] = '0';
HEADERS.file_debug_range['Content-Range'] = '';
HEADERS.file_debug_range['X-Powered-By'] = 'Total.js';
HEADERS.content_mobile_release = {};
HEADERS.content_mobile_release[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.content_mobile_release['Vary'] = 'Accept-Encoding, User-Agent';
HEADERS.content_mobile_release['Content-Encoding'] = 'gzip';
HEADERS.content_mobile_release['Expires'] = '-1';
HEADERS.content_mobile_release['X-Powered-By'] = 'Total.js';
HEADERS.content_mobile = {};
HEADERS.content_mobile[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.content_mobile['Vary'] = 'Accept-Encoding, User-Agent';
HEADERS.content_mobile['Expires'] = '-1';
HEADERS.content_mobile['X-Powered-By'] = 'Total.js';
HEADERS.content_compress = {};
HEADERS.content_compress[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.content_compress['Vary'] = 'Accept-Encoding';
HEADERS.content_compress['Content-Encoding'] = 'gzip';
HEADERS.content_compress['Expires'] = '-1';
HEADERS.content_compress['X-Powered-By'] = 'Total.js';
HEADERS.content = {};
HEADERS.content[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.content['Vary'] = 'Accept-Encoding';
HEADERS.content['Expires'] = '-1';
HEADERS.content['X-Powered-By'] = 'Total.js';
HEADERS.stream_release_compress = {};
HEADERS.stream_release_compress[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.stream_release_compress['Access-Control-Allow-Origin'] = '*';
HEADERS.stream_release_compress['Content-Encoding'] = 'gzip';
HEADERS.stream_release_compress['X-Powered-By'] = 'Total.js';
HEADERS.stream_release = {};
HEADERS.stream_release[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.stream_release['Access-Control-Allow-Origin'] = '*';
HEADERS.stream_release['X-Powered-By'] = 'Total.js';
HEADERS.stream_debug_compress = {};
HEADERS.stream_debug_compress[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.stream_debug_compress['Pragma'] = 'no-cache';
HEADERS.stream_debug_compress['Expires'] = '-1';
HEADERS.stream_debug_compress['Access-Control-Allow-Origin'] = '*';
HEADERS.stream_debug_compress['Content-Encoding'] = 'gzip';
HEADERS.stream_debug_compress['X-Powered-By'] = 'Total.js';
HEADERS.stream_debug = {};
HEADERS.stream_debug[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.stream_debug['Pragma'] = 'no-cache';
HEADERS.stream_debug['Expires'] = '-1';
HEADERS.stream_debug['Access-Control-Allow-Origin'] = '*';
HEADERS.stream_debug['X-Powered-By'] = 'Total.js';
HEADERS.binary_compress = {};
HEADERS.binary_compress[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.binary_compress['Content-Encoding'] = 'gzip';
HEADERS.binary_compress['X-Powered-By'] = 'Total.js';
HEADERS.binary = {};
HEADERS.binary[HEADER_CACHE] = 'public';
HEADERS.binary['X-Powered-By'] = 'Total.js';
HEADERS.authorization = { user: '', password: '', empty: true };
HEADERS.fsStreamRead = { flags: 'r', mode: '0666', autoClose: true };
HEADERS.fsStreamReadRange = { flags: 'r', mode: '0666', autoClose: true, start: 0, end: 0 };
HEADERS.responseLocalize = {};
HEADERS.responseLocalize['Access-Control-Allow-Origin'] = '*';
HEADERS.responseNotModified = {};
HEADERS.responseNotModified[HEADER_CACHE] = 'public, max-age=11111111';
HEADERS.responseNotModified['X-Powered-By'] = 'Total.js';
HEADERS.response503 = {};
HEADERS.response503[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.response503[HEADER_TYPE] = CT_HTML;
HEADERS.response503['X-Powered-By'] = 'Total.js';
HEADERS.response503ddos = {};
HEADERS.response503ddos[HEADER_CACHE] = 'private, no-cache, no-store, max-age=0';
HEADERS.response503ddos[HEADER_TYPE] = CT_TEXT;
HEADERS.response503ddos['X-Powered-By'] = 'Total.js';
Object.freeze(HEADERS.authorization);
var _controller = '';
var _owner = '';
var _flags;
var _prefix;
// GO ONLINE MODE
!global.framework_internal && (global.framework_internal = require('./internal'));
!global.framework_builders && (global.framework_builders = require('./builders'));
!global.framework_utils && (global.framework_utils = require('./utils'));
!global.framework_mail && (global.framework_mail = require('./mail'));
!global.framework_image && (global.framework_image = require('./image'));
!global.framework_session && (global.framework_session = require('./session'));
require('./tangular');
function sessionwrapper(name) {
if (!name)
name = 'default';
if (F.sessions[name])
return F.sessions[name];
var session = new framework_session.Session(name);
session.load();
if (F.sessionscount)
F.sessionscount++;
else
F.sessionscount = 1;
return F.sessions[name] = session;
}
global.SESSION = function(name) {
global.framework_session = require('./session');
global.SESSION = sessionwrapper;
return sessionwrapper(name);
};
var TMPENV = framework_utils.copy(process.env);
TMPENV.istotaljsworker = true;
HEADERS.workers = { cwd: '', silent: false, env: TMPENV };
HEADERS.workers2 = { cwd: '', silent: true, env: TMPENV };
global.Builders = framework_builders;
var U = global.Utils = global.utils = global.U = global.framework_utils;
global.Mail = framework_mail;
global.WTF = (message, name, uri) => F.problem(message, name, uri);
global.NOBIN = global.NOSQLBINARY = (name) => F.nosql(name).binary;
global.NOSQLSTORAGE = (name) => F.nosql(name).storage;
global.NOCOUNTER = global.NOSQLCOUNTER = (name) => F.nosql(name).counter;
function nomemwrapper(name) {
return global.framework_nosql.inmemory(name);
}
global.NOMEM = global.NOSQLMEMORY = function(name) {
if (!global.framework_nosql)
global.framework_nosql = require('./nosql');
global.NOMEM = global.NOSQLMEMORY = global.framework_nosql.inmemory;
return nomemwrapper(name);
};
global.CONFIG = function(name, val) {
return arguments.length === 1 ? CONF[name] : (CONF[name] = val);
};
var prefid;
global.PREF = {};
global.PREF.set = function(name, value) {
if (value === undefined)
return F.pref[name];
if (value === null) {
delete F.pref[name];
} else
F.pref[name] = global.PREF[name] = value;
prefid && clearTimeout(prefid);
prefid = setTimeout(F.onPrefSave, 1000, F.pref);
};
global.CACHE = function(name, value, expire, persistent) {
return arguments.length === 1 ? F.cache.get2(name) : F.cache.set(name, value, expire, persistent);
};
global.CREATE = (group, name) => framework_builders.getschema(group, name).default();
global.SINGLETON = (name, def) => SINGLETONS[name] || (SINGLETONS[name] = (new Function('return ' + (def || '{}')))());
global.FUNCTION = (name) => F.functions[name] || NOOP;
global.FINISHED = framework_internal.onFinished;
global.DESTROY = framework_internal.destroyStream;
function filestoragewrapper(name) {
var key = 'storage_' + name;
return F.databases[key] ? F.databases[key] : (F.databases[key] = new framework_nosql.DatabaseBinary({ name: name }, F.path.databases('fs-' + name + '/'), '.file'));
}
global.FILESTORAGE = function(name) {
if (!global.framework_nosql)
global.framework_nosql = require('./nosql');
global.FILESTORAGE = filestoragewrapper;
return filestoragewrapper(name);
};
global.UID16 = function(type) {
var index;
if (type) {
if (UIDGENERATOR.types[type])
index = UIDGENERATOR.types[type] = UIDGENERATOR.types[type] + 1;
else {
UIDGENERATOR.multiple = true;
index = UIDGENERATOR.types[type] = 1;
}
} else
index = UIDGENERATOR.index++;
return UIDGENERATOR.date16 + index.padLeft(3, '0') + UIDGENERATOR.instance + UIDGENERATOR.date16.length + (index % 2 ? 1 : 0) + 'c'; // "c" version
};
global.UID = function(type) {
var index;
if (type) {
if (UIDGENERATOR.types[type])
index = UIDGENERATOR.types[type] = UIDGENERATOR.types[type] + 1;
else {
UIDGENERATOR.multiple = true;
index = UIDGENERATOR.types[type] = 1;
}
} else
index = UIDGENERATOR.index++;
return UIDGENERATOR.date + index.padLeft(3, '0') + UIDGENERATOR.instance + UIDGENERATOR.date.length + (index % 2 ? 1 : 0) + 'b'; // "b" version
};
global.UIDF = function(type) {
var index;
if (type) {
if (UIDGENERATOR.typesnumber[type])
index = UIDGENERATOR.typesnumber[type] = UIDGENERATOR.typesnumber[type] + 1;
else {
UIDGENERATOR.multiplenumber = true;
index = UIDGENERATOR.typesnumber[type] = 1;
}
} else
index = UIDGENERATOR.indexnumber++;
var div = index > 1000 ? 10000 : 1000;
return (UIDGENERATOR.datenumber + (index / div));
};
global.ERROR = function(name) {
return name == null ? F.errorcallback : function(err) {
err && F.error(err, name);
};
};
global.AUTH = function(fn) {
F.onAuthorize = framework_builders.AuthOptions.wrap(fn);
};
global.WEBSOCKETCLIENT = function(callback) {
var ws = require('./websocketclient').create();
callback && callback.call(ws, ws);
return ws;
};
global.$CREATE = function(schema) {
var o = framework_builders.getschema(schema);
return o ? o.default() : null;
};
global.$MAKE = function(schema, model, filter, callback, novalidate, argument) {
var o = framework_builders.getschema(schema);
var w = null;
if (typeof(filter) === 'function') {
var tmp = callback;
callback = filter;
filter = tmp;
}
if (filter instanceof Array) {
w = {};
for (var i = 0; i < filter.length; i++)
w[filter[i]] = i + 1;
filter = null;
} else if (filter instanceof Object) {
if (!(filter instanceof RegExp)) {
filter = null;
w = filter;
}
}
return o ? o.make(model, filter, callback, argument, novalidate, w) : undefined;
};
global.$QUERY = function(schema, options, callback, controller) {
var o = framework_builders.getschema(schema);
if (o)
o.query(options, callback, controller);
else
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return !!o;
};
global.$GET = global.$READ = function(schema, options, callback, controller) {
var o = framework_builders.getschema(schema);
if (o)
o.get(options, callback, controller);
else
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return !!o;
};
global.$WORKFLOW = function(schema, name, options, callback, controller) {
var o = framework_builders.getschema(schema);
if (o)
o.workflow2(name, options, callback, controller);
else
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return !!o;
};
global.$TRANSFORM = function(schema, name, options, callback, controller) {
var o = framework_builders.getschema(schema);
if (o)
o.transform2(name, options, callback, controller);
else
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return !!o;
};
global.$REMOVE = function(schema, options, callback, controller) {
var o = framework_builders.getschema(schema);
if (typeof(options) === 'function') {
controller = callback;
callback = options;
options = EMPTYOBJECT;
}
if (o)
o.remove(options, callback, controller);
else
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return !!o;
};
global.$SAVE = function(schema, model, options, callback, controller, novalidate) {
return performschema('$save', schema, model, options, callback, controller, novalidate);
};
global.$INSERT = function(schema, model, options, callback, controller, novalidate) {
return performschema('$insert', schema, model, options, callback, controller, novalidate);
};
global.$UPDATE = function(schema, model, options, callback, controller, novalidate) {
return performschema('$update', schema, model, options, callback, controller, novalidate);
};
global.$PATCH = function(schema, model, options, callback, controller, novalidate) {
return performschema('$patch', schema, model, options, callback, controller, novalidate);
};
// GET Users/Neviem --> @query @workflow
global.$ACTION = function(schema, model, callback, controller) {
if (typeof(model) === 'function') {
controller = callback;
callback = model;
model = null;
}
var meta = F.temporary.other[schema];
var tmp, index;
if (!meta) {
index = schema.indexOf('-->');
var op = (schema.substring(index + 3).trim().trim() + ' ').split(/\s@/).trim();
tmp = schema.substring(0, index).split(/\s|\t/).trim();
if (tmp.length !== 2) {
callback('Invalid "{0}" type.'.format(schema));
return;
}
meta = {};
meta.method = tmp[0].toUpperCase();
meta.schema = tmp[1];
if (meta.schema[0] === '*')
meta.schema = meta.schema.substring(1);
meta.op = [];
meta.opcallbackindex = -1;
var name = meta.schema.split('/');
var o = GETSCHEMA(name[0], name[1]);
if (!o) {
callback(new ErrorBuilder().push('', 'Schema "{0}" not found'.format(meta.schema)));
return;
}
for (var i = 0; i < op.length; i++) {
tmp = {};
var item = op[i];
if (item[0] === '@')
item = item.substring(1);
index = item.indexOf('(');
if (index !== -1) {
meta.opcallbackindex = i;
tmp.response = true;
item = item.substring(0, index).trim();
}
tmp.name = item;
tmp.name2 = '$' + tmp.name;
if (o.meta[item] === undefined) {
if (o.meta['workflow#' + item] !== undefined)
tmp.type = '$workflow';
else if (o.meta['transform#' + item] !== undefined)
tmp.type = '$transform';
else if (o.meta['operation#' + item] !== undefined)
tmp.type = '$operation';
else if (o.meta['hook#' + item] !== undefined)
tmp.type = '$hook';
else {
callback(new ErrorBuilder().push('', 'Schema "{0}" doesn\'t contain "{1}" operation.'.format(meta.schema, item)));
return;
}
}
if (tmp.type)
tmp.type2 = tmp.type.substring(1);
meta.op.push(tmp);
}
meta.multiple = meta.op.length > 1;
meta.schema = o;
meta.validate = meta.method !== 'GET';
F.temporary.other[schema] = meta;
}
if (meta.validate) {
var req = controller ? controller.req : null;
if (meta.method === 'PATCH' || meta.method === 'DELETE') {
if (!req)
req = {};
req.$patch = true;
}
var data = {};
data.meta = meta;
data.callback = callback;
data.controller = controller;
meta.schema.make(model, null, performsschemaaction_async, data, null, null, req);
} else
performsschemaaction(meta, null, callback, controller);
};
function performsschemaaction_async(err, response, data) {
if (err)
data.callback(err);
else
performsschemaaction(data.meta, response, data.callback, data.controller);
}
function performsschemaaction(meta, model, callback, controller) {
if (meta.multiple) {
if (!model)
model = meta.schema.default();
model.$$controller = controller;
var async = model.$async(callback, meta.opcallbackindex === - 1 ? null : meta.opcallbackindex);
for (var i = 0; i < meta.op.length; i++) {
var op = meta.op[i];
if (op.type)
async[op.type](op.name);
else
async[op.name2]();
}
} else {
var op = meta.op[0];
if (model) {
model.$$controller = controller;
if (op.type)
model[op.type](op.name, EMPTYOBJECT, callback);
else
model[op.name2](EMPTYOBJECT, callback);
} else {
if (op.type)
meta.schema[op.type2 + '2'](op.name, EMPTYOBJECT, callback, controller);
else
meta.schema[op.name](EMPTYOBJECT, callback, controller);
}
}
}
// type, schema, model, options, callback, controller
function performschema(type, schema, model, options, callback, controller, novalidate) {
if (typeof(options) === 'function') {
novalidate = controller;
controller = callback;
callback = options;
options = null;
}
var o = framework_builders.getschema(schema);
if (!o) {
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return false;
}
var workflow = {};
workflow[type.substring(1)] = 1;
var req = controller ? controller.req : null;
var keys;
if (type === '$patch') {
keys = Object.keys(model);
if (req)
req.$patch = true;
else
req = { $patch: true };
}
o.make(model, null, function(err, model) {
if (err) {
callback && callback(err);
} else {
model.$$keys = keys;
model.$$controller = controller;
model[type](options, callback);
if (req && req.$patch && req.method && (req.method !== 'PATCH' & req.method !== 'DELETE'))
delete req.$patch;
}
}, null, novalidate, workflow, req);
return !!o;
}
global.$ASYNC = function(schema, callback, index, controller) {
if (index && typeof(index) === 'object') {
controller = index;
index = undefined;
}
var o = framework_builders.getschema(schema).default();
if (!o) {
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return EMPTYOBJECT;
}
controller && (o.$$controller = controller);
return o.$async(callback, index);
};
global.$OPERATION = function(schema, name, options, callback, controller) {
var o = framework_builders.getschema(schema);
if (o)
o.operation2(name, options, callback, controller);
else
callback && callback(new Error('Schema "{0}" not found.'.format(getSchemaName(schema))));
return !!o;
};
global.DB = global.DATABASE = function(a, b, c, d) {
return typeof(F.database) === 'object' ? F.database : F.database(a, b, c, d);
};
global.OFF = function() {
return arguments.length > 1 ? F.removeListener.apply(F, arguments) : F.removeAllListeners.apply(F, arguments);
};
global.NEWSCHEMA = function(group, name, make) {
if (typeof(name) === 'function') {
make = name;
name = undefined;
}
if (!name) {
var arr = group.split('/');
if (arr.length === 2) {
name = arr[1];
group = arr[0];
} else {
name = group;
group = 'default';
}
}
var schema = framework_builders.newschema(group, name);
make && make.call(schema, schema);
return schema;
};
global.CLEANUP = function(stream, callback) {
FINISHED(stream, function() {
DESTROY(stream);
if (callback) {
callback();
callback = null;
}
});
};
global.SUCCESS = function(success, value) {
if (typeof(success) === 'function') {
return function(err, value) {
success(err, SUCCESS(err, value));
};
}
var err;
if (success instanceof Error) {
err = success.toString();
success = false;
} else if (success instanceof framework_builders.ErrorBuilder) {
if (success.hasError()) {
err = success.output();
success = false;
} else
success = true;
} else if (success == null)
success = true;
SUCCESSHELPER.success = !!success;
SUCCESSHELPER.value = value === SUCCESSHELPER ? value.value : value == null ? undefined : (value && value.$$schema ? value.$clean() : value);
SUCCESSHELPER.error = err ? err : undefined;
return SUCCESSHELPER;
};
global.TRY = function(fn, err) {
try {
fn();
return true;
} catch (e) {
err && err(e);
return false;
}
};
global.OBSOLETE = function(name, message) {
if (F.config.nowarnings)
return;
console.log(NOW.format('yyyy-MM-dd HH:mm:ss') + ' :: OBSOLETE / IMPORTANT ---> "' + name + '"', message);
if (global.F)
F.stats.other.obsolete++;
};
global.DEBUG = false;
global.TEST = false;
global.RELEASE = false;
global.is_client = false;
global.is_server = true;
var directory = U.$normalize(require.main ? Path.dirname(require.main.filename) : process.cwd());
// F.service() changes the values below:
var DATE_EXPIRES = new Date().add('y', 1).toUTCString();
const _randomstring = 'abcdefghijklmnoprstuwxy'.split('');
function random2string() {
return _randomstring[(Math.random() * _randomstring.length) >> 0] + _randomstring[(Math.random() * _randomstring.length) >> 0];
}
const WEBSOCKET_COMPRESS = Buffer.from([0x00, 0x00, 0xFF, 0xFF]);
const WEBSOCKET_COMPRESS_OPTIONS = { windowBits: Zlib.Z_DEFAULT_WINDOWBITS };
const UIDGENERATOR = { types: {}, typesnumber: {} };
function UIDGENERATOR_REFRESH() {
var ticks = NOW.getTime();
var dt = Math.round(((ticks - 1580511600000) / 1000 / 60));
UIDGENERATOR.date = dt + '';
UIDGENERATOR.date16 = dt.toString(16);
var seconds = ((NOW.getSeconds() / 60) + '').substring(2, 4);
UIDGENERATOR.datenumber = +((((ticks - 1580511600000) / 1000 / 60) >> 0) + seconds); // 1580511600000 means 1.1.2020
UIDGENERATOR.indexnumber = 1;
UIDGENERATOR.index = 1;
UIDGENERATOR.instance = random2string();
var keys;
if (UIDGENERATOR.multiple) {
keys = Object.keys(UIDGENERATOR.types);
for (var i = 0; i < keys.length; i++)
UIDGENERATOR.types[keys[i]] = 0;
}
if (UIDGENERATOR.multiplenumber) {
keys = Object.keys(UIDGENERATOR.typesnumber);
for (var i = 0; i < keys.length; i++)
UIDGENERATOR.typesnumber[keys[i]] = 0;
}
}
UIDGENERATOR_REFRESH();
const EMPTYBUFFER = Buffer.alloc(0);
global.EMPTYBUFFER = EMPTYBUFFER;
const controller_error_status = function(controller, status, problem) {
if (status !== 500 && problem)
controller.problem(problem);
if (controller.res.success || controller.res.headersSent || !controller.isConnected)
return controller;
controller.precache && controller.precache(null, null, null);
controller.req.path = EMPTYARRAY;
controller.req.$total_success();
controller.req.$total_route = F.lookup(controller.req, '#' + status, EMPTYARRAY, 0);
controller.req.$total_exception = problem;
controller.req.$total_execute(status, true);
return controller;
};
var PERF = {};
function Framework() {
var self = this;
self.$id = null; // F.id ==> property
self.version = 3413;
self.version_header = '3.4.13';
self.version_node = process.version.toString();
self.syshash = (__dirname + '-' + Os.hostname() + '-' + Os.platform() + '-' + Os.arch() + '-' + Os.release() + '-' + Os.tmpdir() + JSON.stringify(process.versions)).md5();
self.pref = global.PREF;
global.CONF = self.config = {
debug: true,
trace: true,
trace_console: true,
//nowarnings: process.argv.indexOf('restart') !== -1,
nowarnings: true,
name: 'Total.js',
version: '1.0.0',
author: '',
secret: self.syshash,
secret_uid: self.syshash.substring(10),
'security.txt': 'Contact: mailto:support@totaljs.com\nContact: https://www.totaljs.com/contact/',
etag_version: '',
directory_src: '/.src/',
directory_bundles: '/bundles/',
directory_controllers: '/controllers/',
directory_components: '/components/',
directory_views: '/views/',
directory_definitions: '/definitions/',
directory_temp: '/tmp/',
directory_models: '/models/',
directory_schemas: '/schemas/',
directory_operations: '/operations/',
directory_resources: '/resources/',
directory_public: '/public/',
directory_public_virtual: '/app/',
directory_modules: '/modules/',
directory_source: '/source/',
directory_logs: '/logs/',
directory_tests: '/tests/',
directory_databases: '/databases/',
directory_workers: '/workers/',
directory_packages: '/packages/',
directory_private: '/private/',
directory_isomorphic: '/isomorphic/',
directory_configs: '/configs/',
directory_services: '/services/',
directory_themes: '/themes/',
directory_tasks: '/tasks/',
directory_updates: '/updates/',
// all HTTP static request are routed to directory-public
static_url: '',
static_url_script: '/js/',
static_url_style: '/css/',
static_url_image: '/img/',
static_url_video: '/video/',
static_url_font: '/fonts/',
static_url_download: '/download/',
static_url_components: '/components.',
static_accepts: { flac: true, jpg: true, jpeg: true, png: true, gif: true, ico: true, js: true, mjs: true, css: true, txt: true, xml: true, woff: true, woff2: true, otf: true, ttf: true, eot: true, svg: true, zip: true, rar: true, pdf: true, docx: true, xlsx: true, doc: true, xls: true, html: true, htm: true, appcache: true, manifest: true, map: true, ogv: true, ogg: true, mp4: true, mp3: true, webp: true, webm: true, swf: true, package: true, json: true, md: true, m4v: true, jsx: true, heif: true, heic: true, ics: true },
// 'static-accepts-custom': [],
default_crypto_iv: Buffer.from(self.syshash).slice(0, 16),
default_xpoweredby: 'Total.js',
default_layout: 'layout',
default_theme: '',
default_proxy: '',
default_request_maxkeys: 33,
default_request_maxkey: 25,
// default maximum request size / length
// default 10 kB
default_request_maxlength: 10,
default_websocket_maxlength: 2,
default_websocket_encodedecode: true,
default_maxopenfiles: 100,
default_timezone: 'utc',
default_root: '',
default_response_maxage: '11111111',
default_errorbuilder_status: 200,
// Default originators
default_cors: null,
// Seconds (2 minutes)
default_cors_maxage: 120,
// in milliseconds
default_request_timeout: 3000,
default_dependency_timeout: 1500,
default_restbuilder_timeout: 10000,
// otherwise is used ImageMagick (Heroku supports ImageMagick)
// gm = graphicsmagick or im = imagemagick or magick (new version of ImageMagick)
default_image_converter: 'gm', // command-line name
default_image_quality: 93,
default_image_consumption: 0, // disabled because e.g. GM v1.3.32 throws some error about the memory
allow_static_files: true,
allow_gzip: true,
allow_websocket: true,
allow_websocket_compression: true,
allow_compile: true,
allow_compile_script: true,
allow_compile_style: true,
allow_compile_html: true,
allow_localize: true,
allow_stats_snapshot: true,
allow_performance: false,
allow_custom_titles: false,
allow_cache_snapshot: false,
allow_cache_cluster: false,
allow_debug: false,
allow_head: false,
allow_filter_errors: true,
allow_clear_temp: true,
allow_ssc_validation: true,
allow_workers_silent: false,
allow_sessions_unused: '-20 minutes',
allow_reqlimit: 0,
allow_persistent_images: false,
nosql_worker: false,
nosql_inmemory: null, // String Array
nosql_cleaner: 1440,
nosql_logger: true,
logger: false,
// Used in F.service()
// All values are in minutes
default_interval_clear_resources: 20,
default_interval_clear_cache: 10,
default_interval_clear_dnscache: 30,
default_interval_precompile_views: 61,
default_interval_websocket_ping: 3,
default_interval_uptodate: 5,
set ['mail-smtp'] (val) {
CONF['mail_smtp'] = val;
return null;
},
set ['mail-smtp-options'] (val) {
CONF['mail_smtp_options'] = val;
return null;
},
set ['mail-address-reply'] (val) {
CONF['mail_address_reply'] = val;
return null;
},
set ['mail-address-from'] (val) {
CONF['mail_address_from'] = val;
return null;
},
set ['mail-address-copy'] (val) {
CONF['mail_address_copy'] = val;
return null;
}
};
global.REPO = global.G = self.global = {};
global.MAIN = {};
global.TEMP = {};
self.$bundling = true;
self.resources = {};
self.connections = {};
global.FUNC = self.functions = {};
self.themes = {};
self.versions = null;
self.workflows = {};
self.uptodates = null;
self.schedules = {};
self.isDebug = true;
self.isTest = false;
self.isLoaded = false;
self.isWorker = true;
self.isCluster = process.env.PASSENGER_APP_ENV ? false : require('cluster').isWorker;
self.routes = {
sitemap: null,
web: [],
system: {},
files: [],
filesfallback: null,
cors: [],
corsall: false,
websockets: [],
middleware: {},
redirects: {},
resize: {},
request: [],
views: {},
merge: {},
mapping: {},
packages: {},
blocks: {},
proxies: [],
resources: {}
};
self.owners = [];
self.modificators = null;
self.modificators2 = null;
DEF.helpers = self.helpers = {};
self.modules = {};
self.models = {};
self.sources = {};
self.controllers = {};
self.dependencies = {};
self.isomorphic = {};
self.components = { has: false, css: false, js: false, views: {}, instances: {}, version: null, links: '', groups: {}, files: {} };
self.convertors = [];
self.convertors2 = null;
self.tests = [];
self.errors = [];
self.timeouts = [];
self.problems = [];
self.changes = [];
self.server = null;
self.port = 0;
self.ip = '';
DEF.validators = self.validators = {
email: new RegExp('^[a-zA-Z0-9-_.+]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'),
url: /^http(s)?:\/\/[^,{}\\]*$/i,
phone: /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,8}$/im,
zip: /^[0-9a-z\-\s]{3,20}$/i,
uid: /^\d{14,}[a-z]{3}[01]{1}|^\d{9,14}[a-z]{2}[01]{1}a|^\d{4,18}[a-z]{2}\d{1}[01]{1}b|^[0-9a-f]{4,18}[a-z]{2}\d{1}[01]{1}c|^[0-9a-z]{4,18}[a-z]{2}\d{1}[01]{1}d$/
};
self.workers = {};
self.sessions = {};
self.flows = {};
self.databases = {};
self.databasescleaner = {};
self.directory = HEADERS.workers2.cwd = HEADERS.workers.cwd = directory;
self.isLE = Os.endianness ? Os.endianness() === 'LE' : true;
self.isHTTPS = false;
// Fix for workers crash (port in use) when debugging main process with --inspect or --debug
// See: https://github.com/nodejs/node/issues/14325 and https://github.com/nodejs/node/issues/9435
for (var i = 0; i < process.execArgv.length; i++) {
// Setting inspect/debug port to random unused
if ((/inspect|debug/).test(process.execArgv[i])) {
process.execArgv[i] = '--inspect=0';
break;
}
}
HEADERS.workers.execArgv = process.execArgv;
// It's hidden
// self.waits = {};
self.temporary = {
path: {},
shortcache: {},
notfound: {},
processing: {},
range: {},
views: {},
versions: {},
dependencies: {}, // temporary for module dependencies
other: {},
keys: {}, // for crypto keys
internal: {}, // controllers/modules names for the routing
owners: {},
ready: {},
ddos: {},
service: { redirect: 0, request: 0, file: 0, usage: 0 }
};
self.stats = {
error: 0,
performance: {
request: 0,
message: 0,
external: 0,
file: 0,
open: 0,
dbrm: 0,
dbwm: 0,
online: 0,
usage: 0,
mail: 0
},
other: {
websocketPing: 0,
websocketCleaner: 0,
obsolete: 0,
mail: 0
},
request: {
request: 0,
pending: 0,
web: 0,
xhr: 0,
file: 0,
websocket: 0,
get: 0,
options: 0,
head: 0,
post: 0,
put: 0,
patch: 0,
upload: 0,
schema: 0,
operation: 0,
blocked: 0,
'delete': 0,
mobile: 0,
desktop: 0
},
response: {
ddos: 0,
view: 0,
json: 0,
websocket: 0,
timeout: 0,
custom: 0,
binary: 0,
pipe: 0,
file: 0,
image: 0,
destroy: 0,
stream: 0,
streaming: 0,
plain: 0,
empty: 0,
redirect: 0,
forward: 0,
proxy: 0,
notModified: 0,
sse: 0,
errorBuilder: 0,
error400: 0,
error401: 0,
error403: 0,
error404: 0,
error408: 0,
error409: 0,
error431: 0,
error500: 0,
error501: 0,
error503: 0
}
};
// intialize cache
self.cache = new FrameworkCache();
self.path = global.PATH = new FrameworkPath();
self._request_check_redirect = false;
self._request_check_referer = false;
self._request_check_POST = false;
self._request_check_robot = false;
self._request_check_mobile = false;
self._request_check_proxy = false;
self._length_middleware = 0;
self._length_request_middleware = 0;
self._length_files = 0;
self._length_wait = 0;
self._length_themes = 0;
self._length_cors = 0;
self._length_subdomain_web = 0;
self._length_subdomain_websocket = 0;
self._length_convertors = 0;
self.isVirtualDirectory = false;
self.isTheme = false;
self.isWindows = Os.platform().substring(0, 3).toLowerCase() === 'win';
self.$events = {};
self.commands = { reload_preferences: [loadpreferences] };
}
// ======================================================
// PROTOTYPES
// ======================================================
Framework.prototype = {
get datetime() {
return global.NOW;
},
set datetime(val) {
global.NOW = val;
},
get cluster() {
return require('./cluster');
},
get id() {
return F.$id;
},
set id(value) {
CLUSTER_CACHE_SET.ID = value;
CLUSTER_CACHE_REMOVE.ID = value;
CLUSTER_CACHE_REMOVEALL.ID = value;
CLUSTER_CACHE_CLEAR.ID = value;
F.$id = value;
return F.$id;
}
};
var framework = new Framework();
global.framework = global.F = module.exports = framework;
global.CMD = function(key, a, b, c, d) {
if (F.commands[key]) {
for (var i = 0; i < F.commands[key].length; i++)
F.commands[key][i](a, b, c, d);
}
};
F.callback_redirect = function(url) {
this.url = url;
};
F.dir = function(path) {
F.directory = path;
directory = path;
};
F.refresh = function() {
NOW = new Date();
F.$events.clear && EMIT('clear', 'temporary', F.temporary);
F.temporary.path = {};
F.temporary.range = {};
F.temporary.views = {};
F.temporary.other = {};
F.temporary.keys = {};
global.$VIEWCACHE && global.$VIEWCACHE.length && (global.$VIEWCACHE = []);
// Clears command cache
Image.clear();
CONF.allow_debug && F.consoledebug('clear temporary cache');
var keys = Object.keys(F.temporary.internal);
for (var i = 0; i < keys.length; i++)
if (!F.temporary.internal[keys[i]])
delete F.temporary.internal[keys[i]];
F.$events.clear && EMIT('clear', 'resources');
F.resources = {};
CONF.allow_debug && F.consoledebug('clear resources');
F.$events.clear && EMIT('clear', 'dns');
CMD('clear_dnscache');
CONF.allow_debug && F.consoledebug('clear DNS cache');
return F;
};
F.prototypes = function(fn) {
if (!global.framework_nosql)
global.framework_nosql = require('./nosql');
var proto = {};
proto.Chunker = framework_utils.Chunker.prototype;
proto.Controller = Controller.prototype;
proto.Database = framework_nosql.Database.prototype;
proto.DatabaseBinary = framework_nosql.DatabaseBinary.prototype;
proto.DatabaseBuilder = framework_nosql.DatabaseBuilder.prototype;
proto.DatabaseBuilder2 = framework_nosql.DatabaseBuilder2.prototype;
proto.DatabaseCounter = framework_nosql.DatabaseCounter.prototype;
proto.DatabaseStorage = framework_nosql.DatabaseStorage.prototype;
proto.DatabaseTable = framework_nosql.DatabaseTable.prototype;
proto.ErrorBuilder = framework_builders.ErrorBuilder.prototype;
proto.HttpFile = framework_internal.HttpFile.prototype;
proto.HttpRequest = PROTOREQ;
proto.HttpResponse = PROTORES;
proto.Image = framework_image.Image.prototype;
proto.Message = Mail.Message.prototype;
proto.MiddlewareOptions = MiddlewareOptions.prototype;
proto.OperationOptions = framework_builders.OperationOptions.prototype;
proto.Page = framework_builders.Page.prototype;
proto.Pagination = framework_builders.Pagination.prototype;
proto.RESTBuilder = framework_builders.RESTBuilder.prototype;
proto.RESTBuilderResponse = framework_builders.RESTBuilderResponse.prototype;
proto.SchemaBuilder = framework_builders.SchemaBuilder.prototype;
proto.SchemaOptions = framework_builders.SchemaOptions.prototype;
proto.UrlBuilder = framework_builders.UrlBuilder.prototype;
proto.WebSocket = WebSocket.prototype;
proto.WebSocketClient = WebSocketClient.prototype;
proto.AuthOptions = framework_builders.AuthOptions.prototype;
fn.call(proto, proto);
return F;
};
global.ON = F.on = function(name, fn) {
if (name === 'init' || name === 'ready' || name === 'load') {
if (F.isLoaded) {
fn.call(F);
return;
}
} else if (name.indexOf('#') !== -1) {
var arr = name.split('#');
switch (arr[0]) {
case 'middleware':
F.temporary.ready[name] && fn.call(F);
break;
case 'component':
F.temporary.ready[name] && fn.call(F);
break;
case 'model':
F.temporary.ready[name] && fn.call(F, F.models[arr[1]]);
break;
case 'source':
F.temporary.ready[name] && fn.call(F, F.sources[arr[1]]);
break;
case 'package':
case 'module':
F.temporary.ready[name] && fn.call(F, F.modules[arr[1]]);
break;
case 'controller':
F.temporary.ready[name] && fn.call(F, F.controllers[arr[1]]);
break;
}
}
switch (name) {
case 'cache-set':
case 'controller-render-meta':
case 'request-end':
case 'websocket-begin':
case 'websocket-end':
case 'request-begin':
case 'upload-begin':
case 'upload-end':
OBSOLETE(name, 'Name of event has been replaced to "{0}"'.format(name.replace(/-/g, '_')));
break;
case 'cache-expire':
OBSOLETE(name, 'Name of event has been replaced to "cache_expired"');
break;
}
if (isWORKER && name === 'service' && !F.cache.interval)
F.cache.init_timer();
if (F.$events[name])
F.$events[name].push(fn);
else
F.$events[name] = [fn];
return F;
};
global.EMIT = F.emit = function(name, a, b, c, d, e, f, g) {
var evt = F.$events[name];
if (evt) {
var clean = false;
for (var i = 0, length = evt.length; i < length; i++) {
if (evt[i].$once)
clean = true;
evt[i].call(F, a, b, c, d, e, f, g);
}
if (clean) {
evt = evt.remove(n => n.$once);
if (evt.length)
F.$events[name] = evt;
else
F.$events[name] = undefined;
}
}
return F;
};
global.ONCE = F.once = function(name, fn) {
fn.$once = true;
return F.on(name, fn);
};
F.removeListener = function(name, fn) {
var evt = F.$events[name];
if (evt) {
evt = evt.remove(n => n === fn);
if (evt.length)
F.$events[name] = evt;
else
F.$events[name] = undefined;
}
return F;
};
F.removeAllListeners = function(name) {
if (name)
F.$events[name] = undefined;
else
F.$events = {};
return F;
};
/**
* Internal function
* @return {String} Returns current (dependency type and name) owner.
*/
F.$owner = function() {
return _owner;
};
F.isSuccess = function(obj) {
return obj === SUCCESSHELPER;
};
F.convert = function(value, convertor) {
if (convertor) {
if (F.convertors.findIndex('name', value) !== -1) {
if (convertor == null)
F.convertors = F.convertors.remove('name', value);
return false;
}
if (convertor === Number)
convertor = U.parseFloat;
else if (convertor === Boolean)
convertor = U.parseBoolean;
else if (typeof(convertor) === 'string') {
switch (convertor.toLowerCase()) {
case 'json':
convertor = U.parseJSON;
break;
case 'float':
case 'number':
case 'double':
convertor = U.parseFloat;
break;
case 'int':
case 'integer':
convertor = U.parseInt2;
break;
default:
return console.log('Unknown convertor type:', convertor);
}
}
F.convertors.push({ name: value, convertor: convertor });
F._length_convertors = F.convertors.length;
return true;
}
if (value) {
for (var i = 0, length = F.convertors.length; i < length; i++) {
if (value[F.convertors[i].name] != null)
value[F.convertors[i].name] = F.convertors[i].convertor(value[F.convertors[i].name]);
}
}
return value;
};
/**
* Get a controller
* @param {String} name
* @return {Object}
*/
F.controller = function(name) {
return F.controllers[name] || null;
};
/**
* Use configuration
* @param {String} filename
* @return {Framework}
*/
F.useConfig = function(name) {
OBSOLETE('F.useConfig', 'F.useConfig will be moreved in Total.js v4');
return F.$configure_configs(name, true);
};
Mail.use = function(smtp, options, callback) {
if (typeof(options) === 'function') {
callback = options;
options = undefined;
}
Mail.try(smtp, options, function(err) {
if (!err) {
delete F.temporary.mail_settings;
CONF.mail_smtp = smtp;
CONF.mail_smtp_options = options;
}
if (callback)
callback(err);
else if (err)
F.error(err, 'F.useSMTP()', null);
});
};
F.useSMTP = function(smtp, options, callback) {
OBSOLETE('F.useSMTP', 'Use `Mail.use() instead of F.useSMTP()');
Mail.use(smtp, options, callback);
return F;
};
/**
* Sort all routes
* @return {Framework}
*/
F.$routesSort = function(type) {
F.routes.web.sort((a, b) => a.priority > b.priority ? -1 : a.priority < b.priority ? 1 : 0);
F.routes.websockets.sort((a, b) => a.priority > b.priority ? -1 : a.priority < b.priority ? 1 : 0);
var cache = {};
var length = F.routes.web.length;
var url;
for (var i = 0; i < length; i++) {
var route = F.routes.web[i];
var name = F.temporary.internal[route.controller];
if (name)
route.controller = name;
if (!route.isMOBILE || route.isUPLOAD || route.isXHR || route.isJSON || route.isSYSTEM || route.isXML || route.flags.indexOf('get') === -1)
continue;
url = route.url.join