alchemymvc 1.3.10 → 1.3.12

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.
@@ -352,7 +352,7 @@ Client.setMethod(function createStream() {
352
352
  *
353
353
  * @author Jelle De Loecker <jelle@elevenways.be>
354
354
  * @since 0.2.0
355
- * @version 1.3.10
355
+ * @version 1.3.12
356
356
  *
357
357
  * @param {Function} callback
358
358
  */
@@ -386,7 +386,7 @@ Client.setMethod(function connect(address, data, callback) {
386
386
 
387
387
  if (typeof io != 'undefined') {
388
388
  io_client = io;
389
- } else if (typeof alchemy != 'undefined') {
389
+ } else if (typeof alchemy?.use == 'function') {
390
390
  io_client = alchemy.use('socket.io-client');
391
391
  } else {
392
392
  return callback(new Error('Could not find socket.io client library'));
@@ -9,7 +9,6 @@ const DataProvider = Function.inherits('Alchemy.Base', 'Alchemy.DataProvider', f
9
9
  this.config = config || {};
10
10
  });
11
11
 
12
-
13
12
  /**
14
13
  * Undry
15
14
  *
@@ -47,6 +46,15 @@ DataProvider.setStatic(function addConfig(name, default_value) {
47
46
  });
48
47
  });
49
48
 
49
+ /**
50
+ * Extra context
51
+ *
52
+ * @author Jelle De Loecker <jelle@elevenways.be>
53
+ * @since 1.3.12
54
+ * @version 1.3.12
55
+ */
56
+ DataProvider.addConfig('context');
57
+
50
58
  /**
51
59
  * The wanted page size
52
60
  *
@@ -21,7 +21,7 @@ RemoteDataProvider.addConfig('source');
21
21
  *
22
22
  * @author Jelle De Loecker <jelle@elevenways.be>
23
23
  * @since 1.2.2
24
- * @version 1.2.2
24
+ * @version 1.3.12
25
25
  */
26
26
  RemoteDataProvider.setMethod(async function getAll() {
27
27
 
@@ -29,7 +29,15 @@ RemoteDataProvider.setMethod(async function getAll() {
29
29
  return [];
30
30
  }
31
31
 
32
- let result = await Blast.fetch(this.source);
32
+ let options = {};
33
+
34
+ if (this.context) {
35
+ options.get = {
36
+ context: this.context
37
+ };
38
+ }
39
+
40
+ let result = await alchemy.fetch(this.source, options);
33
41
 
34
42
  return result;
35
43
  });
@@ -111,7 +111,7 @@ PathParamDefinition.enforceProperty(function model_constructor(new_value) {
111
111
  *
112
112
  * @author Jelle De Loecker <jelle@elevenways.be>
113
113
  * @since 1.3.0
114
- * @version 1.3.6
114
+ * @version 1.3.12
115
115
  */
116
116
  PathParamDefinition.setMethod(function parseTypeDefinition() {
117
117
 
@@ -142,7 +142,7 @@ PathParamDefinition.setMethod(function parseTypeDefinition() {
142
142
  current = class_path;
143
143
 
144
144
  for (let piece of this.typedef) {
145
- if (piece[0] != piece[0].toUpperCase()) {
145
+ if (piece[0] != piece[0].toUpperCase() || !String.isLetter(piece[0])) {
146
146
  current = field_path;
147
147
  }
148
148
 
@@ -17,9 +17,9 @@ var shared_objects = {},
17
17
  *
18
18
  * @constructor
19
19
  *
20
- * @author Jelle De Loecker <jelle@develry.be>
20
+ * @author Jelle De Loecker <jelle@elevenways.be>
21
21
  * @since 0.0.1
22
- * @version 1.1.0
22
+ * @version 1.3.11
23
23
  */
24
24
  global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
25
25
 
@@ -43,6 +43,9 @@ global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
43
43
  // The id of this server instance
44
44
  this.discovery_id = Crypto.pseudoHex();
45
45
 
46
+ // Weighted error handlers
47
+ this.error_handlers = new Deck();
48
+
46
49
  // Link to the colors module
47
50
  this.colors = colors;
48
51
 
@@ -105,6 +108,9 @@ global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
105
108
  // Load the settings
106
109
  this.loadSettings();
107
110
 
111
+ // Initialize the error handler
112
+ initializeErrorHandler.call(this);
113
+
108
114
  // Listen to messages from parent processes
109
115
  process.on('message', function gotMessage(message) {
110
116
  if (typeof message == 'string') {
@@ -1956,6 +1962,109 @@ Alchemy.setMethod(function getClientModel(name, init, options) {
1956
1962
  return Classes.Alchemy.Client.Base.prototype.getModel.call(this, name, init, options);
1957
1963
  });
1958
1964
 
1965
+ let error_handler_count = 0;
1966
+
1967
+ /**
1968
+ * Register an error handler
1969
+ *
1970
+ * @author Jelle De Loecker <jelle@elevenways.be>
1971
+ * @since 1.3.11
1972
+ * @version 1.3.11
1973
+ *
1974
+ * @param {Function} callback
1975
+ * @param {Number} weight
1976
+ */
1977
+ Alchemy.setMethod(function registerErrorHandler(callback, weight) {
1978
+
1979
+ const that = this;
1980
+
1981
+ if (error_handler_count == 0) {
1982
+ process.on('uncaughtException', function onException(error) {
1983
+ that.registerError(error, {handled: false});
1984
+ });
1985
+
1986
+ process.on('unhandledRejection', function onRejection(error, promise) {
1987
+ that.registerError(error, {promise, handled: false});
1988
+ });
1989
+ }
1990
+
1991
+ error_handler_count++;
1992
+
1993
+ if (weight == null) {
1994
+ weight = 10;
1995
+ }
1996
+
1997
+ this.error_handlers.push(callback, weight);
1998
+ });
1999
+
2000
+ /**
2001
+ * Process the given error
2002
+ *
2003
+ * @author Jelle De Loecker <jelle@elevenways.be>
2004
+ * @since 1.3.11
2005
+ * @version 1.3.11
2006
+ *
2007
+ * @param {Error} error
2008
+ * @param {Object} info
2009
+ */
2010
+ Alchemy.setMethod(async function registerError(error, info = {}) {
2011
+
2012
+ let handle_count = 0;
2013
+
2014
+ if (!this.error_handlers.insertCount) {
2015
+ return handle_count;
2016
+ }
2017
+
2018
+ let callback;
2019
+
2020
+ for (callback of this.error_handlers) {
2021
+ let result = callback(error, info);
2022
+
2023
+ handle_count++;
2024
+
2025
+ if (result == null) {
2026
+ continue;
2027
+ }
2028
+
2029
+ if (Pledge.isThenable(result)) {
2030
+ result = await result;
2031
+ }
2032
+
2033
+ if (result === false) {
2034
+ break;
2035
+ }
2036
+ }
2037
+
2038
+ return handle_count;
2039
+ });
2040
+
2041
+ /**
2042
+ * Initialize the error handler (if it's enabled)
2043
+ *
2044
+ * @author Jelle De Loecker <jelle@elevenways.be>
2045
+ * @since 1.3.11
2046
+ * @version 1.3.11
2047
+ */
2048
+ function initializeErrorHandler() {
2049
+
2050
+ const config = this.settings.errors ?? {};
2051
+
2052
+ if (config.handle_uncaught) {
2053
+ this.registerErrorHandler((error, info) => {
2054
+
2055
+ let message;
2056
+
2057
+ if (info?.promise) {
2058
+ message = 'Unhandled promise rejection';
2059
+ } else {
2060
+ message = 'Uncaught exception';
2061
+ }
2062
+
2063
+ alchemy.printLog('error', [message, String(error), error], {err: error, level: -2});
2064
+ }, 1);
2065
+ }
2066
+ }
2067
+
1959
2068
  /**
1960
2069
  * The alchemy global, where everything will be stored
1961
2070
  *
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemymvc",
3
3
  "description": "MVC framework for Node.js",
4
- "version": "1.3.10",
4
+ "version": "1.3.12",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -22,7 +22,7 @@
22
22
  "chokidar" : "~3.5.3",
23
23
  "formidable" : "~2.1.1",
24
24
  "graceful-fs" : "~4.2.9",
25
- "hawkejs" : "~2.3.4",
25
+ "hawkejs" : "~2.3.9",
26
26
  "jsondiffpatch" : "~0.4.1",
27
27
  "mime" : "~3.0.0",
28
28
  "minimist" : "~1.2.5",
@@ -31,7 +31,7 @@
31
31
  "mongodb" : "~3.6.6",
32
32
  "ncp" : "~2.0.0",
33
33
  "postcss" : "~8.4.6",
34
- "protoblast" : "~0.8.5",
34
+ "protoblast" : "~0.8.9",
35
35
  "semver" : "~7.3.5",
36
36
  "socket.io" : "~4.6.0",
37
37
  "@11ways/socket.io-stream" : "~0.9.2",