@ti-engine/core 1.3.1 → 1.3.5
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 +26 -0
- package/README.md +100 -97
- package/bin/localization/labels.json +98 -64
- package/components/auditing.js +14 -13
- package/components/service-caller.js +3 -3
- package/components/service-consumer.js +2 -2
- package/components/service-instance.js +3 -3
- package/components/service-provider.js +2 -2
- package/integrations/redis-integration.js +11 -10
- package/package.json +1 -1
- package/utils/config.js +5 -5
- package/utils/exceptions.js +40 -35
- package/utils/localization.js +249 -12
- package/utils/logger.js +3 -3
- package/utils/tools.js +2 -2
|
@@ -1,65 +1,99 @@
|
|
|
1
|
-
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
{
|
|
2
|
+
"system": {
|
|
3
|
+
"exceptions": {
|
|
4
|
+
"0": {
|
|
5
|
+
"en": "Unidentified error encountered or unrecognized exception code provided."
|
|
6
|
+
},
|
|
7
|
+
"1000": {
|
|
8
|
+
"en": "Error thrown by internal JS source."
|
|
9
|
+
},
|
|
10
|
+
"1001": {
|
|
11
|
+
"en": "Attempt to construct an abstract class detected."
|
|
12
|
+
},
|
|
13
|
+
"1002": {
|
|
14
|
+
"en": "Attempt to call an abstract method detected."
|
|
15
|
+
},
|
|
16
|
+
"1003": {
|
|
17
|
+
"en": "Invalid or no service domain name provided at microservice startup."
|
|
18
|
+
},
|
|
19
|
+
"1004": {
|
|
20
|
+
"en": "The system cache required for proper engine operation is unavailable."
|
|
21
|
+
},
|
|
22
|
+
"1005": {
|
|
23
|
+
"en": "The provided service handler is not a proper function."
|
|
24
|
+
},
|
|
25
|
+
"1006": {
|
|
26
|
+
"en": "The requested feature is not supported by current configuration or version."
|
|
27
|
+
},
|
|
28
|
+
"2000": {
|
|
29
|
+
"en": "Invalid authorization token provided."
|
|
30
|
+
},
|
|
31
|
+
"2001": {
|
|
32
|
+
"en": "Invalid or expired session encountered."
|
|
33
|
+
},
|
|
34
|
+
"2002": {
|
|
35
|
+
"en": "Attempt for unauthorized access detected."
|
|
36
|
+
},
|
|
37
|
+
"2003": {
|
|
38
|
+
"en": "The system detected tampering with the message received via message exchange."
|
|
39
|
+
},
|
|
40
|
+
"3000": {
|
|
41
|
+
"en": "General error during cross-application communication."
|
|
42
|
+
},
|
|
43
|
+
"3001": {
|
|
44
|
+
"en": "The message sender instance is currently unavailable."
|
|
45
|
+
},
|
|
46
|
+
"3002": {
|
|
47
|
+
"en": "The execution of a service could not complete within the allowed timeout."
|
|
48
|
+
},
|
|
49
|
+
"3003": {
|
|
50
|
+
"en": "The specified service is not found in the service registry."
|
|
51
|
+
},
|
|
52
|
+
"3004": {
|
|
53
|
+
"en": "The specified service is not found in the service definition interface."
|
|
54
|
+
},
|
|
55
|
+
"3005": {
|
|
56
|
+
"en": "No handler found in the interface for the specified service or service version."
|
|
57
|
+
},
|
|
58
|
+
"3006": {
|
|
59
|
+
"en": "The message receiver instance is currently unavailable."
|
|
60
|
+
},
|
|
61
|
+
"3007": {
|
|
62
|
+
"en": "The message exchange is irrevocably broken and cannot be used any longer."
|
|
63
|
+
},
|
|
64
|
+
"3010": {
|
|
65
|
+
"en": "Connection retry attempts exceeded the configured limit."
|
|
66
|
+
},
|
|
67
|
+
"4000": {
|
|
68
|
+
"en": "The request method is not recognized or not supported."
|
|
69
|
+
},
|
|
70
|
+
"4001": {
|
|
71
|
+
"en": "The request URI is not recognized or not supported."
|
|
72
|
+
},
|
|
73
|
+
"4002": {
|
|
74
|
+
"en": "The request body is not recognized or not supported."
|
|
75
|
+
},
|
|
76
|
+
"4003": {
|
|
77
|
+
"en": "The request query is not recognized or not supported."
|
|
78
|
+
},
|
|
79
|
+
"4004": {
|
|
80
|
+
"en": "The request headers are not recognized or not supported."
|
|
81
|
+
},
|
|
82
|
+
"4005": {
|
|
83
|
+
"en": "The request parameters are not recognized or not supported."
|
|
84
|
+
},
|
|
85
|
+
"4006": {
|
|
86
|
+
"en": "The request format is not recognized or not supported."
|
|
87
|
+
},
|
|
88
|
+
"4007": {
|
|
89
|
+
"en": "The request content type is not recognized or not supported."
|
|
90
|
+
},
|
|
91
|
+
"4008": {
|
|
92
|
+
"en": "The request content length is not recognized or not supported."
|
|
93
|
+
},
|
|
94
|
+
"4009": {
|
|
95
|
+
"en": "The request content encoding is not recognized or not supported."
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
65
99
|
}
|
package/components/auditing.js
CHANGED
|
@@ -11,9 +11,10 @@ const tools = require( "#tools" );
|
|
|
11
11
|
const logger = require( "#logger" );
|
|
12
12
|
const config = require( "#config" );
|
|
13
13
|
const gcloud = require( "#gcloud-integration" );
|
|
14
|
+
const ServiceInstance = require( "#service-instance" );
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
|
-
* @typedef {Object}
|
|
17
|
+
* @typedef {Object} TiLogEntry
|
|
17
18
|
* @property {string} _id Unique identifier that can be used to identify the document in a NoSQL database.
|
|
18
19
|
* @property {TiLogSeverity} severity The log severity level.
|
|
19
20
|
* @property {string} thread The categorization of the log message.
|
|
@@ -59,19 +60,19 @@ class Auditing {
|
|
|
59
60
|
*/
|
|
60
61
|
log( message, severity = logger.logSeverity.DEFAULT, thread = "main", data = {} ) {
|
|
61
62
|
try {
|
|
62
|
-
//
|
|
63
|
+
// Log entries below the minimum allowed level will be directly ignored:
|
|
63
64
|
if ( severity >= config.getSetting( config.setting.AUDITING_LOG_MIN_LEVEL ) ) {
|
|
64
|
-
//
|
|
65
|
-
//
|
|
65
|
+
// Obscure any passwords that might have landed in the data object;
|
|
66
|
+
// Also make sure to convert a potential Error object to a JSON:
|
|
66
67
|
let copyOfData = ( config.getSetting( config.setting.AUDITING_LOG_DETAILS ) === true ) ? _.cloneDeep( data ) : undefined;
|
|
67
68
|
let logEntry = Auditing.#createLogEntry( severity, thread, message, copyOfData );
|
|
68
69
|
|
|
69
|
-
//
|
|
70
|
+
// Make sure there is a console available (especially important for Cloud or containerized environments):
|
|
70
71
|
if ( config.getSetting( config.setting.AUDITING_LOG_CONSOLE_ENABLED ) === true && console ) {
|
|
71
72
|
Auditing.#logToConsole( logEntry );
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
//
|
|
75
|
+
// If this is an actual error, then send it to GCloud error reporting system as well:
|
|
75
76
|
if ( logEntry.severity >= logger.logSeverity.WARNING && data instanceof Error && gcloud.isEnabled() ) {
|
|
76
77
|
gcloud.reportError( data );
|
|
77
78
|
}
|
|
@@ -91,14 +92,14 @@ class Auditing {
|
|
|
91
92
|
* @param {string} thread
|
|
92
93
|
* @param {string} message
|
|
93
94
|
* @param {Object} data
|
|
94
|
-
* @returns {
|
|
95
|
+
* @returns {TiLogEntry}
|
|
95
96
|
* @private
|
|
96
97
|
*/
|
|
97
98
|
static #createLogEntry( severity, thread, message, data ) {
|
|
98
99
|
let currentDate = new Date();
|
|
99
100
|
let logDate = tools.getUTCDateString( currentDate );
|
|
100
101
|
let logTime = tools.getUTCTimeString( currentDate, true );
|
|
101
|
-
let reporter =
|
|
102
|
+
let reporter = ServiceInstance.instanceID;
|
|
102
103
|
|
|
103
104
|
return {
|
|
104
105
|
_id: `${ logDate }-${ logTime }-${ thread }-${ reporter }-${ logger.getSeverityName( severity ) }-${ tools.getUUID() }`,
|
|
@@ -112,13 +113,13 @@ class Auditing {
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
/**
|
|
115
|
-
* Used to write the log entries to the system console (i.e
|
|
116
|
+
* Used to write the log entries to the system console (i.e., STD OUT and STD ERR).
|
|
116
117
|
* <br/>
|
|
117
118
|
* NOTE: There was an issue in previous Node versions with console that can crash the application if the number of
|
|
118
|
-
*
|
|
119
|
+
* outputs exceeds several thousands per second. To be monitored and adjusted as necessary!
|
|
119
120
|
*
|
|
120
121
|
* @method
|
|
121
|
-
* @param {
|
|
122
|
+
* @param {TiLogEntry} logEntry
|
|
122
123
|
* @private
|
|
123
124
|
*/
|
|
124
125
|
static #logToConsole( logEntry ) {
|
|
@@ -140,7 +141,7 @@ class Auditing {
|
|
|
140
141
|
* Used to format a log entry for the Node console.
|
|
141
142
|
*
|
|
142
143
|
* @method
|
|
143
|
-
* @param {
|
|
144
|
+
* @param {TiLogEntry} logEntry
|
|
144
145
|
* @returns {string}
|
|
145
146
|
* @private
|
|
146
147
|
*/
|
|
@@ -153,7 +154,7 @@ class Auditing {
|
|
|
153
154
|
* Used to format a log entry data payload for the Node console.
|
|
154
155
|
*
|
|
155
156
|
* @method
|
|
156
|
-
* @param {
|
|
157
|
+
* @param {TiLogEntry} logEntry
|
|
157
158
|
* @returns {string}
|
|
158
159
|
* @private
|
|
159
160
|
*/
|
|
@@ -48,7 +48,7 @@ const messageDispatcher = require( "#message-dispatcher" );
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* @typedef {Object} ServiceCallResult
|
|
51
|
-
* @property {
|
|
51
|
+
* @property {Exception|undefined} exception If there was exception during the service call processing, it will be set here. Otherwise, it will be 'undefined'.
|
|
52
52
|
* @property {boolean} isSuccessful A flag indicating if this service call can be considered successful or not.
|
|
53
53
|
* @property {Object|string|undefined} payload The payload containing the results from the service call processing. If a string, it is ID of the payload in the memory cache instead.
|
|
54
54
|
*/
|
|
@@ -187,7 +187,7 @@ class ServiceCallProcessor {
|
|
|
187
187
|
} ).catch( ( error ) => {
|
|
188
188
|
clearTimeout( this.#timeoutHandle );
|
|
189
189
|
this.#isProcessed = true;
|
|
190
|
-
logger.log( `Error during service call execution!`, logger.logSeverity.
|
|
190
|
+
logger.log( `Error during service call execution!`, logger.logSeverity.DEBUG, error );
|
|
191
191
|
return {
|
|
192
192
|
isSuccessful: false,
|
|
193
193
|
exception: exceptions.raise( error ),
|
|
@@ -293,7 +293,7 @@ class ServiceCaller extends MessageObserver {
|
|
|
293
293
|
* @public
|
|
294
294
|
*/
|
|
295
295
|
executeServiceCall( serviceAddress, serviceParams, serviceExecContext ) {
|
|
296
|
-
return new Promise( ( resolve
|
|
296
|
+
return new Promise( ( resolve ) => {
|
|
297
297
|
let processor = new ServiceCallProcessor( serviceAddress, serviceParams, serviceExecContext );
|
|
298
298
|
this.#addProcessor( processor.messageID, processor );
|
|
299
299
|
processor.process().then( ( serviceCallResult ) => {
|
|
@@ -32,9 +32,9 @@ class ServiceConsumer extends ServiceInstance {
|
|
|
32
32
|
/**
|
|
33
33
|
* @constructor
|
|
34
34
|
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
35
|
-
* @param {
|
|
35
|
+
* @param {ServiceConfiguration} [serviceConfig] The JSON configuration for this service.
|
|
36
36
|
*/
|
|
37
|
-
constructor( serviceDomainName, serviceConfig
|
|
37
|
+
constructor( serviceDomainName, serviceConfig ) {
|
|
38
38
|
super( serviceDomainName, serviceConfig );
|
|
39
39
|
|
|
40
40
|
// make sure this abstract class cannot be instantiated:
|
|
@@ -17,7 +17,7 @@ const messageDispatcher = require( "#message-dispatcher" );
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @typedef {Object} ServiceConfiguration
|
|
20
|
-
* @property {ServiceDefinition[]} services A list of service definitions to be registered with the {@link ServiceProvider}.
|
|
20
|
+
* @property {ServiceDefinition[]} [services] A list of service definitions to be registered with the {@link ServiceProvider}.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -42,9 +42,9 @@ class ServiceInstance {
|
|
|
42
42
|
/**
|
|
43
43
|
* @constructor
|
|
44
44
|
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
45
|
-
* @param {
|
|
45
|
+
* @param {ServiceConfiguration} [serviceConfig={ services: [] }] The JSON configuration for this service.
|
|
46
46
|
*/
|
|
47
|
-
constructor( serviceDomainName, serviceConfig = {} ) {
|
|
47
|
+
constructor( serviceDomainName, serviceConfig = { services: [] } ) {
|
|
48
48
|
// Ensure this abstract class cannot be instantiated:
|
|
49
49
|
if ( new.target === ServiceInstance ) {
|
|
50
50
|
throw exceptions.raise( exceptions.exceptionCode.E_GEN_ABSTRACT_CLASS_INIT, { name: this.constructor.name } );
|
|
@@ -37,9 +37,9 @@ class ServiceProvider extends ServiceConsumer {
|
|
|
37
37
|
/**
|
|
38
38
|
* @constructor
|
|
39
39
|
* @param {string} serviceDomainName The service domain name for this service instance.
|
|
40
|
-
* @param {
|
|
40
|
+
* @param {ServiceConfiguration} [serviceConfig] The JSON configuration for this service.
|
|
41
41
|
*/
|
|
42
|
-
constructor( serviceDomainName, serviceConfig
|
|
42
|
+
constructor( serviceDomainName, serviceConfig ) {
|
|
43
43
|
super( serviceDomainName, serviceConfig );
|
|
44
44
|
|
|
45
45
|
// make sure this abstract class cannot be instantiated:
|
|
@@ -118,7 +118,7 @@ class RedisClient {
|
|
|
118
118
|
/* Public interface */
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
|
-
* Used to return the Redis client identifier.
|
|
121
|
+
* Used to return the Redis client identifier assigned internally.
|
|
122
122
|
*
|
|
123
123
|
* @property
|
|
124
124
|
* @returns {string}
|
|
@@ -129,7 +129,7 @@ class RedisClient {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
|
-
* Used to return the
|
|
132
|
+
* Used to return the client ID assigned by the Redis server.
|
|
133
133
|
*
|
|
134
134
|
* @property
|
|
135
135
|
* @returns {number}
|
|
@@ -195,9 +195,9 @@ class RedisClient {
|
|
|
195
195
|
// Fetch the server information and store it:
|
|
196
196
|
return this.#fetchServerInfo();
|
|
197
197
|
} ).then( () => {
|
|
198
|
-
return this.#
|
|
198
|
+
return this.#getClientID();
|
|
199
199
|
} ).then( ( clientID ) => {
|
|
200
|
-
// Store the
|
|
200
|
+
// Store the connection ID:
|
|
201
201
|
this.#redisClientID = clientID;
|
|
202
202
|
resolve();
|
|
203
203
|
} ).catch( ( error ) => {
|
|
@@ -476,10 +476,12 @@ class RedisClient {
|
|
|
476
476
|
|
|
477
477
|
this.#redisConnection.once( "ready", () => {
|
|
478
478
|
this.#clientStatus = clientStatusEnum.CONNECTED;
|
|
479
|
+
logger.log( `Connection to Redis server '${ this.#redisConnection.options.host }:${ this.#redisConnection.options.port }' established by client '${ this.identifier }' and is ready to be used.`, logger.logSeverity.INFO );
|
|
479
480
|
this.#notifyConnectionObservers();
|
|
480
481
|
|
|
481
482
|
this.#redisConnection.on( "ready", () => {
|
|
482
483
|
this.#clientStatus = clientStatusEnum.CONNECTED;
|
|
484
|
+
logger.log( `Connection to Redis server '${ this.#redisConnection.options.host }:${ this.#redisConnection.options.port }' reestablished by client '${ this.identifier }' and is ready to be used.`, logger.logSeverity.INFO );
|
|
483
485
|
this.#notifyConnectionObservers();
|
|
484
486
|
} );
|
|
485
487
|
|
|
@@ -515,14 +517,13 @@ class RedisClient {
|
|
|
515
517
|
*/
|
|
516
518
|
#notifyConnectionObservers() {
|
|
517
519
|
// Notify all connection observers about the event:
|
|
518
|
-
_.forEach( this.#connectionObservers, (
|
|
520
|
+
_.forEach( this.#connectionObservers, ( connectionObserver ) => {
|
|
519
521
|
if ( this.#clientStatus === clientStatusEnum.CONNECTED ) {
|
|
520
|
-
|
|
521
|
-
connectionObservers.onConnectionRecovered( this.#clientIdentifier );
|
|
522
|
+
connectionObserver.onConnectionRecovered( this.#clientIdentifier );
|
|
522
523
|
} else if ( this.#clientStatus === clientStatusEnum.DISRUPTED ) {
|
|
523
|
-
|
|
524
|
+
connectionObserver.onConnectionDisrupted( this.#clientIdentifier );
|
|
524
525
|
} else if ( this.#clientStatus === clientStatusEnum.DISCONNECTED ) {
|
|
525
|
-
|
|
526
|
+
connectionObserver.onConnectionLost( this.#clientIdentifier );
|
|
526
527
|
}
|
|
527
528
|
} );
|
|
528
529
|
}
|
|
@@ -574,7 +575,7 @@ class RedisClient {
|
|
|
574
575
|
* @returns {Promise<number>}
|
|
575
576
|
* @private
|
|
576
577
|
*/
|
|
577
|
-
#
|
|
578
|
+
#getClientID() {
|
|
578
579
|
let commandArguments = [ "client", "id" ];
|
|
579
580
|
return this.callCommand( commandArguments ).then( ( clientID ) => Number( clientID ) );
|
|
580
581
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
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
|
"author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
package/utils/config.js
CHANGED
|
@@ -73,7 +73,7 @@ const tools = require( "#tools" );
|
|
|
73
73
|
/**
|
|
74
74
|
* @typedef {Object} SettingsLocalization
|
|
75
75
|
* @property {Array<string>} labelsPath
|
|
76
|
-
* @property {
|
|
76
|
+
* @property {TiLocalizationLanguage} language
|
|
77
77
|
*/
|
|
78
78
|
|
|
79
79
|
/**
|
|
@@ -113,7 +113,7 @@ const tools = require( "#tools" );
|
|
|
113
113
|
* @readonly
|
|
114
114
|
* @enum {string} Keys of this ENUM are strings.
|
|
115
115
|
*/
|
|
116
|
-
|
|
116
|
+
const settingsEnum = tools.enum( {
|
|
117
117
|
AUDITING_LOG_CONSOLE_ENABLED: [ "auditing.logConsoleEnabled", "logConsoleEnabled", "" ],
|
|
118
118
|
AUDITING_LOG_DETAILS: [ "auditing.logDetails", "logDetails", "" ],
|
|
119
119
|
AUDITING_LOG_MIN_LEVEL: [ "auditing.logMinLevel", "logMinLevel", "" ],
|
|
@@ -152,7 +152,7 @@ module.exports.setting = settingsEnum;
|
|
|
152
152
|
/** @type {SettingsMain} */
|
|
153
153
|
const settings = require( "#settings" );
|
|
154
154
|
|
|
155
|
-
//
|
|
155
|
+
// Override the remaining settings with ENV variables (if provided):
|
|
156
156
|
if ( settings.auditing ) {
|
|
157
157
|
settings.auditing.logConsoleEnabled = ( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_CONSOLE_ENABLED ) : settings.auditing.logConsoleEnabled;
|
|
158
158
|
settings.auditing.logDetails = ( process.env.TI_AUDITING_LOG_DETAILS !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_DETAILS ) : settings.auditing.logDetails;
|
|
@@ -160,7 +160,7 @@ if ( settings.auditing ) {
|
|
|
160
160
|
settings.auditing.logUsesJSON = ( process.env.TI_AUDITING_LOG_USES_JSON !== undefined ) ? tools.toBool( process.env.TI_AUDITING_LOG_USES_JSON ) : settings.auditing.logUsesJSON;
|
|
161
161
|
}
|
|
162
162
|
if ( settings.localization ) {
|
|
163
|
-
settings.localization.labelsPath = ( process.env.TI_LOCALIZATION_LABELS_PATH !== undefined ) ? process.env.TI_LOCALIZATION_LABELS_PATH : settings.localization.labelsPath;
|
|
163
|
+
settings.localization.labelsPath = ( process.env.TI_LOCALIZATION_LABELS_PATH !== undefined ) ? [ process.env.TI_LOCALIZATION_LABELS_PATH ] : settings.localization.labelsPath;
|
|
164
164
|
settings.localization.language = ( process.env.TI_LOCALIZATION_LANGUAGE !== undefined ) ? process.env.TI_LOCALIZATION_LANGUAGE : settings.localization.language;
|
|
165
165
|
}
|
|
166
166
|
if ( settings.memoryCache ) {
|
|
@@ -186,7 +186,7 @@ if ( process.env.TI_GCLOUD_ENABLED === true && settings.gcloudIntegration ) {
|
|
|
186
186
|
|
|
187
187
|
settings.operationMode = process.env.NODE_ENV || settings.operationMode;
|
|
188
188
|
|
|
189
|
-
//
|
|
189
|
+
// Prevent further modifications to the settings object:
|
|
190
190
|
Object.freeze( settings );
|
|
191
191
|
|
|
192
192
|
/**
|