======= 2.2.1 (HOTFIX) - updated: `F.on('exit', function(signal) {})` added a signal code - fixed: Image.stream() ======= 2.2.0 - added: `controller.proxy2(url, [callback], [headers], [timeout])` creates a proxy between current request and new URL - added: `Image.watermark(filename, [x], [y], [width], [height])` creates a watermark - added: hidden hack `res.noCompress = true` disables compilation of `.js` or `.css` - added: `RESTBuilder` for creating REST requests (more in docs) - added: new config item `allow-cache-snapshot` - to prevent cache when the framework is restarted - updated: `SINGLETON(name, [def = {}])` about `def` argument - updated: `debug.js` adds timestamps - updated: `F.redirect()` can contain a relative URL of file - updated: NoSQL embedded parser, dates are parsed as date object - updated: `Pagination.next()`, `Pagination.prev()`, `Pagination.last()` and `Pagination.first()` supports new arguments `.html([link_inner_html], [class_name])` - updated: `F.worker()` supports packages `F.worker('@eshop/myworker-script')` - update: `FrameworkImage` when the instance contains no command then `.minify()` method is performed automatically for preventing of empty response - improved: `@{href(key, value)}` performance - improved: Total Package Manager `$ tpm --help` - improved: FrameworkImage command building - fixed: (critical) NoSQL `nosql.modify()` and problem with updating `undefined` values - fixed: (critical) security with GM and IM --> 10000x thanks for Luis Figueiredo - renamed: `F.onLocate` renamed to __`F.onLocale`__ ======= 2.1.0 - added: `F.sitemap_add(string)` for adding entries to sitemap by Martin Smola - added: SchemaBuilderEntity `schema.addHook(name, fn(error, model, options, callback))` - added: SchemaBuilderEntity `schema.hook(name, model, [helper], callback)` - added: `controller.$hook(name, [helper], callback)` - added: `String.parseInt2()` the method searchs number and converts it to integer - added: `String.parseFloat2()` the method searchs number and converts it to float - added: `@{title2('this content will be added to end of current title')}` - added: `String.parseInt2()` the method searchs number and converts it to integer - added: `String.parseFloat2()` the method searchs number and converts it to float - added: `@{absolute(url, [hostname])}` for importing links with absolute URL by George Okojie Davis - added: `sitemap_replace(name, title, url)` can change sitemap `title` and `url` onetime - added: new JavaScript minificator algorithm because of Douglas Crockford "Good, not Evil" - added: NoSQL supports counter for e.g. views or downloads, etc., more in documentation - added: new routing mechanism `F.mmr(url, action)` for streaming `multipart/x-mixed-replace` types (client-->server) - added: `controller.mmr(filename, [stream], callback)` for streaming `multipart/x-mixed-replace` (server-->client) - added: `setTimeout2(key, fn, timeout)` resets old and creates a new `setTimeout` according to the `key` - added: `clearTimeou2(key)` resets existing timeout - added: `dnscache` into the `controller.pipe()` and `F.responsePipe()` - added: `CREATE([group], name)` the methods create an empty object according to the schema - added: `F.group(flags, fn)` for extending routes (web, websocket, file) flags - added: `Number.prototype.filesize([decimals], [type])` formatting file sizes - added: `binary` importing CSV `-csv` - added: `controller.autodestroy([callback])` only for websocket - updated: `framework.view()`, `controller.view()` and `@{view()}` supports `=theme/viewname` - updated: sitemap routing supports localization - updated: `F.cache.fn(name, fnCache, fnCallback(value, isFromCache))` - added argument `isFromCache` - updated: `F.use(name, url, types, [first])` - `first` (default: `false`) argument adds a new middleware to the beginning of a route middleware - updated: `String.toSearch()` - removes duplicates characters + better performance - updated: `String.decode()` - improves decoding by Tom Spaccialbelli - fixed: (critical) NoSQL views - fixed: (critical) view compilation in release mode (problem with just-in-time rendering) - fixed: (critical) `F.eval()` - fixed: (critical) parsing Date instance as Date instance in SchemaBuilder - fixed: `F.resize()` additional path `~` - fixed: `controller.memorize()` threw a timeout when the action contains some error in the memorize scope - fixed: `F.sitemap()` fixed problem with `me` argument - fixed: SchemaBuilderEntity preparing and validation - fixed: QuickSort algorithm (problem with dates) - fixed: `TRY()` scope - fixed: problem with resources in views - fixed: CSS compressor - fixed: CORS - fixed: problem with SUCCESS() and async schemas - fixed: killing the process - fixed: HTML compressor in views ======= 2.0.1 - added: binary supports webserver `totaljs 8000` starts webserver on 8000 port and the current directory will be a public directory - added: configuration supports new subtype (`env` or `environment`) for binding values from `process.env` - added: `SchemaBuilderEntity.$next(type, [name], helper)` --> adds a new operation (type: `workflow`, `transform`, `operation`, `save`, `read`, `query`, `remove`) to async list as next step - added: `SchemaBuilderEntity.$push(type, [name], helper)` --> adds a new operation (type: `workflow`, `transform`, `operation`, `save`, `read`, `query`, `remove`) to async list as last step - added: `SchemaBuilderEntity.$index(index)` can changed `obj.$async()` index (the index can be string e.g. `+1` or `-1`) - added: `SchemaBuilderEntity.$callback(fn)` can changed `obj.$async()` callback - added: `SchemaBuilderEntity.$repository(name, [value])` can get / set temporary value - added: `SchemaBuilderEntity.$output()` sets the current `callback(value)` as output/result for `obj.$async(function(err, output))` - updated: when the config contains `directory-temp` with empty value then the framework uses system temporary directory - updated: `U.reduce()` supports array - fixed: binary `totaljs`, fixed problem with creating localized texts - fixed: `F.responseFile()` problem with cached filename, extension was broken when the framework reads the file from cache - fixed: preparing values with subtype for array in SchemaBuilder - fixed: generation UID - fixed: problem with uninstalling middleware - fixed: email validation, a problem with e.g. `blabla@somedomain.business` by @VarunBatraIT - improved: view engine rendering - improved: view engine memory consumption ======= 2.0.0 - added: new NoSQL version v4.0.0 is fully optimized for total.js - added: `controller.invalid([status])` creates the ErrorBuilder instance and it responds in the next tick - added: `controller.sitemap_url([id])` returns an URL from the sitemap - added: `controller.sitemap_name([id])` returns a name/title from the sitemap - added: `controller.sitemap_change(id, property, newvalue)` can change a current value in the sitemap - added: `controller.sitemap_navigation([parent], [langauge])` can get list of all items according to the parent - added: `@{sitemap_url([id], [arg1], [arg2], [argN])}` returns an URL from the sitemap - added: `@{sitemap_name([id], [arg1], [arg2], [argN])}` returns a name/title from the sitemap - added: `@{sitemap_change(id, property, newvalue)}` can change a current value in the sitemap - added: `@{sitemap_navigation([parent], [language])` can get list of all items according to the parent - added: `/startup/` all scripts in this directory are executed only one (then are renamed automatically) - added: `F.route()` supports a new flag: `cors` (creates a cors route) and `credentials` (enables cookies for cors) - added: `ErrorBuilder.plain()` returns all errors as a simple string - added: `Array.findItem()` alias to `Array.find()` - added: `Number.async(fn(index, next), callback)` for asynchronous operations - added: `UID()` for generating unique identificators (contains minimum 18 chars) - added: `F.restart()` for restarting app - added: `F.on('restart')` - added: quicksort algorithm for sorting arrays - added: `Array.quicksort(property_name, [asc], [maxlength])` for sorting arrays - added: `String.removeTags()` by @harry-stot - added: F.nosql(name) + NOSQL(name) --> alias for NoSQL embedded database (it can be used with e.g. SQL Agent) - added: modificators can handle `INSTALL('view', ...)` - added: `String.isPhone()` for phone number validation - added: `String.isUID()` for UID() validation - added: `String.isZIP()` - added: `Pagination.html(max, format)` returns `String` - added: `Pagination.json(max, format)` returns `String` - added: new schemabuilder types `Email` (string, maxlength 120), `Phone` (string, maxlength 20), `Zip` (string, maxlength 10), `Capitalize` (string), `Lowerize` (string), `Upperize` (string), `UID` (string, minlength 18, maxlength 20), `Url` (string, maxlength 500), `JSON` (string) - added: `SchemaBuilderEntity.fields` and it contains all field names in array. - added: `Mail.send(smtp, options, messages, [callback])` messages must be array - added: `Mail.send2(messages, [callback])` sends messages according to the framework configuration - added: `Mail.try(smtp, options, callback)` tries to open a SMTP - added: `F.datetime` contains current datetime and each 1 minute is the value increased - added: `F.stats.other.restart` contains a new property with count of restarting - added: `F.config.trace` for enable/disable tracing, `Boolean`, in a debug mode: `true`, release mode: `false` - added: `F.trace(message, [name], [uri], [ip])` - added: `controller.trace(message)` - added: `req.split` contains splitted url - added: `F.touch(url/req)` for clearing internal cache of cached static files (it works only in release mode) - added: `F.path.exists(path, callback(exist, size, isFile))` for check of existing file - added: `U.chunker(name, [max])` creates the chunker (for streaming some items) - added: `F.worker2(name, [args], [callback], [timeout])` - added: `SchemaBuilderEntity.allow('fieldname1', 'fieldnameN')` - allows other keys out of defined fields - added: `global.EMPTYOBJECT` - added: `global.EMPTYARRAY` - added: `global.SINGLETON(name)` returns a singleton object instance - added: `controller.referrer` returns a value from `req.headers['referer']` - added: `controller.author(value)` can change ` returns extension without `.` dot - updated: (IMPORTANT) `F.resize(url, action(image), [flags])` new resize routing - updated: `F.resize()` flags can contain http/https `path` e.g. `F.resize('/img/*.*', (image) => image.minify(), ['https://www.totaljs.com/img/']);` - updated: `U.GUID()` supports better charset by Guy Fraser - updated: `Date.add(number)` supports number increase/decrease in milliseconds - updated: `U.send(name, stream, url, callback, [cookies], [headers], [method], [timeout])` supports cookies and timeout - updated: `U.request()` supports a new flag `< 200` (kB), it means that the method stores a content with maxixmum size 200 kB. - updated: `ErrorBuilder` instance contains a new property `instance.unexpected` when is `instance.push()` a classic Error's instance. - updated: configuration files + resources support types like String, Number, Array, Date, etc. via `key (type) : value` - updated: `F.use(name, [url], [types])` - now supports new attributes `url`, and `types` - fixed: `Websocket.destroy()` - fixed: Too many open files with `F.log()` and `F.logger()` - fixed: `String.isJSON()` the problem with `\n` character - fixed: `FrameworkImage.save()` problem with streams - fixed: `CLEANUP(stream)` method - fixed: `controller.memorize()` problem with `controller.content()` - fixed: `multipart/form-data` parser - fixed: `Array.async()` without arguments - fixed: view inline helpers - fixed: `FrameworkImage.save()` doens't work when it doesn't contain any operation - fixed: Windows paths - fixed: problem with `websocket.destroy()` - fixed: `F.cors()` - fixed: WebSocket initialization (critical) - fixed: Mail sender (problem with ZOHO SMTP) - fixed: `Number.add()` problem with percentage - fixed: `U.isDate()` by Guy Fraser - fixed: `U.parseXML` problem with `CDATA` - fixed: `U.join()` problem with Windows path by Martin Smola - fixed: uploading files (problem with unexpected closed requests) - fixed: `F.assert()` a problem with external URL address - renamed: event `route-add` to `route` - renamed: `F.versionNode` to `F.version_node` - removed: (IMPORTANT) `X-Powered-By` header - removed: `SCHEMA()` - removed: composer from `SchemaBuilderEntity` - removed: rules from `SchemaBuilderEntity` - removed: obsolete code - removed: `controller.async()` - removed: `framework.async()` - removed: `Utils.validate()` - removed: `Utils.isEmail()` - removed: `Utils.isURL()` - removed: `Utils.isValid()` - removed: `Utils.isNullOrEmpty()` - removed: `controller.global` property by Guy Fraser (a problem with referrencing) - removed: `controller.database()`, use `F.database()` - removed: `controller.functions()` - removed: `controller.models()` - improved: Controller initialization by Guy Fraser - improved: SMTP sender - improved: redirecting - improved: Array.orderBy(), added quicksort algorithm - improved: ErrorBuilder - improved: `WebSocket.send()` for JSON communication - improved: code (a lot) - improved: preparing `SchemaBuilderEntity` - improved: performance - improved: a lot of code by Guy Fraser ======= 1.9.7 - added: `F.web()` --> alias to F.route() - added: `F.cors(url, flags, credentials)` - added: `config['default-response-maxage']`, default value `11111111` - added: `U.get(obj, path)` reads a value from `obj` by path - added: `U.set(obj, path, value)` sets a value into `obj` by path - added: (IMPORTANT) `config['default-root']` can replace root relative path - added: `FrameworkImage` --> `instance.make(function(image) {})` - added: `FrameworkImage` supports middleware `FrameworkImage.middleware(extension, fn)` - added: `controller.$get([helper], callback)` or alias `controller.$read([helper], callback)` - schema must be defined in the route - added: `controller.$remove([helper], callback)` - schema must be defined in the route - added: `controller.$save([helper], callback)` - schema must be defined in the route - added: `controller.$query([helper], callback)` - schema must be defined in the route - added: `controller.$transform(name, [helper], callback)` - schema must be defined in the route - added: `controller.$workflow([name, [helper], callback)` - schema must be defined in the route - added: `controller.$operation(name, [helper], callback)` - schema must be defined in the route - added: `controller.$async(callback, [index])` - schema must be defined in the route - added: new `F.route()` flag `binary` (works only with `raw` flag) - added: `U.ls2()` --> returns additional information about files (stat Object); - added: `Pagination` is a global variable - added: `SchemaBuilder.workflow2(name, options, callback)` skips preparing and validation - added: `SchemaBuilder.transform2(name, options, callback)` skips preparing and validation - added: `SchemaBuilder.operation2(name, options, callback)` skips preparing and validation - added: `ErrorBuilder.exception(message)` - adds a new exception message - added: `F.findConnection()` finds a websocket connection - added: `F.findConnections()` finds websocket connections - updated: (IMPORTANT) Array.async([NEW: threadCount (Number)], [callback]) supports `threads` - updated: (IMPORTANT) Array.wait(onItem(item, index), [callback], [threadCount]) supports `threads` - updated: (IMPORTANT) U.streamer(beg, [end], callback) --> supports "end" delimiter - updated: Date.format(format, [resource_name]) supports name of months via `MMM` (short) and `MMMM` (full) - updated: Resources support months e.g. `January : Január` - updated: `F.merge()` supports directories, e.g. `F.merge('app.js', '/js/*.js')` - updated: NoSQL embeddded version - updated: `U.ls()` --> [filter] can be `string` or `RegExp` - updated: `@{meta(title, [description], [keywords], [image])}` and `@{keywords(value)}` keywords can be String Array - updated: `@{section name}` can be used in the view more times - updated: `U.request()` flags supports `number` for timeout and encoding `utf8`, `ascii`, etc. - updated: `F.restfull()` each action support SchemaBuilder - fixed: (IMPORTANT) Expires headers - problem with Russian timezone, reported by [Андрей Владимирович](https://github.com/anddesigner) - fixed: (IMPORTANT) SchemaBuilder validation - fixed: (IMPORTANT) view caching - fixed: (IMPORTANT) U.keywords() - fixed: @{checkbox} value binding - fixed: dynamic views translator caching - fixed: URL search string in `F.redirect()` (doesn't work on local relative address) - fixed: binary / executable for Windows - fixed: SUCCESS() - fixed: Schema Validation is performed after F.onAuthorize(). - fixed: checking of maximum request length - fixed: regexp routing - fixed: F.restrictions.allow() - fixed: `U.request()` and fixed `head` method, callback returns headers when is `head` method used - fixed: Pagination by DusanDragula - fixed: View inline helpers - reported by [Андрей Владимирович](https://github.com/anddesigner) - fixed: `Array.findIndex` - reported by [Liao San-Kai](https://github.com/liaosankai) - fixed: `WebSocket.send()` problem with `[id]` and `[blacklist]` - improved: performance in `Expires Header` ======= 1.9.6 - added: MailMessage.manually() and removes auto-sending mail --> works only with `F.mail()` and `controller.Mail()`. - added: view engine supports now `@{'route-to-static-file.jpg'}` - added: `U.clone(obj, [skip])` - added: `U.parseTheme(path)` --> parses theme name - added: `@{href}` or `@{href(obj)}` or `@{href(key, value)}` --> query string manipulation (more in documentation) - added: `.jsx` content-type - added: `robot` flag into the routing (for search engines) - added: property `req.robot` - added: property `controller.robot` - added: property `controller.mobile` - added: support for default theme name, e.g. `=?/index` (the framework replaces `?` for `default-theme`) - added: String.localeCompare2(value) --> same as localeCompare() but this method works with diacritics - added: F.register(filename); --> the methods registers new e.g. resource (it solves the problem with resources in packages) - updated: (IMPORTANT) controller.isSecure was renamed to controller.secured - updated: (IMPORTANT) req.isSecure was renamed to req.secured - updated: (IMPORTANT) Array.wait(onItem, onCallback, [NEW: threadCount (Number) or removeItemFromArray (Boolean)]) supports `threads` - updated: `F.mail()` supports themes with view nema like this `=default/someview'` - updated: `@{import()}` supports movies and images - updated: `@{import()}` can contain schema name in the path like this `=YOURTHEME/somefile.js` - updated: `F.route('/', '=themeName/viewname')` supports inline themes - updated: `F.resize()` added new options parameter --> `direction` (top, center or bottom) - updated: SUCCESS(), now supports function as first argument and the method returns wrapped function too - fixed: problem with views path (`./some/path/in/hdd/` routed view anywhere) - fixed: static file routing (`@{import()}`, `@{routeScript}`, etc..) - fixed: miss `Sec-WebSocket-Protocol` by Liao San-Kai - fixed: `MailMessage.send()` --> `options` argument is optional - fixed: problem with UTF8 in U.request() by Ivan Marchukov - fixed: WebSocket parser - fixed: WebSocket closing message (problem with UTF8) - fixed: U.getExtension() - fixed: problem with WebSocket `destroy` - fixed: sync2() doesn't work - fixed: problem with themes in controller.memorize() - fixed: problem with timeout in controller.memorize() - fixed: fixed unitialized memory block in `mail` (by ChALkeR) - fixed: problem with static files (directories with extensions) - removed: all `controller.current...()` methods - removed: all `@{current...()}` methods - removed: (IMPORTANT) `framework.fs` - removed: (IMPORTANT) `controller.fs` - improved: (IMPORTANT) SchemaBuilder by Ivan Marchukov - improved: (IMPORTANT) ViewEngine performance about 15% - improved: request cookie parsing ======= 1.9.5 I had to skip v1.9.4 version because of NPM (my mistake). - added: (IMPORTANT) new feature: THEMES - added: `@{theme}` --> return String - added: `F.onTheme` delegate - added: `controller.theme(theme_name)` --> select theme; - added: `config['default-theme']` - added: `U.keywords(content, [forSearch], [alternative(true|false|soundex)], [max_count(200)], [max_length(20)], [min_length(2)]);` - added: `String.prototype.keywords([forSearch], [alternative(true|false|soundex)], [max_count(200)], [max_length(20)], [min_length(2)])` - added: `String.prototype.soundex()` - added: `F.wait(name, [enable])` the server waits for pending task and it responds via 503 status code - added: `U.parseQuery()` and `String.parseQuery()` - added: `U.join(path1, path2, path3)` - added: `U.getName(path)` - added: `F.on('error400')` - added: `F.on('error401')` - added: `F.on('error403')` - added: `F.on('error404')` - added: `F.on('error408')` - added: `F.on('error431')` - updated: (IMPORTANT) F.onAuthorization() was renamed to F.onAuthorize() - updated: `Date.format()` supports `w` and `ww` for week number - updated: `Date.add()` supports `w`, `ww`, `week`, `weeks` - updated: MailMessage supports display name `mail.from('Name ');` - updated: MailMessage supports display name `mail.to('Name ');` - updated: MailMessage supports display name `mail.to(email, [name], [clear]);` - updated: MailMessage supports display name `mail.cc('Name ');` - updated: MailMessage supports display name `mail.cc(email, [name], [clear]);` - updated: U.resolve(url, [callback]) --> `callback` is optional - fixed: HTTP cache for HTML 5 offline manifest files - fixed: async() error handling - fixed: NoSQL embedded paths - fixed: problem with empty SMTP options - fixed: ErrorBuilder default transformation to JSON - fixed: Error handling - fixed: SchemaBuilder request auto-validation - fixed: String.isJSON() - fixed: F.responsePipe() --> problem with transmitted headers - fixed: evaluating of @{helpers.helper_name()} - fixed: HTML minification of UTF8 characters - fixed: U.isEqual() - fixed: FrameworkImage.save() in Windows by LiaoTzukai - fixed: SchemaBuilder prefix by Dušan Dragula - improved performance of the response - improved total performance - improved view engine performance ======= 1.9.3 - added: (IMPORTANT) merging supports BLOCKS (.js,.css), e.g. F.merge('merge.js', 'fileA.js#management,common', 'fileB.js#management') - added: (IMPORTANT) a route with schema binding can contain filter e.g. `*Schema#update` or `*Group/Schema#create` --> the framework validates only fields by filter - added: TRANSFORM([transform], obj) - added: NEWTRANSFORM(name, fn, [isDefault]) --> alias for TransformBuilder.addTransform() - added: packages can be stored as directories (recommended for debug mode only) - added: F.localize(name, url, [middleware], [options], [minify]) --> minify argument - added: email supports calendar (.ics) request sending - added: SchemaBuilderEntity.make(function(schema)) - added: F.install() supports packages mapping - added: Support for unicode routing - added: Packages can be loaded in framework structure (/controllers/, /modules/) `exports.booting = true` - added: route flags can contains object --> the object is an additional options for middleware - added: Utils.btoa(str) --> returns base64 - added: Utils.atob(str) --> returns binary - added: global.TRY(fnScope, [fnError]) --> creates safe scope (more in documentation) - added: Utils.getExtension(filename) - added: @{head} can be imported as @{import('head')} - added: @{meta} can be imported as @{import('meta')} - added: controller.cookie('KEY') --> for reading - added: controller.cookie('KEY', 'VALUE', expire, [options]) --> for writting - added: framework.onParseQuery(function(value)) --> for parsing values from the requests - added: framework.onParseXML(function(value)) --> for parsing values from the requests - added: framework.onParseJSON(function(value)) --> for parsing values from the requests - updated: (IMPORTANT) F.onValidation() was renamed to F.onValidate() - updated: (IMPORTANT) SchemaBuilderEntity.onValidation() was renamed to SchemaBuilderEntity.onValidate() - updated: (IMPORTANT) SchemaBuilderEntity.setValidation() was renamed to SchemaBuilderEntity.setValidate() - updated: CSS compressor removes comments - updated: F.restrictions.allow('IP') --> does not have to be full IP - updated: F.restrictions.disallow('IP') --> does not have to be full IP - updated: String.startsWith() and String.endsWith() according to ES6 but with the backward compatibility - updated: String.parseDate() supports JSON format and classic date serialization - updated: U.request() --> response always returns string - updated: debug.js --> now watchs packages - fixed: framework starting path (fixed problem with PM2 module) - fixed: controller.memorize() - prevention for multiple requests - fixed: routing (POST request without content-type is considered as `application/x-www-form-urlencoded`) - fixed: sync2() - fixed: U.minifyHTML() - now compresses JS and CSS in HTML - fixed: Async.cancel() - fixed: email attachments - fixed: throwing error in global middleware - fixed: Pagination.last() - fixed: CSS auto-vendor-prefixes - fixed: `tpm` binary (bug in creating packages on Windows) - fixed: controller generators - fixed: F.install() --> problem with names via URL import - fixed: F.map() on Windows (problem with paths) - fixed: HTML compression in views - fixed: U.Async() object (problem with waitingFor) - fixed: F.map(), problem in Windows - fixed: CLEANUP(stream, [callback]); - fixed: HTTP CACHE - EXAMPLE (NEW): https://github.com/totaljs/examples/tree/master/blocks ======= 1.9.2 (HOTFIX) - added: support for node +v4.0.0 - updated: F.load(.., ..., [path]) path arguments supports '..' for parent directory - updated: PageBuilder (+added properties: `nextPage`, `prevPage`, `firstPage`, `lastPage`) by [Liao San-Kai](https://github.com/liaosankai) - updated: NoSQL - fixed: U.request() --> `DELETE` method has `application/x-www-form-urlencoded` as default content type - fixed: routing with `delete` flag - fixed: F.worker() - fixed: WebSocket event handlers - fixed: sync2() - fixed: @{place} - fixed: @{section} - fixed: controller.memorize() - problem with different layouts - improve: routing performance with F.onAuthorization() ======= 1.9.1 (HOTFIX) - added: new sitemap system - added: a default schema validator is F.onValidation() - added: ErrorBuilder.setContentType() --> default application/json - added: View engine supports `else if` - added: U.parseBoolean(val, [def]) - added: F.backup(filename, path, [callback], [filter]) --> backup some path to one file - added: F.restore(filename, target, [callback], [filter]) --> restore backup file (but not evaluating) - added: MailMessage supports custom headers `message.headers = { key: 'value' }` - added: @{notranslate} --> disables view translation - added: F.mode('debug') or F.mode('release') --> changes a mode of the framework - added: EACHSCHEMA([group], prepare(group, name, schema)) - updated: MailMessage.bcc(email, [clear]) --> added clear - updated: MailMessage.cc(email, [clear]) --> added clear - updated: MailMessage.reply(email, [clear]) --> added clear - fixed: uploading files - fixed: prevention for mail double callback calling (by Andrea Sessa) - fixed: worker messaging - fixed: problem with schema parser (by Andrea Sessa) - fixed: F.load() --> "versions" is configurable - fixed: "raw" receiving of data - fixed: U.request(), the problem with default method - fixed: F.exists() - problem with URL query string - fixed: framework startup path - fixed: Date.format() - fixed: Assertion Testing ======= 1.9.0 - added: (IMPORTANT) ISOMORPHIC using - added: (IMPORTANT) new flag `mobile` (mobile routing), you can create a route to mobile device - added: (IMPORTANT) new flag `delay` for long time operations (it removes timeout) - added: readonly `req.mobile` -> returns `boolean` - added: new view tag: @{mobile} –> returns `boolean` - added: new view tag: @{isomorphic} –> returns `Object` with isomorphic objects - added: `config['disable-clear-temporary-directory'] = false` (after start) - added: `config['allow-compatibility'] = false` - a backward compatibility mode - added: `config['default-timezone']` - added: `config['directory-isomorphic']` - added: `config['directory-private']` - added: `F.path.private([filename])` - added: `F.path.isomorphic([filename])` - added: `Controller.ping()` for WebSocket - added: `global.DB()` --> same as `global.DATABASE()` - added: `global.isomorphic` --> returns `framework.isomorphic` --> returns isomorphic objects - added: `global.is_client` and `global.is_server` for isomorphic - added: cache for HTTP routing - added: RegExp routing `F.route('/{/^\\d+$/}', ...)` - added: `F.responseBinary(req, res, contentType, buffer, [type], [download], [headers])` - added: `SchemaBuilderEntity.filter(custom, [model], [reverse])` - added: `SchemaBuilderEntity.trim = true`(enable/disable trim strings (default: true)) - added: `Number.prototype.add(value, [decimals])` -> supports percentage - added: `Date.prototype.toUTC([ticksOnly])` - added: `Date.prototype.extend()` -> extend current datetime about new date or time (more in documentation) - added: `F.stats.request.mobile`, `F.stats.request.desktop` - added: `res.setHeader('Vary', 'Accept-Encoding, User-Agent')` for same url addresses and different devices (desktop vs mobile) - added: binary - `total --translatecsv` - added: controller.jsonp(method_name, obj, [headers], [beautify], [replacer]); - added: CSS variables likes sass, example: `$color: red;` - added: CSS nesting - added: modificators for dynamic modification before compilation: views, styles and scripts - added: TransformBuilder - added: F.load(debug, load_types, [path]); - added: F.isWorker (is true when is called F.load()) - added: F.isCluster (is true when the framework is running in the cluster) - added: F.logmail(address, [subject], body, [callback]) --> send e-mail message as plain text - added: Array.unique([property]) by Andrea Sessa - added: Array.pair(array, property, fn(itemA, itemB), [remove]) - pair arrays - added: String.base64ToBuffer(); - added: terminal -> `tpm unpack [package_name] [optional: target_directory]` - added: versions is applied to raw HTML - added: versions supports auto-mapping - added: sync2(), e.g. sync2(fn), diff with v1: sync(fn)() and v2: sync2(fn) - added: "dependencies" file for installing dependencies (modules, packages, etc.) - added: @{nocompress html}, @{nocompress js}, @{nocompress css}, @{nocompress all} - added: req.authorize(callback(err, userprofile, isAuthorized)) - added: res.content(code, body, type, [compress]) -> alias for F.responseContent() - added: F.localize(name, path, [middleware], [options]) - auto translating static files - added: F.listener(req, res) -> for multiple server listeners - added: F.restful(url, flags, onQuery, onGet, onSave, onDelete) -> creates routing - added: F.onSchema(req, group, name, callback(err, body)) -> for custom schemas - added: @{import(filename1, filename2, filenameN)} - added: SchemaBuilderEntity.setError(function(error, model, type, name)); - added: F.snapshot(url, filename, [callback]); - added: CLEANUP(stream, [callback]) - clean up readable streams - added: configs directory - added: F.behaviour(url, flags); - added: behaviour: disable-measuring (default: false) - added: behaviour: disable-middleware (default: false) - updated: (IMPORTANT) routing: `json` flag is not required for receiving incomming data as JSON - updated: `F.mail(address, subject, view, [model], [callback], [language])` added language - updated: `F.view(name, model, [layout], [repository], [language])` added language - updated: `F.route(url, ...)`, `F.websocket(url, ...)` --> URL can be function(url, req, [flags]) - updated: `versions` affects F.map() and F.merge() - updated: `controller.mail(address, subject, view, [model], [callback], [language])` added language - updated: `config['allow-performance']` is set to true - updated: (IMPORTANT) `F.map(url, filename/directory, [filter])` supports mapping directories - updated: (IMPORTANT) arguments order `SchemaBuilderEntity.setValidate(function(name, value, path, model, schema){})` - updated: (IMPORTANT) `U.extend(target, source, [rewrite]);` --> rewrite is by default: __true__ - updated: `SchemaBuilderEntity.setPrepare(function(name, value, index, model){})` --> __model__ is new - updated: `SchemaBuilderEntity.define(name, value, required, [custom])` --> __custom__ is new - updated: HTML compressor - updated: favicon `(removed rel="icon")` - updated: binary `tpm create [package] [directory]` (added argument [package], [directory]) - updated: better handling middleware errors and added prevention of "memory leak" - updated: (IMPORTANT): Websocket ping is set to 3 minutes - updated: framework responds for bad requests with HTTP 403 - updated: Mail (added support for Office365) - updated: Date.prototype.add() supports e.g. Date.prototype.add('25 days') - updated: String.prototype.params() -> supports double "{{" - updated: F.schedule(date, [repeat], fn) --> added [repeat] - updated: `F.responseStream()` and `controller.stream()` added [nocompress] argument - updated: binary `tpm` supports install package from different URL - removed: XSS check - fixed: `controller.binary(buffer, contentType, [download], [headers])` - fixed: routing `DELETE` - fixed: `binary` (creating empty-project, bad record with smtp options) - fixed: calling generator action - fixed: `binary --translate` (filenames) - fixed: SchemaBuilderEntity prepare (problem with nullable Boolean) - fixed: (IMPORTANT) 431 system route - fixed: F.log(), F.logger() –> problem with objects, reported by Nikita Shmidt - fixed: Number formatting (problem with negative numbers) - improved: performance +15% - improved: code optimalization - improved: Date.prototype.format() - improved: String.prototype.format() - improved: Number.prototype.pluralize() - improved: view debugging __IMPORTANT:__ `exports.install = function(framework) {}` framework variable is removed but with backward compatibility (`config['allow-compatibility']`). ======= 1.8.0 source-code: "tabs" instead of "spaces" - added: SchemaBuilderEntity->setPrepare(function(name, value, index)) - added: SchemaBuilderEntity–>setPrefix(prefix) - added: SchemaBuilderEntity->setResource(resourcename) - added: auto-trim strings in SchemaBuilderEntity - added: Controller.route; - added: ErrorBuilder is a global class - added: F.on('upload-begin', function(req, file) {}) - added: F.on('upload-end', function(req, file) {}) - added: config['static-accepts']: woff2 - added: F.logger(filename, arg1, ...), controller.logger(...), @{logger(...)} - added: (IMPORTANT) F.exists(req, res, callback(next, filename)) - added: callback: F.responseFile(), controller.file(), response.file() - added: callback: F.responseImage(), controller.image(), response.image() - added: callback: F.responseImageWithoutCache() - added: callback: F.responseStream(), controller.stream(), response.stream() - added: callback: F.responseStatic(), response.continue() - added: Array.prototype.findIndex(cb, [value]) returns Number - added: Array.prototype.toObject([name]) returns Object - added: Array.prototype.limit(max, fn(items, next), [callback]) - added: Array.prototype.compare(propName, arr, comparer) - added: Image.geometry(w, h, options) - added: Image.thumbnail(w, h, options) - added: Image.filter(type) - added: `config['default-maximum-file-descriptors'] = 0` (0 = the watcher is disabled) - added: `config['default-interval-clear-dnscache'] = 2880` for clearing DNS cache of Utils.request(), Utils.download() - added: Utils.resolve(url, callback(err, uri)) DNS cache - added: Utils.clearDNS() clears DNS cache - added: Utils.isObject() - added: String.prototype.parseJSON() - added: Date.prototype.diff([date], type) - added: framework.onCompileView(name, content, model) - added: framework.on('cache-set', function(name, value, expire)) - added: `@{compile handlerbars}CONTENT TO COMPILE@{end}` - added: `@{compile}CONTENT TO COMPILE@{end}` - added: Utils.streamer(delimiter, function(value, index)) returns function - added: HEAD method support for (controller.json(), .view(), .plain(), .file(), .stream()) - added: global.NEWSCHEMA([group], name) for creating new schemas (more in docs) - added: global.GETSCHEMA([group], name) for getting new schemas (more in docs) - added: global.FINISHED(res/stream, callback) --> real end of the stream - added: global.DESTROY(stream) --> destroys the stream - added: (IMPORTANT) node.js generators for the routes - updated: (IMPORTANT): for evaluation multiple roles in routing (@role) framework validates only one role - updated: GZIP compression for static files (added .md, .json) - updated: request schema parser and XML parser -> better handling errors - updated: wrapped decodeURIComponent for prevention of parsing - updated: removed HTTP cache in DEBUG mode - updated: Image.miniature(w,h,color,[filter]) --> added filter - updated: binary supports translation files `--translate my-localization.txt` - updated: framework.mail() --> returns MailMessage - updated: controller.mail() --> returns MailMessage - updated: SchemaBuilderEntity.$async(callback, [return-only-this-index]) - updated: translation @(#KEY) (direct reading) or @(TEXT TO TRANSLATE) (hash reading) - updated: Utils.request(), Utils.download() supports `dnscache` flag for caching host IP - updated: SchemaBuilderEntity.validation() - updated: F.cache.set(key, value, expire, [sync]) - updated: NoSQL - updated: (IMPORTANT): Websocket ping is disabled by default - fixed: Image.resize() - fixed: F.usage() --> fixed queue pendings - fixed: (CRITICAL) SchemaBuilderEntity preparing (problem with prototypes) - fixed: (CRITICAL) a package or module installation from the URL address - fixed: (CRITICAL) response content-length - fixed: framework.redirect() - fixed: HTTP cache (added longer time) - fixed: auto JSON parsing in `json` request - fixed: Pagination.last() (Nikita Shmidt) - fixed: loading packages - fixed: callback error in MailMessage - fixed: TPM restore package - fixed: Utils.request() --> double calling of callback() - fixed: routing with `get` and `json` flag together - replaced: (IMPORTANT) `uri` to `url` in F.problems, F.changes, F.errors (saves memory) - improved: U.removeDiacritics() -> increase about 30% - improved: handling files - improved: auto-image-resizer (routes) - improved: Image.miniature() -> increase about 50% - improved: U.queue() - improved: (IMPORTANT) SchemaBuilder validation and preparation __GENERATORS__: - added: Image.$$save(filename, [writer]) - added: Image.$$measure(); - added: Image.$$identify(); - added: Utils.$$request(); - added: Utils.$$download(); - added: Utils.$$send(); - added: Utils.$$wait(); - added: Utils.$$resolve(); - added: HttpFile.$$copy() - added: HttpFile.$$read() - added: HttpFile.$$md5() ======= 1.7.2 - added: Array.prototype.extend(obj, [rewrite]) - added: SchemaBuilderEntity->constant(name, [value]) - added: Utils.minifyHTML(value); - added: Utils.minifyScript(value); - added: Utils.minifyStyle(value); - added: FrameworkImage.measureSVG(buffer); - added: auto-parsing SVG width/height - added: framework.translator([language], text); - added: TRANSLATOR - added: SUCCESS(boolean, [value]) returns { success: boolean, value: [value] } - added: framework.onLocate(req, res) --> this method sets the current localization - added: new installation event framework.on('module#name'); - added: new installation event framework.on('controller#name'); - added: new installation event framework.on('model#name'); - added: new installation event framework.on('definition#name'); - added: new installation event framework.on('config#name'); - updated: CSS compressor (better compression) - updated: Utils.Request() supports head method - fixed: binary `total --diff` - fixed: debug.js (fixed port) - fixed: F.onCompileStyle and F.onCompileJavaScript (problem with filename) - fixed: Number.prototype.pluralize() - fixed: WebSocket message parsing - fixed: (CRITICAL) mail sender (problem with CRLF in BASE64) - fixed: (CRITICAL) `../src/node_http_parser.cc, line 392.` - fixed: the framework duplicates width/height in upload auto-parser - fixed: JPG width/height auto-parser ======= 1.7.1 (HOTFIX) This version will work on `io.js` without problems. - added: framework.schedule(date/string/number, fn); - added: (IMPORTANT) a prevention for the HeaderSent exception - added: new option `sleep` for framework.http() & framework.https() - added: request.ip caching - added: framework.useConfig(filename-configuration) - updated: String.toSearch() removes non-word characters - updated: Utils.trim() supports arrays - fixed: framework.versionNode (updated for io.js) - fixed: (CRITICAL) if the controller middleware does not exist framework throws exception correctly - fixed: Utils.validation() (for Arrays) - fixed: authorization routing - fixed: (CRITICAL) request with multipart content-type (+fixed problem XSS) - fixed: (CRITICAL) controller.memorize() in JSON output - fixed: (CRITICAL) uploading files, problem with the filename/name field (if it contained `;`) - removed: mmr ======= 1.7.0 Framework supports a backward compatibility. Framework supports: one file only (all libraries in one JS file) Framework loads modules, packages, models, definitions, controllers - added: SCHEMA(name), returns group of schemas - added: Builders.Schema() - schema supports onGet, onSave, onRemove, onQuery - added: Builders.Schema() - schema supports workflows - added: Builders.Schema() - schema supports composer - added: Builders.Schema() - schema supports transformations - added: Builders.Schema() - schema supports grouping `Builders.schema('group').get('schema_name)` - added: Builders.Schema() - schema supports rules - added: Builders.Schema().make(obj, callback(err, model)) - make object with $save, $remove, $compose, etc. - added: framework.mail() - is alias for controller.mail() - added: framework.view(name, [model], [layout], [repository]) - is alias for controller.view() - added: validate handler contains new parameter model -> (name, value, path, schema, model) - added: String.prototype.replaceAt(index, character) - added: String.prototype.parseXML() - added: String.prototype.toSearch() - added: async queue - Utils.queue(name, maximumCalls, fn) (for e.g. EMFILE, too many open files) - added: Utils.isEqual(obj1, obj2, [properties]) - added: ErrorBuilder.prototype.push() - added: ErrorBuilder.prototype.transform() - added: ErrorBuilder.prototype.output() - added: ErrorBuilder.prototype.setTransform(name) - set default transform - added: ErrorBuilder.addTransform(name, fn, [isDefault]) - add transform - added: ErrorBuilder.setDefaultTransform() for all ErrorBuilders - added: Pagination.addTransform(name, fn, [isDefault]) - add transform - added: Pagination.setDefaultTransform(name) for all Paginations - added: Pagination.prototype.transform() - added: Pagination.prototype.setTransform(name) - set default transform - added: Pagination.prototype.first() - added: Pagination.prototype.last() - added: Pagination.prototype.isFirst - added: Pagination.prototype.isLast - added: framework.config['allow-custom-titles'] - (default: false) - added: new option into Mail: rejectUnauthorized (for TLS) - added: @{log()} and @{LOG()} into views - added: @{console} (.log, .info, etc.) into views - added: framework.on('controller-render-head', function(controller) {}) - added: framework.on('controller-render-meta', function(controller) {}) - added: framework.on('init') - added: framework.merge('/merge.js', '/js/file1.js', '/js/file2.js') - added: framework supports X-Forwarded-Protocol header - added: FrameworkImage supports buffer - added: auto-vendor-prefixes: box-sizing - added: new flag `noxhr` or `-xhr` because all route contains +xhr as default - added: config['default-errorbuilder-resource-name'] - added: config['default-errorbuilder-resource-prefix'] - added: config['allow-handle-static-files'] - added: FrameworkCache.get() alias for FrameworkCache.read() - added: supports creating route without action (framework wraps action) - added: .md (markdown) into static-accepts - added: (modules, models, sources and controllers) exports.id instead of export.name - added: framework.map(url, new_filename) - added: framework.config['directory-packages'] for packages - added: (IMPORTANT) PACKAGES (same as modules but package can contain many files in one file) - added: framework.stats.request.request (requests count) - added: FrameworkImage.miniature(w, h, bgColor) - added: Array.first([def]) - added: Array.last([def]) - added: framework.routing(name) - added: global --> ROUTING(name) - added: global --> NOOP() empty function (exists: noop(), Utils.noop()) - added: global --> DEBUG boolean property (is the framework in debug mode?) - added: global --> RELEASE boolean property (is the framework in release mode?) - added: global --> TEST boolean property (is the framework in test mode?) - added: global --> F object property (is alias for "framework") - added: routing supports schemas `*custom-schema/User` and we can define it in flags - added: String.prototype.parseBool() - added: String.prototype.parseJSON() - added: framework.responseImagePrepare(req, res, fnPrepare, fnProcess, [headers]) - added: response.throw400([problem]) - added: response.throw401([problem]) - added: response.throw403([problem]) - added: response.throw404([problem]) - added: response.throw408([problem]) - added: response.throw431([problem]) - added: response.throw500([error]) - added: response.throw501([problem]) - added: response.redirect(url, [permanent]) - added: view supports localization - added: assertion testing --> framework sets global.assert = require('assert') - added: module/controller supports dependencies --> exports.dependencies = ['moduleA', 'moduleB']; - added: framework.dependencies (this object contains all installed total.js dependencies) - added: controller.translate([text]); - added: framework.translate([language], text) - added: @{body.} instead of @{post.} - added: @{query.} instead of @{get.} - added: @{files} uploaded files - added: .manifest to accept list - added: BINARY added --diff for creating difference between two resources - updated: framework.resize(), added: options.cache (true/false, default: true) - updated: the route flag can contian number (TIMEOUT for current route) - updated: (IMPORTANT) framework doesn't remove subdirectories with files in temporary directory - updated: (IMPORTANT) all models are loaded after is the framework loaded - updated: framework.redirect(url, redirectTo, [permanent]) supports relative redirects - updated: Utils.request(), timeout is possible to add as cookie, headers or encoding - updated: Utils.request() returns EventEmitter (begin, end, data(chunk, percentage)) - updated: Utils.request() supports auto-redirect if response status code is 301 - updated: Utils.download() returns EventEmitter (begin, end, data(chunk, percentage)) - updated: Controller.proxy() - returns EventEmitter (begin, end, data(chunk, percentage)) - updated: Array.wait(fnItem, fnCallback, removeItems) - default: function doesn't remove items - updated: Builders.UrlBuilder() -> toString([skipEmpty]) - updated: Number.format([decimals], [separator], [decimalSeparator]) - updated: Date.format([format]) - format is optional, function returns ISO format without "Z" - updated: response.send(), response.json() - supports ErrorBuilder - updated: framework.error() (returns a wrapped delegate if error is undefined) - updated: controller.baa([message]) - read documentation - updated: Array.where(), Array.find(), Array.remove() - added a new functionality - updated: @{view(name, [model], [expire], [expire-key])} - updated: @{cookie(name)} --> read cookie - updated: framework.mail(address, subject, view, model, callback, replyTo) - added: replyTo - updated: controller.view(name) can execute without name (controller.viewname contains name according to URL) - updated: @{post} is deprecated - updated: @{get} is deprecated - updated: String.encode(), String.decode() - updated: (IMPORTANT) changed the arguments in callback for workflow, compose, transform - updated: BINARY total --translate SOME TEXT create translate identificator - renamed: config['directory-angular'] to config['directory-public-virtual'] - renamed: config['allow-compress-html'] to config['allow-compile-html'] - renamed: (IMPORTANT) default view layout from `_layout` to `layout` - renamed: Utils.parseDateExpire() -> Utils.parseDateExpiration() - removed: JS CSS - removed: (IMPORTANT) view markup for Angular.js from the core (it will be a module) - removed: Controller.fileAsync() - removed: Controller.await() - removed: Controller.wait() - removed: Controller.run() - removed: Controller.complete() - removed: Controller.jsonAsync() - removed: Controller.viewAsync() - removed: Controller.redirectAsync() - removed: framework.run() - fixed: LOG() - fixed: view engine rendering (fixed problem with undefined and null values) - fixed: buffer exceeded if a framework receives a data - fixed: if path starts '/' then is view loaded directly from /views/ directory - fixed: xml parser - fixed: problem with parsing a bad JSON datas - framework.decrypt(); - fixed: String.prototype.parseDate() - fixed: path in framework.resize() - fixed: framework.responseImageWithoutCache() - fixed: appending .js or .css through @{head()} - fixed: WebSocket authorization - fixed: WebSocketClient.req - fixed: routing (+ asterix routing) - fixed: controller.cancel() (after framework.emit('controller', ...)) - fixed: view helpers (calling without arguments) - fixed: dynamic cache of views - fixed: mail sending - fixed: clearing temporary directory - fixed: parse JSON by the JSON route - fixed: paths in Windows - fixed: subject encoding in mail (supports UTF-8) - fixed: sender name encoding in mail (supports UTF-8) - fixed: Utils.trim() - fixed: Utils.validation() (problem with schema array) - fixed: Response.cookie() - fixed: String.prototype.format() --> null/undefined --> returns empty string - fixed: Utils.request() problem with unicode - fixed: framework.assert() problem with unicode - fixed: XML parsing - improvements: routing performance - EXAMPLE (NEW): https://github.com/totaljs/examples/tree/master/static-file-merge - EXAMPLE (NEW): https://github.com/totaljs/examples/tree/master/framework-schema-and-validation ======= 1.6.2 (HOTFIX) - updated: obtaining `req.xhr` before middleware ======= 1.6.1 (HOTFIX) - added: `ErrorBuilder.errors` list of errors - added: transform-style, perspective, backface-visibility into the CSS auto-vendor-prefixes - added: WebSocket supports global middleware - added: WebSocketClient.isWebSocket (for middleware instead of Response) - updated: assertion testing (author: @toshipon) - fixed: controller.callback([view_name]), supports NoSQL Embeded Database - fixed: WebSocket auto-ping - fixed: (debug mode) caching of static files - fixed: global middleware (fixed exception in exception) - fixed: Mail (problem with secure option, author: @asessa) - fixed: binary (if debug.pid exists then is deleted and created again) - improvements: framework (comparison of undefined) ======= 1.6.0 - added: framework.http(mode, [options]) - mode: test, debug or development, release or production - added: framework.https(mode, [options]) - I recommend to use NGINX as HTTPS proxy - added: middleware delegate: function(req, res, next, [options], [controller]) { next(); } - added: middleware to framework.websocket(url, funcInitialize, [flags], [protocols], [allow], [maximumSize], [middleware]) - added: middleware to framework.file([name], [fnValidation], [fnExecute], [middleware]) - added: middleware to framework.use(name), this is global middleware - added: middleware can add as flag: '#middleware1', '#middleware2' - added: Response.controller, link to the current controller (if exists) - added: Response.send([code], body, [contentType]) - added: Response.json(obj); - added: Response.file(filename, [downloadName], [headers]) - added: Response.stream(contentType, stream, [downloadName], [headers]) - added: Response.continue(); - added: Response.req (current request) - added: Request.query; - added: Request.body; - added: Request.files; - added: controller.middleware(names, [options], [callback]) - added: controller.body --> is same as Controller.post - added: controller.query --> is same as Controller.get - added: controller.isController (for middleware) - added: controller.json(obj, [beautify], [replacer]) and ErrorBuilder.json([beautify], [replacer]), author: bir - added: utils.wait(fnValid, fnCallback, [timeout(default: 5000 ms)], [interval(default: 500 ms)]) - added: new flag: 'xml' in controller.route() - added: new flag: 'xml' in utils.request() - added: new flag: 'xml' in framework.assert() - added: assertion testing: exports.usage = function() {} for custom results of test - added: assertion testing: exports.disabled = true for disabling current test - added: assertion testing: priority (example: exports.priority = 1) - added: routing supports multiple HTTP-VERBS/METHODS together (author: bir ) - added: routing supports options for middleware, author: bir - added: config-test (new config file) - added: config['default-interval-clear-resources'], default 20 (minutes) - added: config['default-interval-clear-temporary'], default 3 (minutes) - added: config['default-interval-precompile-views'], default 61 (minutes) - added: config['default-interval-websocket-ping'], default 1 (minutes) - added: config['disable-strict-server-certificate-validation'], default true - added: create automatically a ping message for websocket clients - added: global INSTALL(type, name, declaration/url/function, [options], [callback]); - added: global UNINSTALL(type, name, [options]); - added: global CONTROLLER(name); - added: framework.install(type, name, declaration/url/function, [options], [callback]); - added: framework.uninstall(type, name, [options]); - added: framework.on('install', function(type, name) {}); - added: framework.on('uninstall', function(type, name) {}); - added: framework.on('route-add', function(type, route) {}) - added: module/model/source/controller: exports.name = 'name '; - added: module/model/source/controller: exports.version = 'version'; - added: model/source: exports.install = function(framework, options, name) {} - added: module/model/source/controller: exports.uninstall = function(framework, options) {} - added: String.prototype.parseDateExpire() - parse expiration date, example: '1 minute', '1 year' - added: String.parseConfig([default]); - added: framework.fs.create.database() - added: framework.fs.rm.database() - added: controller.isTransfer - added: Date.compare(date) - for instance of date; - added: Date.compare(d1, d2); - added: Controller.date(type, date) - added: Controller.callback([viewName]) - added: HttpFile.type (HttpFile.contentType is deprecated) - added: controller.section(name, [value]); - updated: NoSQL v2.0.8 - updated: String.parseDate('yyyy-MM-dd HH:mm:ss') - time is optional - updated: module: exports.install = function(framework, options) {}; - updated: (IMPORTANT) INCLUDE(name, [options]), SOURCE(name, [options]) –> object - updated: (IMPORTANT) SOURCE(name, [options]), framework.source(name, [options]) –> object - updated: framework.controller(name) - definition was removed (use: framework.install()) - updated: framework.run([http], config, [port], [ip], [options]) - updated: utils.validate(), Builders.validate() –> prepare function (added: schemaName): function(name, value, path, schemaName) - updated: framework.assert() supports "data" as function (for future data) - updated: empty-project - updated: request.signature([key]) - added key param - updated: middleware function to: function(req, res, next) {} - update: expiration supports string (framework.cache, response.cookie), example: '1 minute' - updated: $view(name, model, [expire]), $viewToggle(name, model, [expire]) - added expiration {String} - updated: controller.validate('schema_name', model); - updated: Angular.js version - updated: @{css()} and @{js()} supports multiple values - updated: @{place()} doesn't add `