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.
- package/.editorconfig +11 -0
- package/.gitlab-ci.yml +190 -0
- package/babel.config.js +7 -0
- package/ci/cdn/Dockerfile +12 -0
- package/ci/dev/Dockerfile +30 -0
- package/ci/dev/rootfs/entrypoint.sh +18 -0
- package/ci/dev/rootfs/entrypoint.sh.d/nginx.sh +6 -0
- package/ci/dev/rootfs/entrypoint.sh.d/supervisor.sh +5 -0
- package/ci/dev/rootfs/etc/nginx/_real_ip.conf +2 -0
- package/ci/dev/rootfs/etc/nginx/conf.d/default.conf +20 -0
- package/ci/dev/rootfs/etc/supervisor.d/nginx.ini +11 -0
- package/ci/github/Dockerfile +59 -0
- package/ci/github/release-zip.js +61 -0
- package/ci/npm/Dockerfile +19 -0
- package/config/config.js +24 -0
- package/config/configBuilder.js +126 -0
- package/config/helpers.js +9 -0
- package/config/index.js +1 -0
- package/develop/README.md +42 -0
- package/develop/favicon.png +0 -0
- package/develop/index.html +511 -0
- package/eslint.config.mjs +114 -0
- package/package.json +4 -34
- package/{lib → public}/index.d.ts +10 -10
- package/scripts/zip.js +26 -0
- package/src/core/Pushwoosh.ts +768 -0
- package/src/core/Pushwoosh.types.ts +254 -0
- package/src/core/Safari.types.ts +26 -0
- package/src/core/constants.ts +58 -0
- package/src/core/events.types.ts +46 -0
- package/src/core/functions.ts +33 -0
- package/src/core/legacyEventsMap.ts +64 -0
- package/src/core/logger.ts +64 -0
- package/src/core/modules/EventBus/EventBus.ts +66 -0
- package/src/core/modules/EventBus/index.ts +1 -0
- package/src/core/storage.ts +254 -0
- package/src/helpers/logger.ts +81 -0
- package/src/helpers/pwlogger/Logger.constants.ts +31 -0
- package/src/helpers/pwlogger/Logger.ts +218 -0
- package/src/helpers/pwlogger/Logger.types.ts +66 -0
- package/src/helpers/pwlogger/handlers/handler-console/handler-console.ts +40 -0
- package/src/helpers/pwlogger/index.ts +2 -0
- package/src/helpers/unescape.ts +36 -0
- package/src/models/InboxMessages.ts +202 -0
- package/src/models/InboxMessages.types.ts +111 -0
- package/src/models/NotificationPayload.ts +216 -0
- package/src/models/NotificationPayload.types.ts +65 -0
- package/src/modules/Api/Api.ts +386 -0
- package/src/modules/Api/Api.types.ts +7 -0
- package/src/modules/ApiClient/ApiClient.ts +153 -0
- package/src/modules/ApiClient/ApiClient.types.ts +222 -0
- package/src/modules/Data/Data.ts +345 -0
- package/src/modules/DateModule.ts +53 -0
- package/src/modules/InboxMessagesPublic.ts +222 -0
- package/src/modules/PlatformChecker/PlatformChecker.ts +170 -0
- package/src/modules/PlatformChecker/PlatformChecker.types.ts +5 -0
- package/src/modules/PlatformChecker/index.ts +1 -0
- package/src/modules/storage/Storage.ts +164 -0
- package/src/modules/storage/Storage.types.ts +54 -0
- package/src/modules/storage/Store.ts +104 -0
- package/src/modules/storage/migrations/26-11-2018.ts +25 -0
- package/src/modules/storage/migrations/MigrationExecutor.ts +31 -0
- package/src/modules/storage/migrations/Migrations.ts +41 -0
- package/src/modules/storage/migrations/constants.ts +8 -0
- package/src/modules/storage/migrations/helpers.ts +16 -0
- package/src/modules/storage/migrations/initial.ts +47 -0
- package/src/modules/storage/version.ts +2 -0
- package/src/npm.ts +1 -0
- package/src/pushwoosh-web-notifications.ts +47 -0
- package/src/pushwoosh-widget-inbox.ts +8 -0
- package/src/pushwoosh-widget-subscribe-popup.ts +9 -0
- package/src/pushwoosh-widget-subscription-button.ts +8 -0
- package/src/pushwoosh-widget-subscription-prompt.ts +6 -0
- package/src/service-worker.ts +455 -0
- package/src/services/PushService/PushService.ts +2 -0
- package/src/services/PushService/PushService.types.ts +74 -0
- package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.ts +235 -0
- package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.types.ts +3 -0
- package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.ts +125 -0
- package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.types.ts +4 -0
- package/src/widget-inbox.ts +1 -0
- package/src/widget-subscribe-popup.ts +1 -0
- package/src/widget-subscription-button.ts +1 -0
- package/src/widget-subscription-prompt.ts +33 -0
- package/src/widgets/Inbox/InboxWidget.ts +564 -0
- package/src/widgets/Inbox/constants.ts +49 -0
- package/src/widgets/Inbox/css/inboxWidgetStyle.css +274 -0
- package/src/widgets/Inbox/helpers.ts +63 -0
- package/src/widgets/Inbox/inbox.d.ts +9 -0
- package/src/widgets/Inbox/inbox_widget.types.ts +41 -0
- package/src/widgets/Inbox/index.ts +1 -0
- package/src/widgets/Inbox/widgetTemplates.ts +55 -0
- package/src/widgets/SubscribePopup/SubscribePopup.ts +241 -0
- package/src/widgets/SubscribePopup/constants.ts +66 -0
- package/src/widgets/SubscribePopup/helpers.ts +11 -0
- package/src/widgets/SubscribePopup/index.ts +1 -0
- package/src/widgets/SubscribePopup/popupTemplates.ts +24 -0
- package/src/widgets/SubscribePopup/styles/popup.css +226 -0
- package/src/widgets/SubscribePopup/types/subscribe-popup.ts +68 -0
- package/src/widgets/SubscriptionButton/assets/css/main.css +205 -0
- package/src/widgets/SubscriptionButton/bell.ts +67 -0
- package/src/widgets/SubscriptionButton/constants.ts +28 -0
- package/src/widgets/SubscriptionButton/index.ts +377 -0
- package/src/widgets/SubscriptionButton/positioning.ts +165 -0
- package/src/widgets/SubscriptionButton/subscribe_widget.types.ts +53 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.constants.ts +1 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.helpers.ts +110 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.ts +102 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.types.ts +23 -0
- package/src/widgets/SubscriptionPrompt/constants.ts +22 -0
- package/src/widgets/SubscriptionPrompt/helpers.ts +42 -0
- package/src/widgets/widgets.d.ts +4 -0
- package/src/worker/global.ts +36 -0
- package/src/worker/notification.ts +34 -0
- package/src/worker/worker.types.ts +4 -0
- package/test/__helpers__/apiHelpers.ts +22 -0
- package/test/__helpers__/keyValueHelpers.ts +15 -0
- package/test/__helpers__/platformHelpers.ts +54 -0
- package/test/__helpers__/sinonHelpers.ts +7 -0
- package/test/__helpers__/storageHelpers.ts +56 -0
- package/test/__mocks__/apiRequests.ts +26 -0
- package/test/__mocks__/idbMock.ts +12 -0
- package/test/__mocks__/idbObjectStoreMock.ts +38 -0
- package/test/__mocks__/inboxMessages.ts +292 -0
- package/test/__mocks__/models/inboxModel.ts +71 -0
- package/test/__mocks__/modules/apiClientModule.ts +18 -0
- package/test/__mocks__/modules/dateModule.ts +34 -0
- package/test/__mocks__/modules/inboxParamsModule.ts +21 -0
- package/test/__mocks__/modules/paramsBuilder.ts +12 -0
- package/test/__mocks__/modules/paramsModule.ts +35 -0
- package/test/__mocks__/modules/payloadBuilderModule.ts +15 -0
- package/test/__mocks__/modules/storageModule.ts +58 -0
- package/test/__mocks__/navigator.ts +38 -0
- package/test/__mocks__/notification.ts +84 -0
- package/test/__mocks__/pushwoosh.ts +12 -0
- package/test/__mocks__/userAgents +8 -0
- package/test/functions.test.ts +22 -0
- package/test/ignore-html.js +6 -0
- package/test/mocha.opts +6 -0
- package/test/modules/DateModule/unit.test.ts +80 -0
- package/test/modules/storage/Storage/unit.test.ts +180 -0
- package/test/modules/storage/Store/unit.test.ts +192 -0
- package/testRegister.js +24 -0
- package/tsconfig.json +31 -0
- package/webpack.config.js +163 -0
- package/lib/index.js +0 -2
- package/lib/index.js.map +0 -1
- package/lib/service-worker.js +0 -2
- 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
|
+
}
|