web-push-notifications 3.40.3 → 3.44.1

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 (149) hide show
  1. package/.editorconfig +11 -0
  2. package/.gitlab-ci.yml +190 -0
  3. package/babel.config.js +7 -0
  4. package/ci/cdn/Dockerfile +12 -0
  5. package/ci/dev/Dockerfile +30 -0
  6. package/ci/dev/rootfs/entrypoint.sh +18 -0
  7. package/ci/dev/rootfs/entrypoint.sh.d/nginx.sh +6 -0
  8. package/ci/dev/rootfs/entrypoint.sh.d/supervisor.sh +5 -0
  9. package/ci/dev/rootfs/etc/nginx/_real_ip.conf +2 -0
  10. package/ci/dev/rootfs/etc/nginx/conf.d/default.conf +20 -0
  11. package/ci/dev/rootfs/etc/supervisor.d/nginx.ini +11 -0
  12. package/ci/github/Dockerfile +59 -0
  13. package/ci/github/release-zip.js +61 -0
  14. package/ci/npm/Dockerfile +19 -0
  15. package/config/config.js +24 -0
  16. package/config/configBuilder.js +126 -0
  17. package/config/helpers.js +9 -0
  18. package/config/index.js +1 -0
  19. package/develop/README.md +42 -0
  20. package/develop/favicon.png +0 -0
  21. package/develop/index.html +511 -0
  22. package/eslint.config.mjs +114 -0
  23. package/package.json +4 -34
  24. package/{lib → public}/index.d.ts +10 -10
  25. package/scripts/zip.js +26 -0
  26. package/src/core/Pushwoosh.ts +768 -0
  27. package/src/core/Pushwoosh.types.ts +254 -0
  28. package/src/core/Safari.types.ts +26 -0
  29. package/src/core/constants.ts +58 -0
  30. package/src/core/events.types.ts +46 -0
  31. package/src/core/functions.ts +33 -0
  32. package/src/core/legacyEventsMap.ts +64 -0
  33. package/src/core/logger.ts +64 -0
  34. package/src/core/modules/EventBus/EventBus.ts +66 -0
  35. package/src/core/modules/EventBus/index.ts +1 -0
  36. package/src/core/storage.ts +254 -0
  37. package/src/helpers/logger.ts +81 -0
  38. package/src/helpers/pwlogger/Logger.constants.ts +31 -0
  39. package/src/helpers/pwlogger/Logger.ts +218 -0
  40. package/src/helpers/pwlogger/Logger.types.ts +66 -0
  41. package/src/helpers/pwlogger/handlers/handler-console/handler-console.ts +40 -0
  42. package/src/helpers/pwlogger/index.ts +2 -0
  43. package/src/helpers/unescape.ts +36 -0
  44. package/src/models/InboxMessages.ts +202 -0
  45. package/src/models/InboxMessages.types.ts +111 -0
  46. package/src/models/NotificationPayload.ts +216 -0
  47. package/src/models/NotificationPayload.types.ts +65 -0
  48. package/src/modules/Api/Api.ts +386 -0
  49. package/src/modules/Api/Api.types.ts +7 -0
  50. package/src/modules/ApiClient/ApiClient.ts +153 -0
  51. package/src/modules/ApiClient/ApiClient.types.ts +222 -0
  52. package/src/modules/Data/Data.ts +345 -0
  53. package/src/modules/DateModule.ts +53 -0
  54. package/src/modules/InboxMessagesPublic.ts +222 -0
  55. package/src/modules/PlatformChecker/PlatformChecker.ts +170 -0
  56. package/src/modules/PlatformChecker/PlatformChecker.types.ts +5 -0
  57. package/src/modules/PlatformChecker/index.ts +1 -0
  58. package/src/modules/storage/Storage.ts +164 -0
  59. package/src/modules/storage/Storage.types.ts +54 -0
  60. package/src/modules/storage/Store.ts +104 -0
  61. package/src/modules/storage/migrations/26-11-2018.ts +25 -0
  62. package/src/modules/storage/migrations/MigrationExecutor.ts +31 -0
  63. package/src/modules/storage/migrations/Migrations.ts +41 -0
  64. package/src/modules/storage/migrations/constants.ts +8 -0
  65. package/src/modules/storage/migrations/helpers.ts +16 -0
  66. package/src/modules/storage/migrations/initial.ts +47 -0
  67. package/src/modules/storage/version.ts +2 -0
  68. package/src/npm.ts +1 -0
  69. package/src/pushwoosh-web-notifications.ts +47 -0
  70. package/src/pushwoosh-widget-inbox.ts +8 -0
  71. package/src/pushwoosh-widget-subscribe-popup.ts +9 -0
  72. package/src/pushwoosh-widget-subscription-button.ts +8 -0
  73. package/src/pushwoosh-widget-subscription-prompt.ts +6 -0
  74. package/src/service-worker.ts +455 -0
  75. package/src/services/PushService/PushService.ts +2 -0
  76. package/src/services/PushService/PushService.types.ts +74 -0
  77. package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.ts +235 -0
  78. package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.types.ts +3 -0
  79. package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.ts +125 -0
  80. package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.types.ts +4 -0
  81. package/src/widget-inbox.ts +1 -0
  82. package/src/widget-subscribe-popup.ts +1 -0
  83. package/src/widget-subscription-button.ts +1 -0
  84. package/src/widget-subscription-prompt.ts +33 -0
  85. package/src/widgets/Inbox/InboxWidget.ts +564 -0
  86. package/src/widgets/Inbox/constants.ts +49 -0
  87. package/src/widgets/Inbox/css/inboxWidgetStyle.css +274 -0
  88. package/src/widgets/Inbox/helpers.ts +63 -0
  89. package/src/widgets/Inbox/inbox.d.ts +9 -0
  90. package/src/widgets/Inbox/inbox_widget.types.ts +41 -0
  91. package/src/widgets/Inbox/index.ts +1 -0
  92. package/src/widgets/Inbox/widgetTemplates.ts +55 -0
  93. package/src/widgets/SubscribePopup/SubscribePopup.ts +241 -0
  94. package/src/widgets/SubscribePopup/constants.ts +66 -0
  95. package/src/widgets/SubscribePopup/helpers.ts +11 -0
  96. package/src/widgets/SubscribePopup/index.ts +1 -0
  97. package/src/widgets/SubscribePopup/popupTemplates.ts +24 -0
  98. package/src/widgets/SubscribePopup/styles/popup.css +226 -0
  99. package/src/widgets/SubscribePopup/types/subscribe-popup.ts +68 -0
  100. package/src/widgets/SubscriptionButton/assets/css/main.css +205 -0
  101. package/src/widgets/SubscriptionButton/bell.ts +67 -0
  102. package/src/widgets/SubscriptionButton/constants.ts +28 -0
  103. package/src/widgets/SubscriptionButton/index.ts +377 -0
  104. package/src/widgets/SubscriptionButton/positioning.ts +165 -0
  105. package/src/widgets/SubscriptionButton/subscribe_widget.types.ts +53 -0
  106. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.constants.ts +1 -0
  107. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.helpers.ts +110 -0
  108. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.ts +102 -0
  109. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.types.ts +23 -0
  110. package/src/widgets/SubscriptionPrompt/constants.ts +22 -0
  111. package/src/widgets/SubscriptionPrompt/helpers.ts +42 -0
  112. package/src/widgets/widgets.d.ts +4 -0
  113. package/src/worker/global.ts +36 -0
  114. package/src/worker/notification.ts +34 -0
  115. package/src/worker/worker.types.ts +4 -0
  116. package/test/__helpers__/apiHelpers.ts +22 -0
  117. package/test/__helpers__/keyValueHelpers.ts +15 -0
  118. package/test/__helpers__/platformHelpers.ts +54 -0
  119. package/test/__helpers__/sinonHelpers.ts +7 -0
  120. package/test/__helpers__/storageHelpers.ts +56 -0
  121. package/test/__mocks__/apiRequests.ts +26 -0
  122. package/test/__mocks__/idbMock.ts +12 -0
  123. package/test/__mocks__/idbObjectStoreMock.ts +38 -0
  124. package/test/__mocks__/inboxMessages.ts +292 -0
  125. package/test/__mocks__/models/inboxModel.ts +71 -0
  126. package/test/__mocks__/modules/apiClientModule.ts +18 -0
  127. package/test/__mocks__/modules/dateModule.ts +34 -0
  128. package/test/__mocks__/modules/inboxParamsModule.ts +21 -0
  129. package/test/__mocks__/modules/paramsBuilder.ts +12 -0
  130. package/test/__mocks__/modules/paramsModule.ts +35 -0
  131. package/test/__mocks__/modules/payloadBuilderModule.ts +15 -0
  132. package/test/__mocks__/modules/storageModule.ts +58 -0
  133. package/test/__mocks__/navigator.ts +38 -0
  134. package/test/__mocks__/notification.ts +84 -0
  135. package/test/__mocks__/pushwoosh.ts +12 -0
  136. package/test/__mocks__/userAgents +8 -0
  137. package/test/functions.test.ts +22 -0
  138. package/test/ignore-html.js +6 -0
  139. package/test/mocha.opts +6 -0
  140. package/test/modules/DateModule/unit.test.ts +80 -0
  141. package/test/modules/storage/Storage/unit.test.ts +180 -0
  142. package/test/modules/storage/Store/unit.test.ts +192 -0
  143. package/testRegister.js +24 -0
  144. package/tsconfig.json +31 -0
  145. package/webpack.config.js +163 -0
  146. package/lib/index.js +0 -2
  147. package/lib/index.js.map +0 -1
  148. package/lib/service-worker.js +0 -2
  149. package/lib/service-worker.js.map +0 -1
@@ -0,0 +1,254 @@
1
+ import {
2
+ STORE_NAME_KEY_VALUE,
3
+ STORE_NAME_MAIN_LOG,
4
+ STORE_NAME_MESSAGE_LOG,
5
+ } from '../modules/storage/migrations/constants';
6
+ import MigrationExecutor from '../modules/storage/migrations/MigrationExecutor';
7
+ import { type IIDBOpenEventTargetWithResult } from '../modules/storage/Storage.types';
8
+ import version from '../modules/storage/version';
9
+
10
+ declare const self: ServiceWorkerGlobalScope;
11
+
12
+ function onversionchange(database: IDBDatabase, event: Event) {
13
+ console.info('onversionchange', event);
14
+ database.close();
15
+ }
16
+
17
+ let databasePromise: Promise<IDBDatabase>;
18
+ export function getInstance(): Promise<IDBDatabase> {
19
+ if (!databasePromise) {
20
+ databasePromise = new Promise<IDBDatabase>((resolve, reject) => {
21
+ const request: IDBOpenDBRequest = indexedDB.open('PUSHWOOSH_SDK_STORE', version);
22
+ request.onsuccess = (event) => {
23
+ const database: IDBDatabase = (event.target as IIDBOpenEventTargetWithResult).result;
24
+ database.onversionchange = onversionchange.bind(null, database, reject);
25
+ resolve(database);
26
+ };
27
+
28
+ request.onerror = () => reject(request.error);
29
+
30
+ request.onupgradeneeded = (event) => {
31
+ const database: IDBDatabase = (event.target as IIDBOpenEventTargetWithResult).result;
32
+ database.onversionchange = onversionchange.bind(null, database, reject);
33
+
34
+ const migrationExecutor = new MigrationExecutor(database);
35
+ migrationExecutor.applyMigrations();
36
+ };
37
+ });
38
+ }
39
+ return databasePromise;
40
+ }
41
+
42
+ function getInstanceWithPromise(executor: any): any {
43
+ return getInstance().then((database) => (
44
+ new Promise((resolve, reject) => executor(database, resolve, reject))
45
+ ));
46
+ }
47
+
48
+ function createKeyValue(name: string) {
49
+ return {
50
+ get<K extends string, D>(key: K, defaultValue?: D) {
51
+ return getInstanceWithPromise((database: IDBDatabase, resolve: any, reject: any) => {
52
+ const request = database.transaction(name).objectStore(name).get(key);
53
+
54
+ /** @TODO
55
+ * we cant invoke "resolve" or "reject" in onsuccess or onerror because
56
+ * it leads to bugs in Safari when we try to get permissions for notifications
57
+ *
58
+ * Checking status of request in setTimeout fixes this bug
59
+ */
60
+ let isComplete = false;
61
+ let isError = false;
62
+ let timeout: any;
63
+
64
+ const check = () => {
65
+ clearTimeout(timeout);
66
+ if (isComplete) {
67
+ resolve(request.result?.value || defaultValue);
68
+ } else if (isError) {
69
+ reject(request.error);
70
+ } else {
71
+ timeout = setTimeout(check, 0);
72
+ }
73
+ };
74
+
75
+ request.onsuccess = () => isComplete = true;
76
+ request.onerror = () => isError = true;
77
+ check();
78
+ });
79
+ },
80
+
81
+ getAll() {
82
+ return getInstanceWithPromise((database: IDBDatabase, resolve: any, reject: any) => {
83
+ const result: { [key: string]: any } = {};
84
+ const cursor = database.transaction(name).objectStore(name).openCursor();
85
+ let isComplete = false;
86
+ let isError = false;
87
+ let timeout: any;
88
+
89
+ /** @TODO
90
+ * we cant invoke "resolve" or "reject" in onsuccess or onerror because
91
+ * it leads to bugs in Safari when we try to get permissions for notifications
92
+ *
93
+ * Checking status of request in setTimeout fixes this bug
94
+ */
95
+ const check = () => {
96
+ clearTimeout(timeout);
97
+ if (isComplete) {
98
+ resolve(result);
99
+ } else if (isError) {
100
+ reject(cursor.error);
101
+ } else {
102
+ timeout = setTimeout(check, 0);
103
+ }
104
+ };
105
+
106
+ cursor.onsuccess = (event) => {
107
+ const cursorResult = (event.target as any).result;
108
+ if (cursorResult) {
109
+ result[cursorResult.key] = cursorResult.value.value;
110
+ cursorResult.continue();
111
+ } else {
112
+ isComplete = true;
113
+ }
114
+ };
115
+ cursor.onerror = () => isError = true;
116
+ check();
117
+ });
118
+ },
119
+
120
+ async extend(key: string, value: any) {
121
+ const oldValues = await this.get(key);
122
+ const { ...newValues } = value;
123
+ await this.set(key, { ...oldValues, ...newValues });
124
+ },
125
+
126
+ set<K, D>(key: K, value: D) {
127
+ return getInstanceWithPromise((database: IDBDatabase, resolve: any, reject: any) => {
128
+ const request = database.transaction([name], 'readwrite').objectStore(name).put({ key, value });
129
+ let isComplete = false;
130
+ let isError = false;
131
+ let timeout: any;
132
+
133
+ /** @TODO
134
+ * we cant invoke "resolve" or "reject" in onsuccess or onerror because
135
+ * it leads to bugs in Safari when we try to get permissions for notifications
136
+ *
137
+ * Checking status of request in setTimeout fixes this bug
138
+ */
139
+ const check = () => {
140
+ clearTimeout(timeout);
141
+ if (isComplete) {
142
+ resolve(key);
143
+ } else if (isError) {
144
+ reject(request.error);
145
+ } else {
146
+ timeout = setTimeout(check, 0);
147
+ }
148
+ };
149
+
150
+ request.onsuccess = () => isComplete = true;
151
+ request.onerror = () => isError = true;
152
+ check();
153
+ });
154
+ },
155
+ };
156
+ }
157
+
158
+ export abstract class LogBase {
159
+ protected abstract name: string;
160
+ protected abstract maxItems: number;
161
+ _add(obj: any) {
162
+ return getInstanceWithPromise((database: IDBDatabase, resolve: any, reject: any) => {
163
+ const request = database.transaction([this.name], 'readwrite').objectStore(this.name).add(obj);
164
+ request.onsuccess = () => {
165
+ resolve(obj);
166
+ };
167
+ request.onerror = () => {
168
+ reject(request.error);
169
+ };
170
+ }).then((obj: any) => {
171
+ return this.getAll().then((items: { id: number }[]) => {
172
+ if (Array.isArray(items)) {
173
+ const ids = items.map((i) => i.id).sort((a, b) => {
174
+ if (a == b) return 0;
175
+ return a < b ? 1 : -1;
176
+ });
177
+ if (ids.length > this.maxItems) {
178
+ return Promise.all(ids.slice(this.maxItems).map((id) => this.delete(id))).then(() => obj);
179
+ }
180
+ }
181
+ return obj;
182
+ });
183
+ });
184
+ }
185
+
186
+ delete(key: any) {
187
+ return getInstanceWithPromise((database: IDBDatabase, resolve: any, reject: any) => {
188
+ const request = database.transaction([this.name], 'readwrite').objectStore(this.name).delete(key);
189
+ request.onsuccess = () => {
190
+ resolve(request.result);
191
+ };
192
+ request.onerror = () => {
193
+ reject(request.error);
194
+ };
195
+ });
196
+ }
197
+
198
+ getAll() {
199
+ return getInstanceWithPromise((database: IDBDatabase, resolve: any, reject: any) => {
200
+ const result: any[] = [];
201
+ const cursor = database.transaction(this.name).objectStore(this.name).openCursor();
202
+ cursor.onsuccess = (ev) => {
203
+ const cursorResult = (ev.target as any).result;
204
+ if (cursorResult) {
205
+ if (cursorResult.value) {
206
+ result.push(cursorResult.value);
207
+ }
208
+ cursorResult.continue();
209
+ } else {
210
+ resolve(result);
211
+ }
212
+ };
213
+ cursor.onerror = () => {
214
+ reject(cursor.error);
215
+ };
216
+ });
217
+ }
218
+ }
219
+
220
+ export class LogLog extends LogBase {
221
+ protected name = STORE_NAME_MAIN_LOG;
222
+ protected maxItems = 100;
223
+ protected environment = (typeof self !== 'undefined' && self.registration) ? 'worker' : 'browser';
224
+ add(type: string, message: any, additional?: any) {
225
+ const obj: any = {
226
+ type,
227
+ environment: this.environment,
228
+ message: `${message}`,
229
+ date: new Date(),
230
+ };
231
+ if (message instanceof Error) {
232
+ obj.stack = message.stack;
233
+ }
234
+ if (additional) {
235
+ obj.additional = additional;
236
+ }
237
+ return this._add(obj);
238
+ }
239
+ }
240
+
241
+ export class LogMessage extends LogBase {
242
+ protected name = STORE_NAME_MESSAGE_LOG;
243
+ protected maxItems = 25;
244
+ add(log: any) {
245
+ return this._add({
246
+ ...log,
247
+ date: new Date(),
248
+ });
249
+ }
250
+ }
251
+
252
+ export const keyValue = createKeyValue(STORE_NAME_KEY_VALUE);
253
+ export const log = new LogLog();
254
+ export const message = new LogMessage();
@@ -0,0 +1,81 @@
1
+ import {
2
+ Logger,
3
+ handlerConsole,
4
+ } from './pwlogger';
5
+
6
+ type TLogMessage = {
7
+ message: string;
8
+ code: string;
9
+ error: any;
10
+
11
+ [key: string]: any;
12
+ };
13
+
14
+ const logger = new Logger({
15
+ level: 'error',
16
+ subscribers: [
17
+ {
18
+ level: 'fatal',
19
+ handler: handlerConsole,
20
+ },
21
+ {
22
+ level: 'error',
23
+ handler: handlerConsole,
24
+ },
25
+ ],
26
+ });
27
+
28
+ async function sendFatalLogToRemoteServer(params: TLogMessage) {
29
+ const message = makeMessage(params);
30
+
31
+ return logger.fatal(message.text, message.code, message.options);
32
+ }
33
+
34
+ async function sendErrorLogToRemoteServer(params: TLogMessage) {
35
+ const message = makeMessage(params);
36
+
37
+ return logger.error(message.text, message.code, message.options);
38
+ }
39
+
40
+ function makeMessage(params: TLogMessage) {
41
+ const {
42
+ message,
43
+ code,
44
+ error,
45
+ ...data
46
+ } = params;
47
+
48
+ const cleanError = makeCleanError(error);
49
+
50
+ const options = {
51
+ ...data,
52
+ errorText: cleanError.message,
53
+ errorStack: cleanError.stack,
54
+ };
55
+
56
+ return {
57
+ text: message,
58
+ code,
59
+ options,
60
+ };
61
+ }
62
+
63
+ function makeCleanError(error: any): Error {
64
+ let cleanError: Error = new Error('unknown error');
65
+
66
+ if (typeof error === 'string' || typeof error === 'number' || typeof error === 'boolean') {
67
+ cleanError.message = error.toString();
68
+ }
69
+
70
+ if (error instanceof Error) {
71
+ cleanError = error;
72
+ }
73
+
74
+ return cleanError;
75
+ }
76
+
77
+ export {
78
+ logger,
79
+ sendFatalLogToRemoteServer,
80
+ sendErrorLogToRemoteServer,
81
+ };
@@ -0,0 +1,31 @@
1
+ import {
2
+ type TLoggerLevelSilent,
3
+ type TLoggerLevelFatal,
4
+ type TLoggerLevelError,
5
+ type TLoggerLevelWarn,
6
+ type TLoggerLevelInfo,
7
+ type TLoggerLevelDebug,
8
+ } from './Logger.types';
9
+
10
+ export const LOGGER_LEVEL_SILENT: TLoggerLevelSilent = 'silent';
11
+ export const LOGGER_LEVEL_FATAL: TLoggerLevelFatal = 'fatal';
12
+ export const LOGGER_LEVEL_ERROR: TLoggerLevelError = 'error';
13
+ export const LOGGER_LEVEL_WARN: TLoggerLevelWarn = 'warn';
14
+ export const LOGGER_LEVEL_INFO: TLoggerLevelInfo = 'info';
15
+ export const LOGGER_LEVEL_DEBUG: TLoggerLevelDebug = 'debug';
16
+
17
+ export const LOGGER_LEVEL_VALUE_SILENT = 0;
18
+ export const LOGGER_LEVEL_VALUE_FATAL = 10;
19
+ export const LOGGER_LEVEL_VALUE_ERROR = 20;
20
+ export const LOGGER_LEVEL_VALUE_WARN = 30;
21
+ export const LOGGER_LEVEL_VALUE_INFO = 40;
22
+ export const LOGGER_LEVEL_VALUE_DEBUG = 50;
23
+
24
+ export const loggerRelationsMap = {
25
+ [LOGGER_LEVEL_SILENT]: LOGGER_LEVEL_VALUE_SILENT,
26
+ [LOGGER_LEVEL_FATAL]: LOGGER_LEVEL_VALUE_FATAL,
27
+ [LOGGER_LEVEL_ERROR]: LOGGER_LEVEL_VALUE_ERROR,
28
+ [LOGGER_LEVEL_WARN]: LOGGER_LEVEL_VALUE_WARN,
29
+ [LOGGER_LEVEL_INFO]: LOGGER_LEVEL_VALUE_INFO,
30
+ [LOGGER_LEVEL_DEBUG]: LOGGER_LEVEL_VALUE_DEBUG,
31
+ };
@@ -0,0 +1,218 @@
1
+ import {
2
+ loggerRelationsMap,
3
+ LOGGER_LEVEL_FATAL,
4
+ LOGGER_LEVEL_ERROR,
5
+ LOGGER_LEVEL_WARN,
6
+ LOGGER_LEVEL_INFO,
7
+ LOGGER_LEVEL_DEBUG, LOGGER_LEVEL_SILENT,
8
+ } from './Logger.constants';
9
+ import {
10
+ type ILoggerConfig,
11
+ type TLoggerLevels,
12
+ type TLoggerApplicationType,
13
+ type ILoggerLogOptions,
14
+ type ILoggerLogParams,
15
+ type ILoggerMessage,
16
+ type TLoggerHandler,
17
+ type ILoggerSubscriber,
18
+ type TLoggerOutputLevels,
19
+ type TReject,
20
+ } from './Logger.types';
21
+
22
+ export * from './Logger.types';
23
+ export * from './Logger.constants';
24
+
25
+ export class Logger {
26
+ public readonly relations: typeof loggerRelationsMap = loggerRelationsMap;
27
+ public applicationType: TLoggerApplicationType;
28
+ public level: TLoggerLevels;
29
+ public readonly subscribers: ILoggerSubscriber[];
30
+
31
+ public applicationCode: string | undefined;
32
+ public domain: string | undefined;
33
+ public deviceInfo: { [key: string]: any } | undefined;
34
+
35
+ constructor(config?: ILoggerConfig) {
36
+ this.level = config && typeof (config.level) !== 'undefined' ? config.level : LOGGER_LEVEL_ERROR;
37
+ this.applicationType = config && typeof (config.applicationType) !== 'undefined' ? config.applicationType : 'sdk';
38
+ this.subscribers = config && typeof (config.subscribers) !== 'undefined' ? config.subscribers : [];
39
+ }
40
+
41
+ public updateLogLevel(level: TLoggerLevels): void {
42
+ this.level = level;
43
+ }
44
+
45
+ public updateApplicationType(applicationType: TLoggerApplicationType): void {
46
+ this.applicationType = applicationType;
47
+ }
48
+
49
+ public updateApplicationCode(applicationCode: string): void {
50
+ this.applicationCode = applicationCode;
51
+ }
52
+
53
+ public updateDomain(domain: string): void {
54
+ this.domain = domain;
55
+ }
56
+
57
+ public updateDeviceInfo(deviceInfo: { [key: string]: any }): void {
58
+ this.deviceInfo = deviceInfo;
59
+ }
60
+
61
+ public subscribe(level: TLoggerOutputLevels, handler: TLoggerHandler) {
62
+ this.subscribers.push({
63
+ handler,
64
+ level,
65
+ });
66
+ }
67
+
68
+ public async log(params: ILoggerLogParams): Promise<void> {
69
+ const actions: Array<Promise<void> | void> = [];
70
+ const {
71
+ options,
72
+ ...other
73
+ } = params;
74
+
75
+ let data = other;
76
+
77
+ if (options) {
78
+ const {
79
+ handler: _handler,
80
+ ...additionalData
81
+ } = options;
82
+
83
+ data = {
84
+ ...other,
85
+ ...additionalData,
86
+ };
87
+ }
88
+ const message = this.getMessage(data);
89
+
90
+ this.subscribers.forEach((subscriber) => {
91
+ if (subscriber.level === params.type && this.relations[subscriber.level] <= this.relations[this.level]) {
92
+ actions.push(subscriber.handler.call(null, message));
93
+ }
94
+ });
95
+
96
+ if (options && options.handler && this.level !== LOGGER_LEVEL_SILENT) {
97
+ options.handler.call(null, message);
98
+ }
99
+
100
+ await Promise.all(actions);
101
+ return;
102
+ }
103
+
104
+ public async debug(text: string, options?: ILoggerLogOptions): Promise<void> {
105
+ return this.log({
106
+ type: LOGGER_LEVEL_DEBUG,
107
+ text,
108
+ options,
109
+ });
110
+ }
111
+
112
+ public async info(text: string, options?: ILoggerLogOptions): Promise<void> {
113
+ return this.log({
114
+ type: LOGGER_LEVEL_INFO,
115
+ text,
116
+ options,
117
+ });
118
+ }
119
+
120
+ public async warn(text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
121
+ return this.log({
122
+ type: LOGGER_LEVEL_WARN,
123
+ text,
124
+ code,
125
+ options,
126
+ });
127
+ }
128
+
129
+ public async error(text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
130
+ return this.log({
131
+ type: LOGGER_LEVEL_ERROR,
132
+ text,
133
+ code,
134
+ options,
135
+ });
136
+ }
137
+
138
+ public async fatal(text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
139
+ return this.log({
140
+ type: LOGGER_LEVEL_FATAL,
141
+ text,
142
+ code,
143
+ options,
144
+ });
145
+ }
146
+
147
+ public async errorAndThrow(text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
148
+ return this.logAndThrow({
149
+ type: LOGGER_LEVEL_ERROR,
150
+ text,
151
+ code,
152
+ options,
153
+ });
154
+ }
155
+
156
+ public async errorAndReject(cb: TReject, text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
157
+ return this.logAndReject(cb, {
158
+ type: LOGGER_LEVEL_ERROR,
159
+ text,
160
+ code,
161
+ options,
162
+ });
163
+ }
164
+
165
+ public async fatalAndThrow(text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
166
+ return this.logAndThrow({
167
+ type: LOGGER_LEVEL_FATAL,
168
+ text,
169
+ code,
170
+ options,
171
+ });
172
+ }
173
+
174
+ public async fatalAndReject(cb: TReject, text: string, code?: string, options?: ILoggerLogOptions): Promise<void> {
175
+ return this.logAndReject(cb, {
176
+ type: LOGGER_LEVEL_FATAL,
177
+ text,
178
+ code,
179
+ options,
180
+ });
181
+ }
182
+
183
+ private async logAndThrow(params: ILoggerLogParams): Promise<void> {
184
+ await this.log(params);
185
+
186
+ const error = new Error(params.text);
187
+
188
+ if (params.code) {
189
+ // @ts-ignore
190
+ error.code = params.code;
191
+ }
192
+
193
+ throw error;
194
+ }
195
+
196
+ private async logAndReject(reject: TReject, params: ILoggerLogParams): Promise<void> {
197
+ await this.log(params);
198
+
199
+ const error = new Error(params.text);
200
+
201
+ if (params.code) {
202
+ // @ts-ignore
203
+ error.code = params.code;
204
+ }
205
+
206
+ reject(error);
207
+ }
208
+
209
+ private getMessage(params: ILoggerLogParams): ILoggerMessage {
210
+ return {
211
+ applicationCode: this.applicationCode,
212
+ domain: this.domain,
213
+ applicationType: this.applicationType,
214
+ deviceInfo: this.deviceInfo,
215
+ ...params,
216
+ };
217
+ }
218
+ }
@@ -0,0 +1,66 @@
1
+ export type TLoggerLevelSilent = 'silent';
2
+ export type TLoggerLevelFatal = 'fatal';
3
+ export type TLoggerLevelError = 'error';
4
+ export type TLoggerLevelWarn = 'warn';
5
+ export type TLoggerLevelInfo = 'info';
6
+ export type TLoggerLevelDebug = 'debug';
7
+
8
+ export type TLoggerFromSDK = 'sdk';
9
+ export type TLoggerFromCP = 'cp';
10
+
11
+ export type TLoggerApplicationType =
12
+ | TLoggerFromSDK
13
+ | TLoggerFromCP;
14
+
15
+ export type TLoggerOutputLevels =
16
+ | TLoggerLevelFatal
17
+ | TLoggerLevelError
18
+ | TLoggerLevelWarn
19
+ | TLoggerLevelInfo
20
+ | TLoggerLevelDebug;
21
+
22
+ export type TLoggerLevels =
23
+ | TLoggerLevelSilent
24
+ | TLoggerOutputLevels;
25
+
26
+ export interface ILoggerLogOptions {
27
+ handler?: TLoggerHandler;
28
+ [key: string]: any;
29
+ }
30
+
31
+ export interface ILoggerLogParams {
32
+ type: TLoggerOutputLevels;
33
+ text: string;
34
+ code?: string | number;
35
+ options?: ILoggerLogOptions;
36
+ }
37
+
38
+ export type TLoggerHandler = (message: ILoggerMessage) => void | Promise<void>;
39
+
40
+ export interface ILoggerSubscriber {
41
+ handler: TLoggerHandler;
42
+ level: TLoggerOutputLevels;
43
+ }
44
+
45
+ export interface ILoggerMessage {
46
+ type: TLoggerOutputLevels;
47
+ text: string;
48
+ applicationType: TLoggerApplicationType;
49
+
50
+ code?: string | number;
51
+ applicationCode?: string;
52
+ domain?: string;
53
+ deviceInfo?: {
54
+ [key: string]: any;
55
+ };
56
+
57
+ [key: string]: any;
58
+ }
59
+
60
+ export interface ILoggerConfig {
61
+ level?: TLoggerLevels;
62
+ applicationType?: TLoggerApplicationType;
63
+ subscribers?: ILoggerSubscriber[];
64
+ }
65
+
66
+ export type TReject = (reason: Error) => void;
@@ -0,0 +1,40 @@
1
+ import {
2
+ type ILoggerMessage,
3
+ type TLoggerOutputLevels,
4
+ } from './../../Logger';
5
+
6
+ export function handlerConsole(message: ILoggerMessage) {
7
+ const {
8
+ code,
9
+ text,
10
+ type,
11
+ } = message;
12
+
13
+ const log = getOutputFunction(type);
14
+ // tslint:disable-next-line
15
+ console.groupCollapsed(type);
16
+
17
+ if (code) {
18
+ log(`${code}: ${text}`);
19
+ } else {
20
+ log(text);
21
+ }
22
+
23
+ // tslint:disable-next-line
24
+ console.groupEnd();
25
+ }
26
+
27
+ function getOutputFunction(type: TLoggerOutputLevels): (text: string) => void {
28
+ switch (type) {
29
+ case 'fatal':
30
+ case 'error':
31
+ // tslint:disable-next-line
32
+ return console.error;
33
+
34
+ case 'warn':
35
+ case 'info':
36
+ case 'debug':
37
+ // tslint:disable-next-line
38
+ return console.log;
39
+ }
40
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Logger';
2
+ export * from './handlers/handler-console/handler-console';