@iobroker/js-controller-cli 4.0.0-alpha.6-20210908-7ef2f01b → 4.0.0-alpha.63-20220129-b1a625fb

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/index.js CHANGED
@@ -1,18 +1,19 @@
1
1
  module.exports = {
2
- success: require('./lib/cli/messages').success,
3
- warn: require('./lib/cli/messages').warn,
4
- error: require('./lib/cli/messages').error,
5
- tools: require('./lib/cli/cliTools'),
2
+ success: require('./lib/cli/messages').success,
3
+ warn: require('./lib/cli/messages').warn,
4
+ error: require('./lib/cli/messages').error,
5
+ tools: require('./lib/cli/cliTools'),
6
6
  command: {
7
- object: require('./lib/cli/cliObjects.js'),
8
- state: require('./lib/cli/cliStates.js'),
7
+ object: require('./lib/cli/cliObjects.js'),
8
+ state: require('./lib/cli/cliStates.js'),
9
9
  process: require('./lib/cli/cliProcess.js'),
10
10
  message: require('./lib/cli/cliMessage.js'),
11
- logs: require('./lib/cli/cliLogs.js'),
12
- host: require('./lib/cli/cliHost.js'),
13
- cert: require('./lib/cli/cliCert.js'),
11
+ logs: require('./lib/cli/cliLogs.js'),
12
+ host: require('./lib/cli/cliHost.js'),
13
+ cert: require('./lib/cli/cliCert.js'),
14
14
  compact: require('./lib/cli/cliCompact.js'),
15
- debug: require('./lib/cli/cliDebug.js'),
15
+ debug: require('./lib/cli/cliDebug.js'),
16
16
  plugin: require('./lib/cli/cliPlugin.js')
17
- }
17
+ },
18
+ setupList: require('./lib/setup/setupList')
18
19
  };
@@ -6,7 +6,6 @@ const { tools } = require('@iobroker/js-controller-common');
6
6
 
7
7
  /** Command ioBroker cert ... */
8
8
  module.exports = class CLICert extends CLICommand {
9
-
10
9
  /** @param {import('./cliCommand.js').CLICommandOptions} options */
11
10
  constructor(options) {
12
11
  super(options);
@@ -77,4 +76,4 @@ module.exports = class CLICert extends CLICommand {
77
76
  });
78
77
  });
79
78
  }
80
- };
79
+ };
@@ -6,13 +6,11 @@ const fs = require('fs-extra');
6
6
 
7
7
  /** Command ioBroker compact ... */
8
8
  module.exports = class CLICompact extends CLICommand {
9
-
10
9
  /** @param {import('./cliCommand.js').CLICommandOptions} options */
11
10
  constructor(options) {
12
11
  super(options);
13
12
  this.config = fs.readJSONSync(tools.getConfigFileName());
14
13
  }
15
-
16
14
  /**
17
15
  * Executes a command
18
16
  * @param {any[]} args
@@ -111,13 +109,18 @@ module.exports = class CLICompact extends CLICommand {
111
109
  objects.getObject('system.adapter.' + instance, (err, obj) => {
112
110
  if (!err && obj) {
113
111
  if (!obj.common.compact) {
114
- console.log('This adapter does not support compact mode. The below settings will have no effect!');
112
+ console.log(
113
+ 'This adapter does not support compact mode. The below settings will have no effect!'
114
+ );
115
115
  console.log();
116
116
  } else {
117
117
  console.log('Adapter supports compact mode: ' + !!obj.common.compact);
118
118
  }
119
119
  console.log('Compact mode enabled for instance: ' + !!obj.common.runAsCompactMode);
120
- console.log('Compact group: ' + (obj.common.compactGroup !== undefined ? obj.common.compactGroup : 1));
120
+ console.log(
121
+ 'Compact group: ' +
122
+ (obj.common.compactGroup !== undefined ? obj.common.compactGroup : 1)
123
+ );
121
124
  return void callback();
122
125
  } else {
123
126
  CLI.error.invalidInstance(instance);
@@ -138,7 +141,9 @@ module.exports = class CLICompact extends CLICommand {
138
141
  objects.getObject('system.adapter.' + instance, (err, obj) => {
139
142
  if (!err && obj) {
140
143
  if (!obj.common.compact) {
141
- console.log('This adapter does not support compact mode. The below settings will have no effect!');
144
+ console.log(
145
+ 'This adapter does not support compact mode. The below settings will have no effect!'
146
+ );
142
147
  console.log();
143
148
  } else {
144
149
  console.log('Adapter supports compact mode : ' + !!obj.common.compact);
@@ -158,8 +163,18 @@ module.exports = class CLICompact extends CLICommand {
158
163
  newCompactGroup = groupId;
159
164
  }
160
165
  }
161
- console.log('Compact mode enabled for instance: ' + (newRunAsCompactMode !== undefined ? '--> ' + newRunAsCompactMode : !!obj.common.runAsCompactMode));
162
- console.log('Compact group: ' + (newCompactGroup !== undefined && obj.common.compactGroup !== newCompactGroup ? '--> ' + newCompactGroup : obj.common.compactGroup));
166
+ console.log(
167
+ 'Compact mode enabled for instance: ' +
168
+ (newRunAsCompactMode !== undefined
169
+ ? '--> ' + newRunAsCompactMode
170
+ : !!obj.common.runAsCompactMode)
171
+ );
172
+ console.log(
173
+ 'Compact group: ' +
174
+ (newCompactGroup !== undefined && obj.common.compactGroup !== newCompactGroup
175
+ ? '--> ' + newCompactGroup
176
+ : obj.common.compactGroup)
177
+ );
163
178
  if (newRunAsCompactMode !== undefined || newCompactGroup !== undefined) {
164
179
  if (newCompactGroup !== undefined) {
165
180
  obj.common.compactGroup = newCompactGroup;
@@ -188,5 +203,4 @@ module.exports = class CLICompact extends CLICommand {
188
203
  });
189
204
  });
190
205
  }
191
-
192
206
  };
@@ -2,7 +2,7 @@
2
2
  const CLI = require('./messages.js');
3
3
  const CLICommand = require('./cliCommand.js');
4
4
  const CLITools = require('./cliTools');
5
- const { tools } = require('@iobroker/js-controller-common');
5
+ const { tools, EXIT_CODES } = require('@iobroker/js-controller-common');
6
6
  const child_process = require('child_process');
7
7
 
8
8
  /** Command ioBroker debug ... */
@@ -12,6 +12,32 @@ module.exports = class CLICompact extends CLICommand {
12
12
  super(options);
13
13
  }
14
14
 
15
+ /**
16
+ * Cehcks if the adpter instance is running
17
+ *
18
+ * @param {string} adapter
19
+ * @param {string} instance
20
+ * @return {Promise<boolean>}
21
+ * @private
22
+ */
23
+ _isInstanceRunning(adapter, instance) {
24
+ const { dbConnect } = this.options;
25
+ return new Promise(resolve => {
26
+ dbConnect(async (objects, states) => {
27
+ try {
28
+ const state = await states.getStateAsync(`system.adapter.${adapter}.${instance}.alive`);
29
+ if (state && state.val) {
30
+ resolve(true);
31
+ return;
32
+ }
33
+ } catch {
34
+ // ignore
35
+ }
36
+ resolve(false);
37
+ });
38
+ });
39
+ }
40
+
15
41
  /**
16
42
  * Executes a command
17
43
  * @param {any[]} args
@@ -20,14 +46,16 @@ module.exports = class CLICompact extends CLICommand {
20
46
  const { callback, ...params } = this.options;
21
47
  const adapter = args[0];
22
48
  if (!adapter) {
23
- CLI.error.requiredArgumentMissing(
24
- 'adaptername',
25
- 'debug <adaptername>'
26
- );
49
+ CLI.error.requiredArgumentMissing('adaptername', 'debug <adaptername>');
27
50
  return void callback(34);
28
51
  }
29
52
 
30
- const { instance } = CLITools.splitAdapterOrInstanceIdentifierWithVersion(adapter);
53
+ const { name, instance } = CLITools.splitAdapterOrInstanceIdentifierWithVersion(adapter);
54
+
55
+ if (await this._isInstanceRunning(name, instance || '0')) {
56
+ CLI.error.instanceAlreadyRunning(`${name}.${instance || '0'}`);
57
+ return void callback(EXIT_CODES.ADAPTER_ALREADY_RUNNING);
58
+ }
31
59
 
32
60
  const adapterDir = tools.getAdapterDir(adapter);
33
61
  if (!adapterDir) {
@@ -49,9 +77,7 @@ module.exports = class CLICompact extends CLICommand {
49
77
  const nodeArgs = [
50
78
  ...tools.getDefaultNodeArgs(mainFile),
51
79
  // --inspect[-brk][=[ip]:[port]]
52
- `--inspect${params.wait ? '-brk' : ''}${
53
- !!params.ip || !!params.port ? '=' : ''
54
- }${params.ip || ''}${
80
+ `--inspect${params.wait ? '-brk' : ''}${!!params.ip || !!params.port ? '=' : ''}${params.ip || ''}${
55
81
  !!params.ip && !!params.port ? ':' : ''
56
82
  }${params.port || ''}`
57
83
  ];
@@ -1,14 +1,13 @@
1
1
  'use strict';
2
2
  const CLI = require('./messages.js');
3
3
  const CLICommand = require('./cliCommand.js');
4
- const {enumHosts, enumObjects, getObjectFrom, enumInstances} = require('./cliTools');
4
+ const { enumHosts, enumObjects, getObjectFrom, enumInstances } = require('./cliTools');
5
5
  const { tools } = require('@iobroker/js-controller-common');
6
6
  const os = require('os');
7
7
  const fs = require('fs-extra');
8
8
 
9
9
  /** Command iobroker host ... */
10
10
  module.exports = class CLIHost extends CLICommand {
11
-
12
11
  /** @param {import('./cliCommand').CLICommandOptions} options */
13
12
  constructor(options) {
14
13
  super(options);
@@ -126,7 +125,6 @@ module.exports = class CLIHost extends CLICommand {
126
125
  // Notify the user that we are done
127
126
  CLI.success.hostDeleted(hostname);
128
127
  return void callback();
129
-
130
128
  } catch (err) {
131
129
  CLI.error.unknown(err.message);
132
130
  return void callback(1);
@@ -261,8 +259,8 @@ module.exports = class CLIHost extends CLICommand {
261
259
 
262
260
  // Also rename all instances
263
261
  const instances = await enumInstances(objects);
264
- const instancesToRename = oldHostname === undefined ? instances
265
- : instances.filter(i => i.common.host === oldHostname);
262
+ const instancesToRename =
263
+ oldHostname === undefined ? instances : instances.filter(i => i.common.host === oldHostname);
266
264
  if (instancesToRename.length > 0) {
267
265
  for (const instance of instancesToRename) {
268
266
  // Update each instance object
@@ -272,14 +270,12 @@ module.exports = class CLIHost extends CLICommand {
272
270
  CLI.warn.noInstancesFoundOnHost(oldHostname);
273
271
  }
274
272
  return void callback();
275
-
276
273
  } catch (err) {
277
274
  CLI.error.unknown(err.message);
278
275
  return void callback(1);
279
276
  }
280
277
  });
281
278
  }
282
-
283
279
  };
284
280
 
285
281
  /**
@@ -287,23 +283,19 @@ module.exports = class CLIHost extends CLICommand {
287
283
  * @param {any} objects The objects DB to use
288
284
  * @param {any} instance The instance object
289
285
  * @param {string} newHostname The new hostname the instance should be running on
286
+ * @return Promise<void>
290
287
  */
291
- function changeInstanceHost(objects, instance, newHostname) {
292
- return new Promise(resolve => {
293
- const oldInstanceHost = instance.common.host;
294
- instance.from = getObjectFrom();
295
- instance.ts = Date.now();
296
- instance.common.host = newHostname;
297
- // and save it
298
- objects.setObjectAsync(instance._id, instance)
299
- .then(() => {
300
- CLI.success.instanceHostChanged(instance._id, oldInstanceHost, newHostname);
301
- resolve();
302
- })
303
- .catch(err => {
304
- CLI.error.cannotChangeObject(instance._id, err.message);
305
- // resolve anyways, we don't want to cause errors
306
- resolve();
307
- });
308
- });
288
+ async function changeInstanceHost(objects, instance, newHostname) {
289
+ const oldInstanceHost = instance.common.host;
290
+ instance.from = getObjectFrom();
291
+ instance.ts = Date.now();
292
+ instance.common.host = newHostname;
293
+ // and save it
294
+ try {
295
+ await objects.setObjectAsync(instance._id, instance);
296
+ CLI.success.instanceHostChanged(instance._id, oldInstanceHost, newHostname);
297
+ } catch (e) {
298
+ CLI.error.cannotChangeObject(instance._id, e.message);
299
+ // resolve anyways, we don't want to cause errors
300
+ }
309
301
  }
@@ -10,7 +10,6 @@ const { tools } = require('@iobroker/js-controller-common');
10
10
 
11
11
  /** Command ioBroker state ... */
12
12
  module.exports = class CLILogs extends CLICommand {
13
-
14
13
  /** @param {import('./cliCommand').CLICommandOptions} options */
15
14
  constructor(options) {
16
15
  super(options);
@@ -24,7 +23,6 @@ module.exports = class CLILogs extends CLICommand {
24
23
  * @param {any[]} args
25
24
  */
26
25
  execute(args, params) {
27
-
28
26
  /** @type {string | undefined} */
29
27
  const adapterName = args[0];
30
28
  const watch = params.watch || params.w;
@@ -36,7 +34,7 @@ module.exports = class CLILogs extends CLICommand {
36
34
  };
37
35
 
38
36
  const config = fs.readJSONSync(require.resolve(getConfigFileName()));
39
- const logger = require('../logger')(config.log);
37
+ const logger = require('@iobroker/js-controller-common').logger(config.log);
40
38
  let fileName = logger.getFileName();
41
39
  if (fileName) {
42
40
  let lines = fs.readFileSync(fileName).toString('utf-8').split('\n');
@@ -60,10 +58,10 @@ module.exports = class CLILogs extends CLICommand {
60
58
  fileName = fileName.replace(/\\/g, '/');
61
59
  const parts = fileName.split('/');
62
60
  parts.pop();
63
- chokidar.watch(`${parts.join('/')}/iobroker*`, {awaitWriteFinish: {stabilityThreshold: 500}})
61
+ chokidar
62
+ .watch(`${parts.join('/')}/iobroker*`, { awaitWriteFinish: { stabilityThreshold: 500 } })
64
63
  .on('all', this.watchHandler.bind(this, options))
65
- .on('ready', () => this.isReady = true)
66
- ;
64
+ .on('ready', () => (this.isReady = true));
67
65
  }
68
66
  } else {
69
67
  console.log('No log file found');
@@ -86,12 +84,7 @@ module.exports = class CLILogs extends CLICommand {
86
84
  watchHandler(options, event, path, stats) {
87
85
  if (event === 'add' || !this.fileSizes.has(path)) {
88
86
  this.fileSizes.set(path, stats.size);
89
- if (
90
- stats.size > 0 && (
91
- this.isReady
92
- || (options.complete && this.isTodaysLogfile(path))
93
- )
94
- ) {
87
+ if (stats.size > 0 && (this.isReady || (options.complete && this.isTodaysLogfile(path)))) {
95
88
  this.streamChange(path, 0, options);
96
89
  }
97
90
  } else if (event === 'change') {
@@ -111,7 +104,7 @@ module.exports = class CLILogs extends CLICommand {
111
104
  */
112
105
  isTodaysLogfile(path) {
113
106
  const YYYYMMDDDate = new Date().toJSON().slice(0, 10);
114
- return path.indexOf(YYYYMMDDDate) > -1;
107
+ return path.includes(YYYYMMDDDate);
115
108
  }
116
109
 
117
110
  /**
@@ -123,7 +116,7 @@ module.exports = class CLILogs extends CLICommand {
123
116
  streamChange(path, start, options) {
124
117
  const input = fs.createReadStream(path, {
125
118
  encoding: 'utf8',
126
- start: start,
119
+ start,
127
120
  autoClose: true
128
121
  });
129
122
  if (options.adapterName) {
@@ -131,14 +124,12 @@ module.exports = class CLILogs extends CLICommand {
131
124
  input
132
125
  .pipe(es.split())
133
126
  // @ts-ignore
134
- .pipe(es.filterSync(line => line.indexOf(options.adapterName) > -1))
127
+ .pipe(es.filterSync(line => line.includes(options.adapterName)))
135
128
  .pipe(es.mapSync(line => line + os.EOL))
136
- .pipe(process.stdout)
137
- ;
129
+ .pipe(process.stdout);
138
130
  } else {
139
131
  // just pipe the input through
140
132
  tools.pipeLinewise(input, process.stdout);
141
133
  }
142
134
  }
143
135
  };
144
-
@@ -6,7 +6,6 @@ const { enumInstances } = require('./cliTools');
6
6
 
7
7
  /** Command iobroker object ... */
8
8
  module.exports = class CLIMessage extends CLICommand {
9
-
10
9
  /** @param {import('./cliCommand').CLICommandOptions} options */
11
10
  constructor(options) {
12
11
  super(options);
@@ -19,8 +18,7 @@ module.exports = class CLIMessage extends CLICommand {
19
18
  execute(args) {
20
19
  const { callback, dbConnect, showHelp } = this.options;
21
20
  /** @type {[string, string, any?]} */
22
- // eslint-disable-next-line prefer-const
23
- let [adapter, command, message] = (args);
21
+ let [adapter, command, message] = args;
24
22
  if (adapter === null || adapter === undefined) {
25
23
  CLI.error.requiredArgumentMissing('adapter');
26
24
  showHelp();
@@ -37,11 +35,7 @@ module.exports = class CLIMessage extends CLICommand {
37
35
  }
38
36
  // Try to parse JSON
39
37
  // TODO: can we use the methods from cliObjects?
40
- if (
41
- typeof message === 'string'
42
- && message.startsWith('{')
43
- && message.endsWith('}')
44
- ) {
38
+ if (typeof message === 'string' && message.startsWith('{') && message.endsWith('}')) {
45
39
  message = JSON.parse(message);
46
40
  }
47
41
 
@@ -68,12 +62,9 @@ module.exports = class CLIMessage extends CLICommand {
68
62
  }
69
63
 
70
64
  // Send the message to all targets
71
- const messagePromises = messageTargets.map(
72
- t => sendMessage(states, t, command, message)
73
- );
65
+ const messagePromises = messageTargets.map(t => sendMessage(states, t, command, message));
74
66
  await Promise.all(messagePromises);
75
67
  return void callback();
76
-
77
68
  } catch (err) {
78
69
  CLI.error.unknown(err.message);
79
70
  return void callback(1);
@@ -6,7 +6,6 @@ const { tools } = require('@iobroker/js-controller-common');
6
6
 
7
7
  /** Command iobroker object ... */
8
8
  module.exports = class CLIObjects extends CLICommand {
9
-
10
9
  /** @param {import('./cliCommand').CLICommandOptions} options */
11
10
  constructor(options) {
12
11
  super(options);
@@ -37,6 +36,10 @@ module.exports = class CLIObjects extends CLICommand {
37
36
  case 'delete':
38
37
  case 'del':
39
38
  return this.delete(args);
39
+ case 'getDBVersion':
40
+ return this.getDBVersion(args);
41
+ case 'setDBVersion':
42
+ return this.setDBVersion();
40
43
  default:
41
44
  CLI.error.unknownCommand('object', command);
42
45
  showHelp();
@@ -44,6 +47,49 @@ module.exports = class CLIObjects extends CLICommand {
44
47
  }
45
48
  }
46
49
 
50
+ /**
51
+ * Get the protocol version
52
+ */
53
+ getDBVersion() {
54
+ const { callback, dbConnect } = this.options;
55
+ dbConnect(async objects => {
56
+ const version = await objects.getProtocolVersion();
57
+ console.log(`Current Objects DB protocol version: ${version}`);
58
+ return void callback();
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Set protocol version
64
+ */
65
+ setDBVersion() {
66
+ const { callback, dbConnect } = this.options;
67
+ dbConnect(async objects => {
68
+ const rl = require('readline-sync');
69
+
70
+ let answer = rl.question('Changing the protocol version will restart all hosts! Continue? [N/y]', {
71
+ limit: /^(yes|y|n|no)$/i,
72
+ defaultInput: 'no'
73
+ });
74
+
75
+ answer = answer.toLowerCase();
76
+
77
+ if (answer !== 'y' && answer !== 'yes') {
78
+ console.log('Protocol version has not been changed!');
79
+ return void callback();
80
+ }
81
+
82
+ try {
83
+ await objects.setProtocolVersion(this.options.version);
84
+ } catch (e) {
85
+ console.error(`Cannot update protocol version: ${e.message}`);
86
+ return void callback(1);
87
+ }
88
+ console.log(`Objects DB protocol updated to version ${this.options.version}`);
89
+ return void callback();
90
+ });
91
+ }
92
+
47
93
  /**
48
94
  * Changes access rights for all objects matching the pattern
49
95
  * @param {any[]} args
@@ -74,10 +120,14 @@ module.exports = class CLIObjects extends CLICommand {
74
120
  }
75
121
 
76
122
  dbConnect((objects, states) => {
77
- objects.chmodObject(pattern, { user: 'system.user.admin', object: modeObject, state: modeState }, (err, processed) => {
78
- // Print the new object rights
79
- this.printObjectList(objects, states, err, processed);
80
- });
123
+ objects.chmodObject(
124
+ pattern,
125
+ { user: 'system.user.admin', object: modeObject, state: modeState },
126
+ (err, processed) => {
127
+ // Print the new object rights
128
+ this.printObjectList(objects, states, err, processed);
129
+ }
130
+ );
81
131
  });
82
132
  }
83
133
 
@@ -88,7 +138,7 @@ module.exports = class CLIObjects extends CLICommand {
88
138
  chown(args) {
89
139
  const { callback, dbConnect } = this.options;
90
140
  /** @type {[string, string, any]} */
91
- let [user, group, pattern] = (args.slice(1));
141
+ let [user, group, pattern] = args.slice(1);
92
142
 
93
143
  if (!pattern) {
94
144
  pattern = group;
@@ -110,10 +160,14 @@ module.exports = class CLIObjects extends CLICommand {
110
160
  return void callback(1);
111
161
  }
112
162
  dbConnect((objects, states) => {
113
- objects.chownObject(pattern, { user: 'system.user.admin', owner: user, ownerGroup: group }, (err, processed) => {
114
- // Print the new object rights
115
- this.printObjectList(objects, states, err, processed);
116
- });
163
+ objects.chownObject(
164
+ pattern,
165
+ { user: 'system.user.admin', owner: user, ownerGroup: group },
166
+ (err, processed) => {
167
+ // Print the new object rights
168
+ this.printObjectList(objects, states, err, processed);
169
+ }
170
+ );
117
171
  });
118
172
  }
119
173
 
@@ -131,7 +185,8 @@ module.exports = class CLIObjects extends CLICommand {
131
185
  dbConnect((objects, states) => {
132
186
  objects.getObjectList(pattern, { user: 'system.user.admin', sorted: true }, (err, processed) => {
133
187
  this.printObjectList(
134
- objects, states,
188
+ objects,
189
+ states,
135
190
  err,
136
191
  processed && processed.rows && processed.rows.map(r => r.value)
137
192
  );
@@ -147,7 +202,7 @@ module.exports = class CLIObjects extends CLICommand {
147
202
  get(args) {
148
203
  const { callback, pretty, dbConnect } = this.options;
149
204
  /** @type {[string, string]} */
150
- const [id, propPath] = (args.slice(1));
205
+ const [id, propPath] = args.slice(1);
151
206
  if (!id) {
152
207
  CLI.error.requiredArgumentMissing('id', 'object get id [propertypath]');
153
208
  return void callback(1);
@@ -270,7 +325,7 @@ module.exports = class CLIObjects extends CLICommand {
270
325
  for (const prop in value) {
271
326
  if (typeof res.native[prop] === 'string' && res.encryptedNative.includes(prop)) {
272
327
  try {
273
- config = config || await objects.getObjectAsync('system.config');
328
+ config = config || (await objects.getObjectAsync('system.config'));
274
329
  res.native[prop] = tools.encrypt(config.native.secret, res.native[prop]);
275
330
  } catch (e) {
276
331
  console.error(`Could not auto-encrypt property "${prop}": ${e.message}`);
@@ -323,7 +378,20 @@ module.exports = class CLIObjects extends CLICommand {
323
378
  * @return {Promise<object[]>}
324
379
  */
325
380
  async _collectObjects(objects, params, callback) {
326
- const types = ['state', 'channel', 'device', 'enum', 'instance', 'host', 'adapter', 'meta', 'config', 'group', 'user', 'script'];
381
+ const types = [
382
+ 'state',
383
+ 'channel',
384
+ 'device',
385
+ 'enum',
386
+ 'instance',
387
+ 'host',
388
+ 'adapter',
389
+ 'meta',
390
+ 'config',
391
+ 'group',
392
+ 'user',
393
+ 'script'
394
+ ];
327
395
  const result = [];
328
396
 
329
397
  for (const type of types) {
@@ -348,10 +416,19 @@ module.exports = class CLIObjects extends CLICommand {
348
416
  if (!ids || !ids.length) {
349
417
  return tools.maybeCallback(callback);
350
418
  } else {
419
+ let allEnums;
420
+
421
+ try {
422
+ // cache all enums, else it will be slow to delete many objects
423
+ allEnums = await tools.getAllEnums(objects);
424
+ } catch (e) {
425
+ console.error(`Could not retrieve all enums: ${e.message}`);
426
+ }
427
+
351
428
  for (const id of ids) {
352
429
  try {
353
430
  await objects.delObjectAsync(id);
354
- await tools.removeIdFromAllEnums(objects, id);
431
+ await tools.removeIdFromAllEnums(objects, id, allEnums);
355
432
  } catch (e) {
356
433
  console.warn(`Could not delete object or remove "${id}" from enums: ${e.message}`);
357
434
  }
@@ -377,7 +454,7 @@ module.exports = class CLIObjects extends CLICommand {
377
454
  if (id.endsWith('*')) {
378
455
  const params = {
379
456
  startkey: id.replace(/\*/g, ''),
380
- endkey: id.replace(/\*/g, '\u9999')
457
+ endkey: id.replace(/\*/g, '\u9999')
381
458
  };
382
459
  this._collectObjects(objects, params, result => {
383
460
  if (!result || !result.length) {
@@ -389,12 +466,19 @@ module.exports = class CLIObjects extends CLICommand {
389
466
  // if no auto confirmation, ask user
390
467
  if (!this.options.f && this.options.y && !this.options.yes) {
391
468
  const rl = require('readline').createInterface({
392
- input: process.stdin,
469
+ input: process.stdin,
393
470
  output: process.stdout
394
471
  });
395
- rl.question(result.length + ' object(s) will be deleted. Are you sure? [y/N]: ', answer => {
472
+ rl.question(`${result.length} object(s) will be deleted. Are you sure? [y/N]: `, answer => {
396
473
  rl.close();
397
- if (answer === 'y' || answer === 'yes' || answer === 'j' || answer === 'ja' || answer === 'да' || answer === 'д') {
474
+ if (
475
+ answer === 'y' ||
476
+ answer === 'yes' ||
477
+ answer === 'j' ||
478
+ answer === 'ja' ||
479
+ answer === 'да' ||
480
+ answer === 'д'
481
+ ) {
398
482
  this._deleteObjects(objects, ids, callback);
399
483
  } else {
400
484
  console.log('Aborted.');
@@ -407,18 +491,19 @@ module.exports = class CLIObjects extends CLICommand {
407
491
  });
408
492
  } else {
409
493
  // only one object
410
- objects.delObject(id, err => {
494
+ objects.delObject(id, async err => {
411
495
  if (err) {
412
496
  CLI.error.objectNotFound(id, err);
413
- return void callback(3);
497
+ callback(3);
414
498
  } else {
415
- tools.removeIdFromAllEnums(objects, id).then(() => {
499
+ try {
500
+ await tools.removeIdFromAllEnums(objects, id);
416
501
  CLI.success.objectDeleted(id);
417
- return void callback();
418
- }).catch(e => {
502
+ callback();
503
+ } catch (e) {
419
504
  CLI.error.cannotDeleteObjectFromEnums(id, e.message);
420
- return void callback(3);
421
- });
505
+ callback(3);
506
+ }
422
507
  }
423
508
  });
424
509
  }