@ti-engine/core 1.2.0 → 1.2.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 CHANGED
@@ -2,6 +2,16 @@
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.2.3
6
+ * feat(start instance): add support for providing a custom path to the `.env` file to be used at service startup as process argument. Accepted arguments are `--env`, `--env-file`, `--dotenv`, `--dotenv-path`, and `-e`. The path itself should be relative to the working directory and should include the file name
7
+
8
+ ## Version 1.2.2
9
+ * feat(start instance): change package `dotenv` to `@dotenvx/dotenvx` for loading of ENV variables. The new package supports encrypting the ENV variables. For more information see https://dotenvx.com/docs/
10
+
11
+ ## Version 1.2.1
12
+ * feat(localization): add support for adding custom labels to the localization system. These have to follow the same format as the system labels
13
+ * docs: add section about localization to the `README.md` file
14
+
5
15
  ## Version 1.2.0
6
16
  * feat(config)!: change the setting `localization.labelsPath` to be an array of strings. It can now be used to supply any additional custom labels in one or more files to the framework
7
17
  * feat(message memory cache): implement graceful exception handling during shut down procedure in `receiveMessage` and `sendMessage` methods
package/README.md CHANGED
@@ -497,4 +497,24 @@ OPERATION_MODE
497
497
 
498
498
  ## Advanced topics
499
499
 
500
- Under development...
500
+ ### Localization
501
+
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
+
504
+ The following is an example of a custom localization file (the names in brackets can be replaced with your own values):
505
+
506
+ ```json
507
+ {
508
+ "labels": {
509
+ "[category]": {
510
+ "[sub-category]": {
511
+ "[label]": {
512
+ "en": "[localized label text]"
513
+ }
514
+ }
515
+ }
516
+ }
517
+ }
518
+ ```
519
+
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.
@@ -1,65 +1,65 @@
1
- {
2
- "labels": {
3
- "general": {
4
- "exceptions": {
5
- "0": {
6
- "en": "Unidentified error encountered or unrecognized exception code provided."
7
- },
8
- "1000": {
9
- "en": "Error thrown by internal JS source."
10
- },
11
- "1001": {
12
- "en": "Attempt to construct an abstract class detected."
13
- },
14
- "1002": {
15
- "en": "Attempt to call an abstract method detected."
16
- },
17
- "1003": {
18
- "en": "Invalid or no service domain name provided at microservice startup."
19
- },
20
- "1004": {
21
- "en": "The system cache required for proper engine operation is unavailable."
22
- },
23
- "1005": {
24
- "en": "The provided service handler is not a proper function."
25
- },
26
- "1006": {
27
- "en": "The requested feature is not supported by current configuration or version."
28
- },
29
- "2000": {
30
- "en": "Invalid authorization token provided."
31
- },
32
- "2001": {
33
- "en": "Invalid or expired session encountered."
34
- },
35
- "2002": {
36
- "en": "Attempt for unauthorized access detected."
37
- },
38
- "2003": {
39
- "en": "The system detected tampering with the message received via message exchange."
40
- },
41
- "3000": {
42
- "en": "General error during cross-application communication."
43
- },
44
- "3001": {
45
- "en": "The message sender instance is currently unavailable."
46
- },
47
- "3002": {
48
- "en": "The execution of a service could not complete within the allowed timeout."
49
- },
50
- "3003": {
51
- "en": "The specified service is not found in the service registry."
52
- },
53
- "3004": {
54
- "en": "The specified service is not found in the service definition interface."
55
- },
56
- "3005": {
57
- "en": "No handler found in the interface for the specified service or service version."
58
- },
59
- "3010": {
60
- "en": "Connection retry attempts exceeded the configured limit."
61
- }
62
- }
63
- }
64
- }
1
+ {
2
+ "labels": {
3
+ "general": {
4
+ "exceptions": {
5
+ "0": {
6
+ "en": "Unidentified error encountered or unrecognized exception code provided."
7
+ },
8
+ "1000": {
9
+ "en": "Error thrown by internal JS source."
10
+ },
11
+ "1001": {
12
+ "en": "Attempt to construct an abstract class detected."
13
+ },
14
+ "1002": {
15
+ "en": "Attempt to call an abstract method detected."
16
+ },
17
+ "1003": {
18
+ "en": "Invalid or no service domain name provided at microservice startup."
19
+ },
20
+ "1004": {
21
+ "en": "The system cache required for proper engine operation is unavailable."
22
+ },
23
+ "1005": {
24
+ "en": "The provided service handler is not a proper function."
25
+ },
26
+ "1006": {
27
+ "en": "The requested feature is not supported by current configuration or version."
28
+ },
29
+ "2000": {
30
+ "en": "Invalid authorization token provided."
31
+ },
32
+ "2001": {
33
+ "en": "Invalid or expired session encountered."
34
+ },
35
+ "2002": {
36
+ "en": "Attempt for unauthorized access detected."
37
+ },
38
+ "2003": {
39
+ "en": "The system detected tampering with the message received via message exchange."
40
+ },
41
+ "3000": {
42
+ "en": "General error during cross-application communication."
43
+ },
44
+ "3001": {
45
+ "en": "The message sender instance is currently unavailable."
46
+ },
47
+ "3002": {
48
+ "en": "The execution of a service could not complete within the allowed timeout."
49
+ },
50
+ "3003": {
51
+ "en": "The specified service is not found in the service registry."
52
+ },
53
+ "3004": {
54
+ "en": "The specified service is not found in the service definition interface."
55
+ },
56
+ "3005": {
57
+ "en": "No handler found in the interface for the specified service or service version."
58
+ },
59
+ "3010": {
60
+ "en": "Connection retry attempts exceeded the configured limit."
61
+ }
62
+ }
63
+ }
64
+ }
65
65
  }
@@ -11,7 +11,28 @@
11
11
  const path = require( "path" );
12
12
 
13
13
  // Load any ENV variables defined in a .env file - before including any framework files:
14
- require( "dotenv" ).config( { path: path.join( process.cwd(), ".env" ) } );
14
+ // - If an env file path is provided via process arguments, use it; otherwise, default to CWD/.env
15
+ const envFilePath = ( () => {
16
+ let envPath = path.join( process.cwd(), ".env" );
17
+ try {
18
+ const argv = Array.isArray( process.argv ) ? process.argv.slice( 2 ) : [];
19
+ const aliases = [ "--env", "--env-file", "--dotenv", "--dotenv-path", "-e" ];
20
+ for ( const key of aliases ) {
21
+ const idx = argv.indexOf( key );
22
+ if ( idx !== -1 && idx + 1 < argv.length ) {
23
+ const value = argv[ idx + 1 ];
24
+ if ( typeof value === "string" && !value.startsWith( "-" ) ) {
25
+ envPath = path.join( process.cwd(), value.trim() );
26
+ break;
27
+ }
28
+ }
29
+ }
30
+ } catch {
31
+ }
32
+ return envPath;
33
+ } )();
34
+
35
+ require( "@dotenvx/dotenvx" ).config( { path: envFilePath } );
15
36
 
16
37
  const tools = require( "#tools" );
17
38
  const logger = require( "#logger" );
@@ -36,7 +57,7 @@ const defaultNameFromClass = ( () => {
36
57
 
37
58
  process.env.TI_INSTANCE_NAME = process.env.TI_INSTANCE_NAME || defaultNameFromClass;
38
59
 
39
- // Configure the process error handlers:
60
+ // Configure the process termination handlers to ensure a graceful shutdown:
40
61
 
41
62
  /**
42
63
  * Will be used to gracefully shut down the instance.
@@ -75,6 +96,8 @@ process.on( "SIGBREAK", () => {
75
96
  shutDownInstance( 0 );
76
97
  } );
77
98
 
99
+ // Configure the process general error handlers:
100
+
78
101
  process.on( "unhandledRejection", ( reason ) => {
79
102
  // Check if the fail-fast behavior has been forcefully disabled:
80
103
  const failFastDisabled = tools.toBool( process.env.TI_FAIL_FAST_ON_UNHANDLED_OFF || "" );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ti-engine/core",
3
- "version": "1.2.0",
3
+ "version": "1.2.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",
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "blake2": "^5.0.0",
49
- "dotenv": "^17.2.1",
49
+ "@dotenvx/dotenvx": "^1.49.0",
50
50
  "fs-extra": "^11.3.1",
51
51
  "lodash": "^4.17.21",
52
52
  "node-schedule": "^2.1.1",
@@ -8,16 +8,26 @@
8
8
 
9
9
  const _ = require( "lodash" );
10
10
  const path = require( "path" );
11
+ const labels = require( "#labels" );
11
12
  const config = require( "#config" );
13
+ const logger = require( '#logger' );
14
+ const exceptions = require( '#exceptions' );
12
15
 
13
- // const labelsPath = path.normalize( path.join( process.cwd(), config.getSetting( config.setting.LOCALIZATION_LABELS_PATH ) ) );
14
- // const labels = require( labelsPath );
15
- const labels = require( "#labels" );
16
16
  const defaultEmptyLabel = "!!! label not found !!!";
17
17
 
18
- // TODO: Add functionality to import additional custom labels.
18
+ // Load any custom labels defined in the configuration:
19
+ try {
20
+ const labelsPaths = config.getSetting( config.setting.LOCALIZATION_LABELS_PATH );
21
+ _.forEach( labelsPaths, ( labelsPath ) => {
22
+ let filePath = path.normalize( path.join( process.cwd(), labelsPath ) );
23
+ let fileLabels = require( filePath );
24
+ _.merge( labels, fileLabels );
25
+ } );
26
+ } catch ( error ) {
27
+ logger.log( `Error while trying to load custom labels.`, logger.logSeverity.ERROR, exceptions.raise( error ) );
28
+ }
19
29
 
20
- // prevent further modifications to the labels object:
30
+ // Prevent further modifications to the labels object:
21
31
  Object.freeze( labels );
22
32
 
23
33
  /**