nodester 0.1.4 → 0.2.0

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 (63) hide show
  1. package/Readme.md +16 -55
  2. package/lib/application/index.js +174 -63
  3. package/lib/body/extract.js +89 -0
  4. package/lib/constants/Bounds.js +15 -0
  5. package/lib/constants/Clauses.js +13 -0
  6. package/lib/constants/ResponseFormats.js +2 -2
  7. package/lib/controllers/methods/index.js +7 -0
  8. package/lib/controllers/mixins/index.js +36 -36
  9. package/lib/database/connection.js +6 -0
  10. package/lib/database/migration.js +14 -4
  11. package/lib/facades/methods/index.js +16 -16
  12. package/lib/facades/mixins/index.js +67 -13
  13. package/lib/factories/responses/rest.js +25 -13
  14. package/lib/http/codes/descriptions.js +82 -0
  15. package/lib/http/codes/index.js +70 -145
  16. package/lib/http/codes/symbols.js +82 -0
  17. package/lib/http/{request.js → request/index.js} +53 -75
  18. package/lib/http/request/utils.js +27 -0
  19. package/lib/http/response/headers.js +138 -0
  20. package/lib/http/response/index.js +248 -0
  21. package/lib/http/response/utils.js +38 -0
  22. package/lib/middlewares/SearchParams/index.js +25 -0
  23. package/lib/middlewares/cookies/index.js +44 -0
  24. package/lib/middlewares/etag/index.js +32 -15
  25. package/lib/middlewares/formidable/index.js +30 -25
  26. package/lib/middlewares/ql/sequelize/index.js +13 -4
  27. package/lib/middlewares/ql/sequelize/interpreter/QueryLexer.js +4 -3
  28. package/lib/middlewares/render/index.js +62 -0
  29. package/lib/models/associate.js +25 -1
  30. package/lib/models/define.js +26 -19
  31. package/lib/models/mixins.js +8 -1
  32. package/lib/{queries → query}/traverse.js +118 -77
  33. package/lib/router/handlers.util.js +1 -0
  34. package/lib/router/index.js +194 -99
  35. package/lib/router/markers.js +7 -0
  36. package/lib/router/route.js +5 -0
  37. package/lib/router/routes.util.js +16 -14
  38. package/lib/router/utils.js +7 -0
  39. package/lib/stacks/MarkersStack.js +41 -3
  40. package/lib/stacks/MiddlewaresStack.js +200 -0
  41. package/lib/structures/Enum.js +46 -0
  42. package/lib/structures/Filter.js +156 -0
  43. package/lib/structures/Params.js +55 -0
  44. package/lib/tools/sql.tool.js +7 -0
  45. package/lib/utils/objects.util.js +31 -24
  46. package/lib/utils/sanitizations.util.js +10 -4
  47. package/lib/validators/arguments.js +68 -0
  48. package/lib/validators/dates.js +7 -0
  49. package/lib/validators/numbers.js +7 -0
  50. package/package.json +20 -10
  51. package/lib/database/utils.js +0 -19
  52. package/lib/enums/Enum.js +0 -16
  53. package/lib/http/response.js +0 -1074
  54. package/lib/http/utils.js +0 -254
  55. package/lib/params/Params.js +0 -37
  56. package/lib/policies/Role.js +0 -77
  57. package/lib/policies/RoleExtracting.js +0 -97
  58. package/lib/preprocessors/BodyPreprocessor.js +0 -61
  59. package/lib/queries/Colander.js +0 -107
  60. package/lib/queries/NodesterQueryParams.js +0 -145
  61. package/lib/services/includes.service.js +0 -79
  62. package/lib/services/jwt.service.js +0 -147
  63. package/lib/stacks/MiddlewareStack.js +0 -159
@@ -5,11 +5,13 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const MiddlewareStack = require('../stacks/MiddlewareStack');
8
+ const MiddlewaresStack = require('nodester/stacks/middlewares');
9
9
  const Route = require('./route');
10
+
10
11
  // Markers:
11
12
  const MarkersStack = require('../stacks/MarkersStack');
12
13
  const MarkerMethods = require('./markers');
14
+
13
15
  // Utils:
14
16
  const { typeOf } = require('../utils/types.util');
15
17
  const {
@@ -21,7 +23,11 @@ const { parseProviderFileNames } = require('./utils');
21
23
  const Path = require('path');
22
24
  const fs = require('fs');
23
25
  const commonExtensions = require('common-js-file-extensions');
24
- // Debug & console:
26
+
27
+ // Arguments validator.
28
+ const { ensure } = require('../validators/arguments');
29
+
30
+ // Console:
25
31
  const consl = require('nodester/loggers/console');
26
32
  const debug = require('debug')('nodester:router');
27
33
 
@@ -31,11 +37,11 @@ module.exports = class NodesterRouter {
31
37
  /**
32
38
  * Initialize a new `NodesterRouter`.
33
39
  *
34
- * @param {Object} opts
35
- * - {Array} codeFileExtensions
36
- * - {String} controllersPath
37
- * - {Object} controllers
38
- * - {Boolean} finalhandlerEnabled
40
+ * @param {Object} [opts]
41
+ * @param {Array} opts.codeFileExtensions
42
+ * @param {String} opts.controllersPath
43
+ * @param {Object} opts.controllers
44
+ * @param {Boolean} opts.finalhandlerEnabled
39
45
  *
40
46
  * @api public
41
47
  */
@@ -44,7 +50,7 @@ module.exports = class NodesterRouter {
44
50
  this._controllers = new Map();
45
51
 
46
52
  // Reference to middlewares stack.
47
- this._middlewares = new MiddlewareStack({ finalhandlerEnabled: !!opts.finalhandlerEnabled });
53
+ this._middlewares = new MiddlewaresStack({ finalhandlerEnabled: !!opts.finalhandlerEnabled });
48
54
 
49
55
  // Reference to the markers stack.
50
56
  this._markers = new MarkersStack();
@@ -55,9 +61,6 @@ module.exports = class NodesterRouter {
55
61
  this.codeFileExtensions = commonExtensions.code;
56
62
  this.paths = {};
57
63
 
58
- // Indicates whether we can add more middlewares or no.
59
- this.isLocked = false;
60
-
61
64
  // Options:
62
65
  // if "codeFileExtensions" was set:
63
66
  if (!!opts.codeFileExtensions && Array.isArray(opts.codeFileExtensions)) {
@@ -84,10 +87,7 @@ module.exports = class NodesterRouter {
84
87
 
85
88
  // If "controllers" were provided as an Object:
86
89
  if (!!opts.controllers) {
87
- if (typeOf(opts.controllers) !== 'Object') {
88
- const err = new TypeError(`"controllers" must be an Object.`);
89
- throw err;
90
- }
90
+ ensure(opts.controllers, 'object,required', 'opts.controllers');
91
91
 
92
92
  const entities = Object.entities(opts.controllers);
93
93
  for (const [controllerName, controllerDefinition] of entities) {
@@ -115,10 +115,7 @@ module.exports = class NodesterRouter {
115
115
 
116
116
  // If "providers" were provided as an Object:
117
117
  if (!!opts.providers) {
118
- if (typeOf(opts.providers) !== 'Object') {
119
- const err = new TypeError(`"providers" must be an Object.`);
120
- throw err;
121
- }
118
+ ensure(opts.providers, 'object,required', 'opts.providers');
122
119
 
123
120
  const entities = Object.entities(opts.providers);
124
121
  for (const [providerName, providerDefinition] of entities) {
@@ -127,13 +124,38 @@ module.exports = class NodesterRouter {
127
124
  }
128
125
  }
129
126
 
127
+ // Getters:
128
+
129
+ /**
130
+ * @return {MiddlewaresStack}
131
+ *
132
+ * @api public
133
+ */
134
+ get middlewaresStack() {
135
+ return this._middlewares;
136
+ }
137
+
138
+ /**
139
+ * Indicates whether user can add more middlewares or not.
140
+ *
141
+ * @return {Boolean} isLocked
142
+ *
143
+ * @api public
144
+ */
145
+ get isLocked() {
146
+ return this._middlewares.isLocked;
147
+ }
148
+
149
+ // Getters\
130
150
 
131
151
  /*
132
152
  * Adds:
133
- * - (controller) new controller to the stack;
134
- * - (middleware) new middleware to the stack;
135
- * - (marker) new marker to the stack;
136
- * - (route) new route to the stack;
153
+ * - (controller) new Controller to the stack;
154
+ * - (middleware) new Middleware to the stack;
155
+ * - (provider) new Provicer to the stack;
156
+ * - (marker) new Marker to the stack;
157
+ * - (route) new Route to the stack;
158
+ * - (routes) array[Route] to the stack;
137
159
  *
138
160
  * @api public
139
161
  */
@@ -157,21 +179,29 @@ module.exports = class NodesterRouter {
157
179
  *
158
180
  * @api public
159
181
  */
160
- addController(fnOrObject, controllerName=null) {
161
- const controllerType = typeOf(fnOrObject);
162
- const name = controllerName ?? fnOrObject?.name ?? fnOrObject.constructor.name;
182
+ addController(controller, controllerName=null) {
183
+ try {
184
+ ensure(controller, 'object|function,required', 'controller');
163
185
 
164
- // If controller was exported as Object:
165
- if (controllerType === 'Object') {
166
- this._controllers.set(name, fnOrObject);
167
- }
168
- // If controller was exported as a constructor function:
169
- else if (controllerType === 'function') {
170
- this._controllers.set(name, new fnOrObject());
186
+ const controllerType = typeOf(controller);
187
+ const name = controllerName ?? controller?.name ?? controller.constructor.name;
188
+
189
+ // If controller was exported as Object:
190
+ if (controllerType === 'Object') {
191
+ this._controllers.set(name, controller);
192
+ }
193
+ // If controller was exported as a constructor function:
194
+ else if (controllerType === 'function') {
195
+ this._controllers.set(name, new controller());
196
+ }
197
+ else {
198
+ const err = new TypeError(`Please check how you exported '${ name }', it should be either Object or a constructor function.`);
199
+ throw err;
200
+ }
171
201
  }
172
- else {
173
- const err = new TypeError(`Please check how you exported ${ name }, it should be either Object or constructor function.`);
174
- throw err;
202
+ catch(error) {
203
+ Error.captureStackTrace(error, this.addController);
204
+ throw error;
175
205
  }
176
206
  }
177
207
 
@@ -182,12 +212,21 @@ module.exports = class NodesterRouter {
182
212
  * @param {Function} fn
183
213
  * @param {Integer} index (0 or undefined)
184
214
  *
185
- * @return {Integer} index of new middleware
215
+ * @return {Integer} index of the new middleware
186
216
  *
187
217
  * @api public
188
218
  */
189
219
  addMiddleware(fn, index) {
190
- return this._middlewares.add(fn, index);
220
+ try {
221
+ ensure(fn, 'function,required', 'fn');
222
+ ensure(index, 'number', 'index');
223
+
224
+ return this._middlewares.add(fn, index);
225
+ }
226
+ catch(error) {
227
+ Error.captureStackTrace(error, this.addMiddleware);
228
+ throw error;
229
+ }
191
230
  }
192
231
 
193
232
 
@@ -200,17 +239,26 @@ module.exports = class NodesterRouter {
200
239
  * @api public
201
240
  */
202
241
  addMarker(markerName='', fn) {
203
- if (markerName.length > 0 && markerName.indexOf('/') > -1) {
204
- const err = new TypeError(`"markerName" can't contain slashes "/"`);
205
- throw err;
206
- }
242
+ try {
243
+ ensure(markerName, 'string,required', 'markerName');
244
+ ensure(fn, 'function,required', 'fn');
207
245
 
208
- if (this._markers.get(markerName)) {
209
- const err = new Error(`Marker with name ${ markerName } is already set.`);
210
- throw err;
211
- }
246
+ if (markerName.length > 0 && markerName.indexOf('/') > -1) {
247
+ const err = new TypeError(`'markerName' can't contain slashes '/'.`);
248
+ throw err;
249
+ }
212
250
 
213
- this._markers.add(markerName, fn);
251
+ if (this._markers.get(markerName)) {
252
+ const err = new Error(`Marker with a name '${ markerName }' is already set.`);
253
+ throw err;
254
+ }
255
+
256
+ this._markers.add(markerName, fn);
257
+ }
258
+ catch(error) {
259
+ Error.captureStackTrace(error, this.addMarker);
260
+ throw error;
261
+ }
214
262
  }
215
263
 
216
264
 
@@ -222,21 +270,30 @@ module.exports = class NodesterRouter {
222
270
  *
223
271
  * @api public
224
272
  */
225
- addProvider(fnOrObject, providerName=null) {
226
- const providerType = typeOf(fnOrObject);
227
- const name = providerName ?? fnOrObject?.name ?? fnOrObject.constructor.name;
273
+ addProvider(provider, providerName=null) {
274
+ try {
275
+ ensure(provider, 'object|function,required', 'provider');
276
+ ensure(providerName, 'string', 'providerName');
228
277
 
229
- // If provider was exported as Object:
230
- if (providerType === 'Object') {
231
- this._providers.set(name, fnOrObject);
232
- }
233
- // If provider was exported as a constructor function:
234
- else if (providerType === 'function') {
235
- this._providers.set(name, new fnOrObject());
278
+ const providerType = typeOf(provider);
279
+ const name = providerName ?? provider?.name ?? provider.constructor.name;
280
+
281
+ // If provider was exported as Object:
282
+ if (providerType === 'Object') {
283
+ this._providers.set(name, provider);
284
+ }
285
+ // If provider was exported as a constructor function:
286
+ else if (providerType === 'function') {
287
+ this._providers.set(name, new provider());
288
+ }
289
+ else {
290
+ const err = new TypeError(`Please check how you exported ${ name }, it should be either Object or constructor function.`);
291
+ throw err;
292
+ }
236
293
  }
237
- else {
238
- const err = new TypeError(`Please check how you exported ${ name }, it should be either Object or constructor function.`);
239
- throw err;
294
+ catch(error) {
295
+ Error.captureStackTrace(error, this.addProvider);
296
+ throw error;
240
297
  }
241
298
  }
242
299
 
@@ -250,20 +307,29 @@ module.exports = class NodesterRouter {
250
307
  * @api public
251
308
  */
252
309
  addRoute(route='', handler) {
253
- const parsedRoute = new Route(route);
254
- // Will throw exception if not valid.
255
- validateParsedRouteMethood(parsedRoute);
256
-
257
- const handlerType = typeOf(handler);
258
-
259
- if (handlerType === 'Object' && !this.paths.controllers && !this.paths.providers) {
260
- const msg = `Please set "controllersPath" or "providersPath" during Router initialization.`;
261
- const err = new TypeError(msg);
262
- throw err;
263
- }
310
+ try {
311
+ ensure(route, 'string,required', 'route');
312
+ ensure(handler, 'object|function,required', 'handler');
313
+
314
+ const parsedRoute = new Route(route);
315
+ // Will throw exception if not valid.
316
+ validateParsedRouteMethood(parsedRoute);
317
+
318
+ const handlerType = typeOf(handler);
319
+
320
+ if (handlerType === 'Object' && !this.paths.controllers && !this.paths.providers) {
321
+ const msg = `Please set 'controllersPath' or 'providersPath' during Router initialization.`;
322
+ const err = new TypeError(msg);
323
+ throw err;
324
+ }
264
325
 
265
- const wrapped = wrapRouteHandler.call(this, parsedRoute, handler);
266
- return this.addMiddleware(wrapped);
326
+ const wrapped = wrapRouteHandler.call(this, parsedRoute, handler);
327
+ return this.addMiddleware(wrapped);
328
+ }
329
+ catch(error) {
330
+ Error.captureStackTrace(error, this.addRoute);
331
+ throw error;
332
+ }
267
333
  }
268
334
 
269
335
 
@@ -276,8 +342,16 @@ module.exports = class NodesterRouter {
276
342
  * @api public
277
343
  */
278
344
  addRoutes(routes={}) {
279
- for (const [route, handler] of Object.entries(routes)) {
280
- this.addRoute(route, handler);
345
+ try {
346
+ ensure(routes, 'object,required', 'routes');
347
+
348
+ for (const [route, handler] of Object.entries(routes)) {
349
+ this.addRoute(route, handler);
350
+ }
351
+ }
352
+ catch(error) {
353
+ Error.captureStackTrace(error, this.addRoutes);
354
+ throw error;
281
355
  }
282
356
  }
283
357
 
@@ -290,14 +364,22 @@ module.exports = class NodesterRouter {
290
364
  * @api public
291
365
  */
292
366
  use(fnOrRouter) {
293
- let fn = fnOrRouter;
367
+ try {
368
+ ensure(fnOrRouter, 'object|function,required', 'fnOrRouter');
294
369
 
295
- // If Router:
296
- if (fnOrRouter instanceof NodesterRouter) {
297
- fn = fnOrRouter.handle.bind(fnOrRouter);
298
- }
370
+ let fn = fnOrRouter;
299
371
 
300
- return this.add.middleware(fn);
372
+ // If Router:
373
+ if (fnOrRouter instanceof NodesterRouter) {
374
+ fn = fnOrRouter.handle.bind(fnOrRouter);
375
+ }
376
+
377
+ return this.add.middleware(fn);
378
+ }
379
+ catch(error) {
380
+ Error.captureStackTrace(error, this.use);
381
+ throw error;
382
+ }
301
383
  }
302
384
 
303
385
 
@@ -309,12 +391,20 @@ module.exports = class NodesterRouter {
309
391
  * @api public
310
392
  */
311
393
  only(markerName='') {
312
- const self = this;
313
- const markerFn = this._markers.get(markerName);
394
+ try {
395
+ ensure(markerName, 'string,required', 'markerName');
314
396
 
315
- return {
316
- route: (route, fn) => MarkerMethods.onlyRoute.call(self, route, fn, markerFn),
317
- use: (fnOrRouter) => MarkerMethods.onlyUse.call(self, fnOrRouter, markerFn),
397
+ const self = this;
398
+ const markerFn = this._markers.get(markerName);
399
+
400
+ return {
401
+ route: (route, fn) => MarkerMethods.onlyRoute.call(self, route, fn, markerFn),
402
+ use: (fnOrRouter) => MarkerMethods.onlyUse.call(self, fnOrRouter, markerFn),
403
+ }
404
+ }
405
+ catch(error) {
406
+ Error.captureStackTrace(error, this.only);
407
+ throw error;
318
408
  }
319
409
  }
320
410
 
@@ -336,11 +426,8 @@ module.exports = class NodesterRouter {
336
426
  */
337
427
  lock() {
338
428
  // Stack is ready.
339
- this.isLocked = true;
340
-
341
- debug(`router is locked`);
342
-
343
429
  this._middlewares.lock();
430
+ debug(`router is locked`);
344
431
  }
345
432
 
346
433
 
@@ -350,11 +437,8 @@ module.exports = class NodesterRouter {
350
437
  * @api public
351
438
  */
352
439
  unlock() {
353
- this.isLocked = false;
354
-
355
- debug(`router is unlocked`);
356
-
357
440
  this._middlewares.unlock();
441
+ debug(`router is unlocked`);
358
442
  }
359
443
 
360
444
 
@@ -378,8 +462,16 @@ module.exports = class NodesterRouter {
378
462
  * @api public
379
463
  */
380
464
  removeMiddleware(index=-1) {
381
- this._middlewares.remove(index);
382
- return this._middlewares.length;
465
+ try {
466
+ ensure(index, 'number,required', 'index');
467
+
468
+ this._middlewares.remove(index);
469
+ return this._middlewares.length;
470
+ }
471
+ catch(error) {
472
+ Error.captureStackTrace(error, this.removeMiddleware);
473
+ throw error;
474
+ }
383
475
  }
384
476
 
385
477
 
@@ -389,14 +481,17 @@ module.exports = class NodesterRouter {
389
481
  *
390
482
  * @param {String} key
391
483
  * @param {Any} fnOrProperty
484
+ *
392
485
  * @return {Any} fnOrProperty in Router
393
486
  *
394
487
  * @api public
395
488
  */
396
489
  extend(key='', fnOrProperty) {
397
- const keys = Object.keys(this);
398
- if (keys.indexOf(key) > -1) {
399
- const err = new TypeError(`Key ${ key } is already present in Router instance`);
490
+ ensure(key, 'string,required', 'key');
491
+ ensure(fnOrProperty, 'required', 'fnOrProperty');
492
+
493
+ if (typeof this[key] !== 'undefined') {
494
+ const err = new TypeError(`Key '${ key }' is already present in Router instance.`);
400
495
  throw err;
401
496
  }
402
497
 
@@ -1,3 +1,10 @@
1
+ /*!
2
+ * /nodester
3
+ * MIT Licensed
4
+ */
5
+
6
+ 'use strict';
7
+
1
8
  const Route = require('./route');
2
9
  // Utils.
3
10
  const {
@@ -8,6 +8,9 @@
8
8
  // Utils.
9
9
  const { typeOf } = require('../utils/types.util');
10
10
 
11
+ // Arguments validator.
12
+ const { ensure } = require('../validators/arguments');
13
+
11
14
 
12
15
  module.exports = class NodesterRoute {
13
16
 
@@ -23,6 +26,8 @@ module.exports = class NodesterRoute {
23
26
  * @api public
24
27
  */
25
28
  constructor(routeStringOrOpts={}) {
29
+ ensure(routeStringOrOpts, 'object|string,required', 'routeStringOrOpts');
30
+
26
31
  if (typeOf(routeStringOrOpts) === 'Object') {
27
32
  this.method = opts.method ?? undefined;
28
33
  this.route = opts.route ?? null;
@@ -27,14 +27,14 @@ function _validateParsedRouteMethood(parsedRoute) {
27
27
 
28
28
 
29
29
  /**
30
- * Wraps route handler.
31
- *
32
- * @param {Route} routeInstance
33
- * @param {Function} handler
34
- *
35
- * @alias wrapRouteHandler
36
- * @api public
37
- */
30
+ * Wraps route handler.
31
+ *
32
+ * @param {Route} routeInstance
33
+ * @param {Function} handler
34
+ *
35
+ * @alias wrapRouteHandler
36
+ * @api public
37
+ */
38
38
  function _wrapRouteHandler(routeInstance, handler) {
39
39
  const handlerType = typeOf(handler);
40
40
 
@@ -81,14 +81,16 @@ function _wrapRouteHandler(routeInstance, handler) {
81
81
  }
82
82
  // If Provider\
83
83
 
84
- // If User set any handler before,
85
- // call it first:
84
+ // If User set any middleware before:
86
85
  if (typeOf(parsedHandler.before) === 'function') {
87
- // Expose nquery first.
88
- await parsedHandler.before(req.nquery, req, res);
86
+ const _next = () => providedAction(req, res);
87
+ await parsedHandler.before(req, res, _next);
88
+ }
89
+ // If response was not sent,
90
+ // perform action
91
+ else if (res.headersSent === false) {
92
+ await providedAction(req, res);
89
93
  }
90
-
91
- await providedAction(req, res);
92
94
  }
93
95
  };
94
96
 
@@ -1,3 +1,10 @@
1
+ /*!
2
+ * /nodester
3
+ * MIT Licensed
4
+ */
5
+
6
+ 'use strict';
7
+
1
8
 
2
9
  module.exports = {
3
10
  parseProviderFileNames: _parseProviderFileNames
@@ -1,24 +1,54 @@
1
+ /*!
2
+ * /nodester
3
+ * MIT Licensed
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ // Arguments validator.
9
+ const { ensure } = require('../validators/arguments');
10
+
11
+ // Console:
1
12
  const consl = require('nodester/loggers/console');
2
13
  const debug = require('debug')('nodester:MiddlewareStack');
3
14
 
4
15
 
16
+ /*
17
+ * Creates new MarkersStack.
18
+ *
19
+ * @return {MarkersStack}
20
+ *
21
+ */
5
22
  module.exports = class MarkersStack {
6
23
  constructor() {
7
- this.markers = new Map();
24
+ this._markers = new Map();
8
25
  }
9
26
 
27
+ get markers() {
28
+ return this._markers;
29
+ }
10
30
 
11
31
  /**
12
32
  * Add the given middleware `fn` to the stack.
13
33
  *
14
34
  * @param {String} markerName
15
35
  * @param {Function} fn
36
+ *
16
37
  * @return {Integer} index of new middleware
17
38
  *
18
39
  * @api public
19
40
  */
20
41
  add(markerName='', fn) {
21
- return this.markers.set(markerName, fn);
42
+ try {
43
+ ensure(markerName, 'string,required', 'markerName');
44
+ ensure(fn, 'function,required', 'fn');
45
+
46
+ return this._markers.set(markerName, fn);
47
+ }
48
+ catch(error) {
49
+ Error.captureStackTrace(error, this.add);
50
+ throw error;
51
+ }
22
52
  }
23
53
 
24
54
 
@@ -30,6 +60,14 @@ module.exports = class MarkersStack {
30
60
  * @api public
31
61
  */
32
62
  get(markerName='') {
33
- return this.markers.get(markerName);
63
+ try {
64
+ ensure(markerName, 'string,required', 'markerName');
65
+
66
+ return this._markers.get(markerName);
67
+ }
68
+ catch(error) {
69
+ Error.captureStackTrace(error, this.get);
70
+ throw error;
71
+ }
34
72
  }
35
73
  }