@63klabs/cache-data 1.2.10 → 1.3.2
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 +24 -0
- package/LICENSE.txt +1 -1
- package/README.md +4 -4
- package/package.json +5 -6
- package/src/lib/tools/AWS.classes.js +34 -42
- package/src/lib/tools/DebugAndLog.class.js +194 -148
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,30 @@ Report all vulnerabilities under the [Security menu](https://github.com/63Klabs/
|
|
|
8
8
|
|
|
9
9
|
> Note: This project is still in beta. Even though changes are tested and breaking changes are avoided, things may break.
|
|
10
10
|
|
|
11
|
+
## 1.3.2 (2025-09-12)
|
|
12
|
+
|
|
13
|
+
### Enhancements
|
|
14
|
+
|
|
15
|
+
- `DebugAndLog`: The environment variable `AWS_LAMBDA_LOG_LEVEL` is now checked as well for setting logging level. `LOG_LEVEL` has priority.
|
|
16
|
+
|
|
17
|
+
### Fixes
|
|
18
|
+
|
|
19
|
+
- `DebugAndLog`: Environment and Logging Level value checks are fixed
|
|
20
|
+
|
|
21
|
+
## 1.3.0 (2025-07-16)
|
|
22
|
+
|
|
23
|
+
### Enhancements
|
|
24
|
+
|
|
25
|
+
- Removed AWS SDK V2 support which closes [issue-213](https://github.com/63Klabs/cache-data/issues/213). AWS SDK V2 was for versions of Node 16 and under, and since they are no longer supported Lambda runtimes, support has been removed from cache-data.
|
|
26
|
+
|
|
27
|
+
### Fixes
|
|
28
|
+
|
|
29
|
+
- Addressed deprecation warnings (handled by Amazon Q Developer):
|
|
30
|
+
- Eliminated Warning:
|
|
31
|
+
- querystring@0.2.0 - From aws-sdk v2 (removed aws-sdk v2)
|
|
32
|
+
- Remaining Warning (unavoidable):
|
|
33
|
+
- lodash.get@4.4.2 - From sinon dependency (external package)
|
|
34
|
+
|
|
11
35
|
## 1.2.10 (2025-07-15)
|
|
12
36
|
|
|
13
37
|
### Enhancements
|
package/LICENSE.txt
CHANGED
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ See [Change Log](CHANGELOG.md) for version history and changes.
|
|
|
69
69
|
|
|
70
70
|
## Issues, Features, and Enhancements
|
|
71
71
|
|
|
72
|
-
Visit the [Issues section of the @63Klabs Cache-Data GitHub repository](https://github.com/
|
|
72
|
+
Visit the [Issues section of the @63Klabs Cache-Data GitHub repository](https://github.com/63Klabs/cache-data/issues) for information on reported issues, upcoming fixes and enhancements, and to submit requests.
|
|
73
73
|
|
|
74
74
|
## License
|
|
75
75
|
|
|
@@ -81,8 +81,8 @@ This project is licensed under the MIT License - see the LICENSE.txt file for de
|
|
|
81
81
|
|
|
82
82
|
- Software, DevOps, and Developer Experience Engineer
|
|
83
83
|
- [AWS Certified Developer - Associate](https://www.credly.com/users/chad-kluck/badges)
|
|
84
|
-
- [Website](https://chadkluck.me/)
|
|
85
|
-
- [GitHub](https://github.com/chadkluck)
|
|
86
|
-
- [GitHub
|
|
84
|
+
- [Website: chadkluck.me](https://chadkluck.me/)
|
|
85
|
+
- [GitHub: chadkluck](https://github.com/chadkluck)
|
|
86
|
+
- [GitHub: 63Klabs](https://github.com/63klabs)
|
|
87
87
|
- [Mastodon: @chadkluck@universeodon.com](https://universeodon.com/@chadkluck)
|
|
88
88
|
- [LinkedIn](https://www.linkedin.com/in/chadkluck/)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@63klabs/cache-data",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Cache data from an API endpoint or application process using AWS S3 and DynamoDb",
|
|
5
5
|
"author": "Chad Leigh Kluck (https://chadkluck.me)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"test": "test"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
|
-
"node": ">=
|
|
16
|
+
"node": ">=18.0.0"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"aws-xray-sdk-core": "^3.6.0",
|
|
@@ -25,10 +25,9 @@
|
|
|
25
25
|
"@aws-sdk/client-s3": "3.x",
|
|
26
26
|
"@aws-sdk/client-ssm": "3.x",
|
|
27
27
|
"@aws-sdk/lib-dynamodb": "3.x",
|
|
28
|
-
"
|
|
29
|
-
"chai": "^5.2
|
|
30
|
-
"
|
|
31
|
-
"mocha": "^11.1.0",
|
|
28
|
+
"chai": "^6.0.1",
|
|
29
|
+
"chai-http": "^5.1.2",
|
|
30
|
+
"mocha": "^11.7.1",
|
|
32
31
|
"sinon": "^21.0.0"
|
|
33
32
|
},
|
|
34
33
|
"scripts": {
|
|
@@ -4,19 +4,29 @@ const isTrue = (value) => {
|
|
|
4
4
|
(typeof value === 'string' && value.toLowerCase() === "true")));
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
const USE_XRAY = isTrue(process.env?.CacheData_AWSXRayOn) || isTrue(process.env?.CACHE_DATA_AWS_X_RAY_ON);
|
|
8
|
+
|
|
9
|
+
let AWSXRay = null;
|
|
10
|
+
let xrayInitialized = false;
|
|
11
|
+
|
|
12
|
+
const initializeXRay = () => {
|
|
13
|
+
if (!xrayInitialized && USE_XRAY) {
|
|
14
|
+
try {
|
|
15
|
+
AWSXRay = require("aws-xray-sdk-core");
|
|
16
|
+
const captureOptions = {
|
|
17
|
+
captureRequestInit: true,
|
|
18
|
+
captureResponse: true,
|
|
19
|
+
generateUniqueId: true
|
|
20
|
+
};
|
|
21
|
+
AWSXRay.captureHTTPsGlobal(require('http'), captureOptions);
|
|
22
|
+
AWSXRay.captureHTTPsGlobal(require("https"), captureOptions);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
AWSXRay = null;
|
|
25
|
+
}
|
|
26
|
+
xrayInitialized = true;
|
|
27
|
+
}
|
|
28
|
+
return AWSXRay;
|
|
29
|
+
};
|
|
20
30
|
|
|
21
31
|
/**
|
|
22
32
|
* AWS Helper Functions - Functions to perform common get and put operations for DynamoDB, S3, and SSM parameter store.
|
|
@@ -78,7 +88,9 @@ class AWS {
|
|
|
78
88
|
static #nodeVer = [];
|
|
79
89
|
static #aws_region = null;
|
|
80
90
|
|
|
81
|
-
static #XRayOn
|
|
91
|
+
static get #XRayOn() {
|
|
92
|
+
return initializeXRay() !== null;
|
|
93
|
+
}
|
|
82
94
|
|
|
83
95
|
constructor() {}
|
|
84
96
|
|
|
@@ -133,38 +145,15 @@ class AWS {
|
|
|
133
145
|
REGION: this.REGION,
|
|
134
146
|
SDK_V2: this.SDK_V2,
|
|
135
147
|
SDK_V3: this.SDK_V3,
|
|
136
|
-
AWSXRayOn:
|
|
148
|
+
AWSXRayOn: USE_XRAY
|
|
137
149
|
});
|
|
138
150
|
}
|
|
139
151
|
|
|
140
152
|
static #SDK = (
|
|
141
153
|
function(){
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
dynamo: {
|
|
146
|
-
client: (new DynamoDB.DocumentClient( {region: AWS.REGION} )),
|
|
147
|
-
put: (client, params) => client.put(params).promise(),
|
|
148
|
-
get: (client, params) => client.get(params).promise(),
|
|
149
|
-
scan: (client, params) => client.scan(params).promise(),
|
|
150
|
-
delete: (client, params) => client.delete(params).promise(),
|
|
151
|
-
update: (client, params) => client.update(params).promise(),
|
|
152
|
-
sdk: { DynamoDB }
|
|
153
|
-
},
|
|
154
|
-
s3: {
|
|
155
|
-
client: (new S3()),
|
|
156
|
-
put: (client, params) => client.putObject(params).promise(),
|
|
157
|
-
get: (client, params) => client.getObject(params).promise(),
|
|
158
|
-
sdk: { S3 }
|
|
159
|
-
},
|
|
160
|
-
ssm: {
|
|
161
|
-
client: (new SSM( {region: AWS.REGION} )),
|
|
162
|
-
getByName: (client, params) => client.getParameters(params).promise(),
|
|
163
|
-
getByPath: (client, params) => client.getParametersByPath(params).promise(),
|
|
164
|
-
sdk: { SSM }
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
154
|
+
|
|
155
|
+
if (AWS.SDK_V3) {
|
|
156
|
+
|
|
168
157
|
const { DynamoDBClient} = require("@aws-sdk/client-dynamodb");
|
|
169
158
|
const { DynamoDBDocumentClient, GetCommand, PutCommand, ScanCommand, DeleteCommand, UpdateCommand } = require("@aws-sdk/lib-dynamodb");
|
|
170
159
|
const { S3, GetObjectCommand, PutObjectCommand } = require("@aws-sdk/client-s3");
|
|
@@ -212,7 +201,10 @@ class AWS {
|
|
|
212
201
|
GetParametersCommand
|
|
213
202
|
}
|
|
214
203
|
}
|
|
215
|
-
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
throw new Error("AWS SDK v2 is no longer supported. Please upgrade to Node.js 18 or higher to use AWS SDK v3.");
|
|
216
208
|
}
|
|
217
209
|
}
|
|
218
210
|
)();
|
|
@@ -1,153 +1,230 @@
|
|
|
1
1
|
const { sanitize } = require("./utils");
|
|
2
2
|
const util = require('util');
|
|
3
3
|
|
|
4
|
+
const _getNodeEnv = function() {
|
|
5
|
+
return process.env?.NODE_ENV === "development" ? "development" : "production";
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
"use strict"
|
|
9
|
+
|
|
4
10
|
/**
|
|
5
11
|
* A simple Debug and Logging class.
|
|
6
12
|
*/
|
|
7
13
|
class DebugAndLog {
|
|
8
14
|
|
|
9
15
|
static #logLevel = -1;
|
|
10
|
-
static #
|
|
16
|
+
static #environment = null;
|
|
17
|
+
static #initialNodeEnv = _getNodeEnv();
|
|
18
|
+
static #nodeEnvChangeWarnCount = 0;
|
|
19
|
+
|
|
20
|
+
// in priority order
|
|
21
|
+
static ALLOWED_ENV_TYPE_VAR_NAMES = ["CACHE_DATA_ENV", "DEPLOY_ENVIRONMENT", "DEPLOY_ENV", "ENV_TYPE", "deploy_environment", "ENV", "env", "deployEnvironment", "ENVIRONMENT", "environment"];
|
|
22
|
+
static ALLOWED_LOG_VAR_NAMES = ["CACHE_DATA_LOG_LEVEL", "LOG_LEVEL", "log_level", "detailedLogs", "logLevel", "AWS_LAMBDA_LOG_LEVEL"]
|
|
11
23
|
|
|
12
24
|
static PROD = "PROD";
|
|
13
25
|
static TEST = "TEST";
|
|
14
26
|
static DEV = "DEV";
|
|
15
27
|
|
|
16
|
-
static ENVIRONMENTS = [DebugAndLog.PROD, DebugAndLog.TEST, DebugAndLog.DEV];
|
|
28
|
+
static ENVIRONMENTS = ["PROD", "TEST", "DEV"];//[DebugAndLog.PROD, DebugAndLog.TEST, DebugAndLog.DEV];
|
|
29
|
+
|
|
30
|
+
static LOG = "LOG";
|
|
31
|
+
static ERROR = "ERROR";
|
|
32
|
+
static WARN = "WARN";
|
|
33
|
+
static INFO = "INFO";
|
|
34
|
+
static MSG = "MSG";
|
|
35
|
+
static DIAG = "DIAG";
|
|
36
|
+
static DEBUG = "DEBUG";
|
|
37
|
+
|
|
38
|
+
static LOG_LEVEL_NUM = 0;
|
|
39
|
+
static ERROR_LEVEL_NUM = 0;
|
|
40
|
+
static WARN_LEVEL_NUM = 1;
|
|
41
|
+
static INFO_LEVEL_NUM = 2;
|
|
42
|
+
static MSG_LEVEL_NUM = 3;
|
|
43
|
+
static DIAG_LEVEL_NUM = 4;
|
|
44
|
+
static DEBUG_LEVEL_NUM = 5;
|
|
17
45
|
|
|
18
|
-
static
|
|
19
|
-
static WARN = "WARN"; // 0
|
|
20
|
-
static LOG = "LOG"; // 0
|
|
21
|
-
static MSG = "MSG"; // 1
|
|
22
|
-
static DIAG = "DIAG"; // 3
|
|
23
|
-
static DEBUG = "DEBUG"; // 5
|
|
46
|
+
static PROD_DEFAULT_LEVEL_NUM = 2;
|
|
24
47
|
|
|
25
48
|
constructor() {
|
|
26
49
|
};
|
|
27
50
|
|
|
28
51
|
/**
|
|
29
52
|
* Set the log level.
|
|
53
|
+
* Deprecated. Set Lambda Environment variable CACHE_DATA_LOG_LEVEL, LOG_LEVEL, or AWS_LAMBDA_LOG_LEVEL instead.
|
|
30
54
|
* @param {number} logLevel 0 - 5
|
|
31
|
-
* @param {*} expiration
|
|
55
|
+
* @param {*} expiration Deprecated - no effect
|
|
32
56
|
*/
|
|
33
57
|
static setLogLevel(logLevel = -1, expiration = -1) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
let time = new Date( expiration );
|
|
40
|
-
this.#expiration = time.toISOString();
|
|
41
|
-
} else {
|
|
42
|
-
this.#expiration = -1;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if ( logLevel === -1 || this.nonDefaultLogLevelExpired()) {
|
|
46
|
-
this.#logLevel = this.getDefaultLogLevel();
|
|
58
|
+
DebugAndLog.warn(`DebugAndLog.setLogLevel(${logLevel}, ${expiration}) is deprecated. Use CACHE_DATA_LOG_LEVEL, LOG_LEVEL, or AWS_LAMBDA_LOG_LEVEL environment variable instead.`);
|
|
59
|
+
|
|
60
|
+
if (DebugAndLog.isProduction()) {
|
|
61
|
+
if (Number.isFinite(Number(logLevel)) && Number(logLevel) <= DebugAndLog.PROD_DEFAULT_LEVEL_NUM) {
|
|
62
|
+
this.#logLevel = Number(logLevel);
|
|
47
63
|
} else {
|
|
48
|
-
|
|
49
|
-
DebugAndLog.warn("DebugAndLog: Production environment. Cannot set logLevel higher than 0. Ignoring call to DebugAndLog.setLogLevel("+logLevel+"). Default LogLevel override code should be removed before production");
|
|
50
|
-
this.#logLevel = this.getDefaultLogLevel();
|
|
51
|
-
} else {
|
|
52
|
-
this.#logLevel = logLevel;
|
|
53
|
-
DebugAndLog.msg("DebugAndLog: Override of log level default set: "+logLevel+". Default LogLevel override code should be removed before production");
|
|
54
|
-
if ( this.#expiration === -1 ) {
|
|
55
|
-
DebugAndLog.warn("DebugAndLog: Override of log level default set WITHOUT EXPIRATION. An expiration is recommended.");
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
static nonDefaultLogLevelExpired() {
|
|
64
|
-
let r = false;
|
|
65
|
-
|
|
66
|
-
if ( this.#expiration !== -1 ) {
|
|
67
|
-
let now = new Date();
|
|
68
|
-
if ( now.toISOString() > this.#expiration ) {
|
|
69
|
-
DebugAndLog.warn("DebugAndLog: Override of log level default expired. Call to DebugAndLog.setLogLevel() should be commented out or removed");
|
|
70
|
-
r = true;
|
|
64
|
+
this.#logLevel = DebugAndLog.PROD_DEFAULT_LEVEL_NUM;
|
|
71
65
|
}
|
|
66
|
+
} else if (Number.isFinite(Number(logLevel))) {
|
|
67
|
+
this.#logLevel = Number(logLevel);
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
return
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
*
|
|
79
|
-
* @returns {string} The expiration date of the set log level
|
|
80
|
-
*/
|
|
81
|
-
static getExpiration() {
|
|
82
|
-
return this.#expiration;
|
|
83
|
-
}
|
|
70
|
+
return this.#logLevel;
|
|
71
|
+
};
|
|
84
72
|
|
|
85
73
|
/**
|
|
86
74
|
*
|
|
87
75
|
* @returns {number} The current log level
|
|
88
76
|
*/
|
|
89
77
|
static getLogLevel() {
|
|
90
|
-
|
|
91
|
-
|
|
78
|
+
|
|
79
|
+
if ( this.#logLevel < 0 || DebugAndLog.nodeEnvIsDevelopment() || DebugAndLog.nodeEnvHasChanged() ) {
|
|
80
|
+
this.#logLevel = this.getDefaultLogLevel();
|
|
92
81
|
}
|
|
93
82
|
|
|
94
83
|
return this.#logLevel;
|
|
95
84
|
|
|
96
85
|
}
|
|
97
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Alias for getEnvType()
|
|
89
|
+
*/
|
|
90
|
+
static getEnv() {
|
|
91
|
+
return DebugAndLog.getEnvType();
|
|
92
|
+
};
|
|
93
|
+
|
|
98
94
|
/**
|
|
99
95
|
* Check process.env for an environment variable named
|
|
100
96
|
* env, deployEnvironment, environment, or stage. If they
|
|
101
97
|
* are not set it will return DebugAndLog.PROD which
|
|
102
98
|
* is considered safe (most restrictive)
|
|
103
99
|
* Note: This is the application environment, not the NODE_ENV
|
|
104
|
-
* @returns {string} The current environment.
|
|
100
|
+
* @returns {string} PROD|TEST|DEV - The current environment.
|
|
105
101
|
*/
|
|
106
|
-
static
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
let uE = possibleVars[i].toUpperCase();
|
|
114
|
-
if (e in process.env && process.env[e] !== "" && process.env[e] !== null) {
|
|
115
|
-
env = process.env[e].toUpperCase();
|
|
116
|
-
break; // break out of the for loop
|
|
117
|
-
} else if (uE in process.env && process.env[uE] !== "" && process.env[uE] !== null) {
|
|
118
|
-
env = process.env[uE].toUpperCase();
|
|
119
|
-
break; // break out of the for loop
|
|
120
|
-
}
|
|
121
|
-
};
|
|
102
|
+
static getEnvType() {
|
|
103
|
+
// We can switch if NODE_ENV is set to "development"
|
|
104
|
+
if ( this.#environment === null || DebugAndLog.nodeEnvIsDevelopment() || DebugAndLog.nodeEnvHasChanged) {
|
|
105
|
+
const nodeEnvType = (DebugAndLog.nodeEnvIsDevelopment() ? DebugAndLog.DEV : DebugAndLog.PROD); // if env or deployEnvironment not set, fail to safe
|
|
106
|
+
const envType = DebugAndLog.getEnvTypeFromEnvVar();
|
|
107
|
+
|
|
108
|
+
this.#environment = (DebugAndLog.ENVIRONMENTS.includes(envType) ? envType : nodeEnvType);
|
|
122
109
|
}
|
|
123
|
-
|
|
124
|
-
|
|
110
|
+
|
|
111
|
+
return this.#environment;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
* @returns {string} PROD|TEST|DEV|NONE based upon first environment variable from DebugAndLog.ALLOWED_ENV_TYPE_VAR_NAMES found
|
|
116
|
+
*/
|
|
117
|
+
static getEnvTypeFromEnvVar() {
|
|
118
|
+
let environmentType = "none";
|
|
119
|
+
const possibleVars = DebugAndLog.ALLOWED_ENV_TYPE_VAR_NAMES; // - this is the application env, not the NODE_ENV
|
|
120
|
+
|
|
121
|
+
for (let i in possibleVars) {
|
|
122
|
+
let e = possibleVars[i];
|
|
123
|
+
if (e in process.env && process.env[e] !== "" && process.env[e] !== null && DebugAndLog.ENVIRONMENTS.includes(process.env[e].toUpperCase())) {
|
|
124
|
+
environmentType = process.env[e].toUpperCase();
|
|
125
|
+
break; // break out of the for loop
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return environmentType;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Is Environment Variable NODE_ENV set to "development"?
|
|
134
|
+
*/
|
|
135
|
+
static nodeEnvIsDevelopment() {
|
|
136
|
+
return DebugAndLog.getNodeEnv() === "development";
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Is Environment Variable NODE_ENV set to "production" or "" or undefined?
|
|
141
|
+
*/
|
|
142
|
+
static nodeEnvIsProduction() {
|
|
143
|
+
return !this.nodeEnvIsDevelopment();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Get the current NODE_ENV (returns "production" if not set or if NODE_ENV is set to anything other than "development")
|
|
148
|
+
* Calls DebugAndLog.nodeEnvHasChanged() to log a warning if the value has changed since initialization. Should only change during testing.
|
|
149
|
+
* @returns {string} development|production
|
|
150
|
+
*/
|
|
151
|
+
static getNodeEnv() {
|
|
152
|
+
DebugAndLog.nodeEnvHasChanged();
|
|
153
|
+
return _getNodeEnv();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Checks to see if the current NODE_ENV environment variable has changed since DebugAndLog was initialized.
|
|
158
|
+
* The only time this should happen is while running tests. This should never happen in a production application.
|
|
159
|
+
* If these warnings are triggered as you application is running, something is modifying process.env.NODE_ENV during execution.
|
|
160
|
+
* @returns {boolean}
|
|
161
|
+
*/
|
|
162
|
+
static nodeEnvHasChanged() {
|
|
163
|
+
const hasChanged = _getNodeEnv() !== this.#initialNodeEnv;
|
|
164
|
+
if (hasChanged && this.#logLevel > -1) {
|
|
165
|
+
this.#nodeEnvChangeWarnCount++;
|
|
166
|
+
// if this.#nodeEnvChangeWarnCount == 1 or is divisible by 25
|
|
167
|
+
if (this.#nodeEnvChangeWarnCount === 1 || this.#nodeEnvChangeWarnCount % 100 === 0) {
|
|
168
|
+
DebugAndLog.warn(`DebugAndLog: NODE_ENV changed from initial value of '${this.#initialNodeEnv}' to '${_getNodeEnv()}' during execution. This is not recommended outside of tests.`);
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
this.#nodeEnvChangeWarnCount = 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return hasChanged;
|
|
175
|
+
}
|
|
125
176
|
|
|
126
177
|
/**
|
|
127
178
|
*
|
|
128
179
|
* @returns {number} log level
|
|
129
180
|
*/
|
|
130
181
|
static getDefaultLogLevel() {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
let possibleVars = DebugAndLog.ALLOWED_LOG_VAR_NAMES; // in priority order and we want to evaluate AWS_LAMBDA_LOG_LEVEL as upper
|
|
183
|
+
let logLevel = DebugAndLog.PROD_DEFAULT_LEVEL_NUM;
|
|
184
|
+
let found = false;
|
|
185
|
+
|
|
186
|
+
for (let i in possibleVars) {
|
|
187
|
+
let lev = possibleVars[i];
|
|
188
|
+
if (lev in process.env && process.env[lev] !== "" && process.env[lev] !== null) {
|
|
189
|
+
if (lev === "AWS_LAMBDA_LOG_LEVEL") {
|
|
190
|
+
|
|
191
|
+
switch (process.env.AWS_LAMBDA_LOG_LEVEL) {
|
|
192
|
+
case "DEBUG":
|
|
193
|
+
logLevel = DebugAndLog.DEBUG_LEVEL_NUM;
|
|
194
|
+
found = true;
|
|
195
|
+
break;
|
|
196
|
+
case "INFO":
|
|
197
|
+
logLevel = DebugAndLog.INFO_LEVEL_NUM;
|
|
198
|
+
found = true;
|
|
199
|
+
break;
|
|
200
|
+
case "WARN":
|
|
201
|
+
logLevel = DebugAndLog.WARN_LEVEL_NUM;
|
|
202
|
+
found = true;
|
|
203
|
+
break;
|
|
204
|
+
case "ERROR":
|
|
205
|
+
logLevel = DebugAndLog.ERROR_LEVEL_NUM;
|
|
206
|
+
found = true;
|
|
207
|
+
break;
|
|
208
|
+
default: // invalid
|
|
209
|
+
break;
|
|
146
210
|
}
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
211
|
|
|
150
|
-
|
|
212
|
+
} else if (Number.isFinite(Number(process.env[lev]))) {
|
|
213
|
+
logLevel = Number(process.env[lev]);
|
|
214
|
+
found = true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (found) {
|
|
218
|
+
if (DebugAndLog.isProduction()) {
|
|
219
|
+
if (logLevel > DebugAndLog.PROD_DEFAULT_LEVEL_NUM) {
|
|
220
|
+
DebugAndLog.warn(`DebugAndLog: ${lev} set to ${logLevel} in production environment. Only 0-2 is allowed in production. Setting to ${DebugAndLog.PROD_DEFAULT_LEVEL_NUM}`);
|
|
221
|
+
logLevel = DebugAndLog.PROD_DEFAULT_LEVEL_NUM;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
break; // break out of the for loop
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
151
228
|
|
|
152
229
|
return logLevel;
|
|
153
230
|
};
|
|
@@ -205,44 +282,6 @@ class DebugAndLog {
|
|
|
205
282
|
const FORMAT_WITH_OBJ = '[%s] %s | %s';
|
|
206
283
|
const FORMAT_WITHOUT_OBJ = '[%s] %s';
|
|
207
284
|
|
|
208
|
-
// const baseLog = function(level, tag, message, obj = null) {
|
|
209
|
-
// // Validate inputs
|
|
210
|
-
// if (typeof level !== 'string') {
|
|
211
|
-
// throw new TypeError('Log level must be a string');
|
|
212
|
-
// }
|
|
213
|
-
|
|
214
|
-
// // Ensure tag and message are strings
|
|
215
|
-
// const safeTag = String(tag || '');
|
|
216
|
-
// const safeMessage = String(message || '');
|
|
217
|
-
|
|
218
|
-
// // Validate log level is allowed
|
|
219
|
-
// if (!Object.prototype.hasOwnProperty.call(logLevels, level)) {
|
|
220
|
-
// level = 'info'; // Default to info if invalid level
|
|
221
|
-
// }
|
|
222
|
-
|
|
223
|
-
// const logFn = logLevels[level];
|
|
224
|
-
|
|
225
|
-
// try {
|
|
226
|
-
// let formattedMessage;
|
|
227
|
-
// if (obj !== null) {
|
|
228
|
-
// formattedMessage = util.format(
|
|
229
|
-
// '[%s] %s | %s',
|
|
230
|
-
// safeTag,
|
|
231
|
-
// safeMessage,
|
|
232
|
-
// util.inspect(sanitize(obj), { depth: null })
|
|
233
|
-
// );
|
|
234
|
-
// } else {
|
|
235
|
-
// formattedMessage = util.format(
|
|
236
|
-
// '[%s] %s',
|
|
237
|
-
// safeTag,
|
|
238
|
-
// safeMessage
|
|
239
|
-
// );
|
|
240
|
-
// }
|
|
241
|
-
// logFn(formattedMessage);
|
|
242
|
-
// } catch (error) {
|
|
243
|
-
// console.error('Logging failed:', error);
|
|
244
|
-
// }
|
|
245
|
-
// };
|
|
246
285
|
const baseLog = function(level, tag, message, obj = null) {
|
|
247
286
|
// Early return for invalid input
|
|
248
287
|
if (typeof level !== 'string') {
|
|
@@ -288,33 +327,29 @@ class DebugAndLog {
|
|
|
288
327
|
const info = (tag, message, obj) => baseLog('info', tag, message, obj);
|
|
289
328
|
const debug = (tag, message, obj) => baseLog('debug', tag, message, obj);
|
|
290
329
|
|
|
291
|
-
let lvl = DebugAndLog.getLogLevel();
|
|
292
|
-
|
|
330
|
+
// let lvl = (this.#logLevel > -1) ? DebugAndLog.getLogLevel() : DebugAndLog.MSG_LEVEL_NUM;
|
|
331
|
+
let lvl = (this.#logLevel > -1) ? this.#logLevel : DebugAndLog.INFO_LEVEL_NUM;
|
|
293
332
|
|
|
294
|
-
|
|
295
|
-
// let msgObj = obj;
|
|
296
|
-
// if ( Array.isArray(msgObj)) { msgObj = { array: msgObj};}
|
|
297
|
-
// if ( ""+msgObj === "[object Object]" || ""+msgObj === "[object Array]") {
|
|
298
|
-
// msgObj = JSON.stringify(sanitize(msgObj));
|
|
299
|
-
// }
|
|
300
|
-
// message += " | "+msgObj;
|
|
301
|
-
// }
|
|
333
|
+
tag = tag.toUpperCase();
|
|
302
334
|
|
|
303
335
|
switch (tag) {
|
|
304
336
|
case DebugAndLog.ERROR:
|
|
305
337
|
error(tag, message, obj);
|
|
306
338
|
break;
|
|
307
339
|
case DebugAndLog.WARN:
|
|
308
|
-
warn(tag, message, obj);
|
|
340
|
+
if (lvl >= DebugAndLog.WARN_LEVEL_NUM) { warn(tag, message, obj); }
|
|
309
341
|
break;
|
|
342
|
+
case DebugAndLog.INFO:
|
|
343
|
+
if (lvl >= DebugAndLog.INFO_LEVEL_NUM) { info(tag, message, obj); }
|
|
344
|
+
break;
|
|
310
345
|
case DebugAndLog.MSG:
|
|
311
|
-
if (lvl >=
|
|
346
|
+
if (lvl >= DebugAndLog.MSG_LEVEL_NUM) { info(tag, message, obj); }
|
|
312
347
|
break;
|
|
313
348
|
case DebugAndLog.DIAG:
|
|
314
|
-
if (lvl >=
|
|
349
|
+
if (lvl >= DebugAndLog.DIAG_LEVEL_NUM) { debug(tag, message, obj); }
|
|
315
350
|
break;
|
|
316
351
|
case DebugAndLog.DEBUG:
|
|
317
|
-
if (lvl >=
|
|
352
|
+
if (lvl >= DebugAndLog.DEBUG_LEVEL_NUM) { debug(tag, message, obj); }
|
|
318
353
|
break;
|
|
319
354
|
default: // log
|
|
320
355
|
log(tag, message, obj);
|
|
@@ -343,7 +378,7 @@ class DebugAndLog {
|
|
|
343
378
|
};
|
|
344
379
|
|
|
345
380
|
/**
|
|
346
|
-
* Level
|
|
381
|
+
* Level 2 - Short messages and status
|
|
347
382
|
* @param {string} message
|
|
348
383
|
* @param {object} obj
|
|
349
384
|
*/
|
|
@@ -352,7 +387,7 @@ class DebugAndLog {
|
|
|
352
387
|
};
|
|
353
388
|
|
|
354
389
|
/**
|
|
355
|
-
* Level
|
|
390
|
+
* Level 2 - Short messages and status
|
|
356
391
|
* (same as DebugAndLog.msg() )
|
|
357
392
|
* @param {string} message
|
|
358
393
|
* @param {object} obj
|
|
@@ -361,6 +396,15 @@ class DebugAndLog {
|
|
|
361
396
|
return DebugAndLog.msg(message, obj);
|
|
362
397
|
};
|
|
363
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Level 1 - Short messages and status
|
|
401
|
+
* @param {string} message
|
|
402
|
+
* @param {object} obj
|
|
403
|
+
*/
|
|
404
|
+
static async info(message, obj = null) {
|
|
405
|
+
return DebugAndLog.writeLog(DebugAndLog.INFO, message, obj);
|
|
406
|
+
};
|
|
407
|
+
|
|
364
408
|
/**
|
|
365
409
|
* Level 0 - Production worthy log entries that are not errors or warnings
|
|
366
410
|
* These should be formatted in a consistent manner and typically only
|
|
@@ -413,4 +457,6 @@ class DebugAndLog {
|
|
|
413
457
|
|
|
414
458
|
};
|
|
415
459
|
|
|
460
|
+
DebugAndLog.getLogLevel();
|
|
461
|
+
|
|
416
462
|
module.exports = DebugAndLog;
|