@ti-engine/core 1.3.1 → 1.3.3
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 +18 -0
- package/README.md +7 -9
- package/bin/localization/labels.json +98 -64
- package/components/auditing.js +14 -13
- package/components/service-caller.js +2 -2
- 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
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
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.3
|
|
6
|
+
* feat(exceptions): add new parameter `includeData` to `Exception.asJSON` method which allows the exclusion of the data parameter from the returned JSON
|
|
7
|
+
* feat(exceptions): remove several excessive exception codes that were unlikely to be used
|
|
8
|
+
* fix(localization): add several missing exception labels
|
|
9
|
+
|
|
10
|
+
## Version 1.3.2
|
|
11
|
+
* feat(exceptions): add a set of new exception codes for the needs of any wrapping `web-server` standard communication
|
|
12
|
+
* feat(exception)!: change the default prefix path for exception labels to `system.exceptions.`
|
|
13
|
+
* feat(localization): add an Enum list of all language codes based on ISO 639-1 standard
|
|
14
|
+
* feat(localization): add an option to the `getLabel` method to provide the language code to use for localization. If not provided, the system will use the language code from the `localization.language` setting
|
|
15
|
+
* feat(localization)!: change the default structure of system labels from `labels.general.[...]` to `system.[...]`
|
|
16
|
+
* refactor(localization): add typedefs and JSDoc structure for the objects used in localization
|
|
17
|
+
* refactor(exceptions): refactor and fix various JSDoc descriptions
|
|
18
|
+
* refactor(auditing): change the type name of `LogEntry` to `TiLogEntry` and fix some JSDoc descriptions
|
|
19
|
+
* fix(exceptions): fix an issue which caused the exception to disregard the `description` value sent in the constructor and use the default one instead
|
|
20
|
+
* fix(config): fix an issue with the `TI_LOCALIZATION_LABELS_PATH` variable not respecting that the underlying setting expected an array. Now it is expected to be a single path and it will be wrapped into an array automatically
|
|
21
|
+
* 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
|
|
22
|
+
|
|
5
23
|
## Version 1.3.1
|
|
6
24
|
* feat(service caller): refactor the entire service call execution flow for clarity and better performance
|
|
7
25
|
* feat(service caller): create a new private class `ServiceCallProcessor` to handle individual service calls in a contained scope
|
package/README.md
CHANGED
|
@@ -397,7 +397,7 @@ GCLOUD_PROJECT_ID (Alpha)
|
|
|
397
397
|
LOCALIZATION_LABELS_PATH
|
|
398
398
|
: JSON path `localization.labelsPath`, type `Array<string>`, default `[]`
|
|
399
399
|
: ENV variable `TI_LOCALIZATION_LABELS_PATH`
|
|
400
|
-
: This setting holds a list of paths to custom `.json` files containing additional localization information. By default, the framework also provides such a file with english texts that can be customized further. All additional JSONs in these files have to follow the rules and structure of the `localization` module.
|
|
400
|
+
: This setting holds a list of paths to custom `.json` files containing additional localization information. By default, the framework also provides such a file with english texts that can be customized further. All additional JSONs in these files have to follow the rules and structure of the `localization` module. The ENV variable currently supports providing only a single custom path.
|
|
401
401
|
|
|
402
402
|
LOCALIZATION_LANGUAGE
|
|
403
403
|
: JSON path `localization.language`, type `string`, default `en`
|
|
@@ -501,20 +501,18 @@ OPERATION_MODE
|
|
|
501
501
|
|
|
502
502
|
The **ti-engine** framework provides a localization mechanism that allows you to translate labels into localized text. The framework comes with a default set of labels that can be found in the `localization` module. You can add your own custom labels to this set by providing one or more JSON files with the same structure as the default one (see below). The path to these files should be specified in the `LOCALIZATION_LABELS_PATH` setting. On startup, the framework will load all the JSON files and merge them into a single repository.
|
|
503
503
|
|
|
504
|
-
The following is an example of a custom localization file
|
|
504
|
+
The following is an example of a custom localization file. The names in brackets can be replaced with your own values. The depth of the three is unlimited and can be used to create a hierarchy of labels.
|
|
505
505
|
|
|
506
506
|
```json
|
|
507
507
|
{
|
|
508
|
-
"
|
|
509
|
-
"[category]": {
|
|
510
|
-
"[
|
|
511
|
-
"[
|
|
512
|
-
"en": "[localized label text]"
|
|
513
|
-
}
|
|
508
|
+
"[category]": {
|
|
509
|
+
"[sub-category]": {
|
|
510
|
+
"[label]": {
|
|
511
|
+
"[language code]": "[localized label text]"
|
|
514
512
|
}
|
|
515
513
|
}
|
|
516
514
|
}
|
|
517
515
|
}
|
|
518
516
|
```
|
|
519
517
|
|
|
520
|
-
The individual languages are specified with a two-letter code. 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.
|
|
518
|
+
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.
|
|
@@ -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
|
*/
|
|
@@ -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 ) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
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
|
/**
|
package/utils/exceptions.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* 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.
|
|
3
|
-
* Copyright © 2021-
|
|
3
|
+
* Copyright © 2021-2025 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
4
4
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
5
5
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
6
6
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
@@ -15,7 +15,7 @@ const tools = require( "#tools" );
|
|
|
15
15
|
* @readonly
|
|
16
16
|
* @enum {number}
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
const exceptionCodeEnum = tools.enum( {
|
|
19
19
|
E_UNKNOWN_ERROR: [ 0, "unknown error", "Unidentified error encountered or unrecognized exception code provided." ],
|
|
20
20
|
/** General exceptions - codes under 1xxx */
|
|
21
21
|
E_GEN_JS_INTERNAL_ERROR: [ 1000, "js internal error", "Error thrown by internal JS source." ],
|
|
@@ -25,7 +25,7 @@ let exceptionCodeEnum = tools.enum( {
|
|
|
25
25
|
E_GEN_SYSTEM_CACHE_UNAVAILABLE: [ 1004, "system cache unavailable", "The system cache required for proper engine operation is unavailable." ],
|
|
26
26
|
E_GEN_BAD_SERVICE_HANDLER: [ 1005, "bad service handler", "The provided service handler is not a proper function." ],
|
|
27
27
|
E_GEN_FEATURE_UNSUPPORTED: [ 1006, "feature unsupported", "The requested feature is not supported by current configuration or version." ],
|
|
28
|
-
/** Security & Administration
|
|
28
|
+
/** Security & Administration exceptions - codes under 2xxx */
|
|
29
29
|
E_SEC_INVALID_AUTH_TOKEN: [ 2000, "invalid auth token", "Invalid authorization token provided." ],
|
|
30
30
|
E_SEC_INVALID_EXPIRED_SESSION: [ 2001, "invalid or expired session", "Invalid or expired session encountered." ],
|
|
31
31
|
E_SEC_UNAUTHORIZED_ACCESS: [ 2002, "unauthorized access", "Attempt for unauthorized access detected." ],
|
|
@@ -39,16 +39,18 @@ let exceptionCodeEnum = tools.enum( {
|
|
|
39
39
|
E_COM_SERVICE_HANDLER_NOT_FOUND: [ 3005, "service handler not found", "No handler found in the interface for the specified service or service version." ],
|
|
40
40
|
E_COM_MESSAGE_RECEIVER_UNAVAILABLE: [ 3006, "message receiver unavailable", "The message receiver instance is currently unavailable." ],
|
|
41
41
|
E_COM_MESSAGE_EXCHANGE_BROKEN: [ 3007, "message exchange broken", "The message exchange is irrevocably broken and cannot be used any longer." ],
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
E_COM_RETRY_ATTEMPTS_EXCEEDED: [ 3010, "retry attempts exceeded", "Connection retry attempts exceeded the configured limit." ],
|
|
43
|
+
/** Web server exceptions - codes under 4xxx */
|
|
44
|
+
E_WEB_INVALID_REQUEST_METHOD: [ 4000, "invalid request method", "The request method is not recognized or not supported." ],
|
|
45
|
+
E_WEB_INVALID_REQUEST_URI: [ 4001, "invalid request uri", "The request URI is not recognized or not supported." ],
|
|
46
|
+
E_WEB_INVALID_REQUEST_BODY: [ 4002, "invalid request body", "The request body is not recognized or not supported." ],
|
|
47
|
+
E_WEB_INVALID_REQUEST_QUERY: [ 4003, "invalid request query", "The request query is not recognized or not supported." ],
|
|
48
|
+
E_WEB_INVALID_REQUEST_HEADERS: [ 4004, "invalid request headers", "The request headers are not recognized or not supported." ],
|
|
49
|
+
E_WEB_INVALID_REQUEST_PARAMETERS: [ 4005, "invalid request parameters", "The request parameters are not recognized or not supported." ],
|
|
50
|
+
E_WEB_INVALID_REQUEST_FORMAT: [ 4006, "invalid request format", "The request format is not recognized or not supported." ],
|
|
51
|
+
E_WEB_INVALID_REQUEST_CONTENT_TYPE: [ 4007, "invalid request content type", "The request content type is not recognized or not supported." ],
|
|
52
|
+
E_WEB_INVALID_REQUEST_CONTENT_LENGTH: [ 4008, "invalid request content length", "The request content length is not recognized or not supported." ],
|
|
53
|
+
E_WEB_INVALID_REQUEST_CONTENT_ENCODING: [ 4009, "invalid request content encoding", "The request content encoding is not recognized or not supported." ]
|
|
52
54
|
} );
|
|
53
55
|
|
|
54
56
|
/**
|
|
@@ -56,6 +58,8 @@ let exceptionCodeEnum = tools.enum( {
|
|
|
56
58
|
*/
|
|
57
59
|
module.exports.exceptionCode = exceptionCodeEnum;
|
|
58
60
|
|
|
61
|
+
const labelPath = "system.exceptions.";
|
|
62
|
+
|
|
59
63
|
/**
|
|
60
64
|
* Represents an exception.
|
|
61
65
|
*
|
|
@@ -84,8 +88,8 @@ class Exception {
|
|
|
84
88
|
this.#id = id;
|
|
85
89
|
this.#code = exceptionCode;
|
|
86
90
|
this.#httpCode = undefined;
|
|
87
|
-
this.#label =
|
|
88
|
-
this.#description = exceptionCodeEnum.properties[ exceptionCode ].description;
|
|
91
|
+
this.#label = labelPath + exceptionCode;
|
|
92
|
+
this.#description = description || exceptionCodeEnum.properties[ exceptionCode ].description;
|
|
89
93
|
this.#data = data || {};
|
|
90
94
|
}
|
|
91
95
|
|
|
@@ -94,8 +98,8 @@ class Exception {
|
|
|
94
98
|
/**
|
|
95
99
|
* Unique identifier of the exception instance. Can be used for tracing problems with customer support cases.
|
|
96
100
|
*
|
|
97
|
-
* @
|
|
98
|
-
* @
|
|
101
|
+
* @property
|
|
102
|
+
* @returns {string}
|
|
99
103
|
* @public
|
|
100
104
|
*/
|
|
101
105
|
get id() {
|
|
@@ -105,8 +109,8 @@ class Exception {
|
|
|
105
109
|
/**
|
|
106
110
|
* Identifier code of the exception type.
|
|
107
111
|
*
|
|
108
|
-
* @
|
|
109
|
-
* @
|
|
112
|
+
* @property
|
|
113
|
+
* @returns {TiExceptionCode}
|
|
110
114
|
* @public
|
|
111
115
|
*/
|
|
112
116
|
get code() {
|
|
@@ -116,8 +120,8 @@ class Exception {
|
|
|
116
120
|
/**
|
|
117
121
|
* HTTP error code if relevant.
|
|
118
122
|
*
|
|
119
|
-
* @
|
|
120
|
-
* @
|
|
123
|
+
* @property
|
|
124
|
+
* @returns {number}
|
|
121
125
|
* @public
|
|
122
126
|
*/
|
|
123
127
|
get httpCode() {
|
|
@@ -127,7 +131,7 @@ class Exception {
|
|
|
127
131
|
/**
|
|
128
132
|
* HTTP error code if relevant.
|
|
129
133
|
*
|
|
130
|
-
* @
|
|
134
|
+
* @property
|
|
131
135
|
* @param {number} httpCode
|
|
132
136
|
* @public
|
|
133
137
|
*/
|
|
@@ -138,8 +142,8 @@ class Exception {
|
|
|
138
142
|
/**
|
|
139
143
|
* Localized label identifier.
|
|
140
144
|
*
|
|
141
|
-
* @
|
|
142
|
-
* @
|
|
145
|
+
* @property
|
|
146
|
+
* @returns {string}
|
|
143
147
|
* @public
|
|
144
148
|
*/
|
|
145
149
|
get label() {
|
|
@@ -149,8 +153,8 @@ class Exception {
|
|
|
149
153
|
/**
|
|
150
154
|
* Description or additional technical information that is NOT localized.
|
|
151
155
|
*
|
|
152
|
-
* @
|
|
153
|
-
* @
|
|
156
|
+
* @property
|
|
157
|
+
* @returns {string}
|
|
154
158
|
* @public
|
|
155
159
|
*/
|
|
156
160
|
get description() {
|
|
@@ -160,8 +164,8 @@ class Exception {
|
|
|
160
164
|
/**
|
|
161
165
|
* JSON containing any additional data that has relevance for the exception. Can be converted JavaScript {@link Error} object as well.
|
|
162
166
|
*
|
|
163
|
-
* @
|
|
164
|
-
* @
|
|
167
|
+
* @property
|
|
168
|
+
* @returns {Object}
|
|
165
169
|
* @public
|
|
166
170
|
*/
|
|
167
171
|
get data() {
|
|
@@ -171,7 +175,7 @@ class Exception {
|
|
|
171
175
|
/**
|
|
172
176
|
* JSON containing any additional data that has relevance for the exception. Can be converted JavaScript {@link Error} object as well.
|
|
173
177
|
*
|
|
174
|
-
* @
|
|
178
|
+
* @property
|
|
175
179
|
* @param {Object} data
|
|
176
180
|
* @public
|
|
177
181
|
*/
|
|
@@ -183,17 +187,18 @@ class Exception {
|
|
|
183
187
|
* Extracts the essential information about the Exception and returns it as JSON.
|
|
184
188
|
*
|
|
185
189
|
* @method
|
|
190
|
+
* @param {boolean} [includeData=true] Whether to include the data property in the output.
|
|
186
191
|
* @returns {Object}
|
|
187
192
|
* @public
|
|
188
193
|
*/
|
|
189
|
-
asJSON() {
|
|
194
|
+
asJSON( includeData = true ) {
|
|
190
195
|
return {
|
|
191
196
|
id: this.id,
|
|
192
197
|
code: this.code,
|
|
193
198
|
httpCode: this.httpCode,
|
|
194
199
|
label: this.label,
|
|
195
200
|
description: this.description,
|
|
196
|
-
data: this.data
|
|
201
|
+
data: ( includeData === true ) ? this.data : undefined
|
|
197
202
|
};
|
|
198
203
|
}
|
|
199
204
|
}
|
|
@@ -203,7 +208,7 @@ class Exception {
|
|
|
203
208
|
*
|
|
204
209
|
* @method
|
|
205
210
|
* @param {Error|TiExceptionCode|Exception} source Could be a standard JS Error, an ExceptionCode, or another Exception (in which case it will be raised further).
|
|
206
|
-
* @param {Object} [data] Additional JSON data that can
|
|
211
|
+
* @param {Object} [data] Additional JSON data that can go with the exception. If more data is added on later Raise calls, it will be merged with the existing one.
|
|
207
212
|
* @param {string} [exceptionID] Should be used only in cases when we have a recognizable exception ID beforehand. Should not be entered otherwise!
|
|
208
213
|
* @returns {Exception}
|
|
209
214
|
* @public
|
|
@@ -226,13 +231,13 @@ module.exports.raise = ( source, data, exceptionID ) => {
|
|
|
226
231
|
exception = new Exception( exceptionID || tools.getUUID(), ( exceptionCodeEnum.properties[ source ] ) ? source : module.exports.exceptionCode.E_UNKNOWN_ERROR );
|
|
227
232
|
}
|
|
228
233
|
|
|
229
|
-
//
|
|
234
|
+
// Merge the default exception data with the additional one if it's provided:
|
|
230
235
|
if ( data ) {
|
|
231
236
|
exception.data = _.mergeWith( ( exception.data || {} ), _.cloneDeep( data ), ( objValue, srcValue ) => {
|
|
232
237
|
return ( _.isArray( objValue ) ) ? objValue.concat( srcValue ) : undefined;
|
|
233
238
|
} );
|
|
234
239
|
|
|
235
|
-
//
|
|
240
|
+
// Make sure to eliminate any circular dependencies inside the data object (these should never be needed for an error description):
|
|
236
241
|
exception.data = tools.decycle( exception.data );
|
|
237
242
|
}
|
|
238
243
|
|
|
@@ -243,7 +248,7 @@ module.exports.raise = ( source, data, exceptionID ) => {
|
|
|
243
248
|
* Verifies if the passed object is an Exception.
|
|
244
249
|
*
|
|
245
250
|
* @method
|
|
246
|
-
* @param object
|
|
251
|
+
* @param {*} object
|
|
247
252
|
* @returns {boolean}
|
|
248
253
|
* @public
|
|
249
254
|
*/
|
package/utils/localization.js
CHANGED
|
@@ -6,38 +6,275 @@
|
|
|
6
6
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
const path = require( "node:path" );
|
|
9
10
|
const _ = require( "lodash" );
|
|
10
|
-
const path = require( "path" );
|
|
11
|
-
const labels = require( "#labels" );
|
|
12
11
|
const config = require( "#config" );
|
|
13
|
-
const
|
|
14
|
-
const exceptions = require( '#exceptions' );
|
|
12
|
+
const tools = require( "#tools" );
|
|
15
13
|
|
|
16
14
|
const defaultEmptyLabel = "!!! label not found !!!";
|
|
17
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Enum for defining a localization language based on the ISO 639-1 language code.
|
|
18
|
+
*
|
|
19
|
+
* @readonly
|
|
20
|
+
* @enum {string}
|
|
21
|
+
*/
|
|
22
|
+
const localizationLanguageEnum = tools.enum( {
|
|
23
|
+
// A:
|
|
24
|
+
ABKHAZIAN: [ "ab", "Abkhazian", "Abkhazian" ],
|
|
25
|
+
AFAR: [ "aa", "Afar", "Afar" ],
|
|
26
|
+
AFRIKAANS: [ "af", "Afrikaans", "Afrikaans" ],
|
|
27
|
+
AKAN: [ "ak", "Akan", "Akan" ],
|
|
28
|
+
ALBANIAN: [ "sq", "Albanian", "Albanian" ],
|
|
29
|
+
AMHARIC: [ "am", "Amharic", "Amharic" ],
|
|
30
|
+
ARABIC: [ "ar", "Arabic", "Arabic" ],
|
|
31
|
+
ARAGONESE: [ "an", "Aragonese", "Aragonese" ],
|
|
32
|
+
ARMENIAN: [ "hy", "Armenian", "Armenian" ],
|
|
33
|
+
ASSAMESE: [ "as", "Assamese", "Assamese" ],
|
|
34
|
+
AVARIC: [ "av", "Avaric", "Avaric" ],
|
|
35
|
+
AVESTAN: [ "ae", "Avestan", "Avestan" ],
|
|
36
|
+
AYMARA: [ "ay", "Aymara", "Aymara" ],
|
|
37
|
+
AZERBAIJANI: [ "az", "Azerbaijani", "Azerbaijani" ],
|
|
38
|
+
// B:
|
|
39
|
+
BAMBARA: [ "bm", "Bambara", "Bambara" ],
|
|
40
|
+
BASHKIR: [ "ba", "Bashkir", "Bashkir" ],
|
|
41
|
+
BASQUE: [ "eu", "Basque", "Basque" ],
|
|
42
|
+
BELARUSIAN: [ "be", "Belarusian", "Belarusian" ],
|
|
43
|
+
BENGALI: [ "bn", "Bengali", "Bengali" ],
|
|
44
|
+
BIHARI_LANGUAGES: [ "bh", "Bihari languages", "Bihari languages" ],
|
|
45
|
+
BISLAMA: [ "bi", "Bislama", "Bislama" ],
|
|
46
|
+
BOSNIAN: [ "bs", "Bosnian", "Bosnian" ],
|
|
47
|
+
BRETON: [ "br", "Breton", "Breton" ],
|
|
48
|
+
BULGARIAN: [ "bg", "Bulgarian", "Bulgarian" ],
|
|
49
|
+
BURMESE: [ "my", "Burmese", "Burmese" ],
|
|
50
|
+
// C:
|
|
51
|
+
CATALAN: [ "ca", "Catalan", "Catalan" ],
|
|
52
|
+
CENTRAL_KHMER: [ "km", "Central Khmer", "Central Khmer" ],
|
|
53
|
+
CHAMORRO: [ "ch", "Chamorro", "Chamorro" ],
|
|
54
|
+
CHECHEN: [ "ce", "Chechen", "Chechen" ],
|
|
55
|
+
CHICHEWA: [ "ny", "Chichewa", "Chichewa" ],
|
|
56
|
+
CHINESE: [ "zh", "Chinese", "Chinese" ],
|
|
57
|
+
CHURCH_SLAVIC: [ "cu", "Church Slavic", "Church Slavic" ],
|
|
58
|
+
CHUVASH: [ "cv", "Chuvash", "Chuvash" ],
|
|
59
|
+
CORNISH: [ "kw", "Cornish", "Cornish" ],
|
|
60
|
+
CORSICAN: [ "co", "Corsican", "Corsican" ],
|
|
61
|
+
CREE: [ "cr", "Cree", "Cree" ],
|
|
62
|
+
CROATIAN: [ "hr", "Croatian", "Croatian" ],
|
|
63
|
+
CZECH: [ "cs", "Czech", "Czech" ],
|
|
64
|
+
// D:
|
|
65
|
+
DANISH: [ "da", "Danish", "Danish" ],
|
|
66
|
+
DIVEHI: [ "dv", "Divehi", "Divehi" ],
|
|
67
|
+
DUTCH: [ "nl", "Dutch", "Dutch" ],
|
|
68
|
+
DZONGKHA: [ "dz", "Dzongkha", "Dzongkha" ],
|
|
69
|
+
// E:
|
|
70
|
+
ENGLISH: [ "en", "English", "English" ],
|
|
71
|
+
ESPERANTO: [ "eo", "Esperanto", "Esperanto" ],
|
|
72
|
+
ESTONIAN: [ "et", "Estonian", "Estonian" ],
|
|
73
|
+
EWE: [ "ee", "Ewe", "Ewe" ],
|
|
74
|
+
// F:
|
|
75
|
+
FAROESE: [ "fo", "Faroese", "Faroese" ],
|
|
76
|
+
FIJIAN: [ "fj", "Fijian", "Fijian" ],
|
|
77
|
+
FINNISH: [ "fi", "Finnish", "Finnish" ],
|
|
78
|
+
FRENCH: [ "fr", "French", "French" ],
|
|
79
|
+
FULAH: [ "ff", "Fulah", "Fulah" ],
|
|
80
|
+
FRISIAN_WESTERN: [ "fy", "Western Frisian", "Western Frisian" ],
|
|
81
|
+
// G:
|
|
82
|
+
GAELIC_SCOTTISH: [ "gd", "Scottish Gaelic", "Scottish Gaelic" ],
|
|
83
|
+
GALICIAN: [ "gl", "Galician", "Galician" ],
|
|
84
|
+
GANDA: [ "lg", "Ganda", "Ganda" ],
|
|
85
|
+
GEORGIAN: [ "ka", "Georgian", "Georgian" ],
|
|
86
|
+
GERMAN: [ "de", "German", "German" ],
|
|
87
|
+
GREEK_MODERN: [ "el", "Greek, Modern (1453–)", "Greek, Modern (1453–)" ],
|
|
88
|
+
GUARANI: [ "gn", "Guarani", "Guarani" ],
|
|
89
|
+
GUJARATI: [ "gu", "Gujarati", "Gujarati" ],
|
|
90
|
+
// H:
|
|
91
|
+
HAITIAN: [ "ht", "Haitian", "Haitian" ],
|
|
92
|
+
HAUSA: [ "ha", "Hausa", "Hausa" ],
|
|
93
|
+
HEBREW: [ "he", "Hebrew", "Hebrew" ],
|
|
94
|
+
HERERO: [ "hz", "Herero", "Herero" ],
|
|
95
|
+
HINDI: [ "hi", "Hindi", "Hindi" ],
|
|
96
|
+
HIRI_MOTU: [ "ho", "Hiri Motu", "Hiri Motu" ],
|
|
97
|
+
HUNGARIAN: [ "hu", "Hungarian", "Hungarian" ],
|
|
98
|
+
// I:
|
|
99
|
+
ICELANDIC: [ "is", "Icelandic", "Icelandic" ],
|
|
100
|
+
IDO: [ "io", "Ido", "Ido" ],
|
|
101
|
+
IGBO: [ "ig", "Igbo", "Igbo" ],
|
|
102
|
+
INTERLINGUA: [ "ia", "Interlingua", "Interlingua" ],
|
|
103
|
+
INTERLINGUE: [ "ie", "Interlingue", "Interlingue" ],
|
|
104
|
+
INDONESIAN: [ "id", "Indonesian", "Indonesian" ],
|
|
105
|
+
INUKTITUT: [ "iu", "Inuktitut", "Inuktitut" ],
|
|
106
|
+
INUPIAQ: [ "ik", "Inupiaq", "Inupiaq" ],
|
|
107
|
+
IRISH: [ "ga", "Irish", "Irish" ],
|
|
108
|
+
ITALIAN: [ "it", "Italian", "Italian" ],
|
|
109
|
+
// J:
|
|
110
|
+
JAPANESE: [ "ja", "Japanese", "Japanese" ],
|
|
111
|
+
JAVANESE: [ "jv", "Javanese", "Javanese" ],
|
|
112
|
+
// K:
|
|
113
|
+
KALAALLISUT: [ "kl", "Kalaallisut", "Kalaallisut" ],
|
|
114
|
+
KANNADA: [ "kn", "Kannada", "Kannada" ],
|
|
115
|
+
KASHMIRI: [ "ks", "Kashmiri", "Kashmiri" ],
|
|
116
|
+
KAZAKH: [ "kk", "Kazakh", "Kazakh" ],
|
|
117
|
+
KIKUYU: [ "ki", "Kikuyu", "Kikuyu" ],
|
|
118
|
+
KINYARWANDA: [ "rw", "Kinyarwanda", "Kinyarwanda" ],
|
|
119
|
+
KIRGHIZ: [ "ky", "Kirghiz", "Kirghiz" ],
|
|
120
|
+
KOMI: [ "kv", "Komi", "Komi" ],
|
|
121
|
+
KONGO: [ "kg", "Kongo", "Kongo" ],
|
|
122
|
+
KOREAN: [ "ko", "Korean", "Korean" ],
|
|
123
|
+
KUANYAMA: [ "kj", "Kuanyama", "Kuanyama" ],
|
|
124
|
+
KURDISH: [ "ku", "Kurdish", "Kurdish" ],
|
|
125
|
+
// L:
|
|
126
|
+
LAO: [ "lo", "Lao", "Lao" ],
|
|
127
|
+
LATIN: [ "la", "Latin", "Latin" ],
|
|
128
|
+
LATVIAN: [ "lv", "Latvian", "Latvian" ],
|
|
129
|
+
LIMBURGAN: [ "li", "Limburgan", "Limburgan" ],
|
|
130
|
+
LINGALA: [ "ln", "Lingala", "Lingala" ],
|
|
131
|
+
LITHUANIAN: [ "lt", "Lithuanian", "Lithuanian" ],
|
|
132
|
+
LUBA_KATANGA: [ "lu", "Luba-Katanga", "Luba-Katanga" ],
|
|
133
|
+
LUXEMBOURGISH: [ "lb", "Luxembourgish", "Luxembourgish" ],
|
|
134
|
+
// M:
|
|
135
|
+
MACEDONIAN: [ "mk", "Macedonian", "Macedonian" ],
|
|
136
|
+
MALAGASY: [ "mg", "Malagasy", "Malagasy" ],
|
|
137
|
+
MALAY: [ "ms", "Malay", "Malay" ],
|
|
138
|
+
MALAYALAM: [ "ml", "Malayalam", "Malayalam" ],
|
|
139
|
+
MALTESE: [ "mt", "Maltese", "Maltese" ],
|
|
140
|
+
MANX: [ "gv", "Manx", "Manx" ],
|
|
141
|
+
MAORI: [ "mi", "Maori", "Maori" ],
|
|
142
|
+
MARATHI: [ "mr", "Marathi", "Marathi" ],
|
|
143
|
+
MARSHALLESE: [ "mh", "Marshallese", "Marshallese" ],
|
|
144
|
+
MONGOLIAN: [ "mn", "Mongolian", "Mongolian" ],
|
|
145
|
+
// N:
|
|
146
|
+
NAURU: [ "na", "Nauru", "Nauru" ],
|
|
147
|
+
NAVAJO: [ "nv", "Navajo", "Navajo" ],
|
|
148
|
+
NDEBELE_NORTH: [ "nd", "North Ndebele", "North Ndebele" ],
|
|
149
|
+
NDEBELE_SOUTH: [ "nr", "South Ndebele", "South Ndebele" ],
|
|
150
|
+
NDONGA: [ "ng", "Ndonga", "Ndonga" ],
|
|
151
|
+
NEPALI: [ "ne", "Nepali", "Nepali" ],
|
|
152
|
+
NORTHERN_SAMI: [ "se", "Northern Sami", "Northern Sami" ],
|
|
153
|
+
NORWEGIAN: [ "no", "Norwegian", "Norwegian" ],
|
|
154
|
+
NORWEGIAN_BOKMAL: [ "nb", "Norwegian Bokmål", "Norwegian Bokmål" ],
|
|
155
|
+
NORWEGIAN_NYNORSK: [ "nn", "Norwegian Nynorsk", "Norwegian Nynorsk" ],
|
|
156
|
+
// O:
|
|
157
|
+
OCCITAN: [ "oc", "Occitan", "Occitan" ],
|
|
158
|
+
OJIBWA: [ "oj", "Ojibwa", "Ojibwa" ],
|
|
159
|
+
ORIYA: [ "or", "Oriya", "Oriya" ],
|
|
160
|
+
OROMO: [ "om", "Oromo", "Oromo" ],
|
|
161
|
+
OSSETIAN: [ "os", "Ossetian", "Ossetian" ],
|
|
162
|
+
// P:
|
|
163
|
+
PANJABI: [ "pa", "Panjabi", "Panjabi" ],
|
|
164
|
+
PALI: [ "pi", "Pali", "Pali" ],
|
|
165
|
+
PASHTO: [ "ps", "Pashto", "Pashto" ],
|
|
166
|
+
POLISH: [ "pl", "Polish", "Polish" ],
|
|
167
|
+
PORTUGUESE: [ "pt", "Portuguese", "Portuguese" ],
|
|
168
|
+
// Q:
|
|
169
|
+
QUECHUA: [ "qu", "Quechua", "Quechua" ],
|
|
170
|
+
// R:
|
|
171
|
+
ROMANIAN: [ "ro", "Romanian", "Romanian" ],
|
|
172
|
+
ROMANSH: [ "rm", "Romansh", "Romansh" ],
|
|
173
|
+
RUNDI: [ "rn", "Rundi", "Rundi" ],
|
|
174
|
+
RUSSIAN: [ "ru", "Russian", "Russian" ],
|
|
175
|
+
// S:
|
|
176
|
+
SANGO: [ "sg", "Sango", "Sango" ],
|
|
177
|
+
SANSKRIT: [ "sa", "Sanskrit", "Sanskrit" ],
|
|
178
|
+
SARDINIAN: [ "sc", "Sardinian", "Sardinian" ],
|
|
179
|
+
SERBIAN: [ "sr", "Serbian", "Serbian" ],
|
|
180
|
+
SHONA: [ "sn", "Shona", "Shona" ],
|
|
181
|
+
SINDHI: [ "sd", "Sindhi", "Sindhi" ],
|
|
182
|
+
SINHALA: [ "si", "Sinhala", "Sinhala" ],
|
|
183
|
+
SLOVAK: [ "sk", "Slovak", "Slovak" ],
|
|
184
|
+
SLOVENIAN: [ "sl", "Slovenian", "Slovenian" ],
|
|
185
|
+
SOMALI: [ "so", "Somali", "Somali" ],
|
|
186
|
+
SOTHO_SOUTHERN: [ "st", "Southern Sotho", "Southern Sotho" ],
|
|
187
|
+
SPANISH: [ "es", "Spanish", "Spanish" ],
|
|
188
|
+
SUNDANESE: [ "su", "Sundanese", "Sundanese" ],
|
|
189
|
+
SWAHILI: [ "sw", "Swahili", "Swahili" ],
|
|
190
|
+
SWATI: [ "ss", "Swati", "Swati" ],
|
|
191
|
+
SWEDISH: [ "sv", "Swedish", "Swedish" ],
|
|
192
|
+
// T:
|
|
193
|
+
TAGALOG: [ "tl", "Tagalog", "Tagalog" ],
|
|
194
|
+
TAHITIAN: [ "ty", "Tahitian", "Tahitian" ],
|
|
195
|
+
TAJIK: [ "tg", "Tajik", "Tajik" ],
|
|
196
|
+
TAMIL: [ "ta", "Tamil", "Tamil" ],
|
|
197
|
+
TATAR: [ "tt", "Tatar", "Tatar" ],
|
|
198
|
+
TELUGU: [ "te", "Telugu", "Telugu" ],
|
|
199
|
+
THAI: [ "th", "Thai", "Thai" ],
|
|
200
|
+
TIBETAN: [ "bo", "Tibetan", "Tibetan" ],
|
|
201
|
+
TIGRINYA: [ "ti", "Tigrinya", "Tigrinya" ],
|
|
202
|
+
TONGA: [ "to", "Tonga", "Tonga" ],
|
|
203
|
+
TSONGA: [ "ts", "Tsonga", "Tsonga" ],
|
|
204
|
+
TSWANA: [ "tn", "Tswana", "Tswana" ],
|
|
205
|
+
TURKISH: [ "tr", "Turkish", "Turkish" ],
|
|
206
|
+
TURKMEN: [ "tk", "Turkmen", "Turkmen" ],
|
|
207
|
+
TWI: [ "tw", "Twi", "Twi" ],
|
|
208
|
+
// U:
|
|
209
|
+
UIGHUR: [ "ug", "Uighur", "Uighur" ],
|
|
210
|
+
UKRAINIAN: [ "uk", "Ukrainian", "Ukrainian" ],
|
|
211
|
+
URDU: [ "ur", "Urdu", "Urdu" ],
|
|
212
|
+
UZBEK: [ "uz", "Uzbek", "Uzbek" ],
|
|
213
|
+
// V:
|
|
214
|
+
VENDA: [ "ve", "Venda", "Venda" ],
|
|
215
|
+
VIETNAMESE: [ "vi", "Vietnamese", "Vietnamese" ],
|
|
216
|
+
VOLAPUK: [ "vo", "Volapük", "Volapük" ],
|
|
217
|
+
// W:
|
|
218
|
+
WALLON: [ "wa", "Walloon", "Walloon" ],
|
|
219
|
+
WELSH: [ "cy", "Welsh", "Welsh" ],
|
|
220
|
+
WOLOF: [ "wo", "Wolof", "Wolof" ],
|
|
221
|
+
// X:
|
|
222
|
+
XHOSA: [ "xh", "Xhosa", "Xhosa" ],
|
|
223
|
+
// Y:
|
|
224
|
+
YIDDISH: [ "yi", "Yiddish", "Yiddish" ],
|
|
225
|
+
YORUBA: [ "yo", "Yoruba", "Yoruba" ],
|
|
226
|
+
// Z:
|
|
227
|
+
ZHUANG: [ "za", "Zhuang", "Zhuang" ],
|
|
228
|
+
ZULU: [ "zu", "Zulu", "Zulu" ]
|
|
229
|
+
} );
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* @typedef {string} TiLocalizationLanguage
|
|
233
|
+
*/
|
|
234
|
+
module.exports.localizationLanguage = localizationLanguageEnum;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The key of this object is the language code, and the value is the textual representation of the label.
|
|
238
|
+
*
|
|
239
|
+
* @typedef {Object<TiLocalizationLanguage, string>} TiLocalizedLabel
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A nested labels tree where intermediate nodes are objects and leaf nodes are language-to-text maps.
|
|
244
|
+
*
|
|
245
|
+
* @typedef {Object<string, TiLocalizedLabel | TiLabelsTree>} TiLabelsTree
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @typedef {Object} TiLabels
|
|
250
|
+
* @property {TiLabelsTree} labels
|
|
251
|
+
*/
|
|
252
|
+
|
|
253
|
+
/** @type {TiLabels} */
|
|
254
|
+
const labels = require( "#labels" );
|
|
255
|
+
|
|
18
256
|
// Load any custom labels defined in the configuration:
|
|
19
|
-
|
|
20
|
-
|
|
257
|
+
const labelsPaths = config.getSetting( config.setting.LOCALIZATION_LABELS_PATH );
|
|
258
|
+
if ( labelsPaths && _.isArray( labelsPaths ) && labelsPaths.length > 0 ) {
|
|
21
259
|
_.forEach( labelsPaths, ( labelsPath ) => {
|
|
22
260
|
let filePath = path.normalize( path.join( process.cwd(), labelsPath ) );
|
|
23
261
|
let fileLabels = require( filePath );
|
|
24
262
|
_.merge( labels, fileLabels );
|
|
25
263
|
} );
|
|
26
|
-
} catch ( error ) {
|
|
27
|
-
logger.log( `Error while trying to load custom labels.`, logger.logSeverity.ERROR, exceptions.raise( error ) );
|
|
28
264
|
}
|
|
29
265
|
|
|
30
|
-
// Prevent further modifications to the
|
|
266
|
+
// Prevent further modifications to the TiLabels object:
|
|
31
267
|
Object.freeze( labels );
|
|
32
268
|
|
|
33
269
|
/**
|
|
34
|
-
* Used to return the textual value for a label based on the current system language.
|
|
270
|
+
* Used to return the textual value for a label based on the current system language by default or the specified language code if provided.
|
|
35
271
|
*
|
|
36
272
|
* @method
|
|
37
273
|
* @param {string} label This should be a dot-separated JSON path string.
|
|
274
|
+
* @param {TiLocalizationLanguage} [language] The language code to use for the lookup. If not provided, the current system language will be used.
|
|
38
275
|
* @returns {string}
|
|
39
276
|
* @public
|
|
40
277
|
*/
|
|
41
|
-
module.exports.getLabel = ( label ) => {
|
|
42
|
-
return _.get( labels, label + "." + config.getSetting( config.setting.LOCALIZATION_LANGUAGE ), defaultEmptyLabel );
|
|
278
|
+
module.exports.getLabel = ( label, language ) => {
|
|
279
|
+
return _.get( labels, label + "." + ( ( language ) ? language : config.getSetting( config.setting.LOCALIZATION_LANGUAGE ) ), defaultEmptyLabel );
|
|
43
280
|
};
|
package/utils/logger.js
CHANGED
|
@@ -17,7 +17,7 @@ const localization = require( "#localization" );
|
|
|
17
17
|
* @readonly
|
|
18
18
|
* @enum {number}
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
const logSeverityEnum = tools.enum( {
|
|
21
21
|
DEFAULT: [ 0, "default", "The log entry has no assigned severity level." ],
|
|
22
22
|
DEBUG: [ 100, "debug", "Debug or trace information." ],
|
|
23
23
|
INFO: [ 200, "info", "Routine information, such as ongoing status or performance." ],
|
|
@@ -46,7 +46,7 @@ module.exports.getSeverityName = ( severity ) => {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* Used to extract information from an Exception and convert it to loggable data object.
|
|
49
|
+
* Used to extract information from an Exception and convert it to a loggable data object.
|
|
50
50
|
*
|
|
51
51
|
* @method
|
|
52
52
|
* @param {Exception} exception
|
|
@@ -62,7 +62,7 @@ const exceptionToLog = ( exception ) => {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
|
-
* Used to generate and store a log entry
|
|
65
|
+
* Used to generate and store a new log entry via the active {@link Auditing} instance.
|
|
66
66
|
*
|
|
67
67
|
* @method
|
|
68
68
|
* @param {string} message The primary log message.
|
package/utils/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* 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.
|
|
3
|
-
* Copyright © 2021-
|
|
3
|
+
* Copyright © 2021-2025 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
4
4
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
5
5
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
6
6
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const _ = require( "lodash" );
|
|
10
10
|
const fs = require( "fs-extra" );
|
|
11
|
-
const crypto = require( "crypto" );
|
|
11
|
+
const crypto = require( "node:crypto" );
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @typedef {Object} TiEnumValue
|