@ti-engine/core 1.3.11 → 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.
- package/CHANGELOG.md +33 -0
- package/README.md +3 -1
- package/bin/localization/labels.json +3 -0
- package/package.json +2 -2
- package/utils/config.js +1 -1
- package/utils/exceptions.js +1 -0
- package/utils/localization.js +41 -7
- package/utils/tools.js +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,30 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
This document will contain the list of changes made to the framework. The format is based on the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
|
|
4
4
|
|
|
5
|
+
## Version 1.3.12
|
|
6
|
+
|
|
7
|
+
* feat(exceptions): add new exception code `E_COM_SERVICE_EXEC_FAILED`
|
|
8
|
+
* feat(localization): add new public method `getAllLabels`
|
|
9
|
+
* feat(localization): use new `deepFreeze` method to freeze all label trees
|
|
10
|
+
* feat(tools): add new public method `deepFreeze` for freezing an object and all its sub-objects recursively
|
|
11
|
+
* feat(config): use new `deepFreeze` method to freeze all configuration settings
|
|
12
|
+
* docs: add more information about the `localization` module in `README.md` file
|
|
13
|
+
* build(npm): update npm dependencies to their latest versions
|
|
14
|
+
|
|
5
15
|
## Version 1.3.11
|
|
16
|
+
|
|
6
17
|
* feat(tools): add `arrayUniques` method to the tools module that helps extract only the unique array values
|
|
7
18
|
* fix(start instance): fix `undefined` instance ID in the log message about starting the instance
|
|
8
19
|
|
|
9
20
|
## Version 1.3.10
|
|
21
|
+
|
|
10
22
|
* chore: fix various minor issues reported by the linter
|
|
11
23
|
* build(npm): add more information and options to the `package.json` file
|
|
12
24
|
* docs: add some JSDoc descriptions to classes and methods
|
|
13
25
|
|
|
14
26
|
## Version 1.3.9
|
|
27
|
+
|
|
15
28
|
* feat(exceptions): add new exception code `E_GEN_NOT_INITIALIZED`
|
|
16
29
|
* docs: fix image links in the `README.md` file
|
|
17
30
|
|
|
18
31
|
## Version 1.3.8
|
|
32
|
+
|
|
19
33
|
* fix(tester): fix the relative paths of various files in the tester service. The configuration now assumes that the working directory is the root of the tester package instead of the repository itself
|
|
20
34
|
* build(npm): update npm dependencies to their latest versions
|
|
21
35
|
* docs: fix some outdated information in the `README.md` file and add some more details
|
|
22
36
|
|
|
23
37
|
## Version 1.3.7
|
|
38
|
+
|
|
24
39
|
* feat(exceptions): add new exception code `E_SEC_UNRECOGNIZED_AUTH_METHOD`
|
|
25
40
|
* fix(config): fix potential issue with `TI_GCLOUD_ENABLED` parsing as boolean
|
|
26
41
|
* docs: adjust some of the JSDoc descriptions and definitions
|
|
27
42
|
|
|
28
43
|
## Version 1.3.6
|
|
44
|
+
|
|
29
45
|
* feat(exceptions): add new exception code `E_GEN_INVALID_ARGUMENT_TYPE`
|
|
30
46
|
* feat(exceptions): add public enum with all HTTP codes exported as `httpCode` and typedef `TiHttpCode`. Use it as the type for the `httpCode` exception property
|
|
31
47
|
* feat(tools): add `description` property to enum objects
|
|
@@ -41,19 +57,23 @@ This document will contain the list of changes made to the framework. The format
|
|
|
41
57
|
* build(npm)!: bump the minimum supported Node.js version to 18.0.0
|
|
42
58
|
|
|
43
59
|
## Version 1.3.5
|
|
60
|
+
|
|
44
61
|
* fix(redis integration): fix a duplicated log entry on connection ready event if multiple observers are registered
|
|
45
62
|
* feat(service caller)!: change log level of error result in `process` method from `ERROR` to `DEBUG`. Implementers are expected to handle this and decide if the error should be propagated further or not
|
|
46
63
|
* docs: update and fix various issues with the `README.md` file
|
|
47
64
|
|
|
48
65
|
## Version 1.3.4
|
|
66
|
+
|
|
49
67
|
* fix(service instance): fix the way `ServiceConfiguration` is propagated via child classes and remove unnecessary defaults. Also update the relevant JSDoc
|
|
50
68
|
|
|
51
69
|
## Version 1.3.3
|
|
70
|
+
|
|
52
71
|
* feat(exceptions): add new parameter `includeData` to `Exception.asJSON` method which allows the exclusion of the data parameter from the returned JSON
|
|
53
72
|
* feat(exceptions): remove several excessive exception codes that were unlikely to be used
|
|
54
73
|
* fix(localization): add several missing exception labels
|
|
55
74
|
|
|
56
75
|
## Version 1.3.2
|
|
76
|
+
|
|
57
77
|
* feat(exceptions): add a set of new exception codes for the needs of any wrapping `web-server` standard communication
|
|
58
78
|
* feat(exception)!: change the default prefix path for exception labels to `system.exceptions.`
|
|
59
79
|
* feat(localization): add an Enum list of all language codes based on ISO 639-1 standard
|
|
@@ -67,6 +87,7 @@ This document will contain the list of changes made to the framework. The format
|
|
|
67
87
|
* fix(auditing): fix a potential problem with setting the log entry reporter from an ENV variable; instead, the system will now use the `ServiceInstance.instanceID` property
|
|
68
88
|
|
|
69
89
|
## Version 1.3.1
|
|
90
|
+
|
|
70
91
|
* feat(service caller): refactor the entire service call execution flow for clarity and better performance
|
|
71
92
|
* feat(service caller): create a new private class `ServiceCallProcessor` to handle individual service calls in a contained scope
|
|
72
93
|
* feat(message observer): add new property `priority` to the message observer class. It is used to determine the order in which the observers are notified about the messages
|
|
@@ -77,6 +98,7 @@ This document will contain the list of changes made to the framework. The format
|
|
|
77
98
|
* fix(redis integration): fix an issue which was setting the client status to `DISCONNECTED` during a normal shut down procedure
|
|
78
99
|
|
|
79
100
|
## Version 1.3.0
|
|
101
|
+
|
|
80
102
|
* feat(redis integration)!: change `reconnectOnError` behavior to also resubmit the failed command in case the error was of type `READONLY`
|
|
81
103
|
* feat(redis integration): improve the reliability and usage of the event notification mechanism for connection observers
|
|
82
104
|
* feat(redis integration): implement listener to the `end` event on Redis connection to capture when connection can no longer be recovered
|
|
@@ -90,25 +112,31 @@ This document will contain the list of changes made to the framework. The format
|
|
|
90
112
|
* fix(redis integration): fix broken event propagation on `disrupted` events to some connection observers
|
|
91
113
|
|
|
92
114
|
## Version 1.2.5
|
|
115
|
+
|
|
93
116
|
* feat(cache): extend method `expireValue` to work with has set fields as well
|
|
94
117
|
|
|
95
118
|
## Version 1.2.4
|
|
119
|
+
|
|
96
120
|
* feat(cache): expose the cache module as export in `package.json`
|
|
97
121
|
* feat(cache): add method `hashDeleteField` to remove a hash-set field. This implements the `hdel` Redis command
|
|
98
122
|
* fix(tools): optimize method `stringifyJSON` not to call unnecessary decycling of the value if it's not an object
|
|
99
123
|
* fix(cache): replace `hmset` with `hset` Redis command in both methods that set hash-set values. Also remove unnecessary `_.isObjectLike` call in `hashSetFields` method
|
|
100
124
|
|
|
101
125
|
## Version 1.2.3
|
|
126
|
+
|
|
102
127
|
* feat(start instance): add support for providing a custom path to the `.env` file to be used at service startup as process argument. Accepted arguments are `--env`, `--env-file`, `--dotenv`, `--dotenv-path`, and `-e`. The path itself should be relative to the working directory and should include the file name
|
|
103
128
|
|
|
104
129
|
## Version 1.2.2
|
|
130
|
+
|
|
105
131
|
* feat(start instance): change package `dotenv` to `@dotenvx/dotenvx` for loading of ENV variables. The new package supports encrypting the ENV variables. For more information see https://dotenvx.com/docs/
|
|
106
132
|
|
|
107
133
|
## Version 1.2.1
|
|
134
|
+
|
|
108
135
|
* feat(localization): add support for adding custom labels to the localization system. These have to follow the same format as the system labels
|
|
109
136
|
* docs: add section about localization to the `README.md` file
|
|
110
137
|
|
|
111
138
|
## Version 1.2.0
|
|
139
|
+
|
|
112
140
|
* feat(config)!: change the setting `localization.labelsPath` to be an array of strings. It can now be used to supply any additional custom labels in one or more files to the framework
|
|
113
141
|
* feat(message memory cache): implement graceful exception handling during shut down procedure in `receiveMessage` and `sendMessage` methods
|
|
114
142
|
* fix(default message sender): add missing initialization of the memory cache on enable
|
|
@@ -121,21 +149,25 @@ This document will contain the list of changes made to the framework. The format
|
|
|
121
149
|
* fix(service executor)!: change the individual service registration process to ensure service registration does actually happen before the service provider finishes its initialization
|
|
122
150
|
|
|
123
151
|
## Version 1.1.10
|
|
152
|
+
|
|
124
153
|
* fix(cache): fix redis client creation sequence. It is now created inside the constructor as intended. It still needs to be initialized explicitly using the `initialize` method.
|
|
125
154
|
|
|
126
155
|
## Version 1.1.9
|
|
156
|
+
|
|
127
157
|
* feat(redis integration)!: change the way the `redis` client is initialized. Instead of happening automatically on class instantiation, it is now initialized on demand using the `initialize` method.
|
|
128
158
|
* feat(cache): change the way the main cache instance is initialized in compliance with the new redis integration
|
|
129
159
|
* feat(message memory cache)!: change the way the message memory cache is initialized in compliance with the new redis integration. The `initialize` method needs to be called explicitly to initialize the cache instance before it can be used.
|
|
130
160
|
* fix(message dispatcher): fix the way the `messageExchange` is initialized in the `MessageDispatcher` class (was not returning a promise)
|
|
131
161
|
|
|
132
162
|
## Version 1.1.8
|
|
163
|
+
|
|
133
164
|
* feat(auditing): change export of the singleton class in an `instance` variable for consistency and clarity
|
|
134
165
|
* feat(message dispatcher): change export of the singleton class in an `instance` variable for consistency and clarity
|
|
135
166
|
* feat(cache): change export of the singleton class in an `instance` variable for consistency and clarity
|
|
136
167
|
* feat(service executor): implement service registration retry policy
|
|
137
168
|
|
|
138
169
|
## Version 1.1.7
|
|
170
|
+
|
|
139
171
|
* feat(start instance): add support for the detection of `SIGBREAK` events and graceful shutdown on Windows
|
|
140
172
|
* feat(service instance)!: prevent the initialization of multiple `ServiceInstance` within the same process
|
|
141
173
|
* feat(message tracer)!: covert to singleton instance and add initialization method
|
|
@@ -145,6 +177,7 @@ This document will contain the list of changes made to the framework. The format
|
|
|
145
177
|
* fix(redis integration): update links to official commands documentation
|
|
146
178
|
|
|
147
179
|
## Version 1.1.6
|
|
180
|
+
|
|
148
181
|
* feat(start instance): add fail-fast mode as default behavior on promise unhandled rejections
|
|
149
182
|
* feat(start instance): implement functionality to derive safe default service domain name when none is provided in the configuration
|
|
150
183
|
* feat(config): add support for new ENV variable `TI_FAIL_FAST_ON_UNHANDLED_OFF` that controls the fail-fast mode
|
package/README.md
CHANGED
|
@@ -544,4 +544,6 @@ The following is an example of a custom localization file. The names in brackets
|
|
|
544
544
|
}
|
|
545
545
|
```
|
|
546
546
|
|
|
547
|
-
The individual languages are specified with a two-letter code according to ISO 639-1. The default language is `en` (English). If you want to use a different language, you can set the `LOCALIZATION_LANGUAGE` setting to the desired language code.
|
|
547
|
+
The individual languages are specified with a two-letter code according to ISO 639-1. The default language is `en` (English). If you want to use a different language, you can set the `LOCALIZATION_LANGUAGE` setting to the desired language code.
|
|
548
|
+
|
|
549
|
+
If you want to localize the system labels of the framework, you can do so by providing a custom localization file with the same structure as the default one but containing only the languages you want to add. For example, the default English label for `E_UNKNOWN_ERROR` is found in JSON path `system.exceptions.0.en`. To add an entry for German, your file needs to contain a `system.exceptions.0.de` property. The localization module will handle the rest. You can use the same approach to modify the existing English labels as well. The full list of system labels is found in the `bin/localization/labels.json` file. Avoid modifying the default file since it might get overwritten by future updates.
|
|
@@ -70,6 +70,9 @@
|
|
|
70
70
|
"3007": {
|
|
71
71
|
"en": "The message exchange is irrevocably broken and cannot be used any longer."
|
|
72
72
|
},
|
|
73
|
+
"3008": {
|
|
74
|
+
"en": "The execution of a service reported a failure. This might be a business logic error or a system error."
|
|
75
|
+
},
|
|
73
76
|
"3010": {
|
|
74
77
|
"en": "Connection retry attempts exceeded the configured limit."
|
|
75
78
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.12",
|
|
4
4
|
"description": "The ti-engine is an open source, free to use—both for personal and commercial projects—framework for the creation of microservice-based solutions using node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"microservices",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@dotenvx/dotenvx": "^1.51.0",
|
|
61
61
|
"blake2": "^5.0.0",
|
|
62
|
-
"ioredis": "^5.8.
|
|
62
|
+
"ioredis": "^5.8.2",
|
|
63
63
|
"lodash": "^4.17.21",
|
|
64
64
|
"node-schedule": "^2.1.1"
|
|
65
65
|
},
|
package/utils/config.js
CHANGED
|
@@ -185,7 +185,7 @@ if ( tools.toBool( process.env.TI_GCLOUD_ENABLED ) === true && settings.gcloudIn
|
|
|
185
185
|
settings.operationMode = process.env.NODE_ENV || settings.operationMode;
|
|
186
186
|
|
|
187
187
|
// Prevent further modifications to the settings object:
|
|
188
|
-
|
|
188
|
+
tools.deepFreeze( settings );
|
|
189
189
|
|
|
190
190
|
/**
|
|
191
191
|
* A standard getter method for fetching a setting.
|
package/utils/exceptions.js
CHANGED
|
@@ -43,6 +43,7 @@ const exceptionCodeEnum = tools.enum( {
|
|
|
43
43
|
E_COM_SERVICE_HANDLER_NOT_FOUND: [ 3005, "service handler not found", "No handler found in the interface for the specified service or service version." ],
|
|
44
44
|
E_COM_MESSAGE_RECEIVER_UNAVAILABLE: [ 3006, "message receiver unavailable", "The message receiver instance is currently unavailable." ],
|
|
45
45
|
E_COM_MESSAGE_EXCHANGE_BROKEN: [ 3007, "message exchange broken", "The message exchange is irrevocably broken and cannot be used any longer." ],
|
|
46
|
+
E_COM_SERVICE_EXEC_FAILED: [ 3008, "service exec failed", "The execution of a service reported a failure. This might be a business logic error or a system error." ],
|
|
46
47
|
E_COM_RETRY_ATTEMPTS_EXCEEDED: [ 3010, "retry attempts exceeded", "Connection retry attempts exceeded the configured limit." ],
|
|
47
48
|
/** Web server exceptions - codes under 4xxx */
|
|
48
49
|
E_WEB_INVALID_REQUEST_METHOD: [ 4000, "invalid request method", "The request method is not recognized or not supported." ],
|
package/utils/localization.js
CHANGED
|
@@ -245,12 +245,7 @@ module.exports.localizationLanguage = localizationLanguageEnum;
|
|
|
245
245
|
* @typedef {Object<string, TiLocalizedLabel | TiLabelsTree>} TiLabelsTree
|
|
246
246
|
*/
|
|
247
247
|
|
|
248
|
-
/**
|
|
249
|
-
* @typedef {Object} TiLabels
|
|
250
|
-
* @property {TiLabelsTree} labels
|
|
251
|
-
*/
|
|
252
|
-
|
|
253
|
-
/** @type {TiLabels} */
|
|
248
|
+
/** @type {TiLabelsTree} */
|
|
254
249
|
const labels = require( "#labels" );
|
|
255
250
|
|
|
256
251
|
// Load any custom labels defined in the configuration:
|
|
@@ -264,7 +259,7 @@ if ( labelsPaths && _.isArray( labelsPaths ) && labelsPaths.length > 0 ) {
|
|
|
264
259
|
}
|
|
265
260
|
|
|
266
261
|
// Prevent further modifications to the TiLabels object:
|
|
267
|
-
|
|
262
|
+
tools.deepFreeze( labels );
|
|
268
263
|
|
|
269
264
|
/**
|
|
270
265
|
* Used to return the textual value for a label based on the current system language by default or the specified language code if provided.
|
|
@@ -277,4 +272,43 @@ Object.freeze( labels );
|
|
|
277
272
|
*/
|
|
278
273
|
module.exports.getLabel = ( label, language ) => {
|
|
279
274
|
return _.get( labels, label + "." + ( ( language ) ? language : config.getSetting( config.setting.LOCALIZATION_LANGUAGE ) ), defaultEmptyLabel );
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const labelsCacheByLanguage = new Map();
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Used to return the entire labels tree.
|
|
281
|
+
* <br/>
|
|
282
|
+
* NOTE: The result will be a modified copy of the label tree that has no "language" end-nodes and keeps only the appropriate labels for the requested language.
|
|
283
|
+
* For example, if the original JSON path is "path.to.label.language", the returned path will be just "path.to.label" corresponding to the text label.
|
|
284
|
+
*
|
|
285
|
+
* @method
|
|
286
|
+
* @param {TiLocalizationLanguage} [language] The language code to use for the lookup. If not provided, the current system language will be used.
|
|
287
|
+
* @returns {TiLabelsTree}
|
|
288
|
+
* @public
|
|
289
|
+
*/
|
|
290
|
+
module.exports.getAllLabels = ( language ) => {
|
|
291
|
+
const usedLanguage = language || config.getSetting( config.setting.LOCALIZATION_LANGUAGE );
|
|
292
|
+
|
|
293
|
+
if ( labelsCacheByLanguage.has( usedLanguage ) ) {
|
|
294
|
+
return labelsCacheByLanguage.get( usedLanguage );
|
|
295
|
+
} else {
|
|
296
|
+
const labelsByLanguage = _.cloneDeepWith( labels, ( value ) => {
|
|
297
|
+
if ( _.isPlainObject( value ) ) {
|
|
298
|
+
const values = Object.values( value );
|
|
299
|
+
const isLeaf = values.length > 0 && values.every( v => _.isString( v ) || _.isNil( v ) );
|
|
300
|
+
if ( isLeaf ) {
|
|
301
|
+
// Return only the desired language or default placeholder if missing:
|
|
302
|
+
return _.get( value, usedLanguage, defaultEmptyLabel );
|
|
303
|
+
}
|
|
304
|
+
} else {
|
|
305
|
+
// Return undefined to let lodash handle default deep cloning for non-leaves:
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
} );
|
|
309
|
+
|
|
310
|
+
tools.deepFreeze( labelsByLanguage );
|
|
311
|
+
labelsCacheByLanguage.set( usedLanguage, labelsByLanguage );
|
|
312
|
+
return labelsByLanguage;
|
|
313
|
+
}
|
|
280
314
|
};
|
package/utils/tools.js
CHANGED
|
@@ -35,6 +35,27 @@ module.exports.getUUID = () => {
|
|
|
35
35
|
return crypto.randomUUID( { disableEntropyCache: true } );
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Used to deep-freeze an object.
|
|
40
|
+
*
|
|
41
|
+
* @method
|
|
42
|
+
* @param {Object} object
|
|
43
|
+
* @param {WeakSet} [seen]
|
|
44
|
+
* @return {Object}
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
module.exports.deepFreeze = ( object, seen = new WeakSet() ) => {
|
|
48
|
+
if ( object === null || typeof object !== "object" || seen.has( object ) ) {
|
|
49
|
+
return object;
|
|
50
|
+
} else {
|
|
51
|
+
seen.add( object );
|
|
52
|
+
_.forOwn( object, ( value ) => {
|
|
53
|
+
module.exports.deepFreeze( value, seen );
|
|
54
|
+
} );
|
|
55
|
+
return Object.freeze( object );
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
38
59
|
/**
|
|
39
60
|
* Used to create a custom Enum list.
|
|
40
61
|
*
|