iobroker.gotify-ws 0.1.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.
- package/LICENSE +21 -0
- package/README.md +97 -0
- package/admin/gotify-ws.png +0 -0
- package/admin/i18n/de/translations.json +26 -0
- package/admin/i18n/en/translations.json +26 -0
- package/admin/i18n/es/translations.json +26 -0
- package/admin/i18n/fr/translations.json +26 -0
- package/admin/i18n/it/translations.json +26 -0
- package/admin/i18n/nl/translations.json +26 -0
- package/admin/i18n/pl/translations.json +26 -0
- package/admin/i18n/pt/translations.json +26 -0
- package/admin/i18n/ru/translations.json +26 -0
- package/admin/i18n/uk/translations.json +26 -0
- package/admin/i18n/zh-cn/translations.json +26 -0
- package/admin/jsonConfig.json +270 -0
- package/admin/words.js +43 -0
- package/io-package.json +145 -0
- package/lib/adapter-config.d.ts +19 -0
- package/main.js +411 -0
- package/package.json +81 -0
package/main.js
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/* eslint-disable prefer-const */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const WebSocket = require('ws');
|
|
5
|
+
const utils = require('@iobroker/adapter-core');
|
|
6
|
+
const adapterName = require('./package.json').name.split('.').pop();
|
|
7
|
+
|
|
8
|
+
let systemLang = 'de'; // system language
|
|
9
|
+
let ws = null;
|
|
10
|
+
let timer = null;
|
|
11
|
+
let stop = false;
|
|
12
|
+
|
|
13
|
+
class GotifyWs extends utils.Adapter {
|
|
14
|
+
/**
|
|
15
|
+
* @param {Partial<utils.AdapterOptions>} [options={}]
|
|
16
|
+
*/
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super({
|
|
19
|
+
...options,
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
name: adapterName,
|
|
22
|
+
});
|
|
23
|
+
this.on('ready', this.onReady.bind(this));
|
|
24
|
+
this.on('message', this.onMessage.bind(this));
|
|
25
|
+
this.on('unload', this.onUnload.bind(this));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async onReady() {
|
|
29
|
+
const sysLang = await this.getForeignObjectAsync('system.config');
|
|
30
|
+
|
|
31
|
+
if (sysLang && sysLang.common && sysLang.common.language) {
|
|
32
|
+
systemLang = sysLang.common.language;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
this.setState('info.connection', false, true);
|
|
36
|
+
this.connectWebSocket();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {() => void} callback
|
|
41
|
+
*/
|
|
42
|
+
onUnload(callback) {
|
|
43
|
+
this.setState('info.connection', false, true);
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
if (ws) {
|
|
47
|
+
stop = true;
|
|
48
|
+
ws.close();
|
|
49
|
+
ws.terminate();
|
|
50
|
+
clearTimeout(timer);
|
|
51
|
+
timer = null;
|
|
52
|
+
}
|
|
53
|
+
callback();
|
|
54
|
+
} catch (e) {
|
|
55
|
+
callback();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {{ command: string; from: string; callback: ioBroker.MessageCallback | ioBroker.MessageCallbackInfo | undefined; }} obj
|
|
61
|
+
*/
|
|
62
|
+
async onMessage(obj) {
|
|
63
|
+
switch (obj.command) {
|
|
64
|
+
case 'sendToInstance':
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
if (obj && obj.command === 'sendToInstance' && obj.message && obj.message.type) {
|
|
67
|
+
// eslint-disable-next-line prefer-const
|
|
68
|
+
let resultInstances = [];
|
|
69
|
+
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
const instances = await this.getObjectViewAsync('system', 'instance', {
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
startkey: `system.adapter.${obj.message.type}.`,
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
endkey: `system.adapter.${obj.message.type}.\u9999`,
|
|
76
|
+
}).catch((err) => this.log.error(err));
|
|
77
|
+
|
|
78
|
+
if (instances && instances.rows && instances.rows.length != 0) {
|
|
79
|
+
instances.rows.forEach(async (row) => {
|
|
80
|
+
resultInstances.push({
|
|
81
|
+
label: row.id.replace('system.adapter.', ''),
|
|
82
|
+
value: row.id.replace('system.adapter.', ''),
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
resultInstances.push({
|
|
87
|
+
label: this._('none', systemLang),
|
|
88
|
+
value: 'none',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
this.log.debug(`sendToInstance - ${JSON.stringify(obj)}`);
|
|
92
|
+
this.sendTo(obj.from, obj.command, resultInstances, obj.callback);
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
|
|
96
|
+
case 'sendToTelegramUser':
|
|
97
|
+
// eslint-disable-next-line no-case-declarations
|
|
98
|
+
let useUsername = false;
|
|
99
|
+
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
if (obj && obj.command === 'sendToTelegramUser' && obj.message && obj.message.instance) {
|
|
102
|
+
// @ts-ignore
|
|
103
|
+
const inst = obj.message.instance ? obj.message.instance : this.config.telegramInstance;
|
|
104
|
+
const userList = await this.getForeignStateAsync(`${inst}.communicate.users`);
|
|
105
|
+
const configTelegram = await this.getForeignObjectAsync(`system.adapter.${inst}`);
|
|
106
|
+
|
|
107
|
+
if (configTelegram && configTelegram.native) {
|
|
108
|
+
const native = configTelegram.native;
|
|
109
|
+
useUsername = native.useUsername;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// eslint-disable-next-line prefer-const
|
|
113
|
+
let resultUser = [{ label: this._('All Receiver', systemLang), value: 'allTelegramUsers' }];
|
|
114
|
+
|
|
115
|
+
if (userList && userList.val) {
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
const users = JSON.parse(userList.val);
|
|
118
|
+
|
|
119
|
+
for (const i in users) {
|
|
120
|
+
resultUser.push({
|
|
121
|
+
label: useUsername === true ? users[i].userName : users[i].firstName,
|
|
122
|
+
value: useUsername === true ? users[i].userName : users[i].firstName,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
this.sendTo(obj.from, obj.command, resultUser, obj.callback);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
this.log.error(`Cannot parse stored user IDs from Telegram: ${err}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
case 'sendToDiscordTarget':
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
if (obj && obj.command === 'sendToDiscordTarget' && obj.message && obj.message.instance) {
|
|
137
|
+
let resultTarget = [{ label: this._('none', systemLang), value: 'none' }];
|
|
138
|
+
// @ts-ignore
|
|
139
|
+
const targetList = await this.sendToAsync(obj.message.instance, 'getNotificationTargets', {});
|
|
140
|
+
|
|
141
|
+
if (Array.isArray(targetList)) {
|
|
142
|
+
for (const i in targetList) {
|
|
143
|
+
resultTarget.push({
|
|
144
|
+
label: targetList[i].value,
|
|
145
|
+
value: targetList[i].value,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
this.sendTo(obj.from, obj.command, resultTarget, obj.callback);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
this.log.error(`Cannot parse stored user IDs from Discord: ${err}`);
|
|
154
|
+
}
|
|
155
|
+
} else if (obj && obj.command === 'sendToDiscordTarget') {
|
|
156
|
+
let resultTarget = [{ label: this._('none', systemLang), value: 'none' }];
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
this.sendTo(obj.from, obj.command, resultTarget, obj.callback);
|
|
160
|
+
} catch (err) {
|
|
161
|
+
this.log.error(`Cannot parse stored user IDs from Discord: ${err}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async connectWebSocket() {
|
|
169
|
+
if (this.config.ip && this.config.port) {
|
|
170
|
+
const uri = `ws://${this.config.ip}:${this.config.port}/stream`;
|
|
171
|
+
|
|
172
|
+
ws = new WebSocket(uri, {
|
|
173
|
+
headers: {
|
|
174
|
+
'X-Gotify-Key': this.config.token,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
ws.on('open', () => {
|
|
179
|
+
this.setState('info.connection', true, true);
|
|
180
|
+
this.log.info('WebSocket connected');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
ws.on('message', async (data) => {
|
|
184
|
+
const line = JSON.parse(data);
|
|
185
|
+
this.pushMessage(line);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
ws.on('close', () => {
|
|
189
|
+
this.setState('info.connection', false, true);
|
|
190
|
+
this.log.info('WebSocket closed');
|
|
191
|
+
if (stop === false) {
|
|
192
|
+
timer = setTimeout(this.connectWebSocket, 5000);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
ws.on('error', (err) => {
|
|
197
|
+
this.setState('info.connection', false, true);
|
|
198
|
+
// @ts-ignore
|
|
199
|
+
this.log.error('WebSocket error:', err);
|
|
200
|
+
});
|
|
201
|
+
} else {
|
|
202
|
+
this.log.error('WebSocket error: Please check your Configuration');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async pushMessage(line) {
|
|
207
|
+
if (this.config.notificationType) {
|
|
208
|
+
switch (this.config.notificationType) {
|
|
209
|
+
case 'telegram':
|
|
210
|
+
if (
|
|
211
|
+
this.config.telegramUser &&
|
|
212
|
+
this.config.telegramUser === 'allTelegramUsers' &&
|
|
213
|
+
this.config.telegramInstance
|
|
214
|
+
) {
|
|
215
|
+
const message = line.message.replace(/[`]/g, '');
|
|
216
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
217
|
+
const title =
|
|
218
|
+
line.title != '' ? `<b>${line.title.replace(/[`]/g, '')}</b>` : '<b>Gotifi WS Message</b>';
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
this.sendTo(this.config.telegramInstance, 'send', {
|
|
222
|
+
parse_mode: 'HTML',
|
|
223
|
+
text: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
224
|
+
});
|
|
225
|
+
} catch (err) {
|
|
226
|
+
this.log.warn(`Error sending Telegram message: ${err}`);
|
|
227
|
+
}
|
|
228
|
+
} else if (
|
|
229
|
+
this.config.telegramUser &&
|
|
230
|
+
this.config.telegramUser != 'allTelegramUsers' &&
|
|
231
|
+
this.config.telegramInstance
|
|
232
|
+
) {
|
|
233
|
+
const message = line.message.replace(/[`]/g, '');
|
|
234
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
235
|
+
const title =
|
|
236
|
+
line.title != '' ? `<b>${line.title.replace(/[`]/g, '')}</b>` : '<b>Gotifi WS Message</b>';
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
this.sendTo(this.config.telegramInstance, 'send', {
|
|
240
|
+
user: this.config.telegramUser,
|
|
241
|
+
parse_mode: 'HTML',
|
|
242
|
+
text: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
243
|
+
});
|
|
244
|
+
} catch (err) {
|
|
245
|
+
this.log.warn(`Error sending Telegram message: ${err}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
case 'email':
|
|
250
|
+
if (this.config.emailInstance && this.config.emailReceiver && this.config.emailSender) {
|
|
251
|
+
const message = line.message.replace(/[`]/g, '');
|
|
252
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
253
|
+
const title = line.title != '' ? line.title.replace(/[`]/g, '') : 'Gotifi WS Message';
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
this.sendTo(this.config.emailInstance, 'send', {
|
|
257
|
+
text: formatMessage,
|
|
258
|
+
to: this.config.emailReceiver,
|
|
259
|
+
subject: title,
|
|
260
|
+
from: this.config.emailSender,
|
|
261
|
+
});
|
|
262
|
+
} catch (err) {
|
|
263
|
+
this.log.warn(`Error sending E-Mail message: ${err}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
267
|
+
case 'pushover':
|
|
268
|
+
if (
|
|
269
|
+
this.config.pushoverSilentNotice === true &&
|
|
270
|
+
this.config.pushoverInstance &&
|
|
271
|
+
this.config.pushoverDeviceID
|
|
272
|
+
) {
|
|
273
|
+
const message = line.message.replace(/[`]/g, '');
|
|
274
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
275
|
+
const title =
|
|
276
|
+
line.title != '' ? `<b>${line.title.replace(/[`]/g, '')}</b>` : '<b>Gotifi WS Message</b>';
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
this.sendTo(this.config.pushoverInstance, 'send', {
|
|
280
|
+
message: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
281
|
+
sound: '',
|
|
282
|
+
priority: -1,
|
|
283
|
+
title: title,
|
|
284
|
+
device: this.config.pushoverDeviceID,
|
|
285
|
+
html: 1,
|
|
286
|
+
});
|
|
287
|
+
} catch (err) {
|
|
288
|
+
this.log.warn(`Error sending Pushover message: ${err}`);
|
|
289
|
+
}
|
|
290
|
+
} else if (this.config.pushoverInstance && this.config.pushoverDeviceID) {
|
|
291
|
+
const message = line.message.replace(/[`]/g, '');
|
|
292
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
293
|
+
const title =
|
|
294
|
+
line.title != '' ? `<b>${line.title.replace(/[`]/g, '')}</b>` : '<b>Gotifi WS Message</b>';
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
this.sendTo(this.config.pushoverInstance, 'send', {
|
|
298
|
+
message: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
299
|
+
sound: '',
|
|
300
|
+
title: title,
|
|
301
|
+
device: this.config.pushoverDeviceID,
|
|
302
|
+
html: 1,
|
|
303
|
+
});
|
|
304
|
+
} catch (err) {
|
|
305
|
+
this.log.warn(`Error sending Pushover message: ${err}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
case 'whatsapp-cmb':
|
|
310
|
+
if (this.config.whatsappInstance) {
|
|
311
|
+
const message = line.message.replace(/[`]/g, '');
|
|
312
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
313
|
+
const title = line.title != '' ? `*${line.title.replace(/[`]/g, '')}*` : '*Gotifi WS Message*';
|
|
314
|
+
|
|
315
|
+
try {
|
|
316
|
+
this.sendTo(this.config.whatsappInstance, 'send', {
|
|
317
|
+
text: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
318
|
+
});
|
|
319
|
+
} catch (err) {
|
|
320
|
+
this.log.warn(`Error sending WhatsApp message: ${err}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
case 'signal-cmb':
|
|
325
|
+
if (this.config.signalInstance) {
|
|
326
|
+
const message = line.message.replace(/[`]/g, '');
|
|
327
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
328
|
+
const title = line.title != '' ? line.title.replace(/[`]/g, '') : 'Gotifi WS Message';
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
this.sendTo(this.config.signalInstance, 'send', {
|
|
332
|
+
text: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
333
|
+
});
|
|
334
|
+
} catch (err) {
|
|
335
|
+
this.log.warn(`Error sending Signal message: ${err}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
break;
|
|
339
|
+
case 'matrix':
|
|
340
|
+
if (this.config.matrixInstance) {
|
|
341
|
+
const message = line.message.replace(/[`]/g, '');
|
|
342
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
343
|
+
const title =
|
|
344
|
+
line.title != '' ? `<b>${line.title.replace(/[`]/g, '')}</b>` : '<b>Gotifi WS Message</b>';
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
this.sendTo(this.config.matrixInstance, {
|
|
348
|
+
html: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
349
|
+
});
|
|
350
|
+
} catch (err) {
|
|
351
|
+
this.log.warn(`Error sending Matrix message: ${err}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
break;
|
|
355
|
+
case 'discord':
|
|
356
|
+
if (this.config.discordInstance && this.config.discordTarget) {
|
|
357
|
+
const message = line.message.replace(/[`]/g, '');
|
|
358
|
+
const formatMessage = message.replace(/[']/g, '"');
|
|
359
|
+
const title =
|
|
360
|
+
line.title != '' ? `<b>${line.title.replace(/[`]/g, '')}</b>` : 'Gotifi WS Message';
|
|
361
|
+
|
|
362
|
+
if (this.config.discordTarget.match(/^\d+$/)) {
|
|
363
|
+
// send to a single user
|
|
364
|
+
try {
|
|
365
|
+
this.sendTo(this.config.discordInstance, 'sendMessage', {
|
|
366
|
+
userId: this.config.discordTarget,
|
|
367
|
+
content: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
368
|
+
});
|
|
369
|
+
} catch (err) {
|
|
370
|
+
this.log.warn(`Error sending Discord message: ${err}`);
|
|
371
|
+
}
|
|
372
|
+
} else if (this.config.discordTarget.match(/^\d+\/\d+$/)) {
|
|
373
|
+
// send to a server channel
|
|
374
|
+
const [serverId, channelId] = this.config.discordTarget.split('/');
|
|
375
|
+
try {
|
|
376
|
+
this.sendTo(this.config.discordInstance, 'sendMessage', {
|
|
377
|
+
serverId,
|
|
378
|
+
channelId,
|
|
379
|
+
content: `${title != '' ? `${title}\n` : ''}${formatMessage}`,
|
|
380
|
+
});
|
|
381
|
+
} catch (err) {
|
|
382
|
+
this.log.warn(`Error sending Discord message: ${err}`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
this.log.error('Push-Message error: Please check your Configuration');
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
_(word, systemLang) {
|
|
393
|
+
const translations = require(`./admin/i18n/${systemLang ? systemLang : 'en'}/translations.json`);
|
|
394
|
+
|
|
395
|
+
if (translations[word]) {
|
|
396
|
+
return translations[word];
|
|
397
|
+
} else {
|
|
398
|
+
this.log.debug('Please translate in translations.json: ' + word);
|
|
399
|
+
return word;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (require.main !== module) {
|
|
405
|
+
/**
|
|
406
|
+
* @param {Partial<utils.AdapterOptions>} [options={}]
|
|
407
|
+
*/
|
|
408
|
+
module.exports = (options) => new GotifyWs(options);
|
|
409
|
+
} else {
|
|
410
|
+
new GotifyWs();
|
|
411
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "iobroker.gotify-ws",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Gotify web socket for connection to various notification systems",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "simatec",
|
|
7
|
+
"email": "simatec@simateccloud.de"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/simatec/ioBroker.gotify-ws",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"Gotify",
|
|
13
|
+
"Websocket",
|
|
14
|
+
"Telegram",
|
|
15
|
+
"Whatsapp",
|
|
16
|
+
"Discord",
|
|
17
|
+
"Mail",
|
|
18
|
+
"Pushover"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/simatec/ioBroker.gotify-ws.git"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">= 18"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@iobroker/adapter-core": "^3.1.6",
|
|
29
|
+
"ws": "^8.17.1",
|
|
30
|
+
"axios": "^1.7.2"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@alcalzone/release-script": "^3.7.0",
|
|
34
|
+
"@alcalzone/release-script-plugin-iobroker": "^3.7.1",
|
|
35
|
+
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
36
|
+
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
37
|
+
"@iobroker/adapter-dev": "^1.3.0",
|
|
38
|
+
"@iobroker/testing": "^4.1.3",
|
|
39
|
+
"@tsconfig/node20": "^20.1.4",
|
|
40
|
+
"@types/chai": "^4.3.16",
|
|
41
|
+
"@types/chai-as-promised": "^7.1.8",
|
|
42
|
+
"@types/mocha": "^10.0.6",
|
|
43
|
+
"@types/node": "^20.14.5",
|
|
44
|
+
"@types/proxyquire": "^1.3.31",
|
|
45
|
+
"@types/sinon": "^17.0.3",
|
|
46
|
+
"@types/sinon-chai": "^3.2.12",
|
|
47
|
+
"chai": "^4.3.10",
|
|
48
|
+
"chai-as-promised": "^7.1.2",
|
|
49
|
+
"eslint": "^9.5.0",
|
|
50
|
+
"mocha": "^10.4.0",
|
|
51
|
+
"proxyquire": "^2.1.3",
|
|
52
|
+
"sinon": "^18.0.0",
|
|
53
|
+
"sinon-chai": "^3.7.0",
|
|
54
|
+
"typescript": "~5.4.5"
|
|
55
|
+
},
|
|
56
|
+
"main": "main.js",
|
|
57
|
+
"files": [
|
|
58
|
+
"admin{,/!(src)/**}/!(tsconfig|tsconfig.*|.eslintrc).json",
|
|
59
|
+
"admin{,/!(src)/**}/*.{html,css,png,svg,jpg,js}",
|
|
60
|
+
"lib/",
|
|
61
|
+
"www/",
|
|
62
|
+
"io-package.json",
|
|
63
|
+
"LICENSE",
|
|
64
|
+
"main.js"
|
|
65
|
+
],
|
|
66
|
+
"scripts": {
|
|
67
|
+
"test": "npm run test:package && npm run test:unit",
|
|
68
|
+
"test:package": "mocha test/package --exit",
|
|
69
|
+
"test:unit": "mocha test/unit --exit",
|
|
70
|
+
"test:integration": "mocha test/integration --exit",
|
|
71
|
+
"release": "release-script",
|
|
72
|
+
"release-patch": "release-script patch --yes",
|
|
73
|
+
"release-minor": "release-script minor --yes",
|
|
74
|
+
"release-major": "release-script major --yes",
|
|
75
|
+
"translate": "translate-adapter"
|
|
76
|
+
},
|
|
77
|
+
"bugs": {
|
|
78
|
+
"url": "https://github.com/simatec/ioBroker.gotify-ws/issues"
|
|
79
|
+
},
|
|
80
|
+
"readmeFilename": "README.md"
|
|
81
|
+
}
|