Skip to content

Commit 5d4afea

Browse files
authored
Merge pull request totaljs#542 from totaljs/v2.8.0
v2.8.0
2 parents 88be857 + f9f578a commit 5d4afea

27 files changed

Lines changed: 2813 additions & 924 deletions

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ language: node_js
22
cache:
33
- npm
44
node_js:
5-
- "4.0"
5+
- "6.11"
66
install:
77
- npm install
88
script:
99
- cd test
10-
- sh run.sh
10+
- bash run.sh

bin/totaljs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function display_help() {
2222
console.log('-clean source : cleans a resource file "-clean source"');
2323
console.log('-minify filename : minifies .js, .css or .html file into filename.min.[extension]');
2424
console.log('-v or -version : Total.js version');
25+
console.log('-install : run "totaljs -install help" to see what can be installed');
2526
console.log('8000 : starts a server');
2627
console.log('');
2728
}
@@ -430,6 +431,54 @@ function main() {
430431
return;
431432
}
432433

434+
if (cmd === '-i' || cmd === '-install') {
435+
436+
var libs = ['jc', 'jc.min', 'jcta', 'jcta.min', 'jctajr', 'jctajr.min', 'ta', 'jr', 'jr.jc'];
437+
var tmp = process.argv[i + 1] || '';
438+
439+
if (tmp === 'help') {
440+
return console.log('Following libs can be installed: jc, jc.min, jcta.min, jctajr.min, ta, jr, jr.jc');
441+
}
442+
443+
if (!tmp || libs.indexOf(tmp) < 0)
444+
return console.log('Unknown library: "' + tmp + '"');
445+
446+
console.log('');
447+
console.log('Installing: ' + tmp);
448+
449+
var url = '';
450+
switch(tmp) {
451+
case 'jc':
452+
url = 'https://rawgit.com/totaljs/jComponent/master/jc.js';
453+
break;
454+
case 'jc.min':
455+
url = 'https://rawgit.com/totaljs/jComponent/master/jc.min.js';
456+
break;
457+
case 'jcta.min':
458+
url = 'https://rawgit.com/totaljs/jComponent/master/jcta.min.js';
459+
break;
460+
case 'jctajr.min':
461+
url = 'https://rawgit.com/totaljs/jComponent/master/jctajr.min.js';
462+
break;
463+
case 'ta':
464+
url = 'https://rawgit.com/totaljs/Tangular/master/Tangular.js';
465+
break;
466+
case 'jr':
467+
url = 'https://rawgit.com/totaljs/jRouting/master/jrouting.js';
468+
break;
469+
case 'jr.jc':
470+
url = 'https://rawgit.com/totaljs/jRouting/master/jrouting.jcomponent.js';
471+
break;
472+
}
473+
474+
U.download(url, [], function callback(err,response) {
475+
var target = fs.createWriteStream(path.join(dir, './' + tmp + '.js'));
476+
response.pipe(target);
477+
console.log('Done!');
478+
});
479+
return;
480+
}
481+
433482
if (cmd === '-minify' || cmd === '-compress' || cmd === '-compile') {
434483
$type = 5;
435484
continue;
@@ -585,7 +634,7 @@ function main() {
585634

586635
fs.writeFileSync('translate.resource', '// Total.js translation file\n// Created: ' + new Date().format('yyyy-MM-dd HH:mm') + '\n' + builder.join('\n'));
587636
console.log('Total.js: the translation was created (' + count + ' texts)');
588-
}, (path, dir) => dir ? (path.endsWith('/node_modules') && path.endsWith('/tmp') && path.endsWith('/.git')) ? false : true : true);
637+
}, (path, dir) => dir ? (path.endsWith('/node_modules') || path.endsWith('/tmp') || path.endsWith('/.git')) ? false : true : true);
589638
return;
590639
}
591640

@@ -671,4 +720,4 @@ function main() {
671720
});
672721
}
673722

674-
main();
723+
main();

builders.js

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
/**
2323
* @module FrameworkBuilders
24-
* @version 2.7.0
24+
* @version 2.8.0
2525
*/
2626

2727
'use strict';
@@ -862,6 +862,9 @@ SchemaBuilderEntity.prototype.save = function(model, options, callback, controll
862862
return;
863863
}
864864

865+
if (model && !controller && model.$$controller)
866+
controller = model.$$controller;
867+
865868
var builder = new ErrorBuilder();
866869
self.resourceName && builder.setResource(self.resourceName);
867870
self.resourcePrefix && builder.setPrefix(self.resourcePrefix);
@@ -1278,11 +1281,12 @@ SchemaBuilderEntity.prototype.default = function() {
12781281
item[property] = [];
12791282
} else {
12801283
var tmp = this.find(type.raw);
1281-
if (!tmp) {
1284+
if (tmp) {
1285+
item[property] = tmp.default();
1286+
} else {
12821287
F.error(new Error('Schema: "' + property + '.' + type.raw + '" not found in "' + this.parent.name + '".'));
12831288
item[property] = null;
1284-
} else
1285-
item[property] = tmp.default();
1289+
}
12861290
}
12871291
break;
12881292
// enum + keyvalue
@@ -1794,6 +1798,9 @@ SchemaBuilderEntity.prototype.hook = function(name, model, options, callback, sk
17941798
return self;
17951799
}
17961800

1801+
if (model && !controller && model.$$controller)
1802+
controller = model.$$controller;
1803+
17971804
var $type = 'hook';
17981805

17991806
if (skip === true) {
@@ -1924,6 +1931,9 @@ SchemaBuilderEntity.prototype.$execute = function(type, name, model, options, ca
19241931
return self;
19251932
}
19261933

1934+
if (model && !controller && model.$$controller)
1935+
controller = model.$$controller;
1936+
19271937
if (skip === true) {
19281938
var builder = new ErrorBuilder();
19291939
self.resourceName && builder.setResource(self.resourceName);
@@ -2056,6 +2066,9 @@ SchemaBuilderEntity.prototype.operation = function(name, model, options, callbac
20562066
self.resourceName && builder.setResource(self.resourceName);
20572067
self.resourcePrefix && builder.setPrefix(self.resourcePrefix);
20582068

2069+
if (model && !controller && model.$$controller)
2070+
controller = model.$$controller;
2071+
20592072
if (!isGenerator(self, 'operation.' + name, operation)) {
20602073
if (operation.$newversion) {
20612074
operation.call(self, new SchemaOptions(builder, model, options, function(res) {
@@ -2265,7 +2278,7 @@ SchemaInstance.prototype.$push = function(type, name, helper, first) {
22652278
var self = this;
22662279
var fn;
22672280

2268-
if (type === 'save' || type === 'remove') {
2281+
if (type === 'save') {
22692282

22702283
helper = name;
22712284
name = undefined;
@@ -2282,7 +2295,7 @@ SchemaInstance.prototype.$push = function(type, name, helper, first) {
22822295
}, self.$$controller);
22832296
};
22842297

2285-
} else if (type === 'query' || type === 'get' || type === 'read') {
2298+
} else if (type === 'query' || type === 'get' || type === 'read' || type === 'remove') {
22862299

22872300
helper = name;
22882301
name = undefined;
@@ -2300,7 +2313,6 @@ SchemaInstance.prototype.$push = function(type, name, helper, first) {
23002313
};
23012314

23022315
} else {
2303-
23042316
fn = function(next) {
23052317
self.$$schema[type](name, self, helper, function(err, result) {
23062318
self.$$result && self.$$result.push(err ? null : copy(result));
@@ -2312,7 +2324,6 @@ SchemaInstance.prototype.$push = function(type, name, helper, first) {
23122324
self.$$callback = null;
23132325
}, self.$$controller);
23142326
};
2315-
23162327
}
23172328

23182329
if (first)
@@ -2339,7 +2350,7 @@ SchemaInstance.prototype.$exec = function(name, helper, callback) {
23392350
var workflow = F.workflows[key + '#' + name] || F.workflows[name];
23402351

23412352
if (workflow)
2342-
workflow(this, helper || EMPTYOBJECT, callback || NOOP);
2353+
workflow(this, helper, callback || NOOP);
23432354
else
23442355
callback && callback(new ErrorBuilder().push('Workflow "' + name + '" not found in workflows.'));
23452356

@@ -2360,12 +2371,10 @@ SchemaInstance.prototype.$save = function(helper, callback) {
23602371
};
23612372

23622373
SchemaInstance.prototype.$query = function(helper, callback) {
2363-
23642374
if (this.$$can && this.$$async)
23652375
this.$push('query', helper);
23662376
else
23672377
this.$$schema.query(this, helper, callback, this.$$controller);
2368-
23692378
return this;
23702379
};
23712380

@@ -2379,7 +2388,7 @@ SchemaInstance.prototype.$read = SchemaInstance.prototype.$get = function(helper
23792388
return this;
23802389
};
23812390

2382-
SchemaInstance.prototype.$remove = function(helper, callback) {
2391+
SchemaInstance.prototype.$delete = SchemaInstance.prototype.$remove = function(helper, callback) {
23832392

23842393
if (this.$$can && this.$$async)
23852394
this.$push('remove', helper);
@@ -2945,15 +2954,18 @@ ErrorBuilder.prototype._transform = function(name) {
29452954
return this.items;
29462955
};
29472956

2948-
ErrorBuilder.prototype.output = function() {
2957+
ErrorBuilder.prototype.output = function(isResponse) {
2958+
29492959
if (!this.transformName)
2950-
return this.json();
2960+
return isResponse ? this.json() : this.items;
2961+
29512962
var current = transforms['error'][this.transformName];
29522963
if (current) {
29532964
this.prepare();
2954-
return current.call(this);
2965+
return current.call(this, isResponse);
29552966
}
2956-
return this.json();
2967+
2968+
return isResponse ? this.json() : this.items;
29572969
};
29582970

29592971
/**
@@ -3847,16 +3859,6 @@ RESTBuilder.prototype.stream = function(callback) {
38473859
return U.download(self.$url, flags, self.$data, callback, self.$cookies, self.$headers, undefined, self.$timeout);
38483860
};
38493861

3850-
RESTBuilder.prototype.file = function(name, filename) {
3851-
var self = this;
3852-
var obj = { name: name, filename: filename };
3853-
if (self.$files)
3854-
self.$files.push(obj);
3855-
else
3856-
self.$files = [obj];
3857-
return self;
3858-
};
3859-
38603862
RESTBuilder.prototype.exec = function(callback) {
38613863

38623864
if (!callback)
@@ -3908,7 +3910,20 @@ RESTBuilder.prototype.exec = function(callback) {
39083910
var type = err ? '' : headers['content-type'] || '';
39093911
var output = new RESTBuilderResponse();
39103912

3911-
output.value = type.indexOf('/xml') === -1 ? response.isJSON() ? JSON.parse(response, jsonparser) : F.onParseQuery(response) : response.parseXML();
3913+
switch (type.toLowerCase()) {
3914+
case 'text/xml':
3915+
output.value = response.parseXML();
3916+
break;
3917+
case 'application/x-www-form-urlencoded':
3918+
output.value = F.onParseQuery(response);
3919+
break;
3920+
case 'application/json':
3921+
output.value = response.parseJSON(true);
3922+
break;
3923+
default:
3924+
output.value = response.isJSON() ? response.parseJSON(true) : null;
3925+
break;
3926+
}
39123927

39133928
if (output.value == null)
39143929
output.value = EMPTYOBJECT;
@@ -4025,10 +4040,6 @@ global.OPERATION = function(name, value, callback, param) {
40254040
}
40264041
};
40274042

4028-
function jsonparser(key, value) {
4029-
return typeof(value) === 'string' && value.isJSONDate() ? new Date(value) : value;
4030-
}
4031-
40324043
// ======================================================
40334044
// EXPORTS
40344045
// ======================================================
@@ -4041,6 +4052,7 @@ exports.Page = Page;
40414052
exports.UrlBuilder = UrlBuilder;
40424053
exports.TransformBuilder = TransformBuilder;
40434054
exports.SchemaOptions = SchemaOptions;
4055+
exports.RESTBuilderResponse = RESTBuilderResponse;
40444056
global.RESTBuilder = RESTBuilder;
40454057
global.RESTBuilderResponse = RESTBuilderResponse;
40464058
global.ErrorBuilder = ErrorBuilder;

changes.txt

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,70 @@
1+
======= 2.8.0
2+
3+
- added: `NOSQL().restore()` restores a database (its package)
4+
- added: Mail options support a new property `xoauth2` (it needs to contain a `BASE64` value) for sending emails via OAuth 2.0 tokens (more in docs)
5+
- added: `F.path.mkdir(path)` creates all directories according to the path
6+
- added: `MailMessage.send2([callback])` sends a message according to the framework configuration
7+
- added: a new filter for NoSQL embedded `DatabaseBuilder.contains(name)`
8+
- added: a new filter for NoSQL embedded `DatabaseBuilder.empty(name)`
9+
- added: (IMPORTANT) NoSQL counter supports daily stats (NoSQL counter files will be upgraded automatically and backwards incompatible)
10+
- added: (IMPORTANT) NoSQL database and counter can read data from URL
11+
- added: NoSQL counter `db.counter.daily_sum([id], callback)` for reading stats
12+
- added: NoSQL counter `db.counter.daily_max([id], callback)` for reading stats
13+
- added: NoSQL counter `db.counter.daily_min([id], callback)` for reading stats
14+
- added: NoSQL counter `db.counter.monthly_sum([id], callback)` for reading stats
15+
- added: NoSQL counter `db.counter.monthly_max([id], callback)` for reading stats
16+
- added: NoSQL counter `db.counter.monthly_min([id], callback)` for reading stats
17+
- added: NoSQL counter `db.counter.yearly_sum([id], callback)` for reading stats
18+
- added: NoSQL counter `db.counter.yearly_max([id], callback)` for reading stats
19+
- added: NoSQL counter `db.counter.yearly_min([id], callback)` for reading stats
20+
- added: NoSQL counter `db.counter.stats_sum(top, [year], [month], [day], callback)` for reading stats
21+
- added: NoSQL counter `db.counter.stats_max(top, [year], [month], [day], callback)` for reading stats
22+
- added: NoSQL counter `db.counter.stats_min(top, [year], [month], [day], callback)` for reading stats
23+
- added: NoSQL counter `db.counter.minimum([id], callback)` for reading stats
24+
- added: NoSQL counter `db.counter.maximum([id], callback)` for reading stats
25+
- added: NoSQL counter `db.counter.min(id, value)` for writing stats
26+
- added: NoSQL counter `db.counter.max(id, value)` for writing stats
27+
- added: NoSQL counter `db.counter.sum(id, value)` for writing stats (alias for `db.counter.hit()`)
28+
- added: NoSQL counter: a new event `stats` when the stats are changed
29+
- added: NoSQL logging in `DatabaseBuilder.log(msg, [user])`
30+
- added: NoSQL backuping documents while they are updating/removing in `DatabaseBuilder.backup([user])`
31+
- added: `CLONE(obj)` alias for `U.clone()`
32+
- added: `GROUP(flags, fn)` alias for `F.group()`
33+
- added: `F.cache.set2()` it creates a persistent cache (persistent items are stored in a file)
34+
- added: new View Engine command `@{'%config'}` which reads a value from config directly
35+
- added: `F.config['allow-filter-errors']` for filtering network unhandled errors
36+
- added: `REDIRECT()` alias for `F.redirect()`
37+
38+
- updated: (IMPORTANT) packages compress/decompress function supports streaming data
39+
- updated: (IMPORTANT) `NOSQL().backup()` !!! was changed !!!!
40+
- updated: `controller.view(name/url, [model], [headers], [partial])` can render a view from URL address
41+
- updated: `F.backup()` argument `path` can contain `String Array` file list
42+
- updated: `controller.viewCompile(body, model, [headers], [partial], [cacheKey])` add a cache key
43+
- updated: `image.command(arg, value, [priority], [escape])` a `priority` argument can be `escape` when it contains `boolean` value
44+
- updated: `U.getExtension()` returns lower-case extensions
45+
- updated: `total.js/debug` watchs `/workflows` file
46+
- updated: file `/workflows` supports custom `options`, more in docs
47+
- updated: `Array.random()` algorithm (+70% faster than older)
48+
- updated: `RESTBuilder.file(name, filetarget, [filename])` can contain `filename` instead of buffer
49+
- updated: `U.streamer(beg, [end], onItem(item, index), [skip], [stream])` added a new argument `stream` for flushing buffer
50+
- updated: `ErrorBuilder.addTransform(name, callback(isResponse))` by adding new argument `isresponse`
51+
- updated: `sorting` (framework + NoSQL embedded), now supports `internationalization`
52+
- updated: `total.js/debugger` by adding a new option `options.watch = ['directory']`
53+
- updated: `U.streamer()` supports "cancelation", just return `false`
54+
- updated: CSS auto-prefixer, added: `repeating-linear-gradient`, `radial-gradient`, `repeating-radial-gradient` and removed `-o` prefix
55+
56+
- fixed: (IMPORTANT) long messages in WebSocket
57+
- fixed: (IMPORTANT) `controller` param in schemas
58+
- fixed: moved executing of `MailMessage.callback()` to better place
59+
- fixed: mail auth when `options.user` and `options.password` are blank
60+
- fixed: JS/CSS/HTML blocks
61+
- fixed: `F.prototypes()`
62+
- fixed: `F.decrypt()` a problem with parsing JSON and date formats
63+
- fided: `debug.js` sometimes was created a problem with output informations
64+
65+
- improved: Date formatting (+50%)
66+
- improved: NoSQL performance (around 60% in some cases)
67+
168
======= 2.7.0
269

370
- added: __IMPORTANT__ new unit-testing mechanism

0 commit comments

Comments
 (0)