@iobroker/db-objects-file 7.2.3 → 8.0.0-alpha.2-20260923-99da17fcc

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 (25) hide show
  1. package/build/cjs/index.js +5 -3
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/cjs/lib/objects/objectsInMemFileDB.d.ts +288 -59
  4. package/build/cjs/lib/objects/objectsInMemFileDB.js +225 -109
  5. package/build/cjs/lib/objects/objectsInMemFileDB.js.map +3 -3
  6. package/build/cjs/lib/objects/objectsInMemServerClass.d.ts +41 -8
  7. package/build/cjs/lib/objects/objectsInMemServerClass.js +27 -2
  8. package/build/cjs/lib/objects/objectsInMemServerClass.js.map +3 -3
  9. package/build/cjs/lib/objects/objectsInMemServerRedis.d.ts +50 -30
  10. package/build/cjs/lib/objects/objectsInMemServerRedis.js +72 -37
  11. package/build/cjs/lib/objects/objectsInMemServerRedis.js.map +4 -4
  12. package/build/esm/lib/objects/objectsInMemFileDB.d.ts +288 -59
  13. package/build/esm/lib/objects/objectsInMemFileDB.d.ts.map +1 -1
  14. package/build/esm/lib/objects/objectsInMemFileDB.js +228 -126
  15. package/build/esm/lib/objects/objectsInMemFileDB.js.map +1 -1
  16. package/build/esm/lib/objects/objectsInMemServerClass.d.ts +41 -8
  17. package/build/esm/lib/objects/objectsInMemServerClass.d.ts.map +1 -1
  18. package/build/esm/lib/objects/objectsInMemServerClass.js +25 -1
  19. package/build/esm/lib/objects/objectsInMemServerClass.js.map +1 -1
  20. package/build/esm/lib/objects/objectsInMemServerRedis.d.ts +50 -30
  21. package/build/esm/lib/objects/objectsInMemServerRedis.d.ts.map +1 -1
  22. package/build/esm/lib/objects/objectsInMemServerRedis.js +89 -70
  23. package/build/esm/lib/objects/objectsInMemServerRedis.js.map +1 -1
  24. package/build/tsconfig.build.tsbuildinfo +1 -1
  25. package/package.json +7 -7
@@ -5,6 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
9
  var __export = (target, all) => {
9
10
  for (var name in all)
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -42,6 +43,23 @@ var import_js_controller_common_db = require("@iobroker/js-controller-common-db"
42
43
  var import_db_base2 = require("@iobroker/db-base");
43
44
  var import_objectsInMemFileDB = require("./objectsInMemFileDB.js");
44
45
  class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFileDB {
46
+ static {
47
+ __name(this, "ObjectsInMemoryServer");
48
+ }
49
+ serverConnections = {};
50
+ namespaceObjects;
51
+ namespaceFile;
52
+ namespaceObj;
53
+ namespaceSet;
54
+ namespaceSetLen;
55
+ namespaceFileLen;
56
+ namespaceObjLen;
57
+ namespaceMeta;
58
+ namespaceMetaLen;
59
+ knownScripts = {};
60
+ normalizeFileRegex1;
61
+ normalizeFileRegex2;
62
+ server;
45
63
  /**
46
64
  * Constructor
47
65
  *
@@ -49,8 +67,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
49
67
  */
50
68
  constructor(settings) {
51
69
  super(settings);
52
- this.serverConnections = {};
53
- this.namespaceObjects = `${this.settings.redisNamespace || settings.connection && settings.connection.redisNamespace || "cfg"}.`;
70
+ this.namespaceObjects = `${this.settings.redisNamespace || settings.connection?.redisNamespace || "cfg"}.`;
54
71
  this.namespaceFile = `${this.namespaceObjects}f.`;
55
72
  this.namespaceObj = `${this.namespaceObjects}o.`;
56
73
  this.namespaceSet = `${this.namespaceObjects}s.`;
@@ -59,12 +76,9 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
59
76
  this.namespaceObjLen = this.namespaceObj.length;
60
77
  this.namespaceMeta = `${this.settings.namespaceMeta || "meta"}.`;
61
78
  this.namespaceMetaLen = this.namespaceMeta.length;
62
- this.knownScripts = {};
63
79
  this.normalizeFileRegex1 = new RegExp("^(.*)\\$%\\$(.*)\\$%\\$(meta|data)$");
64
80
  this.normalizeFileRegex2 = new RegExp("^(.*)\\$%\\$(.*)\\/?\\*$");
65
- this.open().then(() => {
66
- return this._initRedisServer(this.settings.connection);
67
- }).then(() => {
81
+ this.open().then(() => this._initRedisServer(this.settings.connection)).then(() => {
68
82
  this.log.debug(`${this.namespace} ${settings.secure ? "Secure " : ""} Redis inMem-objects listening on port ${this.settings.connection.port || 9001}`);
69
83
  if (typeof this.settings.connected === "function") {
70
84
  setImmediate(() => this.settings.connected());
@@ -86,15 +100,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
86
100
  let id = null;
87
101
  let name = "";
88
102
  let isMeta;
89
- if (Array.isArray(idWithNamespace)) {
90
- const ids = [];
91
- idWithNamespace.forEach((el) => {
92
- const { id: id2, namespace } = this._normalizeId(el);
93
- ids.push(id2);
94
- ns = namespace;
95
- });
96
- id = ids;
97
- } else if (typeof idWithNamespace === "string") {
103
+ if (typeof idWithNamespace === "string") {
98
104
  id = idWithNamespace;
99
105
  if (idWithNamespace.startsWith(this.namespaceObjects)) {
100
106
  let idx = -1;
@@ -147,14 +153,14 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
147
153
  * @returns Publish counter 0 or 1 depending on if send out or not
148
154
  */
149
155
  publishToClients(client, type, id, obj) {
150
- if (!client._subscribe || !client._subscribe[type]) {
156
+ if (!client._subscribe?.[type]) {
151
157
  return 0;
152
158
  }
153
159
  const s = client._subscribe[type];
154
160
  const found = s.find((sub) => sub.regex.test(id));
155
161
  if (found) {
156
162
  if (type === "meta") {
157
- this.log.silly(`${this.namespace} Redis Publish Meta ${id}=${obj}`);
163
+ this.log.silly(`${this.namespace} Redis Publish Meta ${id}=${JSON.stringify(obj)}`);
158
164
  const sendPattern = this.namespaceMeta + found.pattern;
159
165
  const sendId = this.namespaceMeta + id;
160
166
  client.sendArray(null, ["pmessage", sendPattern, sendId, obj]);
@@ -234,11 +240,11 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
234
240
  const scriptChecksum = shasum.digest("hex");
235
241
  const scriptDesign = data[1].match(/^-- design: ([a-z0-9A-Z-.]+)\s/m);
236
242
  const scriptFunc = data[1].match(/^-- func: (.+)$/m);
237
- if (scriptDesign && scriptDesign[1]) {
243
+ if (scriptDesign?.[1]) {
238
244
  const design = scriptDesign[1];
239
- let search = null;
245
+ let search;
240
246
  const scriptSearch = data[1].match(/^-- search: ([a-z0-9A-Z-.]*)\s/m);
241
- if (scriptSearch && scriptSearch[1]) {
247
+ if (scriptSearch?.[1]) {
242
248
  search = scriptSearch[1];
243
249
  }
244
250
  this.knownScripts[scriptChecksum] = { design, search };
@@ -246,7 +252,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
246
252
  this.log.silly(`${namespaceLog} Register View LUA Script: ${scriptChecksum} = ${JSON.stringify(this.knownScripts[scriptChecksum])}`);
247
253
  }
248
254
  handler.sendBulk(responseId, scriptChecksum);
249
- } else if (scriptFunc && scriptFunc[1]) {
255
+ } else if (scriptFunc?.[1]) {
250
256
  this.knownScripts[scriptChecksum] = { func: scriptFunc[1] };
251
257
  if (this.settings.connection.enhancedLogging) {
252
258
  this.log.silly(`${namespaceLog} Register Func LUA Script: ${scriptChecksum} = ${JSON.stringify(this.knownScripts[scriptChecksum])}`);
@@ -315,14 +321,14 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
315
321
  });
316
322
  handler.on("publish", (data, responseId) => {
317
323
  const { id, namespace } = this._normalizeId(data[0]);
318
- if (namespace === this.namespaceObj || namespace === this.namespaceMeta || namespace === this.namespaceFile) {
324
+ if (namespace === this.namespaceObj || namespace === this.namespaceMeta || namespace === this.namespaceFile || !id) {
319
325
  return void handler.sendInteger(responseId, 0);
320
326
  }
321
327
  const publishCount = this.publishAll(namespace.substr(0, namespace.length - 1), id, JSON.parse(data[1]));
322
328
  handler.sendInteger(responseId, publishCount);
323
329
  });
324
330
  handler.on("mget", (data, responseId) => {
325
- if (!data || !data.length) {
331
+ if (!data?.length) {
326
332
  return void handler.sendArray(responseId, []);
327
333
  }
328
334
  const { namespace, isMeta } = this._normalizeId(data[0]);
@@ -343,14 +349,14 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
343
349
  } catch (err) {
344
350
  return void handler.sendError(responseId, new Error(`ERROR _getObjects: ${err.message}`));
345
351
  }
346
- result = result.map((el) => el ? JSON.stringify(el) : null);
347
- handler.sendArray(responseId, result);
352
+ const resultObjs = result.map((el) => el ? JSON.stringify(el) : null);
353
+ handler.sendArray(responseId, resultObjs);
348
354
  } else if (namespace === this.namespaceFile) {
349
355
  if (isMeta) {
350
356
  const response = [];
351
357
  data.forEach((dataId) => {
352
358
  const { id, namespace: namespace2, name } = this._normalizeId(dataId);
353
- if (namespace2 !== this.namespaceFile) {
359
+ if (!id || namespace2 !== this.namespaceFile) {
354
360
  response.push(null);
355
361
  this.log.warn(`${namespaceLog} Got MGET request for non File ID in File-ID chunk for ${dataId}`);
356
362
  return;
@@ -382,6 +388,10 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
382
388
  });
383
389
  handler.on("get", (data, responseId) => {
384
390
  const { id, namespace, name, isMeta } = this._normalizeId(data[0]);
391
+ if (!id) {
392
+ handler.sendNull(responseId);
393
+ return;
394
+ }
385
395
  if (namespace === this.namespaceObj) {
386
396
  const result = this._getObject(id);
387
397
  if (!result) {
@@ -413,14 +423,16 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
413
423
  obj = {
414
424
  mimeType: obj,
415
425
  acl: {
416
- owner: this.defaultNewAcl && this.defaultNewAcl.owner || import_db_objects_redis.objectsUtils.CONSTS.SYSTEM_ADMIN_USER,
417
- ownerGroup: this.defaultNewAcl && this.defaultNewAcl.ownerGroup || import_db_objects_redis.objectsUtils.CONSTS.SYSTEM_ADMIN_GROUP,
418
- permissions: this.defaultNewAcl && this.defaultNewAcl.file.permissions || import_db_objects_redis.objectsUtils.CONSTS.ACCESS_USER_ALL | import_db_objects_redis.objectsUtils.CONSTS.ACCESS_GROUP_ALL | import_db_objects_redis.objectsUtils.CONSTS.ACCESS_EVERY_ALL
426
+ owner: this.defaultNewAcl?.owner || import_db_objects_redis.objectsUtils.CONSTS.SYSTEM_ADMIN_USER,
427
+ ownerGroup: this.defaultNewAcl?.ownerGroup || import_db_objects_redis.objectsUtils.CONSTS.SYSTEM_ADMIN_GROUP,
428
+ permissions: this.defaultNewAcl?.file || import_db_objects_redis.objectsUtils.CONSTS.ACCESS_USER_ALL | import_db_objects_redis.objectsUtils.CONSTS.ACCESS_GROUP_ALL | import_db_objects_redis.objectsUtils.CONSTS.ACCESS_EVERY_ALL
419
429
  // 777
420
- }
430
+ },
431
+ stats
421
432
  };
433
+ } else {
434
+ obj.stats = stats;
422
435
  }
423
- obj.stats = stats;
424
436
  handler.sendBulk(responseId, JSON.stringify(obj));
425
437
  } else {
426
438
  let data2;
@@ -441,7 +453,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
441
453
  }
442
454
  } else if (namespace === this.namespaceMeta) {
443
455
  if (id === "objects.primaryHost") {
444
- handler.sendString(this.settings.hostname);
456
+ handler.sendString(responseId, this.settings.hostname);
445
457
  } else {
446
458
  const result = this.getMeta(id);
447
459
  if (result === void 0 || result === null) {
@@ -456,6 +468,9 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
456
468
  });
457
469
  handler.on("set", (data, responseId) => {
458
470
  const { id, namespace, name, isMeta } = this._normalizeId(data[0]);
471
+ if (!id) {
472
+ return void handler.sendError(responseId, new Error(`ERROR setObject id=${id}: id is null`));
473
+ }
459
474
  if (namespace === this.namespaceObj) {
460
475
  try {
461
476
  const obj = JSON.parse(data[1].toString("utf-8"));
@@ -495,7 +510,10 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
495
510
  handler.on("rename", (data, responseId) => {
496
511
  const oldDetails = this._normalizeId(data[0]);
497
512
  const newDetails = this._normalizeId(data[1]);
498
- if (oldDetails.namespace === this.namespaceFile) {
513
+ if (!oldDetails.id || !newDetails.id || oldDetails.namespace === this.namespaceFile) {
514
+ if (!oldDetails.id || !newDetails.id) {
515
+ return void handler.sendError(responseId, new Error("ERROR renameObject: id needs to be not null"));
516
+ }
499
517
  if (oldDetails.id !== newDetails.id) {
500
518
  return void handler.sendError(responseId, new Error("ERROR renameObject: id needs to stay the same"));
501
519
  }
@@ -515,6 +533,9 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
515
533
  });
516
534
  handler.on("del", (data, responseId) => {
517
535
  const { id, namespace, name, isMeta } = this._normalizeId(data[0]);
536
+ if (!id) {
537
+ return void handler.sendError(responseId, new Error("id is null"));
538
+ }
518
539
  if (namespace === this.namespaceObj) {
519
540
  try {
520
541
  this._delObject(id);
@@ -542,6 +563,9 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
542
563
  return void handler.sendInteger(responseId, 0);
543
564
  }
544
565
  const { id, namespace, name } = this._normalizeId(data[0]);
566
+ if (!id) {
567
+ return void handler.sendError(responseId, new Error("id is null"));
568
+ }
545
569
  if (namespace === this.namespaceObj) {
546
570
  let exists;
547
571
  try {
@@ -593,6 +617,9 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
593
617
  });
594
618
  handler.on("psubscribe", (data, responseId) => {
595
619
  const { id, namespace, name } = this._normalizeId(data[0]);
620
+ if (!id) {
621
+ return void handler.sendError(responseId, new Error("id is null"));
622
+ }
596
623
  if (namespace === this.namespaceObj) {
597
624
  this._subscribeConfigForClient(handler, id);
598
625
  handler.sendArray(responseId, ["psubscribe", data[0], 1]);
@@ -608,6 +635,9 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
608
635
  });
609
636
  handler.on("punsubscribe", (data, responseId) => {
610
637
  const { id, namespace, name } = this._normalizeId(data[0]);
638
+ if (!id) {
639
+ return void handler.sendError(responseId, new Error("id is null"));
640
+ }
611
641
  if (namespace === this.namespaceObj) {
612
642
  this._unsubscribeConfigForClient(handler, id);
613
643
  handler.sendArray(responseId, ["punsubscribe", data[0], 1]);
@@ -650,6 +680,8 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
650
680
  } else {
651
681
  handler.sendNull(responseId);
652
682
  }
683
+ } else if (typeof data[0] === "string" && data[0].toLowerCase() === "setinfo") {
684
+ handler.sendString(responseId, "OK");
653
685
  } else {
654
686
  handler.sendError(responseId, new Error(`CLIENT-UNSUPPORTED for ${JSON.stringify(data)}`));
655
687
  }
@@ -659,7 +691,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
659
691
  /**
660
692
  * Return connected RedisHandlers/Connections
661
693
  *
662
- * @returns
694
+ * @returns the currently connected RedisHandlers/Connections
663
695
  */
664
696
  getClients() {
665
697
  return this.serverConnections;
@@ -692,11 +724,14 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
692
724
  *
693
725
  * @param handler RedisHandler instance
694
726
  * @param pattern - pattern without namespace prefix
695
- * @param responseId - Id where response will be sent to
727
+ * @param responseId - ID where response will be sent to
696
728
  * @param isScan - if used by "SCAN" this flag should be true
697
729
  */
698
730
  _handleScanOrKeys(handler, pattern, responseId, isScan = false) {
699
731
  const { id, namespace, name, isMeta } = this._normalizeId(pattern);
732
+ if (id === null) {
733
+ return void handler.sendError(responseId, new Error("id is null"));
734
+ }
700
735
  let response = [];
701
736
  if (namespace === this.namespaceObj || namespace === this.namespaceObjects) {
702
737
  try {
@@ -713,7 +748,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
713
748
  let res;
714
749
  try {
715
750
  res = this._readDir(id, name);
716
- if (!res || !res.length) {
751
+ if (!res?.length) {
717
752
  res = [
718
753
  {
719
754
  file: "_data.json",
@@ -785,7 +820,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
785
820
  * Initialize Redis Server
786
821
  *
787
822
  * @param settings Settings object
788
- * @returns
823
+ * @returns a promise that resolves once the Redis server is listening
789
824
  */
790
825
  _initRedisServer(settings) {
791
826
  return new Promise((resolve, reject) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/lib/objects/objectsInMemServerRedis.js"],
4
- "sourcesContent": ["/**\n * Objects DB in memory - Server with Redis protocol\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport net from 'node:net';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { objectsUtils as utils } from '@iobroker/db-objects-redis';\nimport { tools } from '@iobroker/db-base';\nimport { getLocalAddress } from '@iobroker/js-controller-common-db/tools';\nimport { EXIT_CODES } from '@iobroker/js-controller-common-db';\n\nimport { RedisHandler } from '@iobroker/db-base';\nimport { ObjectsInMemoryFileDB } from './objectsInMemFileDB.js';\n\n// settings = {\n// change: function (id, state) {},\n// connected: function (nameOfServer) {},\n// logger: {\n// silly: function (msg) {},\n// debug: function (msg) {},\n// info: function (msg) {},\n// warn: function (msg) {},\n// error: function (msg) {}\n// },\n// connection: {\n// dataDir: 'relative path'\n// },\n// auth: null, //unused\n// secure: true/false,\n// certificates: as required by createServer\n// port: 9001,\n// host: localhost\n// };\n//\n\n/**\n * This class inherits statesInMemoryFileDB class and adds redis communication layer\n * to access the methods via redis protocol\n */\nexport class ObjectsInMemoryServer extends ObjectsInMemoryFileDB {\n /**\n * Constructor\n *\n * @param settings State and InMem-DB settings\n */\n constructor(settings) {\n super(settings);\n\n this.serverConnections = {};\n this.namespaceObjects = `${\n this.settings.redisNamespace || (settings.connection && settings.connection.redisNamespace) || 'cfg'\n }.`;\n this.namespaceFile = `${this.namespaceObjects}f.`;\n this.namespaceObj = `${this.namespaceObjects}o.`;\n this.namespaceSet = `${this.namespaceObjects}s.`;\n this.namespaceSetLen = this.namespaceSet.length;\n\n // this.namespaceObjectsLen = this.namespaceObjects.length;\n this.namespaceFileLen = this.namespaceFile.length;\n this.namespaceObjLen = this.namespaceObj.length;\n this.namespaceMeta = `${this.settings.namespaceMeta || 'meta'}.`;\n this.namespaceMetaLen = this.namespaceMeta.length;\n\n this.knownScripts = {};\n\n this.normalizeFileRegex1 = new RegExp('^(.*)\\\\$%\\\\$(.*)\\\\$%\\\\$(meta|data)$');\n this.normalizeFileRegex2 = new RegExp('^(.*)\\\\$%\\\\$(.*)\\\\/?\\\\*$');\n\n this.open()\n .then(() => {\n return this._initRedisServer(this.settings.connection);\n })\n .then(() => {\n this.log.debug(\n `${this.namespace} ${settings.secure ? 'Secure ' : ''} Redis inMem-objects listening on port ${\n this.settings.connection.port || 9001\n }`,\n );\n\n if (typeof this.settings.connected === 'function') {\n setImmediate(() => this.settings.connected());\n }\n })\n .catch(e => {\n this.log.error(\n `${this.namespace} Cannot start inMem-objects on port ${this.settings.connection.port || 9001}: ${e.message}`,\n );\n process.exit(EXIT_CODES.NO_CONNECTION_TO_OBJ_DB);\n });\n }\n\n /**\n * Separate Namespace from ID and return both\n *\n * @param idWithNamespace ID or Array of IDs containing a redis namespace and the real ID\n * @returns Object with namespace and the\n * ID/Array of IDs without the namespace\n */\n _normalizeId(idWithNamespace) {\n let ns = this.namespaceObjects;\n let id = null;\n let name = '';\n let isMeta;\n if (Array.isArray(idWithNamespace)) {\n const ids = [];\n idWithNamespace.forEach(el => {\n const { id, namespace } = this._normalizeId(el);\n ids.push(id);\n ns = namespace; // we ignore the pot. case from arrays with different namespaces\n });\n id = ids;\n } else if (typeof idWithNamespace === 'string') {\n id = idWithNamespace;\n if (idWithNamespace.startsWith(this.namespaceObjects)) {\n let idx = -1;\n if (idWithNamespace.startsWith(this.namespaceObj)) {\n idx = this.namespaceObjLen;\n } else if (idWithNamespace.startsWith(this.namespaceFile)) {\n idx = this.namespaceFileLen;\n } else if (idWithNamespace.startsWith(this.namespaceSet)) {\n idx = this.namespaceSetLen;\n }\n\n if (idx !== -1) {\n ns = idWithNamespace.substr(0, idx);\n id = idWithNamespace.substr(idx);\n }\n if (ns === this.namespaceFile) {\n let fileIdDetails = id.match(this.normalizeFileRegex1);\n if (fileIdDetails) {\n id = fileIdDetails[1];\n name = fileIdDetails[2] || '';\n isMeta = fileIdDetails[3] === 'meta';\n } else {\n fileIdDetails = id.match(this.normalizeFileRegex2);\n if (fileIdDetails) {\n id = fileIdDetails[1];\n name = fileIdDetails[2] || '';\n isMeta = undefined;\n } else {\n name = '';\n isMeta = undefined;\n }\n }\n }\n } else if (idWithNamespace.startsWith(this.namespaceMeta)) {\n const idx = this.namespaceMetaLen;\n if (idx !== -1) {\n ns = idWithNamespace.substr(0, idx);\n id = idWithNamespace.substr(idx);\n }\n }\n }\n return { id, namespace: ns, name, isMeta };\n }\n\n /**\n * Publish a subscribed value to one of the redis connections in redis format\n *\n * @param client Instance of RedisHandler\n * @param type Type of subscribed key\n * @param id Subscribed ID\n * @param obj Object to publish\n * @returns Publish counter 0 or 1 depending on if send out or not\n */\n publishToClients(client, type, id, obj) {\n if (!client._subscribe || !client._subscribe[type]) {\n return 0;\n }\n const s = client._subscribe[type];\n\n const found = s.find(sub => sub.regex.test(id));\n\n if (found) {\n if (type === 'meta') {\n this.log.silly(`${this.namespace} Redis Publish Meta ${id}=${obj}`);\n const sendPattern = this.namespaceMeta + found.pattern;\n const sendId = this.namespaceMeta + id;\n client.sendArray(null, ['pmessage', sendPattern, sendId, obj]);\n } else if (type === 'files') {\n const objString = JSON.stringify(obj);\n this.log.silly(`${this.namespace} Redis Publish File ${id}=${objString}`);\n const sendPattern = this.namespaceFile + found.pattern;\n const sendId = this.namespaceFile + id;\n client.sendArray(null, ['pmessage', sendPattern, sendId, objString]);\n } else {\n const objString = JSON.stringify(obj);\n this.log.silly(`${this.namespace} Redis Publish Object ${id}=${objString}`);\n const sendPattern = (type === 'objects' ? '' : this.namespaceObjects) + found.pattern;\n const sendId = (type === 'objects' ? this.namespaceObj : this.namespaceObjects) + id;\n client.sendArray(null, ['pmessage', sendPattern, sendId, objString]);\n }\n return 1;\n }\n return 0;\n }\n\n /**\n * Generate ID for a File\n *\n * @param id ID of the File\n * @param name Name of the file\n * @param isMeta generate a META ID or a Data ID?\n * @returns File-ID\n */\n getFileId(id, name, isMeta) {\n // e.g. ekey.admin and admin/ekey.png\n if (id.endsWith('.admin')) {\n if (name.startsWith('admin/')) {\n name = name.replace(/^admin\\//, '');\n } else if (name.match(/^iobroker.[-\\d\\w]\\/admin\\//i)) {\n // e.g. ekey.admin and iobroker.ekey/admin/ekey.png\n name = name.replace(/^iobroker.[-\\d\\w]\\/admin\\//i, '');\n }\n }\n\n return `${this.namespaceFile + id}$%$${name}${isMeta !== undefined ? (isMeta ? '$%$meta' : '$%$data') : ''}`;\n }\n\n /**\n * Register all event listeners for Handler and implement the relevant logic\n *\n * @param handler RedisHandler instance\n */\n _socketEvents(handler) {\n let connectionName = null;\n let namespaceLog = this.namespace;\n\n // Handle Redis \"INFO\" request\n handler.on('info', (_data, responseId) => {\n let infoString = '# Server\\r\\n';\n infoString += 'redis_version:3.0.0-iobroker\\r\\n';\n infoString += '# Clients\\r\\n';\n infoString += '# Memory\\r\\n';\n infoString += '# Persistence\\r\\n';\n infoString += '# Stats\\r\\n';\n infoString += '# Replication\\r\\n';\n infoString += '# CPU\\r\\n';\n infoString += '# Cluster\\r\\n';\n infoString += '# Keyspace\\r\\n';\n infoString += `db0:keys=${Object.keys(this.dataset).length},expires=0,avg_ttl=98633637897`;\n handler.sendBulk(responseId, infoString);\n });\n\n // Handle Redis \"QUIT\" request\n handler.on('quit', (_data, responseId) => {\n this.log.silly(`${namespaceLog} Redis QUIT received, close connection`);\n handler.sendString(responseId, 'OK');\n handler.close();\n });\n\n // Handle Redis \"SCRIPT\" request\n handler.on('script', (data, responseId) => {\n data[0] = data[0].toLowerCase();\n if (data[0] === 'exists') {\n data.shift();\n const scripts = [];\n data.forEach(checksum => scripts.push(this.knownScripts[checksum] ? 1 : 0));\n handler.sendArray(responseId, scripts);\n } else if (data[0] === 'load') {\n const shasum = crypto.createHash('sha1');\n const buf = Buffer.from(data[1]);\n shasum.update(buf);\n const scriptChecksum = shasum.digest('hex');\n\n const scriptDesign = data[1].match(/^-- design: ([a-z0-9A-Z-.]+)\\s/m);\n const scriptFunc = data[1].match(/^-- func: (.+)$/m);\n if (scriptDesign && scriptDesign[1]) {\n const design = scriptDesign[1];\n let search = null;\n const scriptSearch = data[1].match(/^-- search: ([a-z0-9A-Z-.]*)\\s/m);\n if (scriptSearch && scriptSearch[1]) {\n search = scriptSearch[1];\n }\n\n this.knownScripts[scriptChecksum] = { design: design, search: search };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Register View LUA Script: ${scriptChecksum} = ${JSON.stringify(\n this.knownScripts[scriptChecksum],\n )}`,\n );\n }\n handler.sendBulk(responseId, scriptChecksum);\n } else if (scriptFunc && scriptFunc[1]) {\n this.knownScripts[scriptChecksum] = { func: scriptFunc[1] };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Register Func LUA Script: ${scriptChecksum} = ${JSON.stringify(\n this.knownScripts[scriptChecksum],\n )}`,\n );\n }\n handler.sendBulk(responseId, scriptChecksum);\n } else if (data[1].includes('-- REDLOCK SCRIPT')) {\n // redlock scripts are currently not needed for Simulator\n this.knownScripts[scriptChecksum] = { redlock: true };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Register Func LUA Script: ${scriptChecksum} = ${JSON.stringify(\n this.knownScripts[scriptChecksum],\n )}`,\n );\n }\n handler.sendBulk(responseId, scriptChecksum);\n } else {\n handler.sendError(responseId, new Error(`Unknown LUA script ${data[1]}`));\n }\n } else {\n handler.sendError(responseId, new Error(`Unsupported Script command ${data[0]}`));\n }\n });\n\n // Handle Redis \"EVALSHA\" request\n handler.on('evalsha', (data, responseId) => {\n if (!this.knownScripts[data[0]]) {\n return void handler.sendError(responseId, new Error(`Unknown Script ${data[0]}`));\n }\n if (this.knownScripts[data[0]].design) {\n const scriptDesign = this.knownScripts[data[0]].design;\n if (typeof data[2] === 'string' && data[2].startsWith(this.namespaceObj) && data.length > 4) {\n let scriptSearch = this.knownScripts[data[0]].search;\n if (scriptDesign === 'system' && !scriptSearch && data[5]) {\n scriptSearch = data[5];\n }\n if (!scriptSearch) {\n scriptSearch = 'state';\n }\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Script transformed into getObjectView: design=${scriptDesign}, search=${scriptSearch}`,\n );\n }\n let objs;\n try {\n objs = this._getObjectView(scriptDesign, scriptSearch, {\n startkey: data[3],\n endkey: data[4],\n include_docs: true,\n });\n } catch (err) {\n return void handler.sendError(\n responseId,\n new Error(`_getObjectView Error for ${scriptDesign}/${scriptSearch}: ${err.message}`),\n );\n }\n\n const res = objs.rows.map(obj => JSON.stringify(this.dataset[obj.value._id || obj.id]));\n handler.sendArray(responseId, res);\n }\n } else if (this.knownScripts[data[0]].func && data.length > 4) {\n const scriptFunc = { map: this.knownScripts[data[0]].func.replace('%1', data[5]) };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(`${namespaceLog} Script transformed into _applyView: func=${scriptFunc.map}`);\n }\n const objs = this._applyView(scriptFunc, {\n startkey: data[3],\n endkey: data[4],\n include_docs: true,\n });\n const res = objs.rows.map(obj => JSON.stringify(this.dataset[obj.value._id || obj.id]));\n\n return void handler.sendArray(responseId, res);\n } else if (this.knownScripts[data[0]].redlock) {\n // just return a dummy\n return void handler.sendArray(responseId, [0]);\n } else {\n handler.sendError(responseId, new Error(`Unknown LUA script eval call ${JSON.stringify(data)}`));\n }\n });\n\n // Handle Redis \"PUBLISH\" request\n handler.on('publish', (data, responseId) => {\n const { id, namespace } = this._normalizeId(data[0]);\n\n if (\n namespace === this.namespaceObj ||\n namespace === this.namespaceMeta ||\n namespace === this.namespaceFile\n ) {\n // a \"set\" always comes afterwards, so do not publish\n return void handler.sendInteger(responseId, 0); // do not publish for now\n }\n const publishCount = this.publishAll(namespace.substr(0, namespace.length - 1), id, JSON.parse(data[1]));\n handler.sendInteger(responseId, publishCount);\n });\n\n // Handle Redis \"MGET\" requests\n handler.on('mget', (data, responseId) => {\n if (!data || !data.length) {\n return void handler.sendArray(responseId, []);\n }\n const { namespace, isMeta } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n const keys = [];\n data.forEach(dataId => {\n const { id, namespace } = this._normalizeId(dataId);\n if (namespace !== this.namespaceObj) {\n keys.push(null);\n this.log.warn(\n `${namespaceLog} Got MGET request for non Object-ID in Objects-ID chunk for ${namespace} / ${dataId}`,\n );\n return;\n }\n keys.push(id);\n });\n let result;\n try {\n result = this._getObjects(keys);\n } catch (err) {\n return void handler.sendError(responseId, new Error(`ERROR _getObjects: ${err.message}`));\n }\n result = result.map(el => (el ? JSON.stringify(el) : null));\n handler.sendArray(responseId, result);\n } else if (namespace === this.namespaceFile) {\n // Handle request for Meta data for files\n if (isMeta) {\n const response = [];\n data.forEach(dataId => {\n const { id, namespace, name } = this._normalizeId(dataId);\n if (namespace !== this.namespaceFile) {\n response.push(null);\n this.log.warn(\n `${namespaceLog} Got MGET request for non File ID in File-ID chunk for ${dataId}`,\n );\n return;\n }\n this._loadFileSettings(id);\n if (!this.fileOptions[id] || !this.fileOptions[id][name]) {\n response.push(null);\n return;\n }\n const obj = this._clone(this.fileOptions[id][name]);\n try {\n obj.stats = fs.statSync(path.join(this.objectsDir, id, name));\n } catch (err) {\n if (!name.endsWith('/_data.json')) {\n this.log.warn(\n `${namespaceLog} Got MGET request for non existing file ${dataId}, err: ${err.message}`,\n );\n }\n response.push(null);\n return;\n }\n response.push(JSON.stringify(obj));\n });\n handler.sendArray(responseId, response);\n } else {\n // Handle request for File data\n handler.sendError(responseId, new Error('MGET-UNSUPPORTED for file data'));\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`MGET-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"GET\" requests\n handler.on('get', (data, responseId) => {\n const { id, namespace, name, isMeta } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n const result = this._getObject(id);\n if (!result) {\n handler.sendNull(responseId);\n } else {\n handler.sendBulk(responseId, JSON.stringify(result));\n }\n } else if (namespace === this.namespaceFile) {\n // Handle request for Meta data for files\n if (isMeta) {\n let stats;\n try {\n stats = fs.statSync(path.join(this.objectsDir, id, name));\n } catch {\n return void handler.sendNull(responseId);\n }\n if (stats.isDirectory()) {\n return void handler.sendBulk(\n responseId,\n JSON.stringify({\n file: name,\n stats: {},\n isDir: true,\n }),\n );\n }\n this._loadFileSettings(id);\n if (!this.fileOptions[id] || !this.fileOptions[id][name]) {\n return void handler.sendNull(responseId);\n }\n\n let obj = this._clone(this.fileOptions[id][name]);\n if (typeof obj !== 'object') {\n obj = {\n mimeType: obj,\n acl: {\n owner:\n (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup:\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||\n utils.CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||\n utils.CONSTS.ACCESS_USER_ALL |\n utils.CONSTS.ACCESS_GROUP_ALL |\n utils.CONSTS.ACCESS_EVERY_ALL, // 777\n },\n };\n }\n obj.stats = stats;\n handler.sendBulk(responseId, JSON.stringify(obj));\n } else {\n // Handle request for File data\n let data;\n try {\n data = this._readFile(id, name);\n } catch {\n return void handler.sendNull(responseId);\n }\n if (data.fileContent === undefined || data.fileContent === null) {\n return void handler.sendNull(responseId);\n }\n let fileData = data.fileContent;\n if (!Buffer.isBuffer(fileData) && tools.isObject(fileData)) {\n // if its an invalid object, stringify it and log warning\n fileData = JSON.stringify(fileData);\n this.log.warn(\n `${namespaceLog} Data of \"${id}/${name}\" has invalid structure at file data request: ${fileData}`,\n );\n }\n handler.sendBufBulk(responseId, Buffer.from(fileData));\n }\n } else if (namespace === this.namespaceMeta) {\n // special handling for the primaryHost\n if (id === 'objects.primaryHost') {\n // we are the server -> we are primary\n handler.sendString(this.settings.hostname);\n } else {\n const result = this.getMeta(id);\n if (result === undefined || result === null) {\n handler.sendNull(responseId);\n } else {\n handler.sendBulk(responseId, result);\n }\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`GET-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"SET\" requests\n handler.on('set', (data, responseId) => {\n const { id, namespace, name, isMeta } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n try {\n const obj = JSON.parse(data[1].toString('utf-8'));\n this._setObjectDirect(id, obj);\n } catch (err) {\n return void handler.sendError(responseId, new Error(`ERROR setObject id=${id}: ${err.message}`));\n }\n handler.sendString(responseId, 'OK');\n } else if (namespace === this.namespaceFile) {\n // Handle request to set meta-data, we ignore it because\n // will be set when data are written\n if (isMeta) {\n this._loadFileSettings(id);\n\n try {\n fs.ensureDirSync(path.join(this.objectsDir, id, path.dirname(name)));\n\n // only set if the meta-object is already/still existing\n if (this.fileOptions[id]) {\n this.fileOptions[id][name] = JSON.parse(data[1].toString('utf-8'));\n fs.writeFileSync(\n path.join(this.objectsDir, id, '_data.json'),\n JSON.stringify(this.fileOptions[id]),\n );\n }\n } catch (err) {\n return void handler.sendError(\n responseId,\n new Error(`ERROR writeFile-Meta id=${id}: ${err.message}`),\n );\n }\n handler.sendString(responseId, 'OK');\n } else {\n // Handle request to write the file\n try {\n this._writeFile(id, name, data[1]);\n } catch (err) {\n return void handler.sendError(\n responseId,\n new Error(`ERROR writeFile id=${id}: ${err.message}`),\n );\n }\n handler.sendString(responseId, 'OK');\n }\n } else if (namespace === this.namespaceMeta) {\n this.setMeta(id, data[1].toString('utf-8'));\n handler.sendString(responseId, 'OK');\n } else {\n handler.sendError(\n responseId,\n new Error(`SET-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"RENAME\" requests\n handler.on('rename', (data, responseId) => {\n const oldDetails = this._normalizeId(data[0]);\n const newDetails = this._normalizeId(data[1]);\n\n if (oldDetails.namespace === this.namespaceFile) {\n if (oldDetails.id !== newDetails.id) {\n return void handler.sendError(\n responseId,\n new Error('ERROR renameObject: id needs to stay the same'),\n );\n }\n\n // Handle request for Meta data for files\n if (oldDetails.isMeta) {\n handler.sendString(responseId, 'OK');\n } else {\n // Handle request for File data\n try {\n this._rename(oldDetails.id, oldDetails.name, newDetails.name);\n } catch {\n return void handler.sendNull(responseId);\n }\n handler.sendString(responseId, 'OK');\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`RENAME-UNSUPPORTED for namespace ${oldDetails.namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"DEL\" request for state and session namespace\n handler.on('del', (data, responseId) => {\n const { id, namespace, name, isMeta } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n try {\n this._delObject(id);\n } catch (err) {\n return void handler.sendError(responseId, err);\n }\n handler.sendInteger(responseId, 1);\n } else if (namespace === this.namespaceFile) {\n // Handle request to delete meta-data, we ignore it because\n // will be removed when data are deleted\n if (isMeta) {\n handler.sendString(responseId, 'OK');\n } else {\n // Handle request to remove the file\n try {\n this._unlink(id, name);\n } catch (err) {\n return void handler.sendError(responseId, err);\n }\n handler.sendString(responseId, 'OK');\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`DEL-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n handler.on('exists', (data, responseId) => {\n if (!data || !data.length) {\n return void handler.sendInteger(responseId, 0);\n }\n\n // Note: we only simulate single key existence check\n const { id, namespace, name } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n let exists;\n try {\n exists = this._objectExists(id);\n } catch (e) {\n return void handler.sendError(responseId, e);\n }\n handler.sendInteger(responseId, exists ? 1 : 0);\n } else if (namespace === this.namespaceFile) {\n let exists;\n try {\n exists = this._fileExists(id, name);\n } catch (e) {\n return void handler.sendError(responseId, e);\n }\n handler.sendInteger(responseId, exists ? 1 : 0);\n } else if (namespace === this.namespaceSet) {\n // we are not using sets in simulator, so just say it exists\n return void handler.sendInteger(responseId, 1);\n } else {\n handler.sendError(responseId, new Error(`EXISTS-UNSUPPORTED for namespace ${namespace}`));\n }\n });\n\n // handle Redis \"SCAN\" request for objects namespace\n handler.on('scan', (data, responseId) => {\n if (!data || data.length < 3) {\n return void handler.sendArray(responseId, ['0', []]);\n }\n\n return this._handleScanOrKeys(handler, data[2], responseId, true);\n });\n\n // Handle Redis \"KEYS\" request for state namespace\n handler.on('keys', (data, responseId) => {\n if (!data || !data.length) {\n return void handler.sendArray(responseId, []);\n }\n\n return this._handleScanOrKeys(handler, data[0], responseId);\n });\n\n // commands for redis SETS, just dummies\n handler.on('sadd', (data, responseId) => {\n return void handler.sendInteger(responseId, 1);\n });\n\n handler.on('srem', (data, responseId) => {\n return void handler.sendInteger(responseId, 1);\n });\n\n handler.on('eval', (data, responseId) => {\n return void handler.sendNull(responseId);\n });\n\n handler.on('sscan', (data, responseId) => {\n // for file DB it does the same as scan but data looks different\n if (!data || data.length < 4) {\n return void handler.sendArray(responseId, ['0', []]);\n }\n\n return this._handleScanOrKeys(handler, data[3], responseId, true);\n });\n\n // Handle Redis \"PSUBSCRIBE\" request for state, log and session namespace\n handler.on('psubscribe', (data, responseId) => {\n const { id, namespace, name } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n this._subscribeConfigForClient(handler, id);\n handler.sendArray(responseId, ['psubscribe', data[0], 1]);\n } else if (namespace === this.namespaceMeta) {\n this._subscribeMeta(handler, id);\n handler.sendArray(responseId, ['psubscribe', data[0], 1]);\n } else if (namespace === this.namespaceFile) {\n this._subscribeFileForClient(handler, id, name);\n handler.sendArray(responseId, ['psubscribe', data[0], 1]);\n } else {\n handler.sendError(\n responseId,\n new Error(`PSUBSCRIBE-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"UNSUBSCRIBE\" request for state, log and session namespace\n handler.on('punsubscribe', (data, responseId) => {\n const { id, namespace, name } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n this._unsubscribeConfigForClient(handler, id);\n handler.sendArray(responseId, ['punsubscribe', data[0], 1]);\n } else if (namespace === this.namespaceFile) {\n this._unsubscribeFileForClient(handler, id, name);\n handler.sendArray(responseId, ['punsubscribe', data[0], 1]);\n } else {\n handler.sendError(\n responseId,\n new Error(`PUNSUBSCRIBE-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"SUBSCRIBE\" ... currently mainly ignored\n handler.on('subscribe', (data, responseId) => {\n if (data[0].startsWith('__keyevent@')) {\n // we ignore these type of events because we publish expires anyway directly\n handler.sendArray(responseId, ['subscribe', data[0], 1]);\n } else {\n handler.sendError(responseId, new Error(`SUBSCRIBE-UNSUPPORTED for ${data[0]}`));\n }\n });\n\n // Handle Redis \"CONFIG\" ... currently mainly ignored\n handler.on('config', (data, responseId) => {\n const command = typeof data[0] === 'string' ? data[0].toLowerCase() : data[0].toString().toLowerCase();\n if (command === 'set' && data[1] === 'notify-keyspace-events') {\n // we ignore these type of commands for now, should only be to subscribe to keyspace events\n handler.sendString(responseId, 'OK');\n } else if (command === 'set' && data[1] === 'lua-time-limit') {\n // we ignore these type of commands for now, irrelevant\n handler.sendString(responseId, 'OK');\n } else {\n handler.sendError(responseId, new Error(`CONFIG-UNSUPPORTED for ${JSON.stringify(data)}`));\n }\n });\n\n // handle client SETNAME/GETNAME\n handler.on('client', (data, responseId) => {\n if (data[0] === 'setname' && typeof data[1] === 'string') {\n if (data[1] === '') {\n // on empty string redis sets null again and sends 'OK'\n connectionName = null;\n } else {\n connectionName = data[1];\n namespaceLog = connectionName;\n }\n handler.sendString(responseId, 'OK');\n } else if (data[0] === 'getname') {\n if (typeof connectionName === 'string' && connectionName !== '') {\n handler.sendString(responseId, connectionName);\n } else {\n // redis sends null if no name defined\n handler.sendNull(responseId);\n }\n } else {\n handler.sendError(responseId, new Error(`CLIENT-UNSUPPORTED for ${JSON.stringify(data)}`));\n }\n });\n\n handler.on('error', err => this.log.warn(`${namespaceLog} Redis objects: ${err}`));\n }\n\n /**\n * Return connected RedisHandlers/Connections\n *\n * @returns\n */\n getClients() {\n return this.serverConnections;\n }\n\n /**\n * Destructor of the class. Called by shutting down.\n */\n async destroy() {\n if (this.server) {\n Object.keys(this.serverConnections).forEach(s => {\n this.serverConnections[s].close();\n delete this.serverConnections[s];\n });\n\n await new Promise(resolve => {\n if (!this.server) {\n return void resolve();\n }\n try {\n this.server.close(() => resolve());\n } catch (e) {\n console.log(e.message);\n resolve();\n }\n });\n }\n\n await super.destroy();\n }\n\n /**\n * Get keys matching pattern and send it to given responseId, for \"SCAN\" and \"KEYS\" - Objects and files supported\n *\n * @param handler RedisHandler instance\n * @param pattern - pattern without namespace prefix\n * @param responseId - Id where response will be sent to\n * @param isScan - if used by \"SCAN\" this flag should be true\n */\n _handleScanOrKeys(handler, pattern, responseId, isScan = false) {\n const { id, namespace, name, isMeta } = this._normalizeId(pattern);\n\n let response = [];\n if (namespace === this.namespaceObj || namespace === this.namespaceObjects) {\n try {\n response = this._getKeys(id).map(val => this.namespaceObj + val);\n } catch (e) {\n return void handler.sendError(responseId, e);\n }\n\n // if scan, we send the cursor as first argument\n if (namespace !== this.namespaceObjects) {\n // When it was not the full DB namespace send out response\n return void handler.sendArray(responseId, isScan ? ['0', response] : response);\n }\n }\n if (namespace === this.namespaceFile || namespace === this.namespaceObjects) {\n // Handle request to get meta data keys\n if (isMeta === undefined) {\n let res;\n try {\n res = this._readDir(id, name);\n if (!res || !res.length) {\n res = [\n {\n file: '_data.json',\n stats: {},\n isDir: false,\n virtualFile: true,\n notExists: true,\n },\n ];\n }\n } catch (e) {\n if (!e.message.endsWith(utils.ERRORS.ERROR_NOT_FOUND)) {\n return void handler.sendError(responseId, new Error(`ERROR readDir id=${id}: ${e.message}`));\n }\n res = [];\n }\n let baseName = name || '';\n if (baseName.length && !baseName.endsWith('/')) {\n baseName += '/';\n }\n res.forEach(arr => {\n let entryId = id;\n if (arr.isDir) {\n if (entryId === '' || entryId === '*') {\n entryId = arr.file;\n arr.file = '_data.json'; // We return a \"virtual file\" to mark the directory as existing\n } else {\n arr.file += '/_data.json'; // We return a \"virtual file\" to mark the directory as existing\n }\n }\n // We need to simulate the Meta data here, so return both\n response.push(this.getFileId(entryId, baseName + arr.file, true));\n response.push(this.getFileId(entryId, baseName + arr.file, false));\n });\n handler.sendArray(responseId, isScan ? ['0', response] : response); // send out file or full db response\n } else {\n // such a request should never happen\n handler.sendArray(responseId, isScan ? ['0', []] : []); // send out file or full db response\n }\n } else if (namespace === this.namespaceSet) {\n handler.sendArray(responseId, isScan ? ['0', []] : []); // send out empty array, we have no sets\n } else {\n handler.sendError(\n responseId,\n new Error(`${isScan ? 'SCAN' : 'KEYS'}-UNSUPPORTED for namespace ${namespace}: Pattern=${pattern}`),\n );\n }\n }\n\n /**\n * Initialize RedisHandler for a new network connection\n *\n * @param socket Network socket\n */\n _initSocket(socket) {\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(`${this.namespace} Handling new Redis Objects connection`);\n }\n const options = {\n log: this.log,\n logScope: `${this.settings.namespace || ''} Objects`,\n handleAsBuffers: true,\n enhancedLogging: this.settings.connection.enhancedLogging,\n };\n const handler = new RedisHandler(socket, options);\n this._socketEvents(handler);\n\n this.serverConnections[`${socket.remoteAddress}:${socket.remotePort}`] = handler;\n socket.on('close', () => {\n if (this.serverConnections[`${socket.remoteAddress}:${socket.remotePort}`]) {\n delete this.serverConnections[`${socket.remoteAddress}:${socket.remotePort}`];\n }\n });\n }\n\n /**\n * Initialize Redis Server\n *\n * @param settings Settings object\n * @returns\n */\n _initRedisServer(settings) {\n return new Promise((resolve, reject) => {\n if (settings.secure) {\n reject(new Error('Secure Redis unsupported for File-DB'));\n }\n try {\n this.server = net.createServer();\n this.server.on('error', err =>\n this.log.info(\n `${this.namespace} ${settings.secure ? 'Secure ' : ''} Error inMem-objects listening on port ${\n settings.port || 9001\n }: ${err}`,\n ),\n );\n this.server.on('connection', socket => this._initSocket(socket));\n\n this.server.listen(\n settings.port || 9001,\n settings.host === 'localhost' ? getLocalAddress() : settings.host ? settings.host : undefined,\n () => resolve(),\n );\n } catch (err) {\n reject(err);\n }\n });\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_db_base", "id", "crypto", "namespace", "fs", "path", "utils", "data", "net"]
3
+ "sources": ["../../../../src/lib/objects/objectsInMemServerRedis.ts"],
4
+ "sourcesContent": ["/**\n * Objects DB in memory - Server with Redis protocol\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport net from 'node:net';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { objectsUtils as utils } from '@iobroker/db-objects-redis';\nimport { tools } from '@iobroker/db-base';\nimport { getLocalAddress } from '@iobroker/js-controller-common-db/tools';\nimport { EXIT_CODES } from '@iobroker/js-controller-common-db';\n\nimport { RedisHandler, type ConnectionOptions, type FileDbSettings } from '@iobroker/db-base';\nimport { type FileOptions, ObjectsInMemoryFileDB } from './objectsInMemFileDB.js';\n\n// settings = {\n// change: function (id, state) {},\n// connected: function (nameOfServer) {},\n// logger: {\n// silly: function (msg) {},\n// debug: function (msg) {},\n// info: function (msg) {},\n// warn: function (msg) {},\n// error: function (msg) {}\n// },\n// connection: {\n// dataDir: 'relative path'\n// },\n// auth: null, //unused\n// secure: true/false,\n// certificates: as required by createServer\n// port: 9001,\n// host: localhost\n// };\n//\ntype RedisHandlerInternal = RedisHandler & {\n _subscribe?: Record<\n string,\n {\n pattern: string;\n regex: RegExp;\n }[]\n >;\n};\n\n/**\n * This class inherits statesInMemoryFileDB class and adds redis communication layer\n * to access the methods via redis protocol\n */\nexport class ObjectsInMemoryServer extends ObjectsInMemoryFileDB<RedisHandlerInternal> {\n private readonly serverConnections: Record<string, RedisHandler> = {};\n private readonly namespaceObjects: string;\n private readonly namespaceFile: string;\n private readonly namespaceObj: string;\n private readonly namespaceSet: string;\n private readonly namespaceSetLen: number;\n private readonly namespaceFileLen: number;\n private readonly namespaceObjLen: number;\n private readonly namespaceMeta: string;\n private readonly namespaceMetaLen: number;\n private readonly knownScripts: Record<\n string,\n { design?: string; search?: string; redlock?: boolean; func?: string }\n > = {};\n private readonly normalizeFileRegex1: RegExp;\n private readonly normalizeFileRegex2: RegExp;\n private server: net.Server | undefined;\n\n /**\n * Constructor\n *\n * @param settings State and InMem-DB settings\n */\n constructor(settings: FileDbSettings<ioBroker.AnyObject>) {\n super(settings);\n\n this.namespaceObjects = `${this.settings.redisNamespace || settings.connection?.redisNamespace || 'cfg'}.`;\n this.namespaceFile = `${this.namespaceObjects}f.`;\n this.namespaceObj = `${this.namespaceObjects}o.`;\n this.namespaceSet = `${this.namespaceObjects}s.`;\n this.namespaceSetLen = this.namespaceSet.length;\n\n // this.namespaceObjectsLen = this.namespaceObjects.length;\n this.namespaceFileLen = this.namespaceFile.length;\n this.namespaceObjLen = this.namespaceObj.length;\n this.namespaceMeta = `${this.settings.namespaceMeta || 'meta'}.`;\n this.namespaceMetaLen = this.namespaceMeta.length;\n\n this.normalizeFileRegex1 = new RegExp('^(.*)\\\\$%\\\\$(.*)\\\\$%\\\\$(meta|data)$');\n this.normalizeFileRegex2 = new RegExp('^(.*)\\\\$%\\\\$(.*)\\\\/?\\\\*$');\n\n this.open()\n .then(() => this._initRedisServer(this.settings.connection))\n .then(() => {\n this.log.debug(\n `${this.namespace} ${settings.secure ? 'Secure ' : ''} Redis inMem-objects listening on port ${\n (this.settings.connection.port as number) || 9001\n }`,\n );\n\n if (typeof this.settings.connected === 'function') {\n setImmediate(() => this.settings.connected());\n }\n })\n .catch(e => {\n this.log.error(\n `${this.namespace} Cannot start inMem-objects on port ${(this.settings.connection.port as number) || 9001}: ${e.message}`,\n );\n process.exit(EXIT_CODES.NO_CONNECTION_TO_OBJ_DB);\n });\n }\n\n /**\n * Separate Namespace from ID and return both\n *\n * @param idWithNamespace ID or Array of IDs containing a redis namespace and the real ID\n * @returns Object with namespace and the\n * ID/Array of IDs without the namespace\n */\n _normalizeId(idWithNamespace: string): {\n id: string | null;\n namespace: string;\n name: string;\n isMeta: boolean | undefined;\n } {\n let ns = this.namespaceObjects;\n let id: string | null = null;\n let name = '';\n let isMeta;\n if (typeof idWithNamespace === 'string') {\n id = idWithNamespace;\n if (idWithNamespace.startsWith(this.namespaceObjects)) {\n let idx = -1;\n if (idWithNamespace.startsWith(this.namespaceObj)) {\n idx = this.namespaceObjLen;\n } else if (idWithNamespace.startsWith(this.namespaceFile)) {\n idx = this.namespaceFileLen;\n } else if (idWithNamespace.startsWith(this.namespaceSet)) {\n idx = this.namespaceSetLen;\n }\n\n if (idx !== -1) {\n ns = idWithNamespace.substr(0, idx);\n id = idWithNamespace.substr(idx);\n }\n if (ns === this.namespaceFile) {\n let fileIdDetails = id.match(this.normalizeFileRegex1);\n if (fileIdDetails) {\n id = fileIdDetails[1];\n name = fileIdDetails[2] || '';\n isMeta = fileIdDetails[3] === 'meta';\n } else {\n fileIdDetails = id.match(this.normalizeFileRegex2);\n if (fileIdDetails) {\n id = fileIdDetails[1];\n name = fileIdDetails[2] || '';\n isMeta = undefined;\n } else {\n name = '';\n isMeta = undefined;\n }\n }\n }\n } else if (idWithNamespace.startsWith(this.namespaceMeta)) {\n const idx = this.namespaceMetaLen;\n if (idx !== -1) {\n ns = idWithNamespace.substr(0, idx);\n id = idWithNamespace.substr(idx);\n }\n }\n }\n return { id, namespace: ns, name, isMeta };\n }\n\n /**\n * Publish a subscribed value to one of the redis connections in redis format\n *\n * @param client Instance of RedisHandler\n * @param type Type of subscribed key\n * @param id Subscribed ID\n * @param obj Object to publish\n * @returns Publish counter 0 or 1 depending on if send out or not\n */\n publishToClients(\n client: RedisHandlerInternal,\n type: string,\n id: string,\n obj: ioBroker.AnyObject | ioBroker.DesignObject,\n ): number {\n if (!client._subscribe?.[type]) {\n return 0;\n }\n const s = client._subscribe[type];\n\n const found = s.find(sub => sub.regex.test(id));\n\n if (found) {\n if (type === 'meta') {\n this.log.silly(`${this.namespace} Redis Publish Meta ${id}=${JSON.stringify(obj)}`);\n const sendPattern = this.namespaceMeta + found.pattern;\n const sendId = this.namespaceMeta + id;\n client.sendArray(null, ['pmessage', sendPattern, sendId, obj]);\n } else if (type === 'files') {\n const objString = JSON.stringify(obj);\n this.log.silly(`${this.namespace} Redis Publish File ${id}=${objString}`);\n const sendPattern = this.namespaceFile + found.pattern;\n const sendId = this.namespaceFile + id;\n client.sendArray(null, ['pmessage', sendPattern, sendId, objString]);\n } else {\n const objString = JSON.stringify(obj);\n this.log.silly(`${this.namespace} Redis Publish Object ${id}=${objString}`);\n const sendPattern = (type === 'objects' ? '' : this.namespaceObjects) + found.pattern;\n const sendId = (type === 'objects' ? this.namespaceObj : this.namespaceObjects) + id;\n client.sendArray(null, ['pmessage', sendPattern, sendId, objString]);\n }\n return 1;\n }\n return 0;\n }\n\n /**\n * Generate ID for a File\n *\n * @param id ID of the File\n * @param name Name of the file\n * @param isMeta generate a META ID or a Data ID?\n * @returns File-ID\n */\n getFileId(id: string, name: string, isMeta?: boolean): string {\n // e.g. ekey.admin and admin/ekey.png\n if (id.endsWith('.admin')) {\n if (name.startsWith('admin/')) {\n name = name.replace(/^admin\\//, '');\n } else if (name.match(/^iobroker.[-\\d\\w]\\/admin\\//i)) {\n // e.g. ekey.admin and iobroker.ekey/admin/ekey.png\n name = name.replace(/^iobroker.[-\\d\\w]\\/admin\\//i, '');\n }\n }\n\n return `${this.namespaceFile + id}$%$${name}${isMeta !== undefined ? (isMeta ? '$%$meta' : '$%$data') : ''}`;\n }\n\n /**\n * Register all event listeners for Handler and implement the relevant logic\n *\n * @param handler RedisHandler instance\n */\n _socketEvents(handler: RedisHandler): void {\n let connectionName: string | null = null;\n let namespaceLog = this.namespace;\n\n // Handle Redis \"INFO\" request\n handler.on('info', (_data, responseId) => {\n let infoString = '# Server\\r\\n';\n infoString += 'redis_version:3.0.0-iobroker\\r\\n';\n infoString += '# Clients\\r\\n';\n infoString += '# Memory\\r\\n';\n infoString += '# Persistence\\r\\n';\n infoString += '# Stats\\r\\n';\n infoString += '# Replication\\r\\n';\n infoString += '# CPU\\r\\n';\n infoString += '# Cluster\\r\\n';\n infoString += '# Keyspace\\r\\n';\n infoString += `db0:keys=${Object.keys(this.dataset).length},expires=0,avg_ttl=98633637897`;\n handler.sendBulk(responseId, infoString);\n });\n\n // Handle Redis \"QUIT\" request\n handler.on('quit', (_data, responseId) => {\n this.log.silly(`${namespaceLog} Redis QUIT received, close connection`);\n handler.sendString(responseId, 'OK');\n handler.close();\n });\n\n // Handle Redis \"SCRIPT\" request\n handler.on('script', (data: [command: 'exists' | 'load', buffer: string], responseId) => {\n data[0] = data[0].toLowerCase() as 'exists' | 'load';\n if (data[0] === 'exists') {\n data.shift();\n const scripts: number[] = [];\n data.forEach((checksum: string) => scripts.push(this.knownScripts[checksum] ? 1 : 0));\n handler.sendArray(responseId, scripts);\n } else if (data[0] === 'load') {\n const shasum = crypto.createHash('sha1');\n const buf = Buffer.from(data[1]);\n shasum.update(buf);\n const scriptChecksum = shasum.digest('hex');\n\n const scriptDesign = data[1].match(/^-- design: ([a-z0-9A-Z-.]+)\\s/m);\n const scriptFunc = data[1].match(/^-- func: (.+)$/m);\n if (scriptDesign?.[1]) {\n const design = scriptDesign[1];\n let search: string | undefined;\n const scriptSearch = data[1].match(/^-- search: ([a-z0-9A-Z-.]*)\\s/m);\n if (scriptSearch?.[1]) {\n search = scriptSearch[1];\n }\n\n this.knownScripts[scriptChecksum] = { design, search };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Register View LUA Script: ${scriptChecksum} = ${JSON.stringify(\n this.knownScripts[scriptChecksum],\n )}`,\n );\n }\n handler.sendBulk(responseId, scriptChecksum);\n } else if (scriptFunc?.[1]) {\n this.knownScripts[scriptChecksum] = { func: scriptFunc[1] };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Register Func LUA Script: ${scriptChecksum} = ${JSON.stringify(\n this.knownScripts[scriptChecksum],\n )}`,\n );\n }\n handler.sendBulk(responseId, scriptChecksum);\n } else if (data[1].includes('-- REDLOCK SCRIPT')) {\n // redlock scripts are currently not needed for Simulator\n this.knownScripts[scriptChecksum] = { redlock: true };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Register Func LUA Script: ${scriptChecksum} = ${JSON.stringify(\n this.knownScripts[scriptChecksum],\n )}`,\n );\n }\n handler.sendBulk(responseId, scriptChecksum);\n } else {\n handler.sendError(responseId, new Error(`Unknown LUA script ${data[1]}`));\n }\n } else {\n handler.sendError(responseId, new Error(`Unsupported Script command ${data[0] as string}`));\n }\n });\n\n // Handle Redis \"EVALSHA\" request\n handler.on(\n 'evalsha',\n (\n data: [\n scriptId: string,\n ignore: string,\n name: string,\n startkey: string,\n endkey: string,\n search: string,\n ],\n responseId,\n ) => {\n if (!this.knownScripts[data[0]]) {\n return void handler.sendError(responseId, new Error(`Unknown Script ${data[0]}`));\n }\n if (this.knownScripts[data[0]].design) {\n const scriptDesign: string = this.knownScripts[data[0]].design!;\n if (typeof data[2] === 'string' && data[2].startsWith(this.namespaceObj) && data.length > 4) {\n let scriptSearch = this.knownScripts[data[0]].search;\n if (scriptDesign === 'system' && !scriptSearch && data[5]) {\n scriptSearch = data[5];\n }\n if (!scriptSearch) {\n scriptSearch = 'state';\n }\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(\n `${namespaceLog} Script transformed into getObjectView: design=${scriptDesign}, search=${scriptSearch}`,\n );\n }\n let objs;\n try {\n objs = this._getObjectView(scriptDesign, scriptSearch, {\n startkey: data[3],\n endkey: data[4],\n include_docs: true,\n });\n } catch (err) {\n return void handler.sendError(\n responseId,\n new Error(`_getObjectView Error for ${scriptDesign}/${scriptSearch}: ${err.message}`),\n );\n }\n\n const res = objs.rows.map(obj =>\n JSON.stringify(this.dataset[(obj.value as ioBroker.AnyObject)._id || obj.id]),\n );\n handler.sendArray(responseId, res);\n }\n } else if (this.knownScripts[data[0]].func && data.length > 4) {\n const scriptFunc = { map: this.knownScripts[data[0]].func!.replace('%1', data[5]) };\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(`${namespaceLog} Script transformed into _applyView: func=${scriptFunc.map}`);\n }\n const objs = this._applyView(scriptFunc, {\n startkey: data[3],\n endkey: data[4],\n include_docs: true,\n });\n const res = objs.rows.map(obj =>\n JSON.stringify(this.dataset[(obj.value as ioBroker.AnyObject)._id || obj.id]),\n );\n\n return void handler.sendArray(responseId, res);\n } else if (this.knownScripts[data[0]].redlock) {\n // just return a dummy\n return void handler.sendArray(responseId, [0]);\n } else {\n handler.sendError(responseId, new Error(`Unknown LUA script eval call ${JSON.stringify(data)}`));\n }\n },\n );\n\n // Handle Redis \"PUBLISH\" request\n handler.on('publish', (data: [addr: string, obj: string], responseId) => {\n const { id, namespace } = this._normalizeId(data[0]);\n\n if (\n namespace === this.namespaceObj ||\n namespace === this.namespaceMeta ||\n namespace === this.namespaceFile ||\n !id\n ) {\n // a \"set\" always comes afterwards, so do not publish\n return void handler.sendInteger(responseId, 0); // do not publish for now\n }\n const publishCount = this.publishAll(namespace.substr(0, namespace.length - 1), id, JSON.parse(data[1]));\n handler.sendInteger(responseId, publishCount);\n });\n\n // Handle Redis \"MGET\" requests\n handler.on('mget', (data: string[], responseId) => {\n if (!data?.length) {\n return void handler.sendArray(responseId, []);\n }\n const { namespace, isMeta } = this._normalizeId(data[0]);\n\n if (namespace === this.namespaceObj) {\n const keys: (string | null)[] = [];\n data.forEach((dataId: string) => {\n const { id, namespace } = this._normalizeId(dataId);\n if (namespace !== this.namespaceObj) {\n keys.push(null);\n this.log.warn(\n `${namespaceLog} Got MGET request for non Object-ID in Objects-ID chunk for ${namespace} / ${dataId}`,\n );\n return;\n }\n keys.push(id);\n });\n let result: (ioBroker.AnyObject | ioBroker.DesignObject | Record<string, string> | undefined)[];\n try {\n result = this._getObjects(keys);\n } catch (err) {\n return void handler.sendError(responseId, new Error(`ERROR _getObjects: ${err.message}`));\n }\n const resultObjs = result.map(el => (el ? JSON.stringify(el) : null));\n handler.sendArray(responseId, resultObjs);\n } else if (namespace === this.namespaceFile) {\n // Handle request for Metadata for files\n if (isMeta) {\n const response: (string | null)[] = [];\n data.forEach((dataId: string) => {\n const { id, namespace, name } = this._normalizeId(dataId);\n if (!id || namespace !== this.namespaceFile) {\n response.push(null);\n this.log.warn(\n `${namespaceLog} Got MGET request for non File ID in File-ID chunk for ${dataId}`,\n );\n return;\n }\n this._loadFileSettings(id);\n if (!this.fileOptions[id] || !this.fileOptions[id][name]) {\n response.push(null);\n return;\n }\n const obj: FileOptions = this._clone(this.fileOptions[id][name]);\n try {\n obj.stats = fs.statSync(path.join(this.objectsDir, id, name));\n } catch (err) {\n if (!name.endsWith('/_data.json')) {\n this.log.warn(\n `${namespaceLog} Got MGET request for non existing file ${dataId}, err: ${err.message}`,\n );\n }\n response.push(null);\n return;\n }\n response.push(JSON.stringify(obj));\n });\n handler.sendArray(responseId, response);\n } else {\n // Handle request for File data\n handler.sendError(responseId, new Error('MGET-UNSUPPORTED for file data'));\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`MGET-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"GET\" requests\n handler.on('get', (data, responseId) => {\n const { id, namespace, name, isMeta } = this._normalizeId(data[0]);\n\n if (!id) {\n handler.sendNull(responseId);\n return;\n }\n if (namespace === this.namespaceObj) {\n const result = this._getObject(id);\n if (!result) {\n handler.sendNull(responseId);\n } else {\n handler.sendBulk(responseId, JSON.stringify(result));\n }\n } else if (namespace === this.namespaceFile) {\n // Handle request for Metadata for files\n if (isMeta) {\n let stats: fs.Stats;\n try {\n stats = fs.statSync(path.join(this.objectsDir, id, name));\n } catch {\n return void handler.sendNull(responseId);\n }\n if (stats.isDirectory()) {\n return void handler.sendBulk(\n responseId,\n JSON.stringify({\n file: name,\n stats: {},\n isDir: true,\n }),\n );\n }\n this._loadFileSettings(id);\n if (!this.fileOptions[id] || !this.fileOptions[id][name]) {\n return void handler.sendNull(responseId);\n }\n\n let obj: FileOptions = this._clone(this.fileOptions[id][name]);\n if (typeof obj !== 'object') {\n obj = {\n mimeType: obj,\n acl: {\n owner: this.defaultNewAcl?.owner || utils.CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup: this.defaultNewAcl?.ownerGroup || utils.CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n this.defaultNewAcl?.file ||\n utils.CONSTS.ACCESS_USER_ALL |\n utils.CONSTS.ACCESS_GROUP_ALL |\n utils.CONSTS.ACCESS_EVERY_ALL, // 777\n },\n stats,\n };\n } else {\n obj.stats = stats;\n }\n handler.sendBulk(responseId, JSON.stringify(obj));\n } else {\n // Handle request for File data\n let data;\n try {\n data = this._readFile(id, name);\n } catch {\n return void handler.sendNull(responseId);\n }\n if (data.fileContent === undefined || data.fileContent === null) {\n return void handler.sendNull(responseId);\n }\n let fileData = data.fileContent;\n if (!Buffer.isBuffer(fileData) && tools.isObject(fileData)) {\n // if it's an invalid object, stringify it and log warning\n fileData = JSON.stringify(fileData);\n this.log.warn(\n `${namespaceLog} Data of \"${id}/${name}\" has invalid structure at file data request: ${fileData}`,\n );\n }\n handler.sendBufBulk(responseId, Buffer.from(fileData));\n }\n } else if (namespace === this.namespaceMeta) {\n // special handling for the primaryHost\n if (id === 'objects.primaryHost') {\n // we are the server -> we are primary\n handler.sendString(responseId, this.settings.hostname as string);\n } else {\n const result = this.getMeta(id);\n if (result === undefined || result === null) {\n handler.sendNull(responseId);\n } else {\n handler.sendBulk(responseId, result);\n }\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`GET-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"SET\" requests\n handler.on('set', (data, responseId) => {\n const { id, namespace, name, isMeta } = this._normalizeId(data[0]);\n\n if (!id) {\n return void handler.sendError(responseId, new Error(`ERROR setObject id=${id}: id is null`));\n }\n\n if (namespace === this.namespaceObj) {\n try {\n const obj = JSON.parse(data[1].toString('utf-8'));\n this._setObjectDirect(id, obj);\n } catch (err) {\n return void handler.sendError(responseId, new Error(`ERROR setObject id=${id}: ${err.message}`));\n }\n handler.sendString(responseId, 'OK');\n } else if (namespace === this.namespaceFile) {\n // Handle request to set meta-data, we ignore it because\n // will be set when data are written\n if (isMeta) {\n this._loadFileSettings(id);\n\n try {\n fs.ensureDirSync(path.join(this.objectsDir, id, path.dirname(name)));\n\n // only set if the meta-object is already/still existing\n if (this.fileOptions[id]) {\n this.fileOptions[id][name] = JSON.parse(data[1].toString('utf-8'));\n fs.writeFileSync(\n path.join(this.objectsDir, id, '_data.json'),\n JSON.stringify(this.fileOptions[id]),\n );\n }\n } catch (err) {\n return void handler.sendError(\n responseId,\n new Error(`ERROR writeFile-Meta id=${id}: ${err.message}`),\n );\n }\n handler.sendString(responseId, 'OK');\n } else {\n // Handle request to write the file\n try {\n this._writeFile(id, name, data[1]);\n } catch (err) {\n return void handler.sendError(\n responseId,\n new Error(`ERROR writeFile id=${id}: ${err.message}`),\n );\n }\n handler.sendString(responseId, 'OK');\n }\n } else if (namespace === this.namespaceMeta) {\n this.setMeta(id, data[1].toString('utf-8'));\n handler.sendString(responseId, 'OK');\n } else {\n handler.sendError(\n responseId,\n new Error(`SET-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"RENAME\" requests\n handler.on('rename', (data, responseId) => {\n const oldDetails = this._normalizeId(data[0]);\n const newDetails = this._normalizeId(data[1]);\n\n if (!oldDetails.id || !newDetails.id || oldDetails.namespace === this.namespaceFile) {\n if (!oldDetails.id || !newDetails.id) {\n return void handler.sendError(responseId, new Error('ERROR renameObject: id needs to be not null'));\n }\n if (oldDetails.id !== newDetails.id) {\n return void handler.sendError(\n responseId,\n new Error('ERROR renameObject: id needs to stay the same'),\n );\n }\n\n // Handle request for Metadata for files\n if (oldDetails.isMeta) {\n handler.sendString(responseId, 'OK');\n } else {\n // Handle request for File data\n try {\n this._rename(oldDetails.id, oldDetails.name, newDetails.name);\n } catch {\n return void handler.sendNull(responseId);\n }\n handler.sendString(responseId, 'OK');\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`RENAME-UNSUPPORTED for namespace ${oldDetails.namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"DEL\" request for state and session namespace\n handler.on('del', (data, responseId) => {\n const { id, namespace, name, isMeta } = this._normalizeId(data[0]);\n\n if (!id) {\n return void handler.sendError(responseId, new Error('id is null'));\n }\n if (namespace === this.namespaceObj) {\n try {\n this._delObject(id);\n } catch (err) {\n return void handler.sendError(responseId, err);\n }\n handler.sendInteger(responseId, 1);\n } else if (namespace === this.namespaceFile) {\n // Handle request to delete meta-data, we ignore it because\n // will be removed when data are deleted\n if (isMeta) {\n handler.sendString(responseId, 'OK');\n } else {\n // Handle request to remove the file\n try {\n this._unlink(id, name);\n } catch (err) {\n return void handler.sendError(responseId, err);\n }\n handler.sendString(responseId, 'OK');\n }\n } else {\n handler.sendError(\n responseId,\n new Error(`DEL-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n handler.on('exists', (data, responseId) => {\n if (!data || !data.length) {\n return void handler.sendInteger(responseId, 0);\n }\n\n // Note: we only simulate single key existence check\n const { id, namespace, name } = this._normalizeId(data[0]);\n if (!id) {\n return void handler.sendError(responseId, new Error('id is null'));\n }\n if (namespace === this.namespaceObj) {\n let exists;\n try {\n exists = this._objectExists(id);\n } catch (e) {\n return void handler.sendError(responseId, e);\n }\n handler.sendInteger(responseId, exists ? 1 : 0);\n } else if (namespace === this.namespaceFile) {\n let exists;\n try {\n exists = this._fileExists(id, name);\n } catch (e) {\n return void handler.sendError(responseId, e);\n }\n handler.sendInteger(responseId, exists ? 1 : 0);\n } else if (namespace === this.namespaceSet) {\n // we are not using sets in simulator, so just say it exists\n return void handler.sendInteger(responseId, 1);\n } else {\n handler.sendError(responseId, new Error(`EXISTS-UNSUPPORTED for namespace ${namespace}`));\n }\n });\n\n // handle Redis \"SCAN\" request for objects namespace\n handler.on('scan', (data, responseId) => {\n if (!data || data.length < 3) {\n return void handler.sendArray(responseId, ['0', []]);\n }\n\n return this._handleScanOrKeys(handler, data[2], responseId, true);\n });\n\n // Handle Redis \"KEYS\" request for state namespace\n handler.on('keys', (data, responseId) => {\n if (!data || !data.length) {\n return void handler.sendArray(responseId, []);\n }\n\n return this._handleScanOrKeys(handler, data[0], responseId);\n });\n\n // commands for redis SETS, just dummies\n handler.on('sadd', (data, responseId) => {\n return void handler.sendInteger(responseId, 1);\n });\n\n handler.on('srem', (data, responseId) => {\n return void handler.sendInteger(responseId, 1);\n });\n\n handler.on('eval', (data, responseId) => {\n return void handler.sendNull(responseId);\n });\n\n handler.on('sscan', (data, responseId) => {\n // for file DB it does the same as scan but data looks different\n if (!data || data.length < 4) {\n return void handler.sendArray(responseId, ['0', []]);\n }\n\n return this._handleScanOrKeys(handler, data[3], responseId, true);\n });\n\n // Handle Redis \"PSUBSCRIBE\" request for state, log and session namespace\n handler.on('psubscribe', (data, responseId) => {\n const { id, namespace, name } = this._normalizeId(data[0]);\n if (!id) {\n return void handler.sendError(responseId, new Error('id is null'));\n }\n if (namespace === this.namespaceObj) {\n this._subscribeConfigForClient(handler, id);\n handler.sendArray(responseId, ['psubscribe', data[0], 1]);\n } else if (namespace === this.namespaceMeta) {\n this._subscribeMeta(handler, id);\n handler.sendArray(responseId, ['psubscribe', data[0], 1]);\n } else if (namespace === this.namespaceFile) {\n this._subscribeFileForClient(handler, id, name);\n handler.sendArray(responseId, ['psubscribe', data[0], 1]);\n } else {\n handler.sendError(\n responseId,\n new Error(`PSUBSCRIBE-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"UNSUBSCRIBE\" request for state, log and session namespace\n handler.on('punsubscribe', (data, responseId) => {\n const { id, namespace, name } = this._normalizeId(data[0]);\n if (!id) {\n return void handler.sendError(responseId, new Error('id is null'));\n }\n if (namespace === this.namespaceObj) {\n this._unsubscribeConfigForClient(handler, id);\n handler.sendArray(responseId, ['punsubscribe', data[0], 1]);\n } else if (namespace === this.namespaceFile) {\n this._unsubscribeFileForClient(handler, id, name);\n handler.sendArray(responseId, ['punsubscribe', data[0], 1]);\n } else {\n handler.sendError(\n responseId,\n new Error(`PUNSUBSCRIBE-UNSUPPORTED for namespace ${namespace}: Data=${JSON.stringify(data)}`),\n );\n }\n });\n\n // Handle Redis \"SUBSCRIBE\" ... currently mainly ignored\n handler.on('subscribe', (data, responseId) => {\n if (data[0].startsWith('__keyevent@')) {\n // we ignore these type of events because we publish expires anyway directly\n handler.sendArray(responseId, ['subscribe', data[0], 1]);\n } else {\n handler.sendError(responseId, new Error(`SUBSCRIBE-UNSUPPORTED for ${data[0]}`));\n }\n });\n\n // Handle Redis \"CONFIG\" ... currently mainly ignored\n handler.on('config', (data, responseId) => {\n const command = typeof data[0] === 'string' ? data[0].toLowerCase() : data[0].toString().toLowerCase();\n if (command === 'set' && data[1] === 'notify-keyspace-events') {\n // we ignore these type of commands for now, should only be to subscribe to keyspace events\n handler.sendString(responseId, 'OK');\n } else if (command === 'set' && data[1] === 'lua-time-limit') {\n // we ignore these type of commands for now, irrelevant\n handler.sendString(responseId, 'OK');\n } else {\n handler.sendError(responseId, new Error(`CONFIG-UNSUPPORTED for ${JSON.stringify(data)}`));\n }\n });\n\n // handle client SETNAME/GETNAME\n handler.on('client', (data, responseId) => {\n if (data[0] === 'setname' && typeof data[1] === 'string') {\n if (data[1] === '') {\n // on empty string redis sets null again and sends 'OK'\n connectionName = null;\n } else {\n connectionName = data[1];\n namespaceLog = connectionName;\n }\n handler.sendString(responseId, 'OK');\n } else if (data[0] === 'getname') {\n if (typeof connectionName === 'string' && connectionName !== '') {\n handler.sendString(responseId, connectionName);\n } else {\n // redis sends null if no name defined\n handler.sendNull(responseId);\n }\n } else if (typeof data[0] === 'string' && data[0].toLowerCase() === 'setinfo') {\n // ioredis >= 5.8 announces its lib-name/lib-ver via CLIENT SETINFO on connect.\n // Real Redis (>= 7.2) replies OK, so acknowledge it to stay compatible.\n handler.sendString(responseId, 'OK');\n } else {\n handler.sendError(responseId, new Error(`CLIENT-UNSUPPORTED for ${JSON.stringify(data)}`));\n }\n });\n\n handler.on('error', err => this.log.warn(`${namespaceLog} Redis objects: ${err}`));\n }\n\n /**\n * Return connected RedisHandlers/Connections\n *\n * @returns the currently connected RedisHandlers/Connections\n */\n getClients(): Record<string, RedisHandler> {\n return this.serverConnections;\n }\n\n /**\n * Destructor of the class. Called by shutting down.\n */\n async destroy(): Promise<void> {\n if (this.server) {\n Object.keys(this.serverConnections).forEach(s => {\n this.serverConnections[s].close();\n delete this.serverConnections[s];\n });\n\n await new Promise<void>(resolve => {\n if (!this.server) {\n return void resolve();\n }\n try {\n this.server.close(() => resolve());\n } catch (e) {\n console.log((e as Error).message);\n resolve();\n }\n });\n }\n\n await super.destroy();\n }\n\n /**\n * Get keys matching pattern and send it to given responseId, for \"SCAN\" and \"KEYS\" - Objects and files supported\n *\n * @param handler RedisHandler instance\n * @param pattern - pattern without namespace prefix\n * @param responseId - ID where response will be sent to\n * @param isScan - if used by \"SCAN\" this flag should be true\n */\n _handleScanOrKeys(handler: RedisHandler, pattern: string, responseId: number, isScan = false): void {\n const { id, namespace, name, isMeta } = this._normalizeId(pattern);\n // `_normalizeId` returns id === '' for a full-DB enumeration; only `null` means \"no id\".\n if (id === null) {\n return void handler.sendError(responseId, new Error('id is null'));\n }\n let response: string[] = [];\n if (namespace === this.namespaceObj || namespace === this.namespaceObjects) {\n try {\n response = this._getKeys(id).map(val => this.namespaceObj + val);\n } catch (e) {\n return void handler.sendError(responseId, e);\n }\n\n // if \"scan\", we send the cursor as first argument\n if (namespace !== this.namespaceObjects) {\n // When it was not the full DB namespace send out response\n return void handler.sendArray(responseId, isScan ? ['0', response] : response);\n }\n }\n if (namespace === this.namespaceFile || namespace === this.namespaceObjects) {\n // Handle request to get metadata keys\n if (isMeta === undefined) {\n let res: {\n file: string;\n stats: { size?: number };\n isDir: boolean;\n virtualFile?: boolean;\n notExists?: boolean;\n acl?: {\n read?: boolean;\n write?: boolean;\n owner: ioBroker.ObjectIDs.User;\n ownerGroup: ioBroker.ObjectIDs.Group;\n permissions: number;\n };\n modifiedAt?: number | undefined;\n createdAt?: undefined | number;\n }[];\n try {\n res = this._readDir(id, name);\n if (!res?.length) {\n res = [\n {\n file: '_data.json',\n stats: {},\n isDir: false,\n virtualFile: true,\n notExists: true,\n },\n ];\n }\n } catch (e) {\n if (!e.message.endsWith(utils.ERRORS.ERROR_NOT_FOUND)) {\n return void handler.sendError(responseId, new Error(`ERROR readDir id=${id}: ${e.message}`));\n }\n res = [];\n }\n let baseName = name || '';\n if (baseName.length && !baseName.endsWith('/')) {\n baseName += '/';\n }\n res.forEach(arr => {\n let entryId = id;\n if (arr.isDir) {\n if (entryId === '' || entryId === '*') {\n entryId = arr.file;\n arr.file = '_data.json'; // We return a \"virtual file\" to mark the directory as existing\n } else {\n arr.file += '/_data.json'; // We return a \"virtual file\" to mark the directory as existing\n }\n }\n // We need to simulate the Metadata here, so return both\n response.push(this.getFileId(entryId, baseName + arr.file, true));\n response.push(this.getFileId(entryId, baseName + arr.file, false));\n });\n handler.sendArray(responseId, isScan ? ['0', response] : response); // send out file or full db response\n } else {\n // such a request should never happen\n handler.sendArray(responseId, isScan ? ['0', []] : []); // send out file or full db response\n }\n } else if (namespace === this.namespaceSet) {\n handler.sendArray(responseId, isScan ? ['0', []] : []); // send out empty array, we have no sets\n } else {\n handler.sendError(\n responseId,\n new Error(`${isScan ? 'SCAN' : 'KEYS'}-UNSUPPORTED for namespace ${namespace}: Pattern=${pattern}`),\n );\n }\n }\n\n /**\n * Initialize RedisHandler for a new network connection\n *\n * @param socket Network socket\n */\n _initSocket(socket: net.Socket): void {\n if (this.settings.connection.enhancedLogging) {\n this.log.silly(`${this.namespace} Handling new Redis Objects connection`);\n }\n const options = {\n log: this.log,\n logScope: `${this.settings.namespace || ''} Objects`,\n handleAsBuffers: true,\n enhancedLogging: this.settings.connection.enhancedLogging,\n };\n const handler = new RedisHandler(socket, options);\n this._socketEvents(handler);\n\n this.serverConnections[`${socket.remoteAddress}:${socket.remotePort}`] = handler;\n socket.on('close', () => {\n if (this.serverConnections[`${socket.remoteAddress}:${socket.remotePort}`]) {\n delete this.serverConnections[`${socket.remoteAddress}:${socket.remotePort}`];\n }\n });\n }\n\n /**\n * Initialize Redis Server\n *\n * @param settings Settings object\n * @returns a promise that resolves once the Redis server is listening\n */\n _initRedisServer(settings: ConnectionOptions): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (settings.secure) {\n reject(new Error('Secure Redis unsupported for File-DB'));\n }\n try {\n this.server = net.createServer();\n this.server.on('error', err =>\n this.log.info(\n `${this.namespace} ${settings.secure ? 'Secure ' : ''} Error inMem-objects listening on port ${\n (settings.port as number) || 9001\n }: ${err}`,\n ),\n );\n this.server.on('connection', socket => this._initSocket(socket));\n\n this.server.listen(\n (settings.port as number) || 9001,\n settings.host === 'localhost'\n ? getLocalAddress()\n : settings.host\n ? (settings.host as string)\n : undefined,\n () => resolve(),\n );\n } catch (err) {\n reject(err as Error);\n }\n });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_db_base", "crypto", "namespace", "fs", "path", "utils", "data", "net"]
7
7
  }