nodester 0.4.6 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -289,7 +289,7 @@ module.exports = class QueryLexer {
289
289
  debug('char', char, { token, node: tree.node });
290
290
 
291
291
  // Vertical include:
292
- if (!!previousActive) {
292
+ if (!!previousActive && token.length === 0) {
293
293
  tree.use(previousActive);
294
294
  tree.node.activeParam = PARAM_TOKENS.INCLUDES;
295
295
  token = '';
@@ -42,13 +42,17 @@ function _AST_ModelsTreeNode(node, spacing=0) {
42
42
  ast += `${ spaces }┣ model: ${ node.model }\n`;
43
43
  ast += `${ spaces }┃\n`;
44
44
 
45
+ if (!!node.fields) {
45
46
  ast += `${ spaces }┣ fields (${ node.fields.length }): [\n${ node.fields.map(f => ` • ${ f },\n`) }`;
46
47
  ast += `${ spaces }┃ ]\n`;
47
48
  ast += `${ spaces }┃\n`;
49
+ }
48
50
 
51
+ if (!!node.functions) {
49
52
  ast += `${ spaces }┣ functions (${ node.functions.length }): [\n${ node.functions.map(f => ` • ${ f },\n`) }`;
50
53
  ast += `${ spaces }┃ ]\n`;
51
54
  ast += `${ spaces }┃\n`;
55
+ }
52
56
 
53
57
  ast += `${ spaces }┣ where: ${ JSON.stringify(node.where) }\n`;
54
58
  ast += `${ spaces }┃\n`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodester",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "A versatile REST framework for Node.js",
5
5
  "directories": {
6
6
  "docs": "docs",
@@ -65,6 +65,8 @@
65
65
  "./stacks/markers": "./lib/stacks/MarkersStack.js",
66
66
  "./stacks/middlewares": "./lib/stacks/MiddlewaresStack.js",
67
67
 
68
+ "./tools/nql": "./lib/tools/nql.tool.js",
69
+
68
70
  "./utils/dates": "./lib/utils/dates.js",
69
71
  "./utils/sql": "./lib/utils/sql.util.js",
70
72
  "./utils/strings": "./lib/utils/strings.util.js",
@@ -7,7 +7,7 @@ const {
7
7
  } = require('@jest/globals');
8
8
 
9
9
  // Configs.
10
- const PORT = 8080;
10
+ const PORT = 8100;
11
11
 
12
12
  // Our lib.
13
13
  const Nodester = require('../lib/application');
package/tests/nql.test.js CHANGED
@@ -64,26 +64,30 @@ describe('nodester Query Language', () => {
64
64
  });
65
65
 
66
66
  describe('includes', () => {
67
- const queryStrings = [
67
+ const queryStrings = {
68
68
  // Simple includes.
69
- 'includes=comments&id=7',
70
- // Include with All possible params.
71
- 'includes=comments(id=10&position=4&limit=3&skip=10&order=desc&order_by=index&a=id,content,position)',
72
-
73
- // 2 horizontals
74
- 'includes=comments,users&id=1000',
69
+ 'simple-includes': 'includes=comments&id=7',
70
+ // Include with params.
71
+ 'include-with-params': 'includes=comments(id=10&position=4&limit=3&skip=10&order=desc&order_by=index&a=id,content,position)',
72
+
73
+ // 2 horizontals.
74
+ '2-horizontals': 'includes=comments,users&id=1000',
75
+ // 4 horizontals with subquery.
76
+ '4-horizontals': 'in=categories,replies.users,comments(order_by=position&order=desc),users.avatars',
75
77
 
76
78
  // Horizontals queried.
77
- 'includes=comments(order=desc),users,likes(order=rand),reposts&id=1000',
79
+ 'horizontals-queried': 'includes=comments(order=desc),users,likes(order=rand),reposts&id=1000',
78
80
  // Horizontals queried №2.
79
- 'in=comments(order_by=index&order=asc).users.karma',
81
+ 'horizontals-queried-2': 'in=comments(order_by=index&order=asc).users.karma',
80
82
  // Horizontals queried №3.
81
- 'in=reactions,comments(user_id=gte(4)&skip=10&limit=2).users,likes,reposts',
82
- 'includes=comments(order=rand)&id=7&limit=3&includes=users(a=id,content)',
83
- ];
83
+ 'horizontals-queried-3': 'in=reactions,comments(user_id=gte(4)&skip=10&limit=2).users,likes,reposts',
84
+
85
+ // Separated includes.
86
+ 'separated-includes': 'includes=comments(order=rand)&id=7&limit=3&includes=users(a=id,content)',
87
+ };
84
88
 
85
89
  test('Simple includes', () => {
86
- const lexer = new QueryLexer( queryStrings[0] );
90
+ const lexer = new QueryLexer( queryStrings['simple-includes'] );
87
91
  const result = lexer.query;
88
92
 
89
93
 
@@ -96,7 +100,7 @@ describe('nodester Query Language', () => {
96
100
  });
97
101
 
98
102
  test('Include with all possible params', () => {
99
- const lexer = new QueryLexer( queryStrings[1] );
103
+ const lexer = new QueryLexer( queryStrings['include-with-params'] );
100
104
  const result = lexer.query;
101
105
 
102
106
  const tree = new ModelsTree();
@@ -113,7 +117,7 @@ describe('nodester Query Language', () => {
113
117
  });
114
118
 
115
119
  test('2 horizontals', () => {
116
- const lexer = new QueryLexer( queryStrings[2] );
120
+ const lexer = new QueryLexer( queryStrings['2-horizontals'] );
117
121
  const result = lexer.query;
118
122
 
119
123
 
@@ -126,8 +130,39 @@ describe('nodester Query Language', () => {
126
130
  expect(result).toMatchObject(expected);
127
131
  });
128
132
 
133
+ test('4 horizontals', () => {
134
+ // in=categories,replies.users,comments(order_by=position&order=desc),users.avatars
135
+
136
+ const lexer = new QueryLexer( queryStrings['4-horizontals'] );
137
+ const result = lexer.query;
138
+
139
+
140
+ const tree = new ModelsTree();
141
+ tree.include('categories');
142
+ tree.include('replies');
143
+ tree.include('comments');
144
+ tree.include('users');
145
+
146
+ tree.use('replies');
147
+ tree.include('users');
148
+
149
+ tree.up();
150
+
151
+ tree.use('comments');
152
+ tree.node.order = 'desc';
153
+ tree.node.order_by = 'position';
154
+
155
+ tree.up();
156
+ tree.use('users');
157
+ tree.include('avatars');
158
+
159
+ const expected = tree.root.toObject();
160
+
161
+ expect(result).toMatchObject(expected);
162
+ });
163
+
129
164
  test('Horizontals queried', () => {
130
- const lexer = new QueryLexer( queryStrings[3] );
165
+ const lexer = new QueryLexer( queryStrings['horizontals-queried'] );
131
166
  const result = lexer.query;
132
167
 
133
168
 
@@ -147,7 +182,7 @@ describe('nodester Query Language', () => {
147
182
  });
148
183
 
149
184
  test('Horizontals queried №2', () => {
150
- const lexer = new QueryLexer( queryStrings[4] );
185
+ const lexer = new QueryLexer( queryStrings['horizontals-queried-2'] );
151
186
  const result = lexer.query;
152
187
 
153
188
  const tree = new ModelsTree();
@@ -165,7 +200,7 @@ describe('nodester Query Language', () => {
165
200
  });
166
201
 
167
202
  test('Horizontals queried №3', () => {
168
- const lexer = new QueryLexer( queryStrings[5] );
203
+ const lexer = new QueryLexer( queryStrings['horizontals-queried-3'] );
169
204
  const result = lexer.query;
170
205
 
171
206
  const tree = new ModelsTree();
@@ -192,7 +227,7 @@ describe('nodester Query Language', () => {
192
227
  });
193
228
 
194
229
  test('Separated includes"', () => {
195
- const lexer = new QueryLexer( queryStrings[6] );
230
+ const lexer = new QueryLexer( queryStrings['separated-includes'] );
196
231
  const result = lexer.query;
197
232
 
198
233
  const tree = new ModelsTree();
@@ -1,23 +0,0 @@
1
- const Enum = require('nodester/enum');
2
-
3
-
4
- module.exports = new Enum({
5
- and: Symbol.for('and'),
6
- between: Symbol.for('between'),
7
- contains: Symbol.for('contains'),
8
- eq: Symbol.for('eq'),
9
- ne: Symbol.for('ne'),
10
- gte: Symbol.for('gte'),
11
- gt: Symbol.for('gt'),
12
- lte: Symbol.for('lte'),
13
- lt: Symbol.for('lt'),
14
- not: Symbol.for('not'),
15
- is: Symbol.for('is'),
16
- in: Symbol.for('in'),
17
- notIn: Symbol.for('notIn'),
18
- like: Symbol.for('like'),
19
- notLike: Symbol.for('notLike'),
20
- notBetween: Symbol.for('notBetween'),
21
- or: Symbol.for('or'),
22
- xor: Symbol.for('xor'),
23
- });
@@ -1,38 +0,0 @@
1
- /**
2
- * nodester
3
- * MIT Licensed
4
- */
5
-
6
- 'use strict';
7
-
8
- const {
9
- HTTP_CODE_NOT_FOUND
10
- } = require('nodester/http/codes');
11
-
12
- const { createErrorResponse } = require('nodester/factories/responses/rest');
13
-
14
-
15
- /**
16
- * Initialize `404` middleware.
17
- *
18
- * @param {Object} [options]
19
- *
20
- * @return {Function}
21
- *
22
- * @access public
23
- */
24
- module.exports = function init404Middleware(options={}) {
25
- const context = {
26
- options
27
- }
28
- return handle.bind(context);
29
- }
30
-
31
- function handle(req, res, next) {
32
- const err = new Error('Route not found');
33
-
34
- return createErrorResponse(res, {
35
- error: err,
36
- status: HTTP_CODE_NOT_FOUND
37
- });
38
- }
@@ -1,81 +0,0 @@
1
- /**
2
- * nodester
3
- * MIT Licensed
4
- */
5
-
6
- 'use strict';
7
-
8
- const calculate = require('etag');
9
- const Stream = require('stream');
10
-
11
- // Utils:
12
- const promisify = require('util').promisify;
13
- const fs = require('fs');
14
- const getFileStats = promisify(fs.stat);
15
-
16
-
17
- module.exports = initETagMiddleware;
18
-
19
- /**
20
- * Initialize `etag` middleware.
21
- *
22
- * @param {Object} [options]
23
- * @param {boolean} options.weak
24
- *
25
- * @return {Function}
26
- *
27
- * @access public
28
- */
29
- function initETagMiddleware(options) {
30
- const context = {
31
- options
32
- }
33
- return handle.bind(context);
34
- }
35
-
36
- /**
37
- * Add ETag header field.
38
- */
39
- function handle(req, res, next) {
40
- // console.log('e', req.headers);
41
- return next();
42
- }
43
-
44
- async function _getResponseEntity(res) {
45
- // If body is not defined:
46
- const { body } = res;
47
- if (!body || res.get('etag'))
48
- return;
49
-
50
- // Status code.
51
- const status = res.statusCode / 100 | 0;
52
-
53
- console.log('getResponseEntity', status, { tag: res.get('etag') });
54
-
55
- // 2xx
56
- if (status !== 2)
57
- return;
58
-
59
- if (body instanceof Stream) {
60
- if (!body.path)
61
- return;
62
-
63
- const stats = await getFileStats(body.path);
64
- return stats;
65
- }
66
- else if (typeof body === 'string' || Buffer.isBuffer(body)) {
67
- return body;
68
- }
69
- else {
70
- return JSON.stringify(body);
71
- }
72
- }
73
-
74
- function _setEtag(res, entity, options) {
75
- console.log('setEtag', typeof res, entity);
76
-
77
- if (!entity)
78
- return;
79
-
80
- res.etag = calculate(entity, options);
81
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * nodester
3
- * MIT Licensed
4
- */
5
-
6
- 'use strict';
7
-
8
-
9
- module.exports = function initRenderMiddleware() {
10
- return handle;
11
- }
12
-
13
-
14
- function handle(req, res, next) {
15
- const context = { req, res, next };
16
- res.render = _render.bind(context);
17
- next();
18
- }
19
-
20
-
21
- /**
22
- * Render `view` with the given `options` and optional callback `fn`.
23
- * When a callback function is given a response will _not_ be made
24
- * automatically, otherwise a response of _200_ and _text/html_ is given.
25
- *
26
- * Options:
27
- *
28
- * - `cache` boolean hinting to the engine it should cache
29
- * - `filename` filename of the view being rendered
30
- *
31
- * @alias render
32
- * @access public
33
- */
34
- function _render(view, options, callback) {
35
- const app = this.req.app;
36
- let done = callback;
37
- let opts = options || {};
38
-
39
- const req = this.req;
40
- const res = this.res;
41
- const next = this.next;
42
-
43
- // support callback function as second arg
44
- if (typeof options === 'function') {
45
- done = options;
46
- opts = {};
47
- }
48
-
49
- // merge res.locals
50
- opts._locals = res.locals;
51
-
52
- // default callback to respond
53
- done = done || function (err, str) {
54
- if (err)
55
- return next(err);
56
-
57
- res.send(str);
58
- };
59
-
60
- // render
61
- app.render(view, opts, done);
62
- };
package/tests/ast.js DELETED
@@ -1,18 +0,0 @@
1
- const { ModelsTree } = require('../lib/middlewares/ql/sequelize/interpreter/ModelsTree');
2
- const { AST_ModelsTree } = require('../lib/tools/nql.tool');
3
-
4
- const tree = new ModelsTree();
5
- tree.node.addWhere({ id: ['1000'] });
6
- tree.include('comments').use('comments');
7
- tree.node.order = 'desc';
8
- tree.up();
9
- tree.include('users');
10
- tree.include('likes') && tree.use('likes');
11
- tree.node.order = 'rand';
12
- tree.up();
13
- tree.include('reposts');
14
-
15
- console.debug(
16
- AST_ModelsTree(tree)
17
- );
18
-