iobroker.rest-api 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +49 -8
  2. package/admin/i18n/{de/translations.json → de.json} +22 -22
  3. package/admin/i18n/{en/translations.json → en.json} +22 -23
  4. package/admin/i18n/{es/translations.json → es.json} +22 -23
  5. package/admin/i18n/{fr/translations.json → fr.json} +22 -23
  6. package/admin/i18n/{it/translations.json → it.json} +22 -23
  7. package/admin/i18n/{nl/translations.json → nl.json} +22 -23
  8. package/admin/i18n/{pl/translations.json → pl.json} +22 -23
  9. package/admin/i18n/{pt/translations.json → pt.json} +22 -23
  10. package/admin/i18n/{ru/translations.json → ru.json} +22 -23
  11. package/admin/i18n/uk.json +32 -0
  12. package/admin/i18n/{zh-cn/translations.json → zh-cn.json} +22 -23
  13. package/admin/jsonConfig.json +178 -180
  14. package/admin/rest-api.svg +8 -0
  15. package/dist/lib/api/controllers/common.js +129 -0
  16. package/dist/lib/api/controllers/common.js.map +1 -0
  17. package/dist/lib/api/controllers/enum.js +58 -0
  18. package/dist/lib/api/controllers/enum.js.map +1 -0
  19. package/dist/lib/api/controllers/file.js +104 -0
  20. package/dist/lib/api/controllers/file.js.map +1 -0
  21. package/dist/lib/api/controllers/history.js +262 -0
  22. package/dist/lib/api/controllers/history.js.map +1 -0
  23. package/dist/lib/api/controllers/object.js +346 -0
  24. package/dist/lib/api/controllers/object.js.map +1 -0
  25. package/dist/lib/api/controllers/sendTo.js +118 -0
  26. package/dist/lib/api/controllers/sendTo.js.map +1 -0
  27. package/dist/lib/api/controllers/state.js +545 -0
  28. package/dist/lib/api/controllers/state.js.map +1 -0
  29. package/dist/lib/api/swagger/swagger.yaml +2551 -0
  30. package/{lib → dist/lib}/common.js +8 -10
  31. package/dist/lib/common.js.map +1 -0
  32. package/dist/lib/rest-api.js +1216 -0
  33. package/dist/lib/rest-api.js.map +1 -0
  34. package/dist/main.js +159 -0
  35. package/dist/main.js.map +1 -0
  36. package/examples/demoBrowserClient.html +95 -82
  37. package/examples/demoNodeClient.js +8 -7
  38. package/examples/longPolling.js +46 -45
  39. package/io-package.json +43 -34
  40. package/package.json +36 -24
  41. package/lib/api/controllers/common.js +0 -150
  42. package/lib/api/controllers/enum.js +0 -44
  43. package/lib/api/controllers/file.js +0 -74
  44. package/lib/api/controllers/history.js +0 -239
  45. package/lib/api/controllers/object.js +0 -273
  46. package/lib/api/controllers/sendTo.js +0 -123
  47. package/lib/api/controllers/state.js +0 -565
  48. package/lib/api/swagger/swagger.yaml +0 -2624
  49. package/lib/rest-api.js +0 -1123
  50. package/main.js +0 -173
  51. /package/{lib → dist/lib}/config/default.yaml +0 -0
@@ -25,7 +25,7 @@ class LongPolling {
25
25
  this.subscriptions = {
26
26
  objects: {},
27
27
  states: {},
28
- patterns: {}
28
+ patterns: {},
29
29
  };
30
30
  this.sid = Date.now() + '_' + Math.round(Math.random() * 10000);
31
31
  if (this.options.autoConnect) {
@@ -41,27 +41,30 @@ class LongPolling {
41
41
  setTimeout(() => {
42
42
  Object.keys(this.subscriptions.objects).forEach(id =>
43
43
  fetch(`${IOBROKER_SWAGGER}v1/object/${id}/subscribe?sid=${this.sid}&method=polling`, {
44
- headers: this._getAuthorization()
44
+ headers: this._getAuthorization(),
45
45
  })
46
46
  .then(response => response.json())
47
- .catch(error => console.error('Cannot resubscribe: ' + error)));
47
+ .catch(error => console.error('Cannot resubscribe: ' + error)),
48
+ );
48
49
 
49
50
  Object.keys(this.subscriptions.states).forEach(id =>
50
51
  fetch(`${IOBROKER_SWAGGER}v1/state/${id}/subscribe?sid=${this.sid}&method=polling`, {
51
- headers: this._getAuthorization()
52
+ headers: this._getAuthorization(),
52
53
  })
53
54
  .then(response => response.json())
54
- .catch(error => console.error('Cannot resubscribe: ' + error)));
55
+ .catch(error => console.error('Cannot resubscribe: ' + error)),
56
+ );
55
57
 
56
58
  Object.keys(this.subscriptions.patterns).forEach(pattern =>
57
59
  fetch(`${IOBROKER_SWAGGER}v1/states/subscribe?sid=${this.sid}&method=polling`, {
58
60
  method: 'POST',
59
61
  cache: 'no-cache',
60
62
  headers: this._getAuthorization('application/json'),
61
- body: JSON.stringify({method: 'polling', pattern})
63
+ body: JSON.stringify({ method: 'polling', pattern }),
62
64
  })
63
65
  .then(response => response.json())
64
- .catch(error => console.log('Error: ' + error)));
66
+ .catch(error => console.log('Error: ' + error)),
67
+ );
65
68
 
66
69
  this.options.onConnection && this.options.onConnection(this.isConnected);
67
70
  }, 0);
@@ -74,14 +77,14 @@ class LongPolling {
74
77
  _getAuthorization(contentType) {
75
78
  if (this.options.user) {
76
79
  const headers = {
77
- Authorization: 'Basic ' + btoa(this.options.user + ':' + this.options.password)
80
+ Authorization: 'Basic ' + btoa(this.options.user + ':' + this.options.password),
78
81
  };
79
82
  if (contentType) {
80
- headers['Content-Type'] = 'application/json';
83
+ headers['Content-Type'] = 'application/json';
81
84
  }
82
85
  return headers;
83
86
  } else if (contentType) {
84
- return {'Content-Type': 'application/json'};
87
+ return { 'Content-Type': 'application/json' };
85
88
  } else {
86
89
  return undefined;
87
90
  }
@@ -93,13 +96,16 @@ class LongPolling {
93
96
  // in real the re-connect interval will be added the timeout for fetch which depends on browser.
94
97
  this.options.onConnectionAttempt && this.options.onConnectionAttempt(this.options.reconnectInterval);
95
98
  }
96
- const controller = new AbortController()
99
+ const controller = new AbortController();
97
100
  let timeoutId = setTimeout(() => controller.abort(), this.options.pollingInterval + 1000);
98
101
 
99
- fetch(`${this.host}v1/polling?sid=${this.sid}${isStart ? `&connect&timeout=${this.options.pollingInterval}` : ''}`, {
100
- signal: controller.signal,
101
- headers: this._getAuthorization(),
102
- })
102
+ fetch(
103
+ `${this.host}v1/polling?sid=${this.sid}${isStart ? `&connect&timeout=${this.options.pollingInterval}` : ''}`,
104
+ {
105
+ signal: controller.signal,
106
+ headers: this._getAuthorization(),
107
+ },
108
+ )
103
109
  .then(response => {
104
110
  timeoutId && clearTimeout(timeoutId);
105
111
  timeoutId = null;
@@ -147,7 +153,7 @@ class LongPolling {
147
153
  console.log('Cannot call handler: ' + error);
148
154
  }
149
155
  });
150
- })
156
+ });
151
157
  }
152
158
  } else if (data.id && data.obj) {
153
159
  if (this.subscriptions.objects[data.id]) {
@@ -159,7 +165,7 @@ class LongPolling {
159
165
  console.log('Cannot call handler: ' + error);
160
166
  }
161
167
  });
162
- })
168
+ });
163
169
  }
164
170
  } else if (data.id) {
165
171
  // state and object where deleted
@@ -172,7 +178,7 @@ class LongPolling {
172
178
  console.log('Cannot call handler: ' + error);
173
179
  }
174
180
  });
175
- })
181
+ });
176
182
  } else if (this.subscriptions.state[data.id]) {
177
183
  setTimeout(() => {
178
184
  this.subscriptions.state[data.id].forEach(cb => {
@@ -182,7 +188,7 @@ class LongPolling {
182
188
  console.log('Cannot call handler: ' + error);
183
189
  }
184
190
  });
185
- })
191
+ });
186
192
  }
187
193
  }
188
194
  }
@@ -202,26 +208,26 @@ class LongPolling {
202
208
  this._sendConnectedEvent(false);
203
209
 
204
210
  if (!this.terminate) {
205
- this.connecTimeout = this.connecTimeout || setTimeout(() => {
206
- this.connecTimeout = null;
207
- this._longPolling(true);
208
- }, this.options.reconnectInterval);
211
+ this.connecTimeout =
212
+ this.connecTimeout ||
213
+ setTimeout(() => {
214
+ this.connecTimeout = null;
215
+ this._longPolling(true);
216
+ }, this.options.reconnectInterval);
209
217
  }
210
218
  });
211
219
  }
212
220
 
213
221
  getState(id) {
214
222
  return fetch(`${IOBROKER_SWAGGER}v1/state/${id}`, {
215
- headers: this._getAuthorization()
216
- })
217
- .then(response => response.json())
223
+ headers: this._getAuthorization(),
224
+ }).then(response => response.json());
218
225
  }
219
226
 
220
227
  getObject(id) {
221
228
  return fetch(`${IOBROKER_SWAGGER}v1/object/${id}`, {
222
- headers: this._getAuthorization()
223
- })
224
- .then(response => response.json())
229
+ headers: this._getAuthorization(),
230
+ }).then(response => response.json());
225
231
  }
226
232
 
227
233
  subscribeState(id, cb) {
@@ -229,9 +235,8 @@ class LongPolling {
229
235
  this.subscriptions.states[id] = [];
230
236
  this.subscriptions.states[id].push(cb);
231
237
  return fetch(`${IOBROKER_SWAGGER}v1/state/${id}/subscribe?sid=${this.sid}&method=polling`, {
232
- headers: this._getAuthorization()
233
- })
234
- .then(response => response.json());
238
+ headers: this._getAuthorization(),
239
+ }).then(response => response.json());
235
240
  } else {
236
241
  this.subscriptions.states[id].push(cb);
237
242
  return Promise.resolve();
@@ -246,7 +251,7 @@ class LongPolling {
246
251
  method: 'POST',
247
252
  cache: 'no-cache',
248
253
  headers: this._getAuthorization('application/json'),
249
- body: JSON.stringify({method: 'polling', pattern})
254
+ body: JSON.stringify({ method: 'polling', pattern }),
250
255
  })
251
256
  .then(response => response.json())
252
257
  .catch(error => console.log('Error: ' + error));
@@ -275,9 +280,8 @@ class LongPolling {
275
280
  method: 'POST',
276
281
  cache: 'no-cache',
277
282
  headers: this._getAuthorization('application/json'),
278
- body: JSON.stringify({method: 'polling', pattern})
279
- })
280
- .then(response => response.json());
283
+ body: JSON.stringify({ method: 'polling', pattern }),
284
+ }).then(response => response.json());
281
285
  }
282
286
  } else {
283
287
  return Promise.resolve();
@@ -300,9 +304,8 @@ class LongPolling {
300
304
  delete this.subscriptions.states[id];
301
305
  }
302
306
  return fetch(`${IOBROKER_SWAGGER}v1/state/${id}/unsubscribe?sid=${this.sid}&method=polling`, {
303
- headers: this._getAuthorization()
304
- })
305
- .then(response => response.json());
307
+ headers: this._getAuthorization(),
308
+ }).then(response => response.json());
306
309
  }
307
310
  } else {
308
311
  return Promise.resolve();
@@ -314,9 +317,8 @@ class LongPolling {
314
317
  this.subscriptions.objects[id] = [];
315
318
  this.subscriptions.objects[id].push(cb);
316
319
  return fetch(`${IOBROKER_SWAGGER}v1/object/${id}/subscribe?sid=${this.sid}&method=polling`, {
317
- headers: this._getAuthorization()
318
- })
319
- .then(response => response.json());
320
+ headers: this._getAuthorization(),
321
+ }).then(response => response.json());
320
322
  } else {
321
323
  this.subscriptions.objects[id].push(cb);
322
324
  return Promise.resolve();
@@ -339,9 +341,8 @@ class LongPolling {
339
341
  delete this.subscriptions.objects[id];
340
342
  }
341
343
  return fetch(`${IOBROKER_SWAGGER}v1/object/${id}/unsubscribe?sid=${this.sid}&method=polling`, {
342
- headers: this._getAuthorization()
343
- })
344
- .then(response => response.json());
344
+ headers: this._getAuthorization(),
345
+ }).then(response => response.json());
345
346
  }
346
347
  } else {
347
348
  return Promise.resolve();
package/io-package.json CHANGED
@@ -1,9 +1,22 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "rest-api",
4
- "version": "2.0.2",
4
+ "version": "3.0.0",
5
5
  "news": {
6
- "2.0.2": {
6
+ "3.0.0": {
7
+ "en": "Rewritten in TypeScript\nRemoved binary states",
8
+ "de": "Neu geschrieben in TypeScript\nEntfernte binäre Zustände",
9
+ "ru": "Переписано в TypeScript\nУдаленные бинарные состояния",
10
+ "pt": "Reescrito em TypeScript\nEstados binários removidos",
11
+ "nl": "Herschreven in TypeScript\nBinaire toestanden verwijderd",
12
+ "fr": "Réécrit dans TypeScript\nÉtats binaires supprimés",
13
+ "it": "Rescritto in TypeScript\nStati binari rimossi",
14
+ "es": "Reescrito en TipoScript\nEstados binarios eliminados",
15
+ "pl": "Przepisane w TypeScript\nUsunięte stany binarne",
16
+ "uk": "Записатися в TypeScript\nВилучені бінарні штати",
17
+ "zh-cn": "在类型脚本中重写\n删除二进制状态"
18
+ },
19
+ "2.0.3": {
7
20
  "en": "Changed response for the endpoint get states to the dictionary in swagger",
8
21
  "de": "Geänderte Antwort für den Endpunkt erhalten Zustände zum Wörterbuch in Swagger",
9
22
  "ru": "Измененный ответ для конечной точки получить состояния в словарь в swagger",
@@ -29,19 +42,6 @@
29
42
  "uk": "сайт: www.iobroker.com й\nВиправлені запити історії\nМінімальний необхідний вузол.js версія 16",
30
43
  "zh-cn": "移植到 xqio 经纪人/网络服务器 `\n固定历史请求\n最低要求的节点.js版本为16"
31
44
  },
32
- "2.0.0": {
33
- "en": "Fixed history requests\nMinimum required node.js version is 16",
34
- "de": "Geschichtsanfragen behoben\nMinimum erforderlich node.js Version ist 16",
35
- "ru": "Исправленные просьбы об истории\nМинимальная требуемая версия node.js - 16",
36
- "pt": "Pedidos de histórico fixo\nA versão mínima necessária do node.js é 16",
37
- "nl": "Vaste historische verzoeken\nMinimum vereiste node.js versie is 16",
38
- "fr": "Demande d'historique fixe\nLa version minimum requise node.js est 16",
39
- "it": "Risolte richieste di storia\nVersione minima richiesta node.js è 16",
40
- "es": "Solicitudes de historia fija\nLa versión mínima requerida node.js es 16",
41
- "pl": "Poprawione żądania dotyczące historii\nMinimalna wymagana node.js wersja jest 16",
42
- "uk": "Виправлені запити історії\nМінімальний необхідний вузол.js версія 16",
43
- "zh-cn": "固定历史请求\n最低要求的节点.js版本为16"
44
- },
45
45
  "1.1.0": {
46
46
  "en": "Converting of the setState values to the according type\nImplemented file operations",
47
47
  "de": "Umrechnung der setState-Werte in den entsprechenden Typ\nImplementierung von Dateioperationen",
@@ -78,24 +78,22 @@
78
78
  "it": "Controllare se la porta è occupata solo su interfaccia definita",
79
79
  "es": "Compruebe si el puerto está ocupado sólo en la interfaz definida",
80
80
  "pl": "Jeśli port jest zajęty tylko na określonym interfejsie",
81
+ "uk": "Перевірте, чи порт зайнятий лише на визначеному інтерфейсі",
81
82
  "zh-cn": "如果港口只在界定的界线上被占有,则该港口将被扣押。"
82
- },
83
- "1.0.2": {
84
- "en": "Implemented binary read/write operations",
85
- "de": "Implementierung binärer Schreib-/Lesevorgänge",
86
- "ru": "Внедренные бинарные чтения / записи операции",
87
- "pt": "Operações de leitura/escrita binárias implementadas",
88
- "nl": "Geïmplementeerde binaire las/schrijf operaties",
89
- "fr": "Opérations de lecture/écriture binaires mises en œuvre",
90
- "it": "Operazioni di lettura/scrittura binarie implementate",
91
- "es": "Operaciones de lectura y escritura binarias aplicadas",
92
- "pl": "Poprawianie binarnego odczytu/pisania operacji",
93
- "zh-cn": "执行本文的文字/仪式作业"
94
83
  }
95
84
  },
96
- "title": "REST API",
97
85
  "titleLang": {
98
- "en": "REST API"
86
+ "en": "REST API",
87
+ "de": "REST API",
88
+ "ru": "REST API",
89
+ "pt": "REST API",
90
+ "nl": "REST API",
91
+ "fr": "REST API",
92
+ "it": "REST API",
93
+ "es": "REST API",
94
+ "pl": "REST API",
95
+ "uk": "REST API",
96
+ "zh-cn": "REST API"
99
97
  },
100
98
  "desc": {
101
99
  "en": "This adapter allows to read and write ioBroker objects and state with web RESTful API and Swagger UI",
@@ -107,6 +105,7 @@
107
105
  "it": "Questo adattatore consente di leggere e scrivere oggetti ioBroker e lo stato con l'API RESTful Web e l'interfaccia utente di Swagger",
108
106
  "es": "Este adaptador permite leer y escribir objetos y estados ioBroker con la API RESTful web y la interfaz de usuario Swagger",
109
107
  "pl": "Ten adapter pozwala na odczyt i zapis obiektów ioBroker oraz ich stan za pomocą web RESTful API i Swagger UI",
108
+ "uk": "Цей адаптер дозволяє читати та записувати об'єкти ioBroker та стан з веб RESTful API та Swagger UI",
110
109
  "zh-cn": "该适配器允许使用Web RESTful API和Swagger UI读写ioBroker对象和状态"
111
110
  },
112
111
  "authors": [
@@ -117,9 +116,8 @@
117
116
  "connectionType": "local",
118
117
  "dataSource": "push",
119
118
  "loglevel": "info",
120
- "icon": "rest-api.png",
119
+ "icon": "rest-api.svg",
121
120
  "compact": true,
122
- "materialize": true,
123
121
  "webExtension": "lib/rest-api.js",
124
122
  "readme": "https://github.com/ioBroker/ioBroker.rest-api/blob/master/README.md",
125
123
  "keywords": [
@@ -130,10 +128,15 @@
130
128
  "communication"
131
129
  ],
132
130
  "enabled": true,
133
- "extIcon": "https://raw.githubusercontent.com/ioBroker/ioBroker.rest-api/master/admin/rest-api.png",
131
+ "extIcon": "https://raw.githubusercontent.com/ioBroker/ioBroker.rest-api/master/admin/rest-api.svg",
134
132
  "type": "communication",
135
133
  "stopBeforeUpdate": true,
136
- "localLink": "%protocol%://%ip%:%port%/",
134
+ "localLinks": {
135
+ "_default": {
136
+ "link": "%protocol%://%ip%:%port%/",
137
+ "intro": true
138
+ }
139
+ },
137
140
  "adminUI": {
138
141
  "config": "json"
139
142
  },
@@ -142,9 +145,14 @@
142
145
  "license": "Apache-2.0"
143
146
  },
144
147
  "tier": 3,
148
+ "globalDependencies": [
149
+ {
150
+ "admin": ">=7.4.10"
151
+ }
152
+ ],
145
153
  "dependencies": [
146
154
  {
147
- "js-controller": ">=4.0.0"
155
+ "js-controller": ">=5.0.19"
148
156
  }
149
157
  ],
150
158
  "plugins": {
@@ -162,6 +170,7 @@
162
170
  "certPrivate": "",
163
171
  "certChained": "",
164
172
  "defaultUser": "admin",
173
+ "ttl": 3600,
165
174
  "onlyAllowWhenUserIsOwner": false,
166
175
  "webInstance": "",
167
176
  "leEnabled": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.rest-api",
3
- "version": "2.0.2",
3
+ "version": "3.0.0",
4
4
  "description": "RESTful interface for ioBroker with GUI.",
5
5
  "author": {
6
6
  "name": "bluefox",
@@ -15,60 +15,72 @@
15
15
  "web"
16
16
  ],
17
17
  "engines": {
18
- "node": ">=16"
18
+ "node": ">=18"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
22
22
  "url": "https://github.com/ioBroker/ioBroker.rest-api"
23
23
  },
24
24
  "dependencies": {
25
- "@iobroker/adapter-core": "^3.1.6",
26
- "@iobroker/socket-classes": "^1.5.6",
27
- "@iobroker/webserver": "^1.0.3",
28
- "axios": "^1.7.2",
29
- "body-parser": "^1.20.2",
25
+ "@iobroker/adapter-core": "^3.2.3",
26
+ "@iobroker/socket-classes": "^2.2.16",
27
+ "@iobroker/webserver": "^1.2.7",
28
+ "@iobroker/ws-server": "^4.3.7",
29
+ "@iobroker/js-controller-common-db": "^7.0.7",
30
+ "axios": "^1.9.0",
31
+ "body-parser": "^2.2.0",
32
+ "cookie-parser": "^1.4.7",
30
33
  "cors": "^2.8.5",
31
- "express": "^4.19.2",
32
- "multer": "^1.4.5-lts.1",
34
+ "express": "^4.21.2",
35
+ "multer": "^1.4.5-lts.2",
33
36
  "swagger-node-runner-fork": "^0.8.0",
34
37
  "swagger-ui-express": "^5.0.1",
35
38
  "yamljs": "^0.3.0"
36
39
  },
37
40
  "devDependencies": {
38
- "@alcalzone/release-script": "^3.7.3",
41
+ "@alcalzone/release-script": "^3.8.0",
39
42
  "@alcalzone/release-script-plugin-iobroker": "^3.7.2",
40
43
  "@alcalzone/release-script-plugin-license": "^3.7.0",
41
- "@iobroker/adapter-dev": "^1.3.0",
42
- "@iobroker/testing": "^4.1.3",
43
- "chai": "^4.4.1",
44
- "eslint-plugin-eqeqeq-fix": "^1.0.3",
45
- "eslint-plugin-only-warn": "^1.1.0",
46
- "eslint-plugin-react": "^7.34.3",
47
- "gulp": "^4.0.2",
48
- "mocha": "^10.6.0"
44
+ "@iobroker/adapter-dev": "^1.4.0",
45
+ "@iobroker/eslint-config": "^2.0.1",
46
+ "@iobroker/testing": "^5.0.4",
47
+ "@iobroker/types": "^7.0.7",
48
+ "@types/body-parser": "^1.19.5",
49
+ "@types/cookie-parser": "^1.4.8",
50
+ "@types/cors": "^2.8.17",
51
+ "@types/express": "^4.17.21",
52
+ "@types/multer": "^1.4.12",
53
+ "@types/node": "^22.15.2",
54
+ "@types/swagger-node-runner": "^0.6.6",
55
+ "@types/swagger-ui-express": "^4.1.8",
56
+ "@types/yamljs": "^0.2.34",
57
+ "typescript": "^5.8.3"
49
58
  },
50
59
  "bugs": {
51
60
  "url": "https://github.com/ioBroker/ioBroker.rest-api/issues"
52
61
  },
53
- "main": "main.js",
62
+ "main": "dist/main.js",
54
63
  "files": [
55
64
  "admin/",
56
65
  "img/",
57
- "lib/",
66
+ "dist/",
58
67
  "examples/",
59
68
  "LICENSE",
60
- "main.js",
61
69
  "io-package.json"
62
70
  ],
63
71
  "scripts": {
64
- "build": "gulp",
65
- "test": "node node_modules/mocha/bin/mocha --exit",
72
+ "build": "npm run build:ts && node tasks --copy-yaml",
73
+ "build:all": "npm run build:ts && node tasks",
74
+ "build:ts": "tsc -p tsconfig.build.json",
75
+ "test": "mocha --exit",
66
76
  "release": "release-script",
67
77
  "release-patch": "release-script patch --yes --no-update-lockfile",
68
78
  "release-minor": "release-script minor --yes --no-update-lockfile",
69
79
  "release-major": "release-script major --yes --no-update-lockfile",
70
80
  "translate": "translate-adapter",
71
- "update-packages": "ncu --upgrade"
81
+ "update-packages": "npx -y npm-check-updates --upgrade",
82
+ "npm": "npm i",
83
+ "lint": "eslint -c eslint.config.mjs"
72
84
  },
73
85
  "license": "Apache-2.0"
74
86
  }
@@ -1,150 +0,0 @@
1
- const ERROR_PERMISSION = 'permissionError';
2
-
3
- function checkPermissions(adapter, user, requiredRights, callback) {
4
- adapter.calculatePermissions(user, requiredRights, acl => {
5
- if (user !== 'system.user.admin') {
6
- // type: file, object, state, other
7
- // operation: create, read, write, list, delete, sendto, execute, sendto
8
- if (requiredRights && requiredRights[0] && acl) {
9
- // If permission required
10
- if (requiredRights[0].type) {
11
- if (acl[requiredRights[0].type] &&
12
- acl[requiredRights[0].type][requiredRights[0].operation]) {
13
- return callback(null);
14
- }
15
- } else {
16
- return callback(null);
17
- }
18
- }
19
-
20
- adapter.log.warn(`No permission for "${user}" to call ${JSON.stringify(requiredRights)}`);
21
-
22
- callback(ERROR_PERMISSION);
23
- } else {
24
- return callback(null);
25
- }
26
- });
27
- }
28
-
29
- function findState(adapter, idOrName, user, type, callback) {
30
- if (typeof type === 'function') {
31
- callback = type;
32
- type = null;
33
- }
34
- adapter.findForeignObject(idOrName, type, {user, checked: true, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, callback);
35
- }
36
-
37
- function getState(adapter, idOrName, user, type, callback) {
38
- if (typeof type === 'function') {
39
- callback = type;
40
- type = null;
41
- }
42
- findState(adapter, idOrName, user, type, (err, id, originId) => {
43
- if (err && (!err.message || !err.message.includes('permissionError'))) {
44
- callback && callback(err, undefined, null, originId);
45
- } else {
46
- if (err && err.message.includes('permissionError')) {
47
- // assume it is ID
48
- id = idOrName;
49
- }
50
- if (id) {
51
- adapter.getForeignState(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, (err, state) => {
52
- if (err || !state) {
53
- state = undefined;
54
- }
55
- callback && callback (err, state, id, originId);
56
- });
57
- } else {
58
- callback && callback(null, undefined, null, originId);
59
- }
60
- }
61
- });
62
- }
63
-
64
- function getBinaryState(adapter, idOrName, user, type, callback) {
65
- if (typeof type === 'function') {
66
- callback = type;
67
- type = null;
68
- }
69
- findState(adapter, idOrName, user, type, (err, id, originId) => {
70
- if (err && (!err.message || !err.message.includes('permissionError'))) {
71
- callback && callback(err, undefined, null, originId);
72
- } else {
73
- if (err && err.message.includes('permissionError')) {
74
- // assume it is ID
75
- id = idOrName;
76
- }
77
- if (id) {
78
- if (adapter.getForeignBinaryState) {
79
- adapter.getForeignBinaryState(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, (err, binary) => {
80
- if (err) {
81
- binary = undefined;
82
- }
83
- callback && callback (err, binary, id, originId);
84
- });
85
- } else {
86
- adapter.getBinaryState(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, (err, binary) => {
87
- if (err) {
88
- binary = undefined;
89
- }
90
- callback && callback (err, binary, id, originId);
91
- });
92
- }
93
- } else {
94
- callback && callback(null, undefined, null, originId);
95
- }
96
- }
97
- });
98
- }
99
-
100
- function parseUrl(url, swagger, webExtensionPrefix) {
101
- // "/v1/object/adapter.system.admin.0.alive"
102
- const parts = url.split('?')[0].split('/');
103
- if (parts[1] === webExtensionPrefix) {
104
- parts.shift(); // /
105
- parts.shift(); // remove swagger
106
- parts.shift(); // remove v1
107
- parts.shift(); // remove objects or states
108
- } else {
109
- parts.shift(); // /
110
- parts.shift(); // remove v1
111
- parts.shift(); // remove objects or states
112
- }
113
- const result = {};
114
- if (swagger && swagger.operation && swagger.operation.parameters) {
115
- let i = 0;
116
- swagger.operation.parameters.forEach(param => {
117
- if (param.in === 'path') {
118
- result[param.name] = parts[i] !== undefined ? decodeURIComponent(parts[i]) : '';
119
- i++;
120
- }
121
- });
122
- } else {
123
- parts.forEach((param, i) =>
124
- result['arg' + i] = decodeURIComponent(param));
125
- }
126
-
127
- return result;
128
- }
129
-
130
- function errorResponse(req, res, error, response) {
131
- error = error.toString();
132
- if (error === 'Error: permissionError') {
133
- error = 'permissionError';
134
- }
135
-
136
- req._adapter.log.warn(`Warning by "${req.url}": ${error}`);
137
-
138
- res
139
- .status(error.toString().includes('permissionError') ? 403 : 500)
140
- .json(Object.assign(response || {}, {error: error}));
141
- }
142
-
143
- module.exports = {
144
- checkPermissions,
145
- findState,
146
- getState,
147
- getBinaryState,
148
- parseUrl,
149
- errorResponse,
150
- };
@@ -1,44 +0,0 @@
1
- 'use strict';
2
- const commonLib = require('./common.js');
3
-
4
- module.exports = {
5
- readMainEnums: function (req, res) {
6
- commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
7
- if (error) {
8
- commonLib.errorResponse(req, res, error);
9
- } else {
10
- // check if instance is alive
11
- try {
12
- const enums = await req._adapter.getEnumsAsync('', {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
13
- res.json(enums);
14
- } catch (error) {
15
- req._adapter.log.warn(`Cannot read enums: ${error}`);
16
- commonLib.errorResponse(req, res, error);
17
- }
18
- }
19
- });
20
- },
21
- readEnums: function (req, res) {
22
- commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
23
- if (error) {
24
- commonLib.errorResponse(req, res, error);
25
- } else {
26
- const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
27
- // check if instance is alive
28
- try {
29
- const enums = await req._adapter.getEnumAsync(params.enumId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
30
- if (enums && enums.result) {
31
- res.json(Object.keys(enums.result).filter(id => id.split('.').length > 2).map(id => ({
32
- _id: id,
33
- common: enums.result[id].common
34
- })));
35
- } else {
36
- res.json([]);
37
- }
38
- } catch (error) {
39
- commonLib.errorResponse(req, res, error);
40
- }
41
- }
42
- });
43
- },
44
- };