@iobroker/js-controller-cli 4.0.0-alpha.8-20210909-001a711c → 4.0.3

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.
@@ -4,18 +4,17 @@ const path = require('path');
4
4
  const CLI = require('./messages.js');
5
5
  const CLICommand = require('./cliCommand.js');
6
6
  const { tools } = require('@iobroker/js-controller-common');
7
- const dbTools = require('@iobroker/js-controller-common-db');
7
+ const dbTools = require('@iobroker/js-controller-common-db').tools;
8
8
  const deepClone = require('deep-clone');
9
9
  const { EXIT_CODES } = require('@iobroker/js-controller-common');
10
10
 
11
- const { getObjectFrom, getInstanceName, normalizeAdapterName, enumInstances} = require('./cliTools.js');
11
+ const { getObjectFrom, getInstanceName, normalizeAdapterName, enumInstances } = require('./cliTools.js');
12
12
 
13
13
  // The root of this project. Change this when moving code to another directory
14
14
  const rootDir = tools.getControllerDir();
15
15
  const killAllScriptPath = path.join(rootDir, 'killall.sh');
16
16
 
17
17
  module.exports = class CLIProcess extends CLICommand {
18
-
19
18
  /** @param {import('./cliCommand').CLICommandOptions} options */
20
19
  constructor(options) {
21
20
  super(options);
@@ -62,7 +61,7 @@ module.exports = class CLIProcess extends CLICommand {
62
61
  */
63
62
  stop(args) {
64
63
  const adapterName = normalizeAdapterName(args[0]);
65
- if (adapterName === undefined ) {
64
+ if (adapterName === undefined) {
66
65
  this.stopJSController();
67
66
  } else if (adapterName === 'all') {
68
67
  this.setAllAdaptersEnabled(false);
@@ -99,7 +98,7 @@ module.exports = class CLIProcess extends CLICommand {
99
98
  * @param {boolean} [restartIfRunning=false] Whether running instances should be restarted
100
99
  */
101
100
  setAdapterEnabled(adapter, enabled, restartIfRunning) {
102
- const {callback, dbConnect} = this.options;
101
+ const { callback, dbConnect } = this.options;
103
102
  dbConnect(async objects => {
104
103
  // Due to the many return locations we cannot simply chain the promises here
105
104
  // Use the pre-Node8 async/await pattern
@@ -108,7 +107,10 @@ module.exports = class CLIProcess extends CLICommand {
108
107
  const adapterInstances = await enumInstances(objects, adapter);
109
108
  // If there are multiple instances for this adapter, ask the user to specify which one
110
109
  if (adapterInstances.length > 1) {
111
- CLI.error.specifyInstance(adapter, adapterInstances.map(obj => obj._id.substring('system.adapter.'.length)));
110
+ CLI.error.specifyInstance(
111
+ adapter,
112
+ adapterInstances.map(obj => obj._id.substring('system.adapter.'.length))
113
+ );
112
114
  return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
113
115
  } else if (adapterInstances.length === 0) {
114
116
  CLI.error.noInstancesFound(adapter);
@@ -162,14 +164,14 @@ module.exports = class CLIProcess extends CLICommand {
162
164
  const daemon = setupDaemonize();
163
165
  // On non-Windows OSes start KILLALL script
164
166
  // to make sure nothing keeps running
165
- if (!require('os').platform().match(/^win/)) {
167
+ if (!require('os').platform().startsWith('win')) {
166
168
  daemon.on('stopped', () => {
167
169
  let data = '';
168
170
  if (fs.existsSync(killAllScriptPath)) {
169
171
  fs.chmodSync(killAllScriptPath, '777');
170
172
  const child = require('child_process').spawn(killAllScriptPath, [], { windowsHide: true });
171
- child.stdout.on('data', _data => data += _data.toString().replace(/\n/g, ''));
172
- child.stderr.on('data', _data => data += _data.toString().replace(/\n/g, ''));
173
+ child.stdout.on('data', _data => (data += _data.toString().replace(/\n/g, '')));
174
+ child.stderr.on('data', _data => (data += _data.toString().replace(/\n/g, '')));
173
175
  child.on('exit', exitCode => {
174
176
  console.log('Exit code for "killall.sh": ' + exitCode);
175
177
  return void callback();
@@ -185,9 +187,7 @@ module.exports = class CLIProcess extends CLICommand {
185
187
  /** Restarts the JS controller */
186
188
  restartJSController() {
187
189
  const daemon = setupDaemonize();
188
- daemon
189
- .on('stopped', () => daemon.start())
190
- .on('notrunning', () => daemon.start());
190
+ daemon.on('stopped', () => daemon.start()).on('notrunning', () => daemon.start());
191
191
  daemon.stop();
192
192
  }
193
193
 
@@ -207,7 +207,10 @@ module.exports = class CLIProcess extends CLICommand {
207
207
  const alive = hostAlive ? hostAlive.val : false;
208
208
  CLI.success.controllerStatus(alive);
209
209
  console.log();
210
- if (!dbTools.isLocalStatesDbServer(config.states.type, config.states.host) && !dbTools.isLocalObjectsDbServer(config.objects.type, config.objects.host)) {
210
+ if (
211
+ !dbTools.isLocalStatesDbServer(config.states.type, config.states.host) &&
212
+ !dbTools.isLocalObjectsDbServer(config.objects.type, config.objects.host)
213
+ ) {
211
214
  CLI.success.systemStatus(!isOffline);
212
215
  }
213
216
 
@@ -232,7 +235,10 @@ module.exports = class CLIProcess extends CLICommand {
232
235
  const adapterInstances = await enumInstances(_objects, adapterName);
233
236
  // If there are multiple instances of this adapter, ask the user to specify which one
234
237
  if (adapterInstances.length > 1) {
235
- CLI.error.specifyInstance(adapterName, adapterInstances.map(obj => obj._id.substring('system.adapter.'.length)));
238
+ CLI.error.specifyInstance(
239
+ adapterName,
240
+ adapterInstances.map(obj => obj._id.substring('system.adapter.'.length))
241
+ );
236
242
  return void callback(EXIT_CODES.INVALID_ADAPTER_ID);
237
243
  } else if (adapterInstances.length === 0) {
238
244
  CLI.error.noInstancesFound(adapterName);
@@ -341,7 +347,9 @@ function setupDaemonize() {
341
347
  }
342
348
  } catch {
343
349
  console.warn('Cannot read memoryLimitMB');
344
- console.warn(`May be config file does not exist.\nPlease call "${tools.appName} setup first" to initialize the settings.`);
350
+ console.warn(
351
+ `May be config file does not exist.\nPlease call "${tools.appName} setup first" to initialize the settings.`
352
+ );
345
353
  }
346
354
  const startObj = {
347
355
  main: path.join(rootDir, 'controller.js'),
@@ -1,14 +1,13 @@
1
1
  'use strict';
2
2
  const { tools } = require('@iobroker/js-controller-common');
3
- const CLI = require('./messages.js');
4
- const CLICommand = require('./cliCommand.js');
5
- const {formatValue} = require('./cliTools');
3
+ const CLI = require('./messages.js');
4
+ const CLICommand = require('./cliCommand.js');
5
+ const { formatValue } = require('./cliTools');
6
6
  const ALIAS_STARTS_WITH = 'alias.';
7
7
 
8
8
  /** Command iobroker state ... */
9
9
  module.exports = class CLIStates extends CLICommand {
10
-
11
- /** @param {import('./cliCommand').CLICommandOptions} options */
10
+ /** @param {CLICommandOptions} options */
12
11
  constructor(options) {
13
12
  super(options);
14
13
  }
@@ -33,19 +32,16 @@ module.exports = class CLIStates extends CLICommand {
33
32
  return 'null';
34
33
  }
35
34
 
36
- return [
37
- obj.val,
38
- obj.ack,
39
- obj.from,
40
- obj.ts,
41
- obj.lc
42
- ].map(line => formatValue(line)).join('\n');
35
+ return [obj.val, obj.ack, obj.from, obj.ts, obj.lc].map(line => formatValue(line)).join('\n');
43
36
  };
44
37
  return this.get_(args, resultTransform);
45
38
  case 'getValue':
46
39
  case 'getvalue':
47
- resultTransform = obj => obj ? formatValue(obj.val, pretty) : 'null';
40
+ resultTransform = obj => (obj ? formatValue(obj.val, pretty) : 'null');
48
41
  return this.get_(args, resultTransform);
42
+ case 'getBinary':
43
+ case 'getbinary':
44
+ return this._getBinary(args);
49
45
  case 'set':
50
46
  return this.set_(args);
51
47
  case 'chmod':
@@ -55,6 +51,10 @@ module.exports = class CLIStates extends CLICommand {
55
51
  case 'delete':
56
52
  case 'del':
57
53
  return this.delete(args);
54
+ case 'getDBVersion':
55
+ return this.getDBVersion(args);
56
+ case 'setDBVersion':
57
+ return this.setDBVersion();
58
58
  default:
59
59
  CLI.error.unknownCommand('state', command);
60
60
  showHelp();
@@ -62,32 +62,133 @@ module.exports = class CLIStates extends CLICommand {
62
62
  }
63
63
  }
64
64
 
65
+ /**
66
+ * Get the protocol version
67
+ */
68
+ getDBVersion() {
69
+ const { callback, dbConnect } = this.options;
70
+ dbConnect(async (objects, states) => {
71
+ const version = await states.getProtocolVersion();
72
+ console.log(`Current States DB protocol version: ${version}`);
73
+ return void callback();
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Set protocol version
79
+ */
80
+ setDBVersion() {
81
+ const { callback, dbConnect } = this.options;
82
+ dbConnect(async (objects, states) => {
83
+ const rl = require('readline-sync');
84
+
85
+ let answer = rl.question('Changing the protocol version will restart all hosts! Continue? [N/y]', {
86
+ limit: /^(yes|y|n|no)$/i,
87
+ defaultInput: 'no'
88
+ });
89
+
90
+ answer = answer.toLowerCase();
91
+
92
+ if (answer !== 'y' && answer !== 'yes') {
93
+ console.log('Protocol version has not been changed!');
94
+ return void callback();
95
+ }
96
+
97
+ try {
98
+ await states.setProtocolVersion(this.options.version);
99
+ } catch (e) {
100
+ console.error(`Cannot update protocol version: ${e.message}`);
101
+ return void callback(1);
102
+ }
103
+ console.log(`States DB protocol updated to version ${this.options.version}`);
104
+ return void callback();
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Checks if state is a binary state
110
+ * @param {string} id id of the state
111
+ * @param {object} objects the objects db
112
+ * @param {ioBroker.OtherObject?} obj cached object
113
+ * @return {Promise<boolean>}
114
+ * @private
115
+ */
116
+ async _isBinary(id, objects, obj) {
117
+ obj = obj || (await objects.getObjectAsync(id));
118
+
119
+ return !!(obj && (obj.binary || (obj.common && obj.common.type === 'file')));
120
+ }
121
+
122
+ /**
123
+ * Get and show binary state
124
+ *
125
+ * @param {any[]} args
126
+ * @private
127
+ */
128
+ _getBinary(args) {
129
+ const { callback, dbConnect } = this.options;
130
+ const id = args[1];
131
+ dbConnect(async (objects, states) => {
132
+ try {
133
+ /** @type Buffer | null */
134
+ const state = await states.getBinaryState(id);
135
+
136
+ if (!state) {
137
+ CLI.error.stateNotFound(id);
138
+ return void callback(1);
139
+ }
140
+
141
+ if (Buffer.isBuffer(state)) {
142
+ console.log(state.toString(this.options.encoding));
143
+ return void callback();
144
+ } else {
145
+ CLI.error.stateNotBinary(id);
146
+ return void callback(1);
147
+ }
148
+ } catch (e) {
149
+ CLI.error.unknown(e);
150
+ return void callback(1);
151
+ }
152
+ });
153
+ }
154
+
65
155
  /**
66
156
  * Returns the value of a state
67
157
  * @param {any[]} args
68
158
  * @param {(input: any) => any} resultTransform
69
159
  */
70
160
  get_(args, resultTransform) {
71
- const {callback, dbConnect} = this.options;
161
+ const { callback, dbConnect } = this.options;
72
162
  const id = args[1];
73
163
 
74
- dbConnect((objects, states) => {
164
+ dbConnect(async (objects, states) => {
75
165
  if (id.startsWith(ALIAS_STARTS_WITH)) {
76
166
  objects.getObject(id, (err, targetObj) => {
77
167
  // alias
78
168
  if (targetObj && targetObj.common && targetObj.common.alias && targetObj.common.alias.id) {
79
- const aliasId = typeof targetObj.common.alias.id.read === 'string' ? targetObj.common.alias.id.read : targetObj.common.alias.id;
80
- objects.getObject(aliasId, (err, sourceObj) => {
81
- // write target
82
- states.getState(aliasId, (err, state) => {
83
- if (err || !targetObj) {
84
- CLI.error.unknown(err);
169
+ const aliasId =
170
+ typeof targetObj.common.alias.id.read === 'string'
171
+ ? targetObj.common.alias.id.read
172
+ : targetObj.common.alias.id;
173
+ objects.getObject(aliasId, async (err, sourceObj) => {
174
+ // read target
175
+ try {
176
+ if (await this._isBinary(aliasId, objects, targetObj)) {
177
+ CLI.error.stateBinaryGetUnsupported(aliasId);
178
+ return void callback(1);
179
+ }
180
+
181
+ const state = await states.getStateAsync(aliasId);
182
+ if (!state) {
183
+ CLI.error.stateNotFound(id);
85
184
  } else {
86
185
  tools.formatAliasValue(sourceObj.common, targetObj.common, state, console, '');
87
186
  console.log(resultTransform(state));
88
187
  }
89
- return void callback();
90
- });
188
+ } catch (e) {
189
+ CLI.error.unknown(e);
190
+ }
191
+ return void callback();
91
192
  });
92
193
  } else {
93
194
  CLI.error.unknown(err || `Alias ${id} has no target`);
@@ -95,14 +196,21 @@ module.exports = class CLIStates extends CLICommand {
95
196
  }
96
197
  });
97
198
  } else {
98
- states.getState(id, (err, state) => {
99
- if (err || !state) {
100
- CLI.error.stateNotFound(id, err);
199
+ try {
200
+ if (await this._isBinary(id, objects)) {
201
+ CLI.error.stateBinaryGetUnsupported(id);
202
+ return void callback(1);
203
+ }
204
+ const state = await states.getStateAsync(id);
205
+ if (!state) {
206
+ CLI.error.stateNotFound(id);
101
207
  } else {
102
208
  console.log(resultTransform(state));
103
209
  }
104
- return void callback();
105
- });
210
+ } catch (e) {
211
+ CLI.error.unknown(e);
212
+ }
213
+ return void callback();
106
214
  }
107
215
  });
108
216
  }
@@ -111,7 +219,7 @@ module.exports = class CLIStates extends CLICommand {
111
219
  * @param {any[]} args
112
220
  */
113
221
  set_(args) {
114
- const {callback, dbConnect, showHelp} = this.options;
222
+ const { callback, dbConnect, showHelp } = this.options;
115
223
  // eslint-disable-next-line prefer-const
116
224
  let [id, val, ack] = /** @type {[string, any, any]} */ (args.slice(1));
117
225
  const force = args.includes('--force') || args.includes('-f');
@@ -127,13 +235,20 @@ module.exports = class CLIStates extends CLICommand {
127
235
  }
128
236
 
129
237
  dbConnect((objects, states) => {
130
- const newVal = ack === undefined ? {val, ack: false} : {val, ack: !!ack};
238
+ const newVal = ack === undefined ? { val, ack: false } : { val, ack: !!ack };
131
239
 
132
240
  if (id.startsWith(ALIAS_STARTS_WITH)) {
133
- objects.getObject(id, (err, obj) => {
241
+ objects.getObject(id, async (err, obj) => {
242
+ if (await this._isBinary(id, objects, obj)) {
243
+ CLI.error.stateBinarySetUnsupported(id);
244
+ return void callback(1);
245
+ }
134
246
  // alias
135
247
  if (obj && obj.common && obj.common.alias && obj.common.alias.id) {
136
- const aliasId = typeof obj.common.alias.id.write === 'string' ? obj.common.alias.id.write : obj.common.alias.id;
248
+ const aliasId =
249
+ typeof obj.common.alias.id.write === 'string'
250
+ ? obj.common.alias.id.write
251
+ : obj.common.alias.id;
137
252
 
138
253
  objects.getObject(aliasId, (err, targetObj) => {
139
254
  if (err) {
@@ -152,20 +267,28 @@ module.exports = class CLIStates extends CLICommand {
152
267
  newVal.val = parseFloat(newVal.val);
153
268
  } else if (obj.common.type === 'boolean') {
154
269
  newVal.val = newVal.val.toString();
155
- newVal.val = newVal.val === 'true' || newVal.val === '1' || newVal.val === 'ON' || newVal.val === 'on';
270
+ newVal.val =
271
+ newVal.val === 'true' ||
272
+ newVal.val === '1' ||
273
+ newVal.val === 'ON' ||
274
+ newVal.val === 'on';
156
275
  }
157
276
  }
158
277
 
159
278
  // write target
160
- states.setState(aliasId, tools.formatAliasValue(obj.common, targetObj.common, newVal, console, ''), err => {
161
- if (err) {
162
- CLI.error.unknown(err);
163
- return void callback(1); // ?
164
- } else {
165
- CLI.success.stateUpdated(id, val, !!ack);
166
- return void callback();
279
+ states.setState(
280
+ aliasId,
281
+ tools.formatAliasValue(obj.common, targetObj.common, newVal, console, ''),
282
+ err => {
283
+ if (err) {
284
+ CLI.error.unknown(err);
285
+ return void callback(1); // ?
286
+ } else {
287
+ CLI.success.stateUpdated(id, val, !!ack);
288
+ return void callback();
289
+ }
167
290
  }
168
- });
291
+ );
169
292
  });
170
293
  } else {
171
294
  CLI.error.unknown(`Alias ${id} has no target`);
@@ -173,11 +296,17 @@ module.exports = class CLIStates extends CLICommand {
173
296
  }
174
297
  });
175
298
  } else {
176
- objects.getObject(id, (err, obj) => {
299
+ objects.getObject(id, async (err, obj) => {
177
300
  if (err) {
178
301
  CLI.error.unknown(err);
179
302
  return void callback(1); // access error
180
303
  }
304
+
305
+ if (await this._isBinary(id, objects, obj)) {
306
+ CLI.error.stateBinarySetUnsupported(id);
307
+ return void callback(1);
308
+ }
309
+
181
310
  if (!obj && !force) {
182
311
  CLI.error.objectNotFound(id, 'null');
183
312
  return void callback(1); // object not exists
@@ -190,7 +319,11 @@ module.exports = class CLIStates extends CLICommand {
190
319
  newVal.val = parseFloat(newVal.val);
191
320
  } else if (obj.common.type === 'boolean') {
192
321
  newVal.val = newVal.val.toString();
193
- newVal.val = newVal.val === 'true' || newVal.val === '1' || newVal.val === 'ON' || newVal.val === 'on';
322
+ newVal.val =
323
+ newVal.val === 'true' ||
324
+ newVal.val === '1' ||
325
+ newVal.val === 'ON' ||
326
+ newVal.val === 'on';
194
327
  }
195
328
  }
196
329
 
@@ -213,7 +346,7 @@ module.exports = class CLIStates extends CLICommand {
213
346
  * @param {any[]} args
214
347
  */
215
348
  delete(args) {
216
- const {callback, dbConnect} = this.options;
349
+ const { callback, dbConnect } = this.options;
217
350
  /** @type {string} */
218
351
  const id = args[1];
219
352
  if (!id) {
@@ -230,6 +363,7 @@ module.exports = class CLIStates extends CLICommand {
230
363
  CLI.success.stateDeleted(id);
231
364
  return void callback();
232
365
  }
233
- }));
366
+ })
367
+ );
234
368
  }
235
369
  };
@@ -9,9 +9,7 @@ const { tools } = require('@iobroker/js-controller-common');
9
9
  function formatValue(val, pretty) {
10
10
  // Only use JSON.stringify if we need it (for objects and arrays)
11
11
  const needsStringify = tools.isObject(val) || tools.isArray(val);
12
- const output = !needsStringify ? val
13
- : pretty ? JSON.stringify(val, null, 2)
14
- : JSON.stringify(val);
12
+ const output = !needsStringify ? val : pretty ? JSON.stringify(val, null, 2) : JSON.stringify(val);
15
13
  return output;
16
14
  }
17
15
 
@@ -53,6 +51,7 @@ function validateAdapterOrInstanceIdentifier(name) {
53
51
  * Ensures that the given string contains a valid identifier for
54
52
  * an adapter (without instance number) or instance (with instance number)
55
53
  * @param {string} name
54
+ * @return {{name: string, instance:string|null, version: string|null, nameWithVersion:string}|null}
56
55
  */
57
56
  function splitAdapterOrInstanceIdentifierWithVersion(name) {
58
57
  const res = name.match(/^([a-z0-9\-_]+)\.?(\d+)?@?([a-z0-9\-_.]*)?$/);
@@ -108,7 +107,7 @@ function enumHosts(objects) {
108
107
  function enumObjects(objects, type, startkey) {
109
108
  return new Promise((resolve, reject) => {
110
109
  const endkey = startkey + '\u9999';
111
- objects.getObjectView('system', type, {startkey, endkey}, null, (err, res) => {
110
+ objects.getObjectView('system', type, { startkey, endkey }, null, (err, res) => {
112
111
  if (err) {
113
112
  return reject(err);
114
113
  }
@@ -2,49 +2,39 @@
2
2
  const { tools } = require('@iobroker/js-controller-common');
3
3
 
4
4
  const errorMessages = Object.freeze({
5
- stateNotFound: (
6
- /** @type {string} */ stateID,
7
- /** @type {string?} */ error
8
- ) => `The state ${stateID} was not found!` + (error ? ` Reason: ${error}` : ''),
9
- objectNotFound: (
10
- /** @type {string} */ objectID,
11
- /** @type {string?} */ error
12
- ) => `The object ${objectID} was not found!` + (error ? ` Reason: ${error}` : ''),
13
- cannotUpdateObject: (
14
- /** @type {string} */ objectID,
15
- /** @type {string?} */ error
16
- ) => `The object ${objectID} could not be updated!` + (error ? ` Reason: ${error}` : ''),
17
- cannotDeleteObject: (
18
- /** @type {string} */ objectID,
19
- /** @type {string?} */ error
20
- ) => `The object ${objectID} cannot be deleted!` + (error ? ` Reason: ${error}` : ''),
21
- cannotDeleteObjectFromEnums: (
22
- /** @type {string} */ objectID,
23
- /** @type {string?} */ error
24
- ) => `The object ${objectID} could not be deleted from enums!` + (error ? ` Reason: ${error}` : ''),
25
- cannotChangeObject: (
26
- /** @type {string} */ objectID,
27
- /** @type {string?} */ error
28
- ) => `The object ${objectID} cannot be changed!` + (error ? ` Reason: ${error}` : ''),
29
- objectPropertyNotFound: (
30
- /** @type {string} */ objectID,
31
- /** @type {string} */ propPath
32
- ) => `The requested property "${propPath}" or one of its parents was not found in the object "${objectID}"!`,
5
+ stateNotFound: (/** @type {string} */ stateID, /** @type {string?} */ error) =>
6
+ `The state ${stateID} was not found!` + (error ? ` Reason: ${error}` : ''),
7
+ stateNotBinary: (/** @type {string} */ stateId) => `State "${stateId}" is not binary.`,
8
+ stateBinaryGetUnsupported: (/** @type {string} */ stateId) =>
9
+ `State "${stateId}" is a binary state, please use getBinary.`,
10
+ stateBinarySetUnsupported: (/** @type {string} */ stateId) =>
11
+ `State "${stateId}" is a binary state and cannot be set via cli.`,
12
+ objectNotFound: (/** @type {string} */ objectID, /** @type {string?} */ error) =>
13
+ `The object ${objectID} was not found!` + (error ? ` Reason: ${error}` : ''),
14
+ cannotUpdateObject: (/** @type {string} */ objectID, /** @type {string?} */ error) =>
15
+ `The object ${objectID} could not be updated!` + (error ? ` Reason: ${error}` : ''),
16
+ cannotDeleteObject: (/** @type {string} */ objectID, /** @type {string?} */ error) =>
17
+ `The object ${objectID} cannot be deleted!` + (error ? ` Reason: ${error}` : ''),
18
+ cannotDeleteObjectFromEnums: (/** @type {string} */ objectID, /** @type {string?} */ error) =>
19
+ `The object ${objectID} could not be deleted from enums!` + (error ? ` Reason: ${error}` : ''),
20
+ cannotChangeObject: (/** @type {string} */ objectID, /** @type {string?} */ error) =>
21
+ `The object ${objectID} cannot be changed!` + (error ? ` Reason: ${error}` : ''),
22
+ objectPropertyNotFound: (/** @type {string} */ objectID, /** @type {string} */ propPath) =>
23
+ `The requested property "${propPath}" or one of its parents was not found in the object "${objectID}"!`,
33
24
  invalidPropertyOrValue: () => `The property path or value is not valid. Please make sure the value is valid JSON.`,
34
25
  invalidJSONValue: () => `The given value is not valid JSON.`,
35
26
 
36
- unknownCommand: (
37
- /** @type {string} */ prefix,
38
- /** @type {string} */ command
39
- ) => `Unknown command "${prefix} ${command}"!`,
40
- requiredArgumentMissing: (
41
- /** @type {string} */ argName,
42
- /** @type {string?} */ exampleCommand
43
- ) => `The required argument "${argName}" is missing!` + (exampleCommand ? ` Example: "${exampleCommand}"` : ''),
27
+ unknownCommand: (/** @type {string} */ prefix, /** @type {string} */ command) =>
28
+ `Unknown command "${prefix} ${command}"!`,
29
+ requiredArgumentMissing: (/** @type {string} */ argName, /** @type {string?} */ exampleCommand) =>
30
+ `The required argument "${argName}" is missing!` + (exampleCommand ? ` Example: "${exampleCommand}"` : ''),
44
31
 
45
32
  noInstancesFound: adapter => `Cannot find any instances of "${adapter}"!`,
46
33
  invalidInstance: instance => `The instance "${instance}" does not exist!`,
47
- specifyInstance: (/** @type {string} */ adapter, /** @type {Array<string>?} */adapterInstances) => `The adapter "${adapter}" has multiple instances! Please specify which one should be started: "${adapterInstances.join('", "')}".`,
34
+ specifyInstance: (/** @type {string} */ adapter, /** @type {Array<string>?} */ adapterInstances) =>
35
+ `The adapter "${adapter}" has multiple instances! Please specify which one should be started: "${adapterInstances.join(
36
+ '", "'
37
+ )}".`,
48
38
  adapterDirNotFound: adapter => `Cannot find the installation dir for adapter "${adapter}"!`,
49
39
  mainFileNotFound: adapter => `Cannot find the main file for adapter "${adapter}"!`,
50
40
  cannotLoadIoPackage: adapter => `Cannot load the io-package.json file for adapter "${adapter}"!`,
@@ -53,8 +43,10 @@ const errorMessages = Object.freeze({
53
43
  /** @type {string} */ wrongPrefix,
54
44
  /** @type {string} */ command,
55
45
  /** @type {string?} */ correctPrefix
56
- ) => `The command ${command} is not intended to be used with ${wrongPrefix}!`
57
- + correctPrefix ? `Please use "${correctPrefix} ${command}" instead.` : '',
46
+ ) =>
47
+ `The command ${command} is not intended to be used with ${wrongPrefix}!` + correctPrefix
48
+ ? `Please use "${correctPrefix} ${command}" instead.`
49
+ : '',
58
50
  unknown: err => `An unknown error occurred: ${err}`,
59
51
 
60
52
  cannotChangeRunningSystem: () => `Cannot execute changes on running system. Stop ${tools.appName} first.`,
@@ -63,47 +55,46 @@ const errorMessages = Object.freeze({
63
55
  hostDoesNotExist: hostname => `The host "${hostname}" does not exist!`,
64
56
  dontRemoveCurrentHost: hostname => `Cannot remove host "${hostname}" from itself!`,
65
57
 
66
- pluginNotDefined: (pluginName, host, instance) => `The plugin "${pluginName}" does not exist for ${host ? `host "${host}"` : `instance "${instance}"`}!`,
58
+ pluginNotDefined: (pluginName, host, instance) =>
59
+ `The plugin "${pluginName}" does not exist for ${host ? `host "${host}"` : `instance "${instance}"`}!`,
67
60
 
68
- cert: certName => `Certificate "${certName}" not found or error parsing certificate information.`
61
+ cert: certName => `Certificate "${certName}" not found or error parsing certificate information.`,
62
+ instanceAlreadyRunning: instance => `The instance "${instance}" is already running, please stop instance first.`
69
63
  });
70
64
 
71
65
  const successMessages = Object.freeze({
72
66
  objectUpdated: objectID => `The object "${objectID}" was updated successfully.`,
73
67
  objectDeleted: objectID => `The object "${objectID}" was deleted.`,
74
- stateUpdated: (
75
- /** @type {string} */ stateID,
76
- /** @type {any} */ value,
77
- /** @type {boolean | undefined} */ ack
78
- ) => `The state "${stateID}" was set to "${value}"${ack === undefined ? '' : ` with flag ack=${ack}`}`,
68
+ stateUpdated: (/** @type {string} */ stateID, /** @type {any} */ value, /** @type {boolean | undefined} */ ack) =>
69
+ `The state "${stateID}" was set to "${value}"${ack === undefined ? '' : ` with flag ack=${ack}`}`,
79
70
  stateDeleted: stateID => `The state "${stateID}" was deleted.`,
80
71
  adapterStarted: adapter => `The adapter "${adapter}" was started.`,
81
72
  adapterStopped: adapter => `The adapter "${adapter}" was stopped.`,
82
73
  adapterRestarted: adapter => `The adapter "${adapter}" was restarted.`,
83
- systemStatus: isRunning => isRunning ? `At least one ${tools.appName} host is running.` : `No ${tools.appName} host is running.`,
74
+ systemStatus: isRunning =>
75
+ isRunning ? `At least one ${tools.appName} host is running.` : `No ${tools.appName} host is running.`,
84
76
  controllerStatus: isRunning => `${tools.appName} is ${isRunning ? '' : 'not '}running on this host.`,
85
- messageSent: (
86
- /** @type {string} */ adapter,
87
- /** @type {string} */ command,
88
- /** @type {any} */ message
89
- ) => `The command "${command}" was sent to "${adapter}" with the message "${message}".`,
90
- hostRenamed: (
91
- /** @type {string} */ from,
92
- /** @type {string} */ to
93
- ) => `Host "${from}" successfully renamed to "${to}".`,
94
- instanceHostChanged: (
95
- /** @type {string} */ instance,
96
- /** @type {string} */ from,
97
- /** @type {string} */ to
98
- ) => `The host for instance "${instance}" was changed from "${from}" to "${to}".`,
77
+ messageSent: (/** @type {string} */ adapter, /** @type {string} */ command, /** @type {any} */ message) =>
78
+ `The command "${command}" was sent to "${adapter}" with the message "${message}".`,
79
+ hostRenamed: (/** @type {string} */ from, /** @type {string} */ to) =>
80
+ `Host "${from}" successfully renamed to "${to}".`,
81
+ instanceHostChanged: (/** @type {string} */ instance, /** @type {string} */ from, /** @type {string} */ to) =>
82
+ `The host for instance "${instance}" was changed from "${from}" to "${to}".`,
99
83
  hostDeleted: hostname => `The host "${hostname}" was deleted.`,
100
84
 
101
- pluginEnabledOrDisabled: (pluginName, host, instance, status) => `The plugin "${pluginName}" was successfully ${status ? 'enabled' : 'disabled'} for ${host ? `host "${host}"` : `instance "${instance}"`}.`,
102
- pluginStatus: (pluginName, host, instance, status) => `The plugin "${pluginName}" is ${status ? 'enabled' : 'disabled'} for ${host ? `host "${host}"` : `instance "${instance}"`}.`
85
+ pluginEnabledOrDisabled: (pluginName, host, instance, status) =>
86
+ `The plugin "${pluginName}" was successfully ${status ? 'enabled' : 'disabled'} for ${
87
+ host ? `host "${host}"` : `instance "${instance}"`
88
+ }.`,
89
+ pluginStatus: (pluginName, host, instance, status) =>
90
+ `The plugin "${pluginName}" is ${status ? 'enabled' : 'disabled'} for ${
91
+ host ? `host "${host}"` : `instance "${instance}"`
92
+ }.`
103
93
  });
104
94
 
105
95
  const warnings = Object.freeze({
106
- noInstancesFoundOnHost: hostname => hostname ? `No instances found for host "${hostname}"!` : `No instances found!`
96
+ noInstancesFoundOnHost: hostname =>
97
+ hostname ? `No instances found for host "${hostname}"!` : `No instances found!`
107
98
  });
108
99
 
109
100
  // Capsule success messages in console.log