app-tracker 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -21
- package/app-tracker.service.d.ts +1 -0
- package/app-tracker.service.js +247 -1
- package/log.js +27 -1
- package/main.js +19 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# App Tracker for Web & Node.js
|
|
4
|
+
|
|
5
|
+
App Tracker is a TypeScript/JavaScript library for logging and tracking events in web and Node.js applications. It supports batching, flexible configuration, and sending logs to a central endpoint.
|
|
2
6
|
|
|
3
7
|
## Installation
|
|
4
8
|
|
|
@@ -6,36 +10,69 @@
|
|
|
6
10
|
npm i app-tracker
|
|
7
11
|
```
|
|
8
12
|
|
|
9
|
-
##
|
|
13
|
+
## Registration & API Key
|
|
10
14
|
|
|
11
|
-
-
|
|
12
|
-
- Register on [App Tracker](https://www.app-tracker.cloud/)
|
|
15
|
+
- Register at [App Tracker](https://www.app-tracker.cloud/) and create an application to get your API key.
|
|
13
16
|
|
|
14
|
-
##
|
|
17
|
+
## Quick Start
|
|
15
18
|
|
|
16
|
-
```
|
|
19
|
+
```typescript
|
|
17
20
|
import { AppTracker, AppTrackerService } from "app-tracker";
|
|
18
21
|
|
|
19
|
-
const
|
|
22
|
+
const config = {
|
|
23
|
+
userAgentOrOs: typeof window !== 'undefined' ? navigator.userAgent : require('os'),
|
|
24
|
+
logInConsole: true,
|
|
25
|
+
sendLogsInDevelopment: true,
|
|
26
|
+
// more options below
|
|
27
|
+
};
|
|
28
|
+
const tracker: AppTrackerService = AppTracker.init("API_KEY", config);
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
tracker.debug("Debug message", { foo: "bar" });
|
|
31
|
+
tracker.error("An error occurred", errorObj);
|
|
22
32
|
```
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
| Property | Type | Default | Description |
|
|
37
|
+
|-----------------------------|--------------|--------------------------------|-------------|
|
|
38
|
+
| sendLogsInDevelopment | boolean | false | Send logs during development |
|
|
39
|
+
| logInConsole | boolean | false | Also log to the console |
|
|
40
|
+
| endpointUrl | string | https://app-tracker-api.azurewebsites.net/ | Target endpoint for logs |
|
|
41
|
+
| maxSendTries | number | 5 | Max. send attempts on error |
|
|
42
|
+
| maxLogsCount | number | 10 | Batch size for sending logs |
|
|
43
|
+
| logLevel | LogType[] | [LogType.error] | Which log types are sent |
|
|
44
|
+
| sendLogsByTypesImmediately | LogType[] | [LogType.error, LogType.critical] | Types sent immediately |
|
|
45
|
+
| userAgentOrOs | any | | Browser: navigator.userAgent, Node: require('os') |
|
|
46
|
+
|
|
47
|
+
**LogType:** `debug`, `info`, `log`, `warn`, `error`, `critical`
|
|
25
48
|
|
|
49
|
+
## Architecture & Features
|
|
26
50
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
- **Singleton Service:** Always access via `AppTracker.init()` or `AppTracker.getService()`
|
|
52
|
+
- **Batching:** Logs are collected and sent after `maxLogsCount` or immediately for critical errors
|
|
53
|
+
- **Environment Awareness:** Automatically adapts for browser/Node.js
|
|
54
|
+
- **Secure Sending:** API key required, retry mechanism on errors
|
|
55
|
+
- **External Dependency:** Uses `cross-fetch` for HTTP requests
|
|
56
|
+
|
|
57
|
+
## Build & Development
|
|
58
|
+
|
|
59
|
+
- **Build:** `npm run build` (TypeScript compile & copy to `lib/`)
|
|
60
|
+
- **Minify:** `npm run terser` (Terser minification of JS files)
|
|
61
|
+
- **Lint:** `npm run lint` (TSLint)
|
|
62
|
+
- **Format:** `npm run format` (Prettier)
|
|
37
63
|
|
|
38
64
|
## FAQ
|
|
39
65
|
|
|
40
|
-
|
|
41
|
-
|
|
66
|
+
**Where do I get my API key?**
|
|
67
|
+
> Register at https://www.app-tracker.cloud/ and create an application.
|
|
68
|
+
|
|
69
|
+
**How can I suppress logs in development?**
|
|
70
|
+
> Set `sendLogsInDevelopment: false` in the configuration.
|
|
71
|
+
|
|
72
|
+
**How do I send custom log types?**
|
|
73
|
+
> Use the `debug`, `info`, `warn`, `error`, `critical` methods of the service object.
|
|
74
|
+
|
|
75
|
+
## Further Information
|
|
76
|
+
- See `src/app-tracker.service.ts` for service logic
|
|
77
|
+
- See `src/log.ts` for configuration and log types
|
|
78
|
+
- See `.github/copilot-instructions.md` for developer guidelines
|
package/app-tracker.service.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare class AppTrackerService {
|
|
|
17
17
|
private isRunningLocal;
|
|
18
18
|
private ident;
|
|
19
19
|
private eventListenerAdded;
|
|
20
|
+
private _boundBeforeUnloadHandler?;
|
|
20
21
|
init(apiKey: string, config?: AppTrackerConfig): void;
|
|
21
22
|
private addEventListener;
|
|
22
23
|
private removeEventListener;
|
package/app-tracker.service.js
CHANGED
|
@@ -1 +1,247 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const log_1 = require("./log");
|
|
13
|
+
const cross_fetch_1 = require("cross-fetch");
|
|
14
|
+
const safeFetch = typeof window !== 'undefined' ? cross_fetch_1.default.bind(window) : cross_fetch_1.default;
|
|
15
|
+
class AppTrackerService {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.sendLogsInDevelopment = false;
|
|
18
|
+
this.logInConsole = false;
|
|
19
|
+
this.endpointUrl = 'https://app-tracker-api.azurewebsites.net/';
|
|
20
|
+
this.apiKey = '';
|
|
21
|
+
this.logs = [];
|
|
22
|
+
this.sendTries = 0;
|
|
23
|
+
this.maxSendTries = 5;
|
|
24
|
+
this.isSending = false;
|
|
25
|
+
this.maxLogsCount = 10;
|
|
26
|
+
this.userAgent = '';
|
|
27
|
+
this.logLevel = [log_1.LogType.error];
|
|
28
|
+
this.sendLogsByTypesImmediately = [log_1.LogType.error, log_1.LogType.critical];
|
|
29
|
+
this.isNode = false;
|
|
30
|
+
this.isRunningLocal = true;
|
|
31
|
+
this.ident = '';
|
|
32
|
+
this.eventListenerAdded = false;
|
|
33
|
+
}
|
|
34
|
+
init(apiKey, config) {
|
|
35
|
+
this.apiKey = apiKey;
|
|
36
|
+
if (config) {
|
|
37
|
+
if (typeof config.endpointUrl !== 'undefined')
|
|
38
|
+
this.endpointUrl = config.endpointUrl;
|
|
39
|
+
if (typeof config.maxLogsCount !== 'undefined')
|
|
40
|
+
this.maxLogsCount = config.maxLogsCount;
|
|
41
|
+
if (typeof config.maxSendTries !== 'undefined')
|
|
42
|
+
this.maxSendTries = config.maxSendTries;
|
|
43
|
+
if (typeof config.sendLogsInDevelopment !== 'undefined')
|
|
44
|
+
this.sendLogsInDevelopment = config.sendLogsInDevelopment;
|
|
45
|
+
if (typeof config.logInConsole !== 'undefined')
|
|
46
|
+
this.logInConsole = config.logInConsole;
|
|
47
|
+
if (typeof config.logLevel !== 'undefined')
|
|
48
|
+
this.logLevel = config.logLevel;
|
|
49
|
+
if (typeof config.sendLogsByTypesImmediately !== 'undefined')
|
|
50
|
+
this.sendLogsByTypesImmediately = config.sendLogsByTypesImmediately;
|
|
51
|
+
}
|
|
52
|
+
this.setRunningSystem(config);
|
|
53
|
+
}
|
|
54
|
+
addEventListener(apiKey) {
|
|
55
|
+
if (apiKey != '' && !this.isNode && !this.isRunningLocal && !this.eventListenerAdded) {
|
|
56
|
+
this._boundBeforeUnloadHandler = this._boundBeforeUnloadHandler || ((e) => this.beforeunloadHandler(e));
|
|
57
|
+
window.addEventListener('beforeunload', this._boundBeforeUnloadHandler, true);
|
|
58
|
+
this.eventListenerAdded = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
removeEventListener(apiKey) {
|
|
62
|
+
if (apiKey != '' && !this.isNode && !this.isRunningLocal && this.eventListenerAdded) {
|
|
63
|
+
if (this._boundBeforeUnloadHandler) {
|
|
64
|
+
window.removeEventListener('beforeunload', this._boundBeforeUnloadHandler, true);
|
|
65
|
+
}
|
|
66
|
+
this.eventListenerAdded = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
beforeunloadHandler(event) {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
event.returnValue = '';
|
|
72
|
+
if (!this.isSending) {
|
|
73
|
+
const logsToSend = this.logs;
|
|
74
|
+
this.isSending = true;
|
|
75
|
+
this.logs = [];
|
|
76
|
+
this.sendLogsToServerCore(logsToSend);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
setRunningSystem(config) {
|
|
80
|
+
var _a, _b, _c;
|
|
81
|
+
this.isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
|
|
82
|
+
if (!this.isNode) {
|
|
83
|
+
this.userAgent = (_a = config) === null || _a === void 0 ? void 0 : _a.userAgentOrOs;
|
|
84
|
+
this.ident = this.getIdent();
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.os = (_b = config) === null || _b === void 0 ? void 0 : _b.userAgentOrOs;
|
|
88
|
+
this.userAgent = this.setUserAgentFromOs();
|
|
89
|
+
}
|
|
90
|
+
this.isRunningLocal = this.isNode ? (_c = process.env.NODE_ENV, (_c !== null && _c !== void 0 ? _c : '')).indexOf("development") > -1 : window.location.href.indexOf('localhost') > -1;
|
|
91
|
+
}
|
|
92
|
+
getIdent() {
|
|
93
|
+
var _a;
|
|
94
|
+
let ident = (_a = localStorage) === null || _a === void 0 ? void 0 : _a.getItem('App-Tracker.device-ident');
|
|
95
|
+
if (!ident) {
|
|
96
|
+
ident = this.createUUID();
|
|
97
|
+
localStorage.setItem('App-Tracker.device-ident', ident);
|
|
98
|
+
}
|
|
99
|
+
return ident;
|
|
100
|
+
}
|
|
101
|
+
debug(message, ...optionalParams) {
|
|
102
|
+
this.addLog(log_1.LogType.debug, message, ...optionalParams);
|
|
103
|
+
}
|
|
104
|
+
info(message, ...optionalParams) {
|
|
105
|
+
this.addLog(log_1.LogType.info, message, ...optionalParams);
|
|
106
|
+
}
|
|
107
|
+
log(message, ...optionalParams) {
|
|
108
|
+
this.addLog(log_1.LogType.log, message, ...optionalParams);
|
|
109
|
+
}
|
|
110
|
+
warn(message, ...optionalParams) {
|
|
111
|
+
this.addLog(log_1.LogType.warn, message, ...optionalParams);
|
|
112
|
+
}
|
|
113
|
+
error(message, ...optionalParams) {
|
|
114
|
+
this.addLog(log_1.LogType.error, message, ...optionalParams);
|
|
115
|
+
}
|
|
116
|
+
critical(message, ...optionalParams) {
|
|
117
|
+
this.addLog(log_1.LogType.critical, message, ...optionalParams);
|
|
118
|
+
}
|
|
119
|
+
addLog(type, message, ...optionalParams) {
|
|
120
|
+
if (this.checkLogType(type)) {
|
|
121
|
+
if (this.isRunningLocal && !this.sendLogsInDevelopment) {
|
|
122
|
+
this.logToConsole(type, message, ...optionalParams);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.sendLogsToServer(type, message, ...optionalParams);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.logToConsole(type, message, ...optionalParams);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
logToConsole(type, message, ...optionalParams) {
|
|
133
|
+
if (this.logInConsole) {
|
|
134
|
+
switch (type) {
|
|
135
|
+
case log_1.LogType.debug:
|
|
136
|
+
console.debug(message, ...optionalParams);
|
|
137
|
+
break;
|
|
138
|
+
case log_1.LogType.critical:
|
|
139
|
+
case log_1.LogType.error:
|
|
140
|
+
console.error(message, ...optionalParams);
|
|
141
|
+
break;
|
|
142
|
+
case log_1.LogType.info:
|
|
143
|
+
console.info(message, ...optionalParams);
|
|
144
|
+
break;
|
|
145
|
+
case log_1.LogType.log:
|
|
146
|
+
console.log(message, ...optionalParams);
|
|
147
|
+
break;
|
|
148
|
+
case log_1.LogType.warn:
|
|
149
|
+
console.warn(message, ...optionalParams);
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
console.warn("Unkown LogType: ", type);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
sendLogsToServer(type, message, ...optionalParams) {
|
|
158
|
+
var _a, _b;
|
|
159
|
+
const log = { logType: type, message: message, optionalParams: [], createdAt: new Date(), ident: this.ident };
|
|
160
|
+
optionalParams.forEach((op) => {
|
|
161
|
+
if (Array.isArray(op))
|
|
162
|
+
op.forEach(o => log.optionalParams.push(o));
|
|
163
|
+
else
|
|
164
|
+
log.optionalParams.push(op);
|
|
165
|
+
});
|
|
166
|
+
this.logs.push(log);
|
|
167
|
+
if ((this.logs.length >= this.maxLogsCount && !this.isSending) ||
|
|
168
|
+
((((_a = this.sendLogsByTypesImmediately) === null || _a === void 0 ? void 0 : _a.find(l => l == type)) || type == log_1.LogType.critical) != null && !this.isSending)) {
|
|
169
|
+
const logsToSend = this.logs;
|
|
170
|
+
this.logs = [];
|
|
171
|
+
this.isSending = true;
|
|
172
|
+
this.sendLogsToServerCore(logsToSend);
|
|
173
|
+
this.removeEventListener(this.apiKey);
|
|
174
|
+
}
|
|
175
|
+
if (((_b = this.logs) === null || _b === void 0 ? void 0 : _b.length) > 0 && !this.eventListenerAdded) {
|
|
176
|
+
this.addEventListener(this.apiKey);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
checkLogType(type) {
|
|
180
|
+
if (this.logLevel.find(l => l === type) != null || type === log_1.LogType.critical) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
sendLogsToServerCore(logsToSend) {
|
|
188
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
189
|
+
if (this.sendTries < this.maxSendTries) {
|
|
190
|
+
try {
|
|
191
|
+
const last = this.endpointUrl.charAt(this.endpointUrl.length - 1);
|
|
192
|
+
const response = yield safeFetch(`${this.endpointUrl}${last === '/' ? 'logs/createLog' : '/logs/createLog'}`, {
|
|
193
|
+
method: 'POST',
|
|
194
|
+
headers: {
|
|
195
|
+
'Accept': 'application/json',
|
|
196
|
+
'Content-Type': 'application/json',
|
|
197
|
+
'X-Auth-Key': this.apiKey
|
|
198
|
+
},
|
|
199
|
+
body: JSON.stringify({ logs: logsToSend, userAgent: this.userAgent }, (key, value) => {
|
|
200
|
+
if (value instanceof Error) {
|
|
201
|
+
let error = {};
|
|
202
|
+
Object.getOwnPropertyNames(value).forEach(function (key) {
|
|
203
|
+
error[key] = value[key];
|
|
204
|
+
});
|
|
205
|
+
return error;
|
|
206
|
+
}
|
|
207
|
+
return value;
|
|
208
|
+
})
|
|
209
|
+
});
|
|
210
|
+
logsToSend = [];
|
|
211
|
+
this.isSending = false;
|
|
212
|
+
this.sendTries = 0; // Reset sendTries after successful send
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
console.error(`AppLogger: Could not send Logs to Server try ${this.sendTries}`, error);
|
|
216
|
+
this.sendTries++;
|
|
217
|
+
// Warten, bevor der nächste asynchrone Versuch gestartet wird
|
|
218
|
+
yield new Promise(resolve => setTimeout(resolve, 10000));
|
|
219
|
+
yield this.sendLogsToServerCore(logsToSend);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
this.sendTries = 0;
|
|
224
|
+
this.isSending = false;
|
|
225
|
+
console.error('AppLogger: Could not send Logs to Server finally');
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
setUserAgentFromOs() {
|
|
230
|
+
const osInfo = {
|
|
231
|
+
arch: this.os.arch(),
|
|
232
|
+
platform: this.os.platform(),
|
|
233
|
+
release: this.os.release(),
|
|
234
|
+
type: this.os.type(),
|
|
235
|
+
version: this.os.version(),
|
|
236
|
+
hostname: this.os.hostname()
|
|
237
|
+
};
|
|
238
|
+
return JSON.stringify(osInfo);
|
|
239
|
+
}
|
|
240
|
+
createUUID() {
|
|
241
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
242
|
+
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
|
243
|
+
return v.toString(16);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.AppTrackerService = AppTrackerService;
|
package/log.js
CHANGED
|
@@ -1 +1,27 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class AppTrackerConfig {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.maxLogsCount = 5;
|
|
6
|
+
this.sendLogsByTypesImmediately = [LogType.error];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.AppTrackerConfig = AppTrackerConfig;
|
|
10
|
+
class Log {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.logType = LogType.log;
|
|
13
|
+
this.optionalParams = [];
|
|
14
|
+
this.createdAt = new Date();
|
|
15
|
+
this.ident = '';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.Log = Log;
|
|
19
|
+
var LogType;
|
|
20
|
+
(function (LogType) {
|
|
21
|
+
LogType[LogType["debug"] = 0] = "debug";
|
|
22
|
+
LogType[LogType["info"] = 1] = "info";
|
|
23
|
+
LogType[LogType["log"] = 2] = "log";
|
|
24
|
+
LogType[LogType["warn"] = 3] = "warn";
|
|
25
|
+
LogType[LogType["error"] = 4] = "error";
|
|
26
|
+
LogType[LogType["critical"] = 5] = "critical";
|
|
27
|
+
})(LogType = exports.LogType || (exports.LogType = {}));
|
package/main.js
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const app_tracker_service_1 = require("./app-tracker.service");
|
|
4
|
+
class AppTracker {
|
|
5
|
+
static get service() {
|
|
6
|
+
if (!this._service)
|
|
7
|
+
this._service = new app_tracker_service_1.AppTrackerService();
|
|
8
|
+
return this._service;
|
|
9
|
+
}
|
|
10
|
+
static init(apiKey, config) {
|
|
11
|
+
AppTracker.service.init(apiKey, config);
|
|
12
|
+
return AppTracker.service;
|
|
13
|
+
}
|
|
14
|
+
static getService() {
|
|
15
|
+
return AppTracker.service;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.AppTracker = AppTracker;
|
|
19
|
+
AppTracker._service = null;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "app-tracker",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "App Tracker for Web-Applications",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsc && npm run copyFile",
|
|
8
|
-
"copyFile": "xcopy package.json lib && xcopy README.md lib
|
|
8
|
+
"copyFile": "xcopy package.json lib && xcopy README.md lib",
|
|
9
9
|
"terser": "terser lib/main.js -c -m -o lib/main.js && terser lib/log.js -c -m -o lib/log.js && terser lib/app-tracker.service.js -c -m -o lib/app-tracker.service.js",
|
|
10
10
|
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
|
|
11
11
|
"lint": "tslint -p tsconfig.json"
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"cross-fetch": "^3.1.5"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|