@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.
@@ -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-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
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
- let exceptionCodeEnum = tools.enum( {
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 related exceptions - codes under 2xxx */
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
- // E_COM_UNRECOGNIZED_API_URL: [ 301, "unrecognized api url", "Attempt to access unrecognized or invalid API URL." ],
43
- // E_COM_MISSING_REQUIRED_ARGUMENTS: [ 302, "missing required arguments", "Attempt to execute operation without all required arguments." ],
44
- // E_COM_UNRECOGNIZED_RESPONSE_STRUCTURE: [ 303, "unrecognized response structure", "The received response has unrecognized structure and cannot be parsed or examined." ],
45
- // E_COM_RECEIVED_ERROR_RESPONSE: [ 304, "received error response", "The received response indicates error in the external system." ],
46
- // E_COM_JSON_RPC_DATA_INVALID: [ 305, "json rpc data invalid", "The JSON RPC 2.0 data being verified is not valid." ],
47
- // E_COM_NO_OPEN_CONNECTION: [ 306, "no open connection", "Attempting to do communication request while there is no open connection available." ],
48
- // E_COM_REQUEST_ERROR_RESPONSE: [ 307, "received error response", "The received response indicates error in the external system." ],
49
- // E_COM_CONNECTION_TIMEOUT: [ 308, "connection timeout", "Attempting to do communication request but request timeout." ],
50
- // E_COM_INVALID_API_MAPPING: [ 309, "invalid api mapping", "Attempt to access API URL without proper controller mapping." ],
51
- E_COM_RETRY_ATTEMPTS_EXCEEDED: [ 3010, "retry attempts exceeded", "Connection retry attempts exceeded the configured limit." ]
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 = "labels.general.exceptions." + exceptionCode;
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
- * @method
98
- * @return {string}
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
- * @method
109
- * @return {TiExceptionCode}
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
- * @method
120
- * @return {number}
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
- * @method
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
- * @method
142
- * @return {string}
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
- * @method
153
- * @return {string}
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
- * @method
164
- * @return {Object}
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
- * @method
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 accompany the exception. If more data is added on subsequent Raise calls, it will be merged with the existing one.
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
- // merge the default exception data with the additional one, if it's provided:
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
- // make sure to eliminate any circular dependencies inside the data object (these should never be needed for an error description):
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
  */
@@ -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 logger = require( '#logger' );
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
- try {
20
- const labelsPaths = config.getSetting( config.setting.LOCALIZATION_LABELS_PATH );
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 labels object:
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
- let logSeverityEnum = tools.enum( {
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 in the active cache.
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-2023 Boris Kostadinov <kostadinov.boris@gmail.com>
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