nodester 0.2.5 → 0.2.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.
Files changed (64) hide show
  1. package/.eslintrc.js +13 -0
  2. package/Readme.md +12 -4
  3. package/lib/application/index.js +61 -53
  4. package/lib/body/extract.js +10 -10
  5. package/lib/controllers/methods/index.js +29 -14
  6. package/lib/controllers/mixins/index.js +13 -13
  7. package/lib/database/connection.js +78 -17
  8. package/lib/database/migration.js +9 -3
  9. package/lib/errors/CustomError.js +7 -2
  10. package/lib/errors/NodesterError.js +10 -2
  11. package/lib/errors/NodesterQueryError.js +9 -2
  12. package/lib/errors/index.js +2 -2
  13. package/lib/facades/methods/index.js +15 -15
  14. package/lib/facades/mixins/index.js +12 -12
  15. package/lib/factories/responses/html.js +20 -9
  16. package/lib/factories/responses/rest.js +21 -19
  17. package/lib/http/codes/descriptions.js +4 -3
  18. package/lib/http/codes/index.js +3 -2
  19. package/lib/http/codes/symbols.js +3 -2
  20. package/lib/http/request/index.js +20 -250
  21. package/lib/http/request/utils.js +4 -4
  22. package/lib/http/response/headers.js +16 -19
  23. package/lib/http/response/index.js +25 -28
  24. package/lib/http/response/utils.js +7 -6
  25. package/lib/loggers/console.js +3 -4
  26. package/lib/loggers/dev.js +3 -4
  27. package/lib/middlewares/404/index.js +38 -0
  28. package/lib/middlewares/SearchParams/index.js +3 -3
  29. package/lib/middlewares/cookies/index.js +2 -2
  30. package/lib/middlewares/etag/index.js +10 -8
  31. package/lib/middlewares/formidable/index.js +2 -2
  32. package/lib/middlewares/ql/sequelize/index.js +2 -2
  33. package/lib/middlewares/ql/sequelize/interpreter/ModelsTree.js +25 -4
  34. package/lib/middlewares/ql/sequelize/interpreter/QueryLexer.js +30 -18
  35. package/lib/middlewares/render/index.js +3 -3
  36. package/lib/models/associate.js +3 -2
  37. package/lib/models/define.js +37 -18
  38. package/lib/models/mixins.js +9 -9
  39. package/lib/query/traverse.js +40 -32
  40. package/lib/router/handlers.util.js +5 -5
  41. package/lib/router/index.js +84 -70
  42. package/lib/router/markers.js +5 -5
  43. package/lib/router/route.js +18 -19
  44. package/lib/router/routes.util.js +4 -4
  45. package/lib/router/utils.js +2 -2
  46. package/lib/stacks/MarkersStack.js +11 -9
  47. package/lib/stacks/MiddlewaresStack.js +25 -21
  48. package/lib/structures/Enum.js +8 -2
  49. package/lib/structures/Filter.js +31 -29
  50. package/lib/structures/Params.js +3 -3
  51. package/lib/tools/nql.tool.js +10 -2
  52. package/lib/tools/sql.tool.js +19 -2
  53. package/lib/utils/json.util.js +28 -27
  54. package/lib/utils/models.js +3 -2
  55. package/lib/utils/objects.util.js +10 -11
  56. package/lib/utils/path.util.js +9 -3
  57. package/lib/utils/sanitizations.util.js +3 -2
  58. package/lib/utils/types.util.js +11 -4
  59. package/lib/validators/arguments.js +28 -9
  60. package/lib/validators/dates.js +4 -5
  61. package/lib/validators/numbers.js +4 -4
  62. package/package.json +43 -39
  63. package/tests/nql.test.js +20 -7
  64. /package/lib/constants/{Operations.js → Operators.js} +0 -0
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -12,37 +12,39 @@ const { isModel } = require('../utils/models');
12
12
  const { ensure } = require('nodester/validators/arguments');
13
13
 
14
14
 
15
+ /**
16
+ * @class
17
+ * @classdesc NodesterFilter is a set of rules on how to process client's input.
18
+ *
19
+ * @param {Model} model
20
+ * @param {Object} [options]
21
+ * @param {Array} options.attributes
22
+ * @param {Array} options.clauses
23
+ * @param {Object} options.includes
24
+ *
25
+ * @param {Object} options.bounds
26
+ * @param {Object} options.bounds.attributes
27
+ * @param {Object} options.bounds.clauses
28
+ *
29
+ * @param {Object} options.statics
30
+ * @param {Object} options.statics.attributes
31
+ * @param {Object} options.statics.clauses
32
+ *
33
+ * @access public
34
+ */
15
35
  module.exports = class NodesterFilter {
16
36
 
17
- /*
18
- *
19
- * @param {Model} model
20
- * @param {Object} options
21
- * @param {Array} options.fields
22
- * @param {Array} options.clauses
23
- * @param {Object} options.includes
24
- *
25
- * @param {Object} options.bounds
26
- * @param {Object} options.bounds.fields
27
- * @param {Object} options.bounds.clauses
28
- *
29
- * @param {Object} options.statics
30
- * @param {Object} options.statics.attributes
31
- * @param {Object} options.statics.clauses
32
- *
33
- *
34
- */
35
37
  constructor(model=null, options={}) {
36
38
  ensure(options, 'object,required', 'options');
37
39
 
38
40
  this._model = model;
39
41
 
40
- this._fields = [];
42
+ this._attributes = [];
41
43
  this._clauses = [];
42
44
  this._includes = {};
43
45
 
44
46
  this._bounds = {
45
- fields: {},
47
+ attributes: {},
46
48
  clauses: {}
47
49
  }
48
50
 
@@ -53,7 +55,7 @@ module.exports = class NodesterFilter {
53
55
 
54
56
  // If model is present:
55
57
  if (isModel(this.model)) {
56
- this._fields = Object.keys(this.model.tableAttributes);
58
+ this._attributes = Object.keys(this.model.tableAttributes);
57
59
  this._clauses = CLAUSES.asArray;
58
60
 
59
61
  // ...and no 'bounds' and 'statics' are provided,
@@ -67,7 +69,7 @@ module.exports = class NodesterFilter {
67
69
  }
68
70
 
69
71
  const {
70
- fields,
72
+ attributes,
71
73
  clauses,
72
74
  includes,
73
75
  bounds,
@@ -75,9 +77,9 @@ module.exports = class NodesterFilter {
75
77
  } = options;
76
78
 
77
79
 
78
- // If fields are array:
79
- if (Array.isArray(fields)) {
80
- this._fields = fields;
80
+ // If attributes are array:
81
+ if (Array.isArray(attributes)) {
82
+ this._attributes = attributes;
81
83
  }
82
84
 
83
85
  if (Array.isArray(clauses)) {
@@ -124,8 +126,8 @@ module.exports = class NodesterFilter {
124
126
  }
125
127
 
126
128
  // Getters:
127
- get fields() {
128
- return this._fields;
129
+ get attributes() {
130
+ return this._attributes;
129
131
  }
130
132
 
131
133
  get clauses() {
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -21,7 +21,7 @@ module.exports = Params;
21
21
  *
22
22
  * @return {Object} result
23
23
  *
24
- * @api public
24
+ * @access public
25
25
  */
26
26
  function Params(
27
27
  sourceObj={},
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -14,11 +14,19 @@ module.exports = {
14
14
  AST_ModelsTreeNode: _AST_ModelsTreeNode
15
15
  }
16
16
 
17
+ /**
18
+ * @alias AST_ModelsTree
19
+ * @access public
20
+ */
17
21
  function _AST_ModelsTree(modelsTree) {
18
22
  ensure(modelsTree, 'object,required', 'modelsTree');
19
23
  return _AST_ModelsTreeNode(modelsTree.root);
20
24
  }
21
25
 
26
+ /**
27
+ * @alias AST_ModelsTreeNode
28
+ * @access public
29
+ */
22
30
  function _AST_ModelsTreeNode(node, spacing=0) {
23
31
  ensure(node, 'object,required', 'node');
24
32
  ensure(spacing, 'number,required', 'spacing');
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -20,6 +20,10 @@ module.exports = {
20
20
  rawInsert: _rawInsert
21
21
  }
22
22
 
23
+ /**
24
+ * @alias parseSQLFileContents
25
+ * @access private
26
+ */
23
27
  async function _parseSQLFileContents(filePath) {
24
28
  try {
25
29
  const fileContent = await readFile(filePath, 'utf8');
@@ -35,11 +39,20 @@ async function _parseSQLFileContents(filePath) {
35
39
  }
36
40
  }
37
41
 
42
+ /**
43
+ * @alias rawSelect
44
+ * @access private
45
+ */
38
46
  function _rawSelect(db, tableName) {
39
47
  const query = `select * from ${ tableName }`;
40
48
  return db.query(query, { type: QueryTypes.SELECT });
41
49
  }
42
50
 
51
+
52
+ /**
53
+ * @alias rawUpdate
54
+ * @access private
55
+ */
43
56
  function _rawUpdate(db, tableName, where, data) {
44
57
  const dataKeys = Object.keys(data);
45
58
 
@@ -63,6 +76,10 @@ function _rawUpdate(db, tableName, where, data) {
63
76
  });
64
77
  }
65
78
 
79
+ /**
80
+ * @alias rawInsert
81
+ * @access private
82
+ */
66
83
  function _rawInsert(db, tableName, data) {
67
84
  const dataKeys = Object.keys(data);
68
85
  const dataValues = Object.values(data);
@@ -1,49 +1,50 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
+
5
6
  'use strict';
6
7
 
7
8
 
8
9
  exports = module.exports = {
9
- stringify: _stringify
10
+ stringify: _stringify
10
11
  }
11
12
 
12
13
  /**
13
14
  * Stringify JSON, like JSON.stringify, but v8 optimized, with the
14
15
  * ability to escape characters that can trigger HTML sniffing.
15
16
  *
16
- * @param {*} value
17
- * @param {function} replacer
17
+ * @param {any} value
18
+ * @param {Function} replacer
18
19
  * @param {number} spaces
19
20
  * @param {boolean} escape
20
21
  * @returns {string}
21
22
  *
22
23
  * @alias stringify
23
- * @private
24
+ * @access private
24
25
  */
25
26
  function _stringify (value, replacer, spaces, escape) {
26
- // v8 checks arguments.length for optimizing simple call
27
- // https://bugs.chromium.org/p/v8/issues/detail?id=4730
28
- var json = replacer || spaces
29
- ? JSON.stringify(value, replacer, spaces)
30
- : JSON.stringify(value);
27
+ // v8 checks arguments.length for optimizing simple call
28
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4730
29
+ var json = replacer || spaces
30
+ ? JSON.stringify(value, replacer, spaces)
31
+ : JSON.stringify(value);
31
32
 
32
- if (escape && typeof json === 'string') {
33
- json = json.replace(/[<>&]/g, function (c) {
34
- switch (c.charCodeAt(0)) {
35
- case 0x3c:
36
- return '\\u003c'
37
- case 0x3e:
38
- return '\\u003e'
39
- case 0x26:
40
- return '\\u0026'
41
- /* istanbul ignore next: unreachable default */
42
- default:
43
- return c
44
- }
45
- })
46
- }
33
+ if (escape && typeof json === 'string') {
34
+ json = json.replace(/[<>&]/g, function (c) {
35
+ switch (c.charCodeAt(0)) {
36
+ case 0x3c:
37
+ return '\\u003c'
38
+ case 0x3e:
39
+ return '\\u003e'
40
+ case 0x26:
41
+ return '\\u0026'
42
+ /** istanbul ignore next: unreachable default */
43
+ default:
44
+ return c
45
+ }
46
+ })
47
+ }
47
48
 
48
- return json
49
+ return json;
49
50
  }
@@ -1,7 +1,8 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
+
5
6
  'use strict';
6
7
 
7
8
 
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -17,14 +17,13 @@ module.exports = {
17
17
  /**
18
18
  * Copy key-value of target object
19
19
  *
20
- * @param {object} target - Object to copy attributes from
21
- * @param {array} attributes - Array of keys
20
+ * @param {Object} target - Object to copy attributes from
21
+ * @param {Array} attributes - Array of keys
22
22
  *
23
- * @return {object} New object with attributes of target
23
+ * @return {Object} New object with attributes of target
24
24
  *
25
25
  * @alias copyWithCertainAttributes
26
- *
27
- * @api public
26
+ * @access public
28
27
  */
29
28
  function _copyWithCertainAttributes(target={}, attributes=[]) {
30
29
  ensure(target, 'object,required', 'target');
@@ -40,15 +39,15 @@ function _copyWithCertainAttributes(target={}, attributes=[]) {
40
39
  /**
41
40
  * Merge the property descriptors of `src` into `target`
42
41
  *
43
- * @param {object} target - Object to add descriptors to
44
- * @param {object} src - Object to clone descriptors from
42
+ * @param {Object} target - Object to add descriptors to
43
+ * @param {Object} src - Object to clone descriptors from
45
44
  * @param {boolean} [redefine=true] - Redefine `target` properties with `src` properties
46
45
  *
47
- * @return {object} Reference to target
46
+ * @return {Object} Reference to target
48
47
  *
49
48
  * @alias merge
50
49
  *
51
- * @api public
50
+ * @access public
52
51
  */
53
52
  function _merge (target={}, src={}, redefine=true) {
54
53
  ensure(target, 'object,required', 'target');
@@ -1,3 +1,9 @@
1
+ /**
2
+ * nodester
3
+ * MIT Licensed
4
+ */
5
+
6
+ 'use strict';
1
7
 
2
8
  exports = module.exports = {
3
9
  isAbsolute: _isAbsolute
@@ -6,12 +12,12 @@ exports = module.exports = {
6
12
  /**
7
13
  * Check if `path` looks absolute.
8
14
  *
9
- * @param {String} path
15
+ * @param {string} path
10
16
  *
11
- * @return {Boolean}
17
+ * @return {boolean}
12
18
  *
13
- * @api public
14
19
  * @alias isAbsolute
20
+ * @access public
15
21
  */
16
22
  function _isAbsolute(path) {
17
23
  // Unix:
@@ -1,7 +1,8 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
+
5
6
  'use strict';
6
7
 
7
8
 
@@ -1,3 +1,10 @@
1
+ /**
2
+ * nodester
3
+ * MIT Licensed
4
+ */
5
+
6
+ 'use strict';
7
+
1
8
  const objectRegExp = /^\[object (\S+)\]$/;
2
9
 
3
10
 
@@ -12,7 +19,7 @@ module.exports = {
12
19
  /**
13
20
  *
14
21
  * @alias typeOf
15
- * @public
22
+ * @access public
16
23
  */
17
24
  function _typeOf(obj) {
18
25
  const type = typeof obj;
@@ -32,7 +39,7 @@ function _typeOf(obj) {
32
39
  /**
33
40
  *
34
41
  * @alias isAsync
35
- * @public
42
+ * @access public
36
43
  */
37
44
  function _isAsync(fn) {
38
45
  if (!fn) {
@@ -47,7 +54,7 @@ function _isAsync(fn) {
47
54
  /**
48
55
  *
49
56
  * @alias isRegExp
50
- * @public
57
+ * @access public
51
58
  */
52
59
  function _isRegExp(obj) {
53
60
  if (!obj) {
@@ -62,7 +69,7 @@ function _isRegExp(obj) {
62
69
  /**
63
70
  *
64
71
  * @alias isConstructor
65
- * @public
72
+ * @access public
66
73
  */
67
74
  function _isConstructor(fn) {
68
75
  try {
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -10,17 +10,26 @@ module.exports = {
10
10
  ensure: _ensure
11
11
  }
12
12
 
13
- /*
14
- * Validates given argument against rules.
13
+ /**
14
+ * Validates passed argument against passed rules.
15
15
  *
16
- * @param {Any} argument
17
- * @param {String} rules
18
- * @param {String} argumentName
16
+ * @example
17
+ * ensure(value, 'string|array|object,required', 'value');
18
+ *
19
+ * @param {any} argument
20
+ * @param {string} rules
21
+ * @param {string} [argumentName]
19
22
  *
20
- * @api public
21
23
  * @alias ensure
24
+ * @access public
22
25
  */
23
26
  function _ensure(argument, rules, argumentName) {
27
+ if (typeof rules !== 'string') {
28
+ const err = new TypeError(`'rules' is a required argument.`);
29
+ Error.captureStackTrace(err, _ensure);
30
+ throw err;
31
+ }
32
+
24
33
  const name = argumentName ? `'${ argumentName }'` : 'Argument';
25
34
 
26
35
  let rulesArray = rules.split(',');
@@ -57,8 +66,18 @@ function _ensure(argument, rules, argumentName) {
57
66
 
58
67
  let mismatchedTypesCount = 0;
59
68
  for (const type of types) {
60
- if (typeof argument !== type) {
69
+ if (type === 'array') {
70
+ if (Array.isArray(argument) === false) {
71
+ mismatchedTypesCount++;
72
+ continue;
73
+ }
74
+ else {
75
+ return true;
76
+ }
77
+ }
78
+ else if (typeof argument !== type) {
61
79
  mismatchedTypesCount++;
80
+ continue;
62
81
  }
63
82
  }
64
83
 
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -10,12 +10,11 @@ module.exports = {
10
10
  isValidDate: _isValidDate
11
11
  }
12
12
 
13
-
14
13
  /**
15
- * @param {Any} dateToTest
14
+ * @param {any} dateToTest
16
15
  *
17
16
  * @alias isValidDate
18
- * @api public
17
+ * @access public
19
18
  */
20
19
  function _isValidDate(dateToTest) {
21
20
  // If number:
@@ -1,5 +1,5 @@
1
- /*!
2
- * /nodester
1
+ /**
2
+ * nodester
3
3
  * MIT Licensed
4
4
  */
5
5
 
@@ -11,10 +11,10 @@ module.exports = {
11
11
  }
12
12
 
13
13
  /**
14
- * @param {Any} numToTest
14
+ * @param {any} numToTest
15
15
  *
16
16
  * @alias isValidNumber
17
- * @api public
17
+ * @access public
18
18
  */
19
19
  function _isValidNumber(numToTest){
20
20
  return !isNaN(numToTest);
package/package.json CHANGED
@@ -1,7 +1,15 @@
1
1
  {
2
2
  "name": "nodester",
3
- "version": "0.2.5",
3
+ "version": "0.2.8",
4
4
  "description": "A versatile REST framework for Node.js",
5
+ "directories": {
6
+ "docs": "docs",
7
+ "lib": "lib",
8
+ "tests": "tests"
9
+ },
10
+ "source": [
11
+ "lib"
12
+ ],
5
13
  "exports": {
6
14
  ".": "./lib/application/index.js",
7
15
 
@@ -34,6 +42,7 @@
34
42
  "./loggers/console": "./lib/loggers/console.js",
35
43
  "./loggers/dev": "./lib/loggers/dev.js",
36
44
 
45
+ "./middlewares/404": "./lib/middlewares/404/index.js",
37
46
  "./middlewares/cookies": "./lib/middlewares/cookies/index.js",
38
47
  "./middlewares/formidable": "./lib/middlewares/formidable/index.js",
39
48
  "./middlewares/SearchParams": "./lib/middlewares/SearchParams/index.js",
@@ -55,46 +64,12 @@
55
64
  "./utils/sql": "./lib/utils/sql.util.js",
56
65
  "./utils/strings": "./lib/utils/strings.util.js",
57
66
  "./utils/sanitizations": "./lib/utils/sanitizations.util.js",
67
+ "./utils/types": "./lib/utils/types.util.js",
58
68
 
59
69
  "./validators/arguments": "./lib/validators/arguments.js"
60
70
  },
61
- "directories": {
62
- "docs": "docs",
63
- "lib": "lib",
64
- "tests": "tests"
65
- },
66
- "source": [
67
- "lib"
68
- ],
69
- "scripts": {
70
- "test": "jest",
71
- "examples:rest": "node ./examples/rest/index.js"
72
- },
73
- "author": "Mark Khramko <markkhramko@gmail.com>",
74
- "license": "MIT",
75
- "repository": {
76
- "type": "git",
77
- "url": "git+https://github.com/MarkKhramko/nodester.git"
78
- },
79
- "private": false,
80
- "bugs": {
81
- "url": "https://github.com/MarkKhramko/nodester/issues"
82
- },
83
- "homepage": "https://github.com/MarkKhramko/nodester#readme",
84
- "keywords": [
85
- "nodester",
86
- "framework",
87
- "web",
88
- "http",
89
- "rest",
90
- "restful",
91
- "router",
92
- "app",
93
- "api"
94
- ],
95
71
  "dependencies": {
96
72
  "@js-temporal/polyfill": "^0.4.3",
97
- "accepts": "^1.3.8",
98
73
  "body-parser": "^1.20.2",
99
74
  "common-js-file-extensions": "^1.0.4",
100
75
  "cookie": "^0.5.0",
@@ -117,10 +92,39 @@
117
92
  "type-is": "^1.6.18",
118
93
  "vary": "^1.1.2"
119
94
  },
95
+ "devDependencies": {
96
+ "eslint": "^8.55.0",
97
+ "eslint-plugin-jsdoc": "^46.9.0",
98
+ "jest": "^29.4.2"
99
+ },
120
100
  "engines": {
121
101
  "node": ">= 12.17.0"
122
102
  },
123
- "devDependencies": {
124
- "jest": "^29.4.2"
125
- }
103
+ "scripts": {
104
+ "lint": "eslint .",
105
+ "test": "jest",
106
+ "publish": "npm run lint && npm publish"
107
+ },
108
+ "author": "Mark Khramko <markkhramko@gmail.com>",
109
+ "license": "MIT",
110
+ "repository": {
111
+ "type": "git",
112
+ "url": "git+https://github.com/MarkKhramko/nodester.git"
113
+ },
114
+ "private": false,
115
+ "bugs": {
116
+ "url": "https://github.com/MarkKhramko/nodester/issues"
117
+ },
118
+ "homepage": "https://github.com/MarkKhramko/nodester#readme",
119
+ "keywords": [
120
+ "nodester",
121
+ "framework",
122
+ "web",
123
+ "http",
124
+ "rest",
125
+ "restful",
126
+ "router",
127
+ "app",
128
+ "api"
129
+ ]
126
130
  }