@vpmedia/simplify 1.32.0 → 1.33.0

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.
Files changed (38) hide show
  1. package/SECURITY.md +5 -0
  2. package/package.json +9 -5
  3. package/src/index.js +5 -0
  4. package/src/logging/AbstractLogHandler.js +23 -0
  5. package/src/logging/ConsoleLogHandler.js +45 -0
  6. package/src/logging/Logger.js +74 -90
  7. package/src/logging/Logger.test.js +67 -11
  8. package/src/logging/OpenTelemetryLogHandler.js +31 -0
  9. package/src/logging/SentryLogHandler.js +47 -0
  10. package/src/logging/const.js +22 -0
  11. package/src/logging/util.js +41 -0
  12. package/src/logging/util.test.js +30 -0
  13. package/src/pagelifecycle/util.js +1 -1
  14. package/src/util/getURLParam.js +2 -2
  15. package/types/index.d.ts +5 -0
  16. package/types/logging/AbstractLogHandler.d.ts +20 -0
  17. package/types/logging/AbstractLogHandler.d.ts.map +1 -0
  18. package/types/logging/ConsoleLogHandler.d.ts +9 -0
  19. package/types/logging/ConsoleLogHandler.d.ts.map +1 -0
  20. package/types/logging/Logger.d.ts +43 -31
  21. package/types/logging/Logger.d.ts.map +1 -1
  22. package/types/logging/OpenTelemetryLogHandler.d.ts +11 -0
  23. package/types/logging/OpenTelemetryLogHandler.d.ts.map +1 -0
  24. package/types/logging/SentryLogHandler.d.ts +9 -0
  25. package/types/logging/SentryLogHandler.d.ts.map +1 -0
  26. package/types/logging/const.d.ts +14 -0
  27. package/types/logging/const.d.ts.map +1 -0
  28. package/types/logging/util.d.ts +4 -0
  29. package/types/logging/util.d.ts.map +1 -0
  30. package/types/util/getURLParam.d.ts +1 -1
  31. package/types/util/getURLParam.d.ts.map +1 -1
  32. package/src/logging/getAppEnvironment.js +0 -22
  33. package/types/logging/getAppEnvironment.d.ts +0 -2
  34. package/types/logging/getAppEnvironment.d.ts.map +0 -1
  35. package/types/util/cloneObject.d.ts +0 -7
  36. package/types/util/cloneObject.d.ts.map +0 -1
  37. package/types/util/deg2rot.d.ts +0 -2
  38. package/types/util/deg2rot.d.ts.map +0 -1
package/SECURITY.md ADDED
@@ -0,0 +1,5 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ If you have found a possible vulnerability please email `andras at vpmedia dot hu`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpmedia/simplify",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "@vpmedia/simplify",
5
5
  "author": "Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)",
6
6
  "license": "MIT",
@@ -23,7 +23,7 @@
23
23
  "@eslint/js": "^9.37.0",
24
24
  "@vitest/coverage-v8": "^3.2.4",
25
25
  "eslint": "^9.37.0",
26
- "eslint-plugin-jsdoc": "^61.1.0",
26
+ "eslint-plugin-jsdoc": "^61.1.4",
27
27
  "eslint-plugin-unicorn": "^61.0.2",
28
28
  "globals": "^16.4.0",
29
29
  "jsdom": "^27.0.0",
@@ -41,11 +41,15 @@
41
41
  "@types/node": "^24.7.2",
42
42
  "eventemitter3": "^5.0.1"
43
43
  },
44
+ "optionalDependencies": {
45
+ "@sentry/browser": "^10.20.0"
46
+ },
44
47
  "scripts": {
45
48
  "build": "exit 0",
46
- "test": "vitest --coverage --pass-with-no-tests",
49
+ "check": "pnpm lint && pnpm test && pnpm typecheck",
50
+ "format": "prettier --write \"./**/*.{js,jsx,mjs,cjs,ts,tsx,json,md,css}\"",
47
51
  "lint": "eslint \"**/*.{js,jsx}\"",
48
- "typecheck": "tsc",
49
- "format": "prettier --write \"./**/*.{js,jsx,mjs,cjs,ts,tsx,json,md,css}\""
52
+ "test": "vitest --coverage",
53
+ "typecheck": "rm -rf types && tsc"
50
54
  }
51
55
  }
package/src/index.js CHANGED
@@ -1,6 +1,11 @@
1
1
  // core
2
2
  export * from './const/http_status.js';
3
+ export { AbstractLogHandler } from './logging/AbstractLogHandler.js';
4
+ export { ConsoleLogHandler } from './logging/ConsoleLogHandler.js';
5
+ export * from './logging/const.js';
3
6
  export { Logger } from './logging/Logger.js';
7
+ export { OpenTelemetryLogHandler } from './logging/OpenTelemetryLogHandler.js';
8
+ export { formatLogMessage, getLogLevelName } from './logging/util.js';
4
9
  export * from './pagelifecycle/const.js';
5
10
  export * from './pagelifecycle/event.js';
6
11
  export * from './pagelifecycle/typedef.js';
@@ -0,0 +1,23 @@
1
+ export class AbstractLogHandler {
2
+ /**
3
+ * Abstract log handler.
4
+ * @param {number} level - Log handler level.
5
+ */
6
+ constructor(level) {
7
+ this.level = level;
8
+ }
9
+
10
+ /**
11
+ * Emit log record.
12
+ * @param {import('./Logger.js').Logger} logger - Logger instance.
13
+ * @param {number} timestamp - Log timestamp.
14
+ * @param {number} level - Log level.
15
+ * @param {string} message - Log message.
16
+ * @param {object} extra - Log extra data.
17
+ * @param {Error} error - Log extra data.
18
+ * @throws {Error}
19
+ */
20
+ emit(logger, timestamp, level, message, extra, error) {
21
+ throw new Error('Not implemented.');
22
+ }
23
+ }
@@ -0,0 +1,45 @@
1
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
2
+ import { LOG_LEVEL_DEBUG } from './const.js';
3
+ import { formatLogMessage } from './util.js';
4
+
5
+ const CONSOLE_FUNCTIONS = [
6
+ null, // silent
7
+ console.debug, // debug
8
+ console.info, // info
9
+ console.warn, // warning
10
+ console.error, // error
11
+ console.error, // fatal
12
+ ];
13
+
14
+ export class ConsoleLogHandler extends AbstractLogHandler {
15
+ /**
16
+ * Console log handler.
17
+ * @param {number} level - Log handler level.
18
+ */
19
+ constructor(level = LOG_LEVEL_DEBUG) {
20
+ super(level);
21
+ }
22
+
23
+ /**
24
+ * Emit log record.
25
+ * @param {import('./Logger.js').Logger} logger - Logger instance.
26
+ * @param {number} timestamp - Log timestamp.
27
+ * @param {number} level - Log level.
28
+ * @param {string} message - Log message.
29
+ * @param {object} extra - Log extra data.
30
+ * @param {Error} error - Log extra data.
31
+ * @throws {Error}
32
+ */
33
+ emit(logger, timestamp, level, message, extra, error) {
34
+ const logMessage = formatLogMessage(logger, timestamp, level, message);
35
+ const consoleFunction = CONSOLE_FUNCTIONS[level];
36
+ if (consoleFunction === null) {
37
+ return;
38
+ }
39
+ if (error) {
40
+ extra === null ? consoleFunction(logMessage, error) : consoleFunction(logMessage, error, extra);
41
+ return;
42
+ }
43
+ extra === null ? consoleFunction(logMessage) : consoleFunction(logMessage, extra);
44
+ }
45
+ }
@@ -1,128 +1,112 @@
1
1
  import { getURLParam } from '../util/getURLParam.js';
2
- import { getAppEnvironment } from './getAppEnvironment.js';
2
+ import {
3
+ LOG_LEVEL_DEBUG,
4
+ LOG_LEVEL_ERROR,
5
+ LOG_LEVEL_FATAL,
6
+ LOG_LEVEL_INFO,
7
+ LOG_LEVEL_SILENT,
8
+ LOG_LEVEL_WARNING,
9
+ } from './const.js';
10
+ import { getAppEnvironment } from './util.js';
3
11
 
4
- export const LEVEL_DEBUG = 4;
5
- export const LEVEL_INFO = 3;
6
- export const LEVEL_WARN = 2;
7
- export const LEVEL_ERROR = 1;
8
- export const LEVEL_SILENT = 0;
12
+ const ROOT_LOGGER_NAME = 'root';
9
13
 
10
14
  export class Logger {
11
15
  /**
12
- * @type {(error: Error) => void}
16
+ * @type {import('./AbstractLogHandler.js').AbstractLogHandler[]}
13
17
  */
14
- static exceptionHandler = null;
15
- /**
16
- * @type {(target: string, level: string, message: string, extraData: object) => void}
17
- */
18
- static suppressedLogHandler = null;
18
+ static handlers = [];
19
19
 
20
20
  /**
21
21
  * Creates a new Logger instance.
22
- * @param {string} name - The logger name.
22
+ * @param {string} [name] - The logger name.
23
23
  */
24
- constructor(name) {
25
- this.name = name;
24
+ constructor(name = ROOT_LOGGER_NAME) {
25
+ this.name = name ?? ROOT_LOGGER_NAME;
26
26
  const appEnvironment = getAppEnvironment();
27
27
  const isProduction = appEnvironment === 'production' || appEnvironment === 'release';
28
- const defaultLevel = isProduction ? LEVEL_SILENT : LEVEL_DEBUG;
28
+ const defaultLevel = isProduction ? LOG_LEVEL_SILENT : LOG_LEVEL_DEBUG;
29
29
  const parameterName = `log_${this.name.toLowerCase()}`;
30
30
  this.level = Number.parseInt(getURLParam(parameterName, getURLParam('log_all', defaultLevel)), 10);
31
31
  }
32
32
 
33
33
  /**
34
- * TBD.
35
- * @param {string} message - TBD.
36
- * @param {object} extraData - TBD.
34
+ * Add log handler.
35
+ * @param {import('./AbstractLogHandler.js').AbstractLogHandler} handler - Log handler.
36
+ */
37
+ static addHandler = (handler) => {
38
+ Logger.handlers.push(handler);
39
+ };
40
+
41
+ /**
42
+ * Emit log record.
43
+ * @param {Logger} logger - Logger instance.
44
+ * @param {number} level - Log level.
45
+ * @param {string} message - Log message.
46
+ * @param {object} extra - Log extra data.
47
+ * @param {Error} [error] - Log exception.
37
48
  */
38
- debug(message, extraData = null) {
39
- if (this.level < LEVEL_DEBUG) {
40
- if (Logger.suppressedLogHandler) {
41
- Logger.suppressedLogHandler(this.name, 'debug', message, extraData);
49
+ static emit = (logger, level, message, extra, error) => {
50
+ const timestamp = Date.now();
51
+ for (const handler of Logger.handlers) {
52
+ if (handler.level >= level) {
53
+ handler.emit(logger, timestamp, level, message, extra, error);
42
54
  }
43
- return;
44
- }
45
- const logMessage = `${Date.now()} [${this.name}] ${message}`;
46
- if (extraData !== null) {
47
- console.debug(logMessage, extraData);
48
- return;
49
55
  }
50
- console.debug(logMessage);
56
+ };
57
+
58
+ /**
59
+ * Emit debug log.
60
+ * @param {string} message - Log message.
61
+ * @param {object} [extra] - Log extra data.
62
+ */
63
+ debug(message, extra = null) {
64
+ Logger.emit(this, LOG_LEVEL_DEBUG, message, extra);
51
65
  }
52
66
 
53
67
  /**
54
- * TBD.
55
- * @param {string} message - TBD.
56
- * @param {object} extraData - TBD.
68
+ * Emit info log.
69
+ * @param {string} message - Log message.
70
+ * @param {object} [extra] - Log extra data.
57
71
  */
58
- info(message, extraData = null) {
59
- if (this.level < LEVEL_INFO) {
60
- if (Logger.suppressedLogHandler) {
61
- Logger.suppressedLogHandler(this.name, 'info', message, extraData);
62
- }
63
- return;
64
- }
65
- const logMessage = `${Date.now()} [${this.name}] ${message}`;
66
- if (extraData !== null) {
67
- console.info(logMessage, extraData);
68
- return;
69
- }
70
- console.info(logMessage);
72
+ info(message, extra = null) {
73
+ Logger.emit(this, LOG_LEVEL_INFO, message, extra);
71
74
  }
72
75
 
73
76
  /**
74
- * TBD.
75
- * @param {string} message - TBD.
76
- * @param {object} extraData - TBD.
77
+ * Emit warning log.
78
+ * @param {string} message - Log message.
79
+ * @param {object} [extra] - Log extra data.
77
80
  */
78
- warn(message, extraData = null) {
79
- if (this.level < LEVEL_WARN) {
80
- if (Logger.suppressedLogHandler) {
81
- Logger.suppressedLogHandler(this.name, 'warning', message, extraData);
82
- }
83
- return;
84
- }
85
- const logMessage = `${Date.now()} [${this.name}] ${message}`;
86
- if (extraData !== null) {
87
- console.warn(logMessage, extraData);
88
- return;
89
- }
90
- console.warn(logMessage);
81
+ warn(message, extra = null) {
82
+ Logger.emit(this, LOG_LEVEL_WARNING, message, extra);
91
83
  }
92
84
 
93
85
  /**
94
- * TBD.
95
- * @param {string} message - TBD.
96
- * @param {object} extraData - TBD.
86
+ * Emit warning log.
87
+ * @param {string} message - Log message.
88
+ * @param {object} [extra] - Log extra data.
97
89
  */
98
- error(message, extraData = null) {
99
- if (this.level < LEVEL_ERROR) {
100
- if (Logger.suppressedLogHandler) {
101
- Logger.suppressedLogHandler(this.name, 'error', message, extraData);
102
- }
103
- return;
104
- }
105
- const logMessage = `${Date.now()} [${this.name}] ${message}`;
106
- if (extraData !== null) {
107
- console.error(logMessage, extraData);
108
- return;
109
- }
110
- console.error(logMessage);
90
+ warning(message, extra = null) {
91
+ Logger.emit(this, LOG_LEVEL_WARNING, message, extra);
111
92
  }
112
93
 
113
94
  /**
114
- * TBD.
115
- * @param {string} message - TBD.
116
- * @param {Error} exception - TBD.
95
+ * Emit error log.
96
+ * @param {string} message - Log message.
97
+ * @param {object} [extra] - Log extra data.
117
98
  */
118
- exception(message, exception) {
119
- if (Logger.exceptionHandler) {
120
- Logger.exceptionHandler(exception);
121
- }
122
- if (this.level < LEVEL_ERROR) {
123
- return;
124
- }
125
- const logMessage = `${Date.now()} [${this.name}] ${message}`;
126
- console.error(logMessage, exception);
99
+ error(message, extra = null) {
100
+ Logger.emit(this, LOG_LEVEL_ERROR, message, extra);
101
+ }
102
+
103
+ /**
104
+ * Emit exception log.
105
+ * @param {string} message - Log message.
106
+ * @param {Error} error - Log error.
107
+ * @param {object} [extra] - Log extra data.
108
+ */
109
+ exception(message, error, extra = null) {
110
+ Logger.emit(this, LOG_LEVEL_FATAL, message, extra, error);
127
111
  }
128
112
  }
@@ -1,14 +1,70 @@
1
- import { LEVEL_DEBUG, Logger } from './Logger.js';
1
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
2
+ import { LOG_LEVEL_DEBUG, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_INFO, LOG_LEVEL_WARNING } from './const.js';
3
+ import { Logger } from './Logger.js';
2
4
 
3
- test('Tests Logger', () => {
5
+ class TestLogHandler extends AbstractLogHandler {
6
+ /**
7
+ * Test log handler.
8
+ */
9
+ constructor() {
10
+ super(LOG_LEVEL_DEBUG);
11
+ this.emitLogLogger = null;
12
+ this.emitLogTimestamp = null;
13
+ this.emitLogLevel = null;
14
+ this.emitLogMessage = null;
15
+ this.emitLogExtra = null;
16
+ this.emitLogError = null;
17
+ }
18
+
19
+ /**
20
+ * Emit log record.
21
+ * @param {import('./Logger.js').Logger} logger - Logger instance.
22
+ * @param {number} timestamp - Log timestamp.
23
+ * @param {number} level - Log level.
24
+ * @param {string} message - Log message.
25
+ * @param {object} extra - Log extra data.
26
+ * @param {Error} error - Log extra data.
27
+ */
28
+ emit(logger, timestamp, level, message, extra, error) {
29
+ this.emitLogLogger = logger;
30
+ this.emitLogTimestamp = timestamp;
31
+ this.emitLogLevel = level;
32
+ this.emitLogMessage = message;
33
+ this.emitLogExtra = extra;
34
+ this.emitLogError = error;
35
+ }
36
+ }
37
+
38
+ test('Tests Logger default level', () => {
39
+ const logger = new Logger('test');
40
+ expect(logger.level).toBe(LOG_LEVEL_DEBUG);
41
+ });
42
+
43
+ test('Tests Logger custom handler', () => {
4
44
  const logger = new Logger('test');
5
- expect(Logger.exceptionHandler).toBe(null);
6
- expect(logger.level).toBe(LEVEL_DEBUG);
7
- let handledError = null;
8
- const exceptionHandler = (error) => {
9
- handledError = error;
10
- };
11
- Logger.exceptionHandler = exceptionHandler;
12
- logger.exception('test', 'error');
13
- expect(handledError).toBe('error');
45
+ const testLogHandler = new TestLogHandler();
46
+ Logger.addHandler(testLogHandler);
47
+ // debug
48
+ logger.debug('debug');
49
+ expect(testLogHandler.emitLogLevel).toBe(LOG_LEVEL_DEBUG);
50
+ expect(testLogHandler.emitLogMessage).toBe('debug');
51
+ // info
52
+ logger.info('info');
53
+ expect(testLogHandler.emitLogLevel).toBe(LOG_LEVEL_INFO);
54
+ expect(testLogHandler.emitLogMessage).toBe('info');
55
+ // info
56
+ logger.warn('warning');
57
+ expect(testLogHandler.emitLogLevel).toBe(LOG_LEVEL_WARNING);
58
+ expect(testLogHandler.emitLogMessage).toBe('warning');
59
+ // error
60
+ logger.error('error');
61
+ expect(testLogHandler.emitLogLevel).toBe(LOG_LEVEL_ERROR);
62
+ expect(testLogHandler.emitLogMessage).toBe('error');
63
+ // exception
64
+ logger.exception('test', new Error('test_error'), { context: 'ctx' });
65
+ expect(testLogHandler.emitLogLevel).toBe(LOG_LEVEL_FATAL);
66
+ expect(testLogHandler.emitLogMessage).toBe('test');
67
+ expect(testLogHandler.emitLogError.message).toBe('test_error');
68
+ expect(testLogHandler.emitLogLogger).toBe(logger);
69
+ expect(testLogHandler.emitLogExtra.context).toBe('ctx');
14
70
  });
@@ -0,0 +1,31 @@
1
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
2
+ import { LOG_LEVEL_DEBUG } from './const.js';
3
+
4
+ export class OpenTelemetryLogHandler extends AbstractLogHandler {
5
+ /**
6
+ * Open Telemetry log handler.
7
+ * @param {number} level - Log handler level.
8
+ * @param {(logger: import('./Logger.js').Logger, timestamp: number, level: number, message: string, extra: object, error: Error) => void} emitter - Log handler emitter.
9
+ */
10
+ constructor(level = LOG_LEVEL_DEBUG, emitter) {
11
+ super(level);
12
+ this.emitter = emitter;
13
+ }
14
+
15
+ /**
16
+ * Emit log record.
17
+ * @param {import('./Logger.js').Logger} logger - Logger instance.
18
+ * @param {number} timestamp - Log timestamp.
19
+ * @param {number} level - Log level.
20
+ * @param {string} message - Log message.
21
+ * @param {object} extra - Log extra data.
22
+ * @param {Error} error - Log extra data.
23
+ * @throws {Error}
24
+ */
25
+ emit(logger, timestamp, level, message, extra, error) {
26
+ if (!this.emitter) {
27
+ return;
28
+ }
29
+ this.emitter(logger, timestamp, level, message, extra, error);
30
+ }
31
+ }
@@ -0,0 +1,47 @@
1
+ import { addBreadcrumb, captureException } from '@sentry/browser';
2
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
3
+ import { LOG_LEVEL_DEBUG } from './const.js';
4
+ import { getLogLevelName } from './util.js';
5
+
6
+ const BREADCRUMB_CATEGORY = 'log';
7
+
8
+ export class SentryLogHandler extends AbstractLogHandler {
9
+ /**
10
+ * Console log handler.
11
+ * @param {number} level - Log handler level.
12
+ */
13
+ constructor(level = LOG_LEVEL_DEBUG) {
14
+ super(level);
15
+ }
16
+
17
+ /**
18
+ * Emit log record.
19
+ * @param {import('./Logger.js').Logger} logger - Logger instance.
20
+ * @param {number} timestamp - Log timestamp.
21
+ * @param {number} level - Log level.
22
+ * @param {string} message - Log message.
23
+ * @param {object} extra - Log extra data.
24
+ * @param {Error} error - Log extra data.
25
+ * @throws {Error}
26
+ */
27
+ emit(logger, timestamp, level, message, extra, error) {
28
+ /** @type {import('@sentry/browser').SeverityLevel} */
29
+ // @ts-ignore
30
+ const levelName = getLogLevelName(level);
31
+ const logMessage = `[${logger.name}] ${message}`;
32
+ const breadcrumb = {
33
+ category: BREADCRUMB_CATEGORY,
34
+ message: logMessage,
35
+ level: levelName,
36
+ data: extra,
37
+ };
38
+ if (logger.level < level) {
39
+ // only capture breadcrumbs if logger is silenced with this level,
40
+ // so no console logs are present for Sentry.
41
+ addBreadcrumb(breadcrumb);
42
+ }
43
+ if (error) {
44
+ captureException(error);
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,22 @@
1
+ export const LOG_LEVEL_SILENT = 0;
2
+ export const LOG_LEVEL_FATAL = 1;
3
+ export const LOG_LEVEL_ERROR = 2;
4
+ export const LOG_LEVEL_WARNING = 3;
5
+ export const LOG_LEVEL_INFO = 4;
6
+ export const LOG_LEVEL_DEBUG = 5;
7
+
8
+ export const LOG_LEVEL_NAME_SILENT = 'silent';
9
+ export const LOG_LEVEL_NAME_FATAL = 'fatal';
10
+ export const LOG_LEVEL_NAME_ERROR = 'error';
11
+ export const LOG_LEVEL_NAME_WARNING = 'warning';
12
+ export const LOG_LEVEL_NAME_INFO = 'info';
13
+ export const LOG_LEVEL_NAME_DEBUG = 'debug';
14
+
15
+ export const LOG_LEVEL_NAMES = [
16
+ LOG_LEVEL_NAME_SILENT,
17
+ LOG_LEVEL_NAME_FATAL,
18
+ LOG_LEVEL_NAME_ERROR,
19
+ LOG_LEVEL_NAME_WARNING,
20
+ LOG_LEVEL_NAME_INFO,
21
+ LOG_LEVEL_NAME_DEBUG,
22
+ ];
@@ -0,0 +1,41 @@
1
+ import { LOG_LEVEL_NAMES } from './const.js';
2
+
3
+ /**
4
+ * Format log message.
5
+ * @param {import('./Logger.js').Logger} logger - Logger target name.
6
+ * @param {number} timestamp - Log timestamp.
7
+ * @param {number} level - Log level.
8
+ * @param {string} message - Log message.
9
+ * @returns {string} Formatted log message.
10
+ */
11
+ export const formatLogMessage = (logger, timestamp, level, message) => `${timestamp} [${logger.name}] ${message}`;
12
+
13
+ /**
14
+ * Get log level name.
15
+ * @param {number} level - Log level.
16
+ * @returns {string} Log level name.
17
+ */
18
+ export const getLogLevelName = (level) => LOG_LEVEL_NAMES[level];
19
+
20
+ /**
21
+ * Returns the application environment identifier.
22
+ * @returns {string} App environment type.
23
+ */
24
+ export const getAppEnvironment = () => {
25
+ let appEnvironment = 'local';
26
+ try {
27
+ if (import.meta['env'].VITE_APP_ENVIRONMENT) {
28
+ appEnvironment = import.meta['env'].VITE_APP_ENVIRONMENT;
29
+ }
30
+ } catch {
31
+ // pass
32
+ }
33
+ try {
34
+ if (process.env.APP_ENVIRONMENT) {
35
+ appEnvironment = process.env.APP_ENVIRONMENT;
36
+ }
37
+ } catch {
38
+ // pass
39
+ }
40
+ return appEnvironment;
41
+ };
@@ -0,0 +1,30 @@
1
+ import {
2
+ LOG_LEVEL_DEBUG,
3
+ LOG_LEVEL_ERROR,
4
+ LOG_LEVEL_FATAL,
5
+ LOG_LEVEL_INFO,
6
+ LOG_LEVEL_NAME_DEBUG,
7
+ LOG_LEVEL_NAME_ERROR,
8
+ LOG_LEVEL_NAME_FATAL,
9
+ LOG_LEVEL_NAME_INFO,
10
+ LOG_LEVEL_NAME_SILENT,
11
+ LOG_LEVEL_NAME_WARNING,
12
+ LOG_LEVEL_SILENT,
13
+ LOG_LEVEL_WARNING,
14
+ } from './const.js';
15
+ import { formatLogMessage, getLogLevelName } from './util.js';
16
+
17
+ test('formatLogMessage()', () => {
18
+ expect(
19
+ formatLogMessage({ name: 'loggerName' }, Date.now, LOG_LEVEL_INFO, 'logMessage').endsWith('[loggerName] logMessage')
20
+ ).toBe(true);
21
+ });
22
+
23
+ test('getLogLevelName()', () => {
24
+ expect(getLogLevelName(LOG_LEVEL_DEBUG)).toBe(LOG_LEVEL_NAME_DEBUG);
25
+ expect(getLogLevelName(LOG_LEVEL_INFO)).toBe(LOG_LEVEL_NAME_INFO);
26
+ expect(getLogLevelName(LOG_LEVEL_WARNING)).toBe(LOG_LEVEL_NAME_WARNING);
27
+ expect(getLogLevelName(LOG_LEVEL_ERROR)).toBe(LOG_LEVEL_NAME_ERROR);
28
+ expect(getLogLevelName(LOG_LEVEL_FATAL)).toBe(LOG_LEVEL_NAME_FATAL);
29
+ expect(getLogLevelName(LOG_LEVEL_SILENT)).toBe(LOG_LEVEL_NAME_SILENT);
30
+ });
@@ -28,7 +28,7 @@ let currentDocumentState = null;
28
28
 
29
29
  let isInitialized = false;
30
30
 
31
- /** @type {{[key: string]: Function[]}} */
31
+ /** @type {{[key: string]: (() => void)[]}} */
32
32
  let callbacks = {};
33
33
 
34
34
  /**
@@ -5,14 +5,14 @@ const urlSearchParams = new URLSearchParams(window.location.search);
5
5
  /**
6
6
  * TBD.
7
7
  * @param {string} key - TBD.
8
- * @param {*} defaultValue - TBD.
8
+ * @param {string | number | boolean} defaultValue - TBD.
9
9
  * @param {boolean} isSanitize - TBD.
10
10
  * @returns {string} TBD.
11
11
  */
12
12
  export const getURLParam = (key, defaultValue = null, isSanitize = true) => {
13
13
  const paramValue = urlSearchParams.get(key);
14
14
  if (paramValue === null || paramValue === undefined) {
15
- return defaultValue;
15
+ return String(defaultValue);
16
16
  }
17
17
  if (isSanitize) {
18
18
  return sanitizeURLParam(paramValue);
package/types/index.d.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  export * from "./const/http_status.js";
2
+ export * from "./logging/const.js";
2
3
  export * from "./pagelifecycle/const.js";
3
4
  export * from "./pagelifecycle/event.js";
4
5
  export * from "./pagelifecycle/typedef.js";
5
6
  export * from "./pagelifecycle/util.js";
7
+ export { AbstractLogHandler } from "./logging/AbstractLogHandler.js";
8
+ export { ConsoleLogHandler } from "./logging/ConsoleLogHandler.js";
6
9
  export { Logger } from "./logging/Logger.js";
10
+ export { OpenTelemetryLogHandler } from "./logging/OpenTelemetryLogHandler.js";
7
11
  export { addLeadingZero } from "./util/addLeadingZero.js";
8
12
  export { capitalize } from "./util/capitalize.js";
9
13
  export { deepMerge } from "./util/deepMerge.js";
@@ -21,6 +25,7 @@ export { saveAsFile } from "./util/saveAsFile.js";
21
25
  export { serverDataToState } from "./util/serverDataToState.js";
22
26
  export { setObjValueByPath } from "./util/setObjValueByPath.js";
23
27
  export { underscoreToCamelCase } from "./util/underscoreToCamelCase.js";
28
+ export { formatLogMessage, getLogLevelName } from "./logging/util.js";
24
29
  export { FetchError, fetchRetry, HTTP_0_ANY } from "./util/fetchRetry.js";
25
30
  export { addFloat, fixFloat, subFloat } from "./util/safeFloat.js";
26
31
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,20 @@
1
+ export class AbstractLogHandler {
2
+ /**
3
+ * Abstract log handler.
4
+ * @param {number} level - Log handler level.
5
+ */
6
+ constructor(level: number);
7
+ level: number;
8
+ /**
9
+ * Emit log record.
10
+ * @param {import('./Logger.js').Logger} logger - Logger instance.
11
+ * @param {number} timestamp - Log timestamp.
12
+ * @param {number} level - Log level.
13
+ * @param {string} message - Log message.
14
+ * @param {object} extra - Log extra data.
15
+ * @param {Error} error - Log extra data.
16
+ * @throws {Error}
17
+ */
18
+ emit(logger: import("./Logger.js").Logger, timestamp: number, level: number, message: string, extra: object, error: Error): void;
19
+ }
20
+ //# sourceMappingURL=AbstractLogHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractLogHandler.d.ts","sourceRoot":"","sources":["../../src/logging/AbstractLogHandler.js"],"names":[],"mappings":"AAAA;IACE;;;OAGG;IACH,mBAFW,MAAM,EAIhB;IADC,cAAkB;IAGpB;;;;;;;;;OASG;IACH,aARW,OAAO,aAAa,EAAE,MAAM,aAC5B,MAAM,SACN,MAAM,WACN,MAAM,SACN,MAAM,SACN,KAAK,QAKf;CACF"}
@@ -0,0 +1,9 @@
1
+ export class ConsoleLogHandler extends AbstractLogHandler {
2
+ /**
3
+ * Console log handler.
4
+ * @param {number} level - Log handler level.
5
+ */
6
+ constructor(level?: number);
7
+ }
8
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
9
+ //# sourceMappingURL=ConsoleLogHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleLogHandler.d.ts","sourceRoot":"","sources":["../../src/logging/ConsoleLogHandler.js"],"names":[],"mappings":"AAaA;IACE;;;OAGG;IACH,oBAFW,MAAM,EAIhB;CAwBF;mCA5CkC,yBAAyB"}
@@ -1,53 +1,65 @@
1
- export const LEVEL_DEBUG: 4;
2
- export const LEVEL_INFO: 3;
3
- export const LEVEL_WARN: 2;
4
- export const LEVEL_ERROR: 1;
5
- export const LEVEL_SILENT: 0;
6
1
  export class Logger {
7
2
  /**
8
- * @type {(error: Error) => void}
3
+ * @type {import('./AbstractLogHandler.js').AbstractLogHandler[]}
9
4
  */
10
- static exceptionHandler: (error: Error) => void;
5
+ static handlers: import("./AbstractLogHandler.js").AbstractLogHandler[];
11
6
  /**
12
- * @type {(target: string, level: string, message: string, extraData: object) => void}
7
+ * Add log handler.
8
+ * @param {import('./AbstractLogHandler.js').AbstractLogHandler} handler - Log handler.
13
9
  */
14
- static suppressedLogHandler: (target: string, level: string, message: string, extraData: object) => void;
10
+ static addHandler: (handler: import("./AbstractLogHandler.js").AbstractLogHandler) => void;
11
+ /**
12
+ * Emit log record.
13
+ * @param {Logger} logger - Logger instance.
14
+ * @param {number} level - Log level.
15
+ * @param {string} message - Log message.
16
+ * @param {object} extra - Log extra data.
17
+ * @param {Error} [error] - Log exception.
18
+ */
19
+ static emit: (logger: Logger, level: number, message: string, extra: object, error?: Error) => void;
15
20
  /**
16
21
  * Creates a new Logger instance.
17
- * @param {string} name - The logger name.
22
+ * @param {string} [name] - The logger name.
18
23
  */
19
- constructor(name: string);
24
+ constructor(name?: string);
20
25
  name: string;
21
26
  level: number;
22
27
  /**
23
- * TBD.
24
- * @param {string} message - TBD.
25
- * @param {object} extraData - TBD.
28
+ * Emit debug log.
29
+ * @param {string} message - Log message.
30
+ * @param {object} [extra] - Log extra data.
31
+ */
32
+ debug(message: string, extra?: object): void;
33
+ /**
34
+ * Emit info log.
35
+ * @param {string} message - Log message.
36
+ * @param {object} [extra] - Log extra data.
26
37
  */
27
- debug(message: string, extraData?: object): void;
38
+ info(message: string, extra?: object): void;
28
39
  /**
29
- * TBD.
30
- * @param {string} message - TBD.
31
- * @param {object} extraData - TBD.
40
+ * Emit warning log.
41
+ * @param {string} message - Log message.
42
+ * @param {object} [extra] - Log extra data.
32
43
  */
33
- info(message: string, extraData?: object): void;
44
+ warn(message: string, extra?: object): void;
34
45
  /**
35
- * TBD.
36
- * @param {string} message - TBD.
37
- * @param {object} extraData - TBD.
46
+ * Emit warning log.
47
+ * @param {string} message - Log message.
48
+ * @param {object} [extra] - Log extra data.
38
49
  */
39
- warn(message: string, extraData?: object): void;
50
+ warning(message: string, extra?: object): void;
40
51
  /**
41
- * TBD.
42
- * @param {string} message - TBD.
43
- * @param {object} extraData - TBD.
52
+ * Emit error log.
53
+ * @param {string} message - Log message.
54
+ * @param {object} [extra] - Log extra data.
44
55
  */
45
- error(message: string, extraData?: object): void;
56
+ error(message: string, extra?: object): void;
46
57
  /**
47
- * TBD.
48
- * @param {string} message - TBD.
49
- * @param {Error} exception - TBD.
58
+ * Emit exception log.
59
+ * @param {string} message - Log message.
60
+ * @param {Error} error - Log error.
61
+ * @param {object} [extra] - Log extra data.
50
62
  */
51
- exception(message: string, exception: Error): void;
63
+ exception(message: string, error: Error, extra?: object): void;
52
64
  }
53
65
  //# sourceMappingURL=Logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/logging/Logger.js"],"names":[],"mappings":"AAGA,0BAA2B,CAAC,CAAC;AAC7B,yBAA0B,CAAC,CAAC;AAC5B,yBAA0B,CAAC,CAAC;AAC5B,0BAA2B,CAAC,CAAC;AAC7B,2BAA4B,CAAC,CAAC;AAE9B;IACE;;OAEG;IACH,yBAFU,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAED;IAC/B;;OAEG;IACH,6BAFU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAElD;IAEnC;;;OAGG;IACH,kBAFW,MAAM,EAShB;IANC,aAAgB;IAKhB,cAAkG;IAGpG;;;;OAIG;IACH,eAHW,MAAM,cACN,MAAM,QAehB;IAED;;;;OAIG;IACH,cAHW,MAAM,cACN,MAAM,QAehB;IAED;;;;OAIG;IACH,cAHW,MAAM,cACN,MAAM,QAehB;IAED;;;;OAIG;IACH,eAHW,MAAM,cACN,MAAM,QAehB;IAED;;;;OAIG;IACH,mBAHW,MAAM,aACN,KAAK,QAWf;CACF"}
1
+ {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/logging/Logger.js"],"names":[],"mappings":"AAaA;IACE;;OAEG;IACH,iBAFU,OAAO,yBAAyB,EAAE,kBAAkB,EAAE,CAE3C;IAerB;;;OAGG;IACH,oBAAqB,SAFV,OAAO,yBAAyB,EAAE,kBAEjB,UAE1B;IAEF;;;;;;;OAOG;IACH,cAAe,QANJ,MAMU,EAAE,OALZ,MAKiB,EAAE,SAJnB,MAI0B,EAAE,OAH5B,MAGiC,EAAE,QAFnC,KAEwC,UAOjD;IApCF;;;OAGG;IACH,mBAFW,MAAM,EAShB;IANC,aAAoC;IAKpC,cAAkG;IA4BpG;;;;OAIG;IACH,eAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,cAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,cAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,iBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,eAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;;OAKG;IACH,mBAJW,MAAM,SACN,KAAK,UACL,MAAM,QAIhB;CACF"}
@@ -0,0 +1,11 @@
1
+ export class OpenTelemetryLogHandler extends AbstractLogHandler {
2
+ /**
3
+ * Open Telemetry log handler.
4
+ * @param {number} level - Log handler level.
5
+ * @param {(logger: import('./Logger.js').Logger, timestamp: number, level: number, message: string, extra: object, error: Error) => void} emitter - Log handler emitter.
6
+ */
7
+ constructor(level: number, emitter: (logger: import("./Logger.js").Logger, timestamp: number, level: number, message: string, extra: object, error: Error) => void);
8
+ emitter: (logger: import("./Logger.js").Logger, timestamp: number, level: number, message: string, extra: object, error: Error) => void;
9
+ }
10
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
11
+ //# sourceMappingURL=OpenTelemetryLogHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenTelemetryLogHandler.d.ts","sourceRoot":"","sources":["../../src/logging/OpenTelemetryLogHandler.js"],"names":[],"mappings":"AAGA;IACE;;;;OAIG;IACH,mBAHW,MAAM,WACN,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,EAKxI;IADC,kBAJkB,OAAO,aAAa,EAAE,MAAM,aAAa,MAAM,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,SAAS,KAAK,KAAK,IAAI,CAIjH;CAmBzB;mCA9BkC,yBAAyB"}
@@ -0,0 +1,9 @@
1
+ export class SentryLogHandler extends AbstractLogHandler {
2
+ /**
3
+ * Console log handler.
4
+ * @param {number} level - Log handler level.
5
+ */
6
+ constructor(level?: number);
7
+ }
8
+ import { AbstractLogHandler } from './AbstractLogHandler.js';
9
+ //# sourceMappingURL=SentryLogHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SentryLogHandler.d.ts","sourceRoot":"","sources":["../../src/logging/SentryLogHandler.js"],"names":[],"mappings":"AAOA;IACE;;;OAGG;IACH,oBAFW,MAAM,EAIhB;CAgCF;mCA7CkC,yBAAyB"}
@@ -0,0 +1,14 @@
1
+ export const LOG_LEVEL_SILENT: 0;
2
+ export const LOG_LEVEL_FATAL: 1;
3
+ export const LOG_LEVEL_ERROR: 2;
4
+ export const LOG_LEVEL_WARNING: 3;
5
+ export const LOG_LEVEL_INFO: 4;
6
+ export const LOG_LEVEL_DEBUG: 5;
7
+ export const LOG_LEVEL_NAME_SILENT: "silent";
8
+ export const LOG_LEVEL_NAME_FATAL: "fatal";
9
+ export const LOG_LEVEL_NAME_ERROR: "error";
10
+ export const LOG_LEVEL_NAME_WARNING: "warning";
11
+ export const LOG_LEVEL_NAME_INFO: "info";
12
+ export const LOG_LEVEL_NAME_DEBUG: "debug";
13
+ export const LOG_LEVEL_NAMES: string[];
14
+ //# sourceMappingURL=const.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../src/logging/const.js"],"names":[],"mappings":"AAAA,+BAAgC,CAAC,CAAC;AAClC,8BAA+B,CAAC,CAAC;AACjC,8BAA+B,CAAC,CAAC;AACjC,gCAAiC,CAAC,CAAC;AACnC,6BAA8B,CAAC,CAAC;AAChC,8BAA+B,CAAC,CAAC;AAEjC,oCAAqC,QAAQ,CAAC;AAC9C,mCAAoC,OAAO,CAAC;AAC5C,mCAAoC,OAAO,CAAC;AAC5C,qCAAsC,SAAS,CAAC;AAChD,kCAAmC,MAAM,CAAC;AAC1C,mCAAoC,OAAO,CAAC;AAE5C,uCAOE"}
@@ -0,0 +1,4 @@
1
+ export function formatLogMessage(logger: import("./Logger.js").Logger, timestamp: number, level: number, message: string): string;
2
+ export function getLogLevelName(level: number): string;
3
+ export function getAppEnvironment(): string;
4
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/logging/util.js"],"names":[],"mappings":"AAUO,yCANI,OAAO,aAAa,EAAE,MAAM,aAC5B,MAAM,SACN,MAAM,WACN,MAAM,GACJ,MAAM,CAE8F;AAO1G,uCAHI,MAAM,GACJ,MAAM,CAE6C;AAMzD,qCAFM,MAAM,CAmBlB"}
@@ -1,2 +1,2 @@
1
- export function getURLParam(key: string, defaultValue?: any, isSanitize?: boolean): string;
1
+ export function getURLParam(key: string, defaultValue?: string | number | boolean, isSanitize?: boolean): string;
2
2
  //# sourceMappingURL=getURLParam.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getURLParam.d.ts","sourceRoot":"","sources":["../../src/util/getURLParam.js"],"names":[],"mappings":"AAWO,iCALI,MAAM,iBACN,GAAC,eACD,OAAO,GACL,MAAM,CAWlB"}
1
+ {"version":3,"file":"getURLParam.d.ts","sourceRoot":"","sources":["../../src/util/getURLParam.js"],"names":[],"mappings":"AAWO,iCALI,MAAM,iBACN,MAAM,GAAG,MAAM,GAAG,OAAO,eACzB,OAAO,GACL,MAAM,CAWlB"}
@@ -1,22 +0,0 @@
1
- /**
2
- * Returns the application environment identifier.
3
- * @returns {string} TBD.
4
- */
5
- export const getAppEnvironment = () => {
6
- let appEnvironment = 'local';
7
- try {
8
- if (import.meta['env'].VITE_APP_ENVIRONMENT) {
9
- appEnvironment = import.meta['env'].VITE_APP_ENVIRONMENT;
10
- }
11
- } catch {
12
- // pass
13
- }
14
- try {
15
- if (process.env.APP_ENVIRONMENT) {
16
- appEnvironment = process.env.APP_ENVIRONMENT;
17
- }
18
- } catch {
19
- // pass
20
- }
21
- return appEnvironment;
22
- };
@@ -1,2 +0,0 @@
1
- export function getAppEnvironment(): string;
2
- //# sourceMappingURL=getAppEnvironment.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getAppEnvironment.d.ts","sourceRoot":"","sources":["../../src/logging/getAppEnvironment.js"],"names":[],"mappings":"AAIO,qCAFM,MAAM,CAmBlB"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Clones an object.
3
- * @param {object} source - A reference to the source object.
4
- * @returns {object} The cloned object.
5
- */
6
- export function cloneObject(source: object): object;
7
- //# sourceMappingURL=cloneObject.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cloneObject.d.ts","sourceRoot":"","sources":["../../src/util/cloneObject.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oCAHW,MAAM,GACJ,MAAM,CAKlB"}
@@ -1,2 +0,0 @@
1
- export function deg2rad(deg: number): number;
2
- //# sourceMappingURL=deg2rot.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deg2rot.d.ts","sourceRoot":"","sources":["../../src/util/deg2rot.js"],"names":[],"mappings":"AAKO,6BAHI,MAAM,GACJ,MAAM,CAIlB"}