@iobroker/db-objects-file 7.2.2 → 7.2.3-alpha.1-20260621-61726ea22

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/objects/objectsInMemFileDB.js"],
4
- "sourcesContent": ["/**\n * Object DB in memory - Server\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { InMemoryFileDB } from '@iobroker/db-base';\nimport { tools } from '@iobroker/db-base';\nimport { objectsUtils as utils } from '@iobroker/db-objects-redis';\nimport deepClone from 'deep-clone';\n\n/**\n * This class inherits InMemoryFileDB class and adds all relevant logic for objects\n * including the available methods for use by js-controller directly\n */\nexport class ObjectsInMemoryFileDB extends InMemoryFileDB {\n constructor(settings) {\n settings = settings || {};\n settings.fileDB = settings.fileDB || {\n fileName: 'objects.json',\n backupDirName: 'backup-objects',\n };\n super(settings);\n\n if (!this.change) {\n this.change = id => {\n this.log.silly(`${this.namespace} objects change: ${id} ${JSON.stringify(this.change)}`);\n };\n }\n\n this.META_ID = '**META**';\n this.fileOptions = {};\n this.files = {};\n this.writeTimer = null;\n this.writeIds = [];\n this.preserveSettings = ['custom'];\n this.defaultNewAcl = this.settings.defaultNewAcl || null;\n this.namespace = this.settings.namespace || this.settings.hostname || '';\n this.writeFileInterval =\n this.settings.connection && typeof this.settings.connection.writeFileInterval === 'number'\n ? parseInt(this.settings.connection.writeFileInterval)\n : 5_000;\n if (!settings.jsonlDB) {\n this.log.silly(`${this.namespace} Objects DB uses file write interval of ${this.writeFileInterval} ms`);\n }\n\n this.objectsDir = path.join(this.dataDir, 'files');\n\n // cached meta information for file operations\n this.existingMetaObjects = {};\n\n // Handle some < js-controller 2.0 broken objects and correct them\n for (const obj of Object.values(this.dataset)) {\n if (tools.isObject(obj) && obj.acl && obj.acl.permissions && !obj.acl.object) {\n obj.acl.object = obj.acl.permissions;\n delete obj.acl.permissions;\n }\n }\n\n // init default new acl\n const configObj = this.dataset['system.config'];\n if (configObj && configObj.common && configObj.common.defaultNewAcl) {\n this.defaultNewAcl = deepClone(configObj.common.defaultNewAcl);\n }\n }\n\n // internal functionality\n _normalizeFilename(name) {\n return name ? name.replace(/[/\\\\]+/g, '/') : name;\n }\n\n // -------------- FILE FUNCTIONS -------------------------------------------\n // internal functionality\n _saveFileSettings(id, force) {\n if (typeof id === 'boolean') {\n force = id;\n id = undefined;\n }\n\n id !== undefined && !this.writeIds.includes(id) && this.writeIds.push(id);\n\n this.writeTimer && clearTimeout(this.writeTimer);\n\n // if store immediately\n if (force) {\n this.writeTimer = null;\n // Store dirs description\n for (const writeId of this.writeIds) {\n const location = path.join(this.objectsDir, writeId, '_data.json');\n try {\n if (fs.existsSync(path.join(this.objectsDir, writeId))) {\n fs.writeFileSync(location, JSON.stringify(this.fileOptions[writeId]));\n }\n } catch (e) {\n this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);\n }\n }\n this.writeIds = [];\n } else {\n this.writeTimer = setTimeout(() => {\n // Store dirs description\n for (const writeId of this.writeIds) {\n const location = path.join(this.objectsDir, writeId, '_data.json');\n try {\n fs.writeFileSync(location, JSON.stringify(this.fileOptions[writeId]));\n } catch (e) {\n this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);\n }\n }\n this.writeIds = [];\n }, 1_000);\n }\n }\n\n // internal functionality\n _loadFileSettings(id) {\n if (!this.fileOptions[id]) {\n const location = path.join(this.objectsDir, id, '_data.json');\n if (fs.existsSync(location)) {\n try {\n this.fileOptions[id] = fs.readJSONSync(location);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot parse ${location}: ${e.message}`);\n this.fileOptions[id] = {};\n }\n let corrected = false;\n Object.keys(this.fileOptions[id]).forEach(filename => {\n const normalized = this._normalizeFilename(filename);\n if (normalized !== filename) {\n const options = this.fileOptions[id][filename];\n delete this.fileOptions[id][filename];\n this.fileOptions[id][normalized] = options;\n corrected = true;\n }\n if (corrected) {\n try {\n fs.writeFileSync(location, JSON.stringify(this.fileOptions[id]));\n } catch (e) {\n this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);\n }\n }\n });\n } else {\n this.fileOptions[id] = {};\n }\n }\n }\n\n // server only functionality\n syncFileDirectory(limitId) {\n const resNotifies = [];\n let resSynced = 0;\n\n function getAllFiles(dir) {\n let results = [];\n const list = fs.readdirSync(dir);\n list.forEach(file => {\n file = `${dir}/${file}`;\n const stat = fs.statSync(file);\n if (stat && stat.isDirectory()) {\n /* Recurse into a subdirectory */\n results = results.concat(getAllFiles(file));\n } else {\n /* Is a file */\n results.push(file);\n }\n });\n return results;\n }\n\n const res = this._getObjectView('system', 'meta', null);\n\n // collect meta ids to generate warning if non existing\n const metaIds = res.rows.map(obj => obj.id).filter(id => !limitId || limitId === id);\n\n if (!fs.existsSync(this.objectsDir)) {\n return {\n numberSuccess: resSynced,\n notifications: resNotifies,\n };\n }\n const baseDirs = fs.readdirSync(this.objectsDir);\n baseDirs.forEach(dir => {\n let dirSynced = 0;\n if (dir === '..' || dir === '.') {\n return;\n }\n const dirPath = path.join(this.objectsDir, dir);\n const stat = fs.statSync(dirPath);\n if (!stat.isDirectory()) {\n return;\n }\n if (limitId && dir !== limitId) {\n return;\n }\n if (!metaIds.includes(dir)) {\n resNotifies.push(\n `Ignoring Directory \"${dir}\" because officially not created as meta object. Please remove directory!`,\n );\n return;\n }\n this._loadFileSettings(dir);\n const files = getAllFiles(dirPath);\n files.forEach(file => {\n const localFile = file.substr(dirPath.length + 1);\n if (localFile === '_data.json') {\n return;\n }\n if (!this.fileOptions[dir][localFile]) {\n const fileStat = fs.statSync(file);\n const ext = path.extname(localFile);\n const mime = utils.getMimeType(ext);\n const _mimeType = mime.mimeType;\n const isBinary = mime.isBinary;\n\n this.fileOptions[dir][localFile] = {\n createdAt: fileStat.ctimeMs,\n acl: {\n owner: (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) ||\n utils.CONSTS.ACCESS_USER_RW |\n utils.CONSTS.ACCESS_GROUP_READ |\n utils.CONSTS.ACCESS_EVERY_READ, // 0x644\n },\n mimeType: _mimeType,\n binary: isBinary,\n modifiedAt: fileStat.mtimeMs,\n };\n dirSynced++;\n }\n });\n this._saveFileSettings(dir);\n resSynced += dirSynced;\n dirSynced && resNotifies.push(`Added ${dirSynced} Files in Directory \"${dir}\"`);\n });\n return {\n numberSuccess: resSynced,\n notifications: resNotifies,\n };\n }\n\n // needed by server\n _writeFile(id, name, data, options) {\n if (typeof options === 'string') {\n options = { mimeType: options };\n }\n if (options && options.acl) {\n options.acl = null;\n }\n\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n\n options = options || {};\n\n this._loadFileSettings(id);\n\n this.files[id] = this.files[id] || {};\n\n try {\n if (!fs.existsSync(this.objectsDir)) {\n fs.mkdirSync(this.objectsDir);\n }\n if (!fs.existsSync(path.join(this.objectsDir, id))) {\n fs.mkdirSync(path.join(this.objectsDir, id));\n }\n } catch (e) {\n this.log.error(\n `${this.namespace} Cannot create directories: ${path.join(this.objectsDir, id)}: ${e.message}`,\n );\n this.log.error(\n `${this.namespace} Check the permissions! Or run installation fixer or \"iobroker fix\" command!`,\n );\n throw e;\n }\n\n const ext = path.extname(name);\n const mime = utils.getMimeType(ext);\n const _mimeType = mime.mimeType;\n const isBinary = mime.isBinary;\n\n this.fileOptions[id][name] = this.fileOptions[id][name] || { createdAt: Date.now() };\n this.fileOptions[id][name].acl = this.fileOptions[id][name].acl || {\n owner: options.user || (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup:\n options.group ||\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||\n utils.CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n options.mode ||\n (this.defaultNewAcl && this.defaultNewAcl.file) ||\n utils.CONSTS.ACCESS_USER_RW | utils.CONSTS.ACCESS_GROUP_READ | utils.CONSTS.ACCESS_EVERY_READ, // 0x644\n };\n\n this.fileOptions[id][name].mimeType = options.mimeType || _mimeType;\n this.fileOptions[id][name].binary = isBinary;\n this.fileOptions[id][name].acl.ownerGroup =\n this.fileOptions[id][name].acl.ownerGroup ||\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||\n utils.CONSTS.SYSTEM_ADMIN_GROUP;\n this.fileOptions[id][name].modifiedAt = Date.now();\n\n try {\n // Create directories if complex structure\n fs.ensureDirSync(path.join(this.objectsDir, id, path.dirname(name)));\n // Store file\n fs.writeFileSync(path.join(this.objectsDir, id, name), data, {\n flag: 'w',\n encoding: isBinary ? 'binary' : 'utf8',\n });\n\n if (isBinary) {\n // Reload by read\n delete this.files[id][name];\n } else {\n this.files[id][name] = data;\n }\n\n // Store dir description\n this._saveFileSettings(id);\n } catch (e) {\n this.log.error(\n `${this.namespace} Cannot write files: ${path.join(this.objectsDir, id, name)}: ${e.message}`,\n );\n throw e;\n }\n\n setImmediate(\n (name, size) => {\n // publish event in states\n this.log.silly(`${this.namespace} memory publish ${id} ${JSON.stringify({ name, file: true, size })}`);\n this.publishAll('files', `${id}$%$${name}`, size);\n },\n name,\n data.byteLength,\n );\n }\n\n // needed by server\n _readFile(id, name, options) {\n if (options && options.acl) {\n options.acl = null;\n }\n\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n\n options = options || {};\n try {\n this._loadFileSettings(id);\n\n this.files[id] = this.files[id] || {};\n\n if (!this.files[id][name] || this.settings.connection.noFileCache || options.noFileCache) {\n const location = path.join(this.objectsDir, id, name);\n if (fs.existsSync(location)) {\n // Create description object if not exists\n this.fileOptions[id][name] = this.fileOptions[id][name] || {\n acl: {\n owner: (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 if (typeof this.fileOptions[id][name] !== 'object') {\n this.fileOptions[id][name] = {\n mimeType: this.fileOptions[id][name],\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\n this.files[id][name] = fs.readFileSync(location);\n if (this.fileOptions[id][name].binary === undefined) {\n const ext = path.extname(name);\n const mimeType = utils.getMimeType(ext);\n this.fileOptions[id][name].binary = mimeType.isBinary;\n this.fileOptions[id][name].mimeType = mimeType.mimeType;\n }\n\n if (!this.fileOptions[id][name].binary) {\n if (this.files[id][name]) {\n this.files[id][name] = this.files[id][name].toString();\n }\n }\n } else {\n if (this.fileOptions[id][name] !== undefined) {\n delete this.fileOptions[id][name];\n }\n if (this.files[id][name] !== undefined) {\n delete this.files[id][name];\n }\n }\n }\n\n if (this.fileOptions[id][name] && !this.fileOptions[id][name].acl) {\n // all files belong to admin by default, but everyone can edit it\n this.fileOptions[id][name].acl = {\n owner: (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup:\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) || utils.CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||\n utils.CONSTS.ACCESS_USER_ALL | utils.CONSTS.ACCESS_GROUP_ALL | utils.CONSTS.ACCESS_EVERY_RW, // 776\n };\n }\n\n if (this.fileOptions[id][name] !== null && this.fileOptions[id][name] !== undefined) {\n if (!this.fileOptions[id][name].mimeType) {\n const _ext = path.extname(name);\n const _mimeType = utils.getMimeType(_ext);\n this.fileOptions[id][name].mimeType = _mimeType.mimeType;\n }\n return {\n fileContent: this.files[id][name],\n fileMime: this.fileOptions[id][name].mimeType,\n };\n }\n } catch (e) {\n this.log.warn(`${this.namespace} Cannot read file ${id} / ${name}: ${e.message}`);\n throw e;\n }\n throw new Error(utils.ERRORS.ERROR_NOT_FOUND);\n }\n\n /**\n * Check if given object exists\n *\n * @param id id of the object\n * @returns if the object exists\n */\n // needed by server\n _objectExists(id) {\n if (!id || typeof id !== 'string') {\n throw new Error(`invalid id ${JSON.stringify(id)}`);\n }\n\n try {\n // check if the id exists\n return Object.prototype.hasOwnProperty.call(this.dataset, id);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot check object existence of \"${id}\": ${e.message}`);\n throw new Error(`Cannot check object existence of \"${id}\": ${e.message}`);\n }\n }\n\n /**\n * Check if given file exists\n *\n * @param id id of the namespace\n * @param [name] name of the file\n * @returns\n */\n // needed by server\n _fileExists(id, name) {\n if (typeof name !== 'string') {\n name = '';\n }\n\n const location = path.join(this.objectsDir, id, name);\n\n try {\n const stat = fs.statSync(location);\n return stat.isFile();\n } catch (e) {\n if (e.code !== 'ENOENT') {\n this.log.error(`${this.namespace} Cannot check file existence of \"${location}\": ${e.message}`);\n throw new Error(`Cannot check file existence of \"${location}\": ${e.message}`);\n }\n return false;\n }\n }\n\n /**\n * Check if given directory exists\n *\n * @param id id of the namespace\n * @param [name] name of the directory\n * @returns\n */\n // special functionality only for Server (used together with SyncFileDirectory)\n dirExists(id, name) {\n if (typeof name !== 'string') {\n name = '';\n }\n\n const location = path.join(this.objectsDir, id, name);\n\n try {\n const stat = fs.statSync(location);\n return stat.isDirectory();\n } catch (e) {\n if (e.code !== 'ENOENT') {\n this.log.error(`${this.namespace} Cannot check directory existence of \"${location}\": ${e.message}`);\n throw new Error(`Cannot check directory existence of \"${location}\": ${e.message}`);\n }\n return false;\n }\n }\n\n // needed by server\n _unlink(id, name) {\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n\n this._loadFileSettings(id);\n\n const location = path.join(this.objectsDir, id, name);\n if (fs.existsSync(location)) {\n const stat = fs.statSync(location);\n\n if (stat.isDirectory()) {\n // read all entries and delete every one\n fs.readdirSync(location).forEach(dir => this._unlink(id, `${name}/${dir}`));\n\n this.log.debug(`Delete directory ${path.join(id, name)}`);\n try {\n fs.removeSync(location);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot delete directory \"${path.join(id, name)}\": ${e.message}`);\n throw e;\n }\n\n if (this.fileOptions[id]) {\n delete this.fileOptions[id];\n }\n if (this.files[id] && this.files[id]) {\n delete this.files[id];\n }\n } else {\n this.log.debug(`Delete file ${path.join(id, name)}`);\n try {\n fs.removeSync(location);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot delete file \"${path.join(id, name)}\": ${e.message}`);\n throw e;\n }\n\n if (this.fileOptions[id][name]) {\n delete this.fileOptions[id][name];\n }\n if (this.files[id] && this.files[id][name]) {\n delete this.files[id][name];\n }\n\n // Store dir description\n this._saveFileSettings(id, true);\n }\n\n setImmediate(\n (id, name) => {\n // publish event in states\n this.log.silly(\n `${this.namespace} memory publish ${id} ${JSON.stringify({ name, file: true, size: null })}`,\n );\n this.publishAll('files', `${id}$%$${name}`, null);\n },\n id,\n name,\n );\n }\n }\n\n // needed by server\n _readDir(id, name, options) {\n if (options && options.acl) {\n options.acl = null;\n }\n if ((id === '' || id === '/' || id === '*') && (name === '' || name === '*')) {\n // read root of xxx-data/files\n } else {\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n }\n\n options = options || {};\n // Find all files and directories starts with name\n const _files = [];\n\n if (id && id === '*') {\n id = '';\n }\n if (name && name[name.length - 1] !== '/') {\n name += '/';\n }\n\n this._loadFileSettings(id);\n\n const len = name ? name.length : 0;\n for (const f of Object.keys(this.fileOptions[id])) {\n if (!name || f.substring(0, len) === name) {\n let rest = f.substring(len);\n rest = rest.split('/', 2);\n if (rest[0] && _files.indexOf(rest[0]) === -1) {\n _files.push(rest[0]);\n }\n }\n }\n\n const location = path.join(this.objectsDir, id, name);\n if (fs.existsSync(location) && fs.statSync(location).isDirectory()) {\n const dirFiles = fs.readdirSync(location);\n for (let i = 0; i < dirFiles.length; i++) {\n if (dirFiles[i] === '..' || dirFiles[i] === '.') {\n continue;\n }\n if (dirFiles[i] !== '_data.json' && _files.indexOf(dirFiles[i]) === -1) {\n _files.push(dirFiles[i]);\n }\n }\n } else {\n throw new Error(utils.ERRORS.ERROR_NOT_FOUND);\n }\n\n _files.sort();\n const res = [];\n for (const file of _files) {\n if (file === '..' || file === '.') {\n continue;\n }\n if (fs.existsSync(path.join(location, file))) {\n try {\n const stats = fs.statSync(path.join(location, file));\n const acl =\n this.fileOptions[id][name + file] && this.fileOptions[id][name + file].acl\n ? deepClone(this.fileOptions[id][name + file].acl) // copy settings\n : {\n read: true,\n write: true,\n owner:\n (this.defaultNewAcl && this.defaultNewAcl.owner) ||\n 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_RW |\n utils.CONSTS.ACCESS_GROUP_READ |\n utils.CONSTS.ACCESS_EVERY_READ,\n };\n\n // if filter for user\n if (options.filter && acl) {\n // If user may not write\n if (!options.acl.file.write) {\n // write\n acl.permissions &= ~(\n utils.CONSTS.ACCESS_USER_WRITE |\n utils.CONSTS.ACCESS_GROUP_WRITE |\n utils.CONSTS.ACCESS_EVERY_WRITE\n );\n }\n // If user may not read\n if (!options.acl.file.read) {\n // read\n acl.permissions &= ~(\n utils.CONSTS.ACCESS_USER_READ |\n utils.CONSTS.ACCESS_GROUP_READ |\n utils.CONSTS.ACCESS_EVERY_READ\n );\n }\n\n if (\n options.user !== utils.CONSTS.SYSTEM_ADMIN_USER &&\n options.groups.includes(utils.CONSTS.SYSTEM_ADMIN_GROUP)\n ) {\n if (acl.owner !== options.user) {\n // Check if the user is in the group\n if (options.groups.includes(acl.ownerGroup)) {\n // Check group rights\n if (!(acl.permissions & utils.CONSTS.ACCESS_GROUP_RW)) {\n continue;\n }\n acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_GROUP_READ);\n acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_GROUP_WRITE);\n } else {\n // everybody\n if (!(acl.permissions & utils.CONSTS.ACCESS_EVERY_RW)) {\n continue;\n }\n acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_EVERY_READ);\n acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_EVERY_WRITE);\n }\n } else {\n // Check user rights\n if (!(acl.permissions & utils.CONSTS.ACCESS_USER_RW)) {\n continue;\n }\n acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_USER_READ);\n acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_USER_WRITE);\n }\n } else {\n acl.read = true;\n acl.write = true;\n }\n }\n\n res.push({\n file,\n stats: stats,\n isDir: stats.isDirectory(),\n acl: acl,\n modifiedAt: this.fileOptions[id][name + file]\n ? this.fileOptions[id][name + file].modifiedAt\n : undefined,\n createdAt: this.fileOptions[id][name + file]\n ? this.fileOptions[id][name + file].createdAt\n : undefined,\n });\n } catch (e) {\n this.log.error(\n `${this.namespace} Cannot read permissions of ${path.join(this.objectsDir, id, name, file)}: ${\n e.message\n }`,\n );\n }\n }\n }\n\n return res;\n }\n\n // needed by server\n _rename(id, oldName, newName) {\n const _path = utils.sanitizePath(id, oldName);\n id = _path.id;\n oldName = _path.name;\n if (newName[0] === '/') {\n newName = newName.substring(1);\n }\n\n this._loadFileSettings(id);\n\n if (fs.existsSync(path.join(this.objectsDir, id, oldName))) {\n fs.renameSync(path.join(this.objectsDir, id, oldName), path.join(this.objectsDir, id, newName));\n } else {\n throw new Error(utils.ERRORS.ERROR_NOT_FOUND);\n }\n\n Object.keys(this.fileOptions[id]).forEach(name => {\n const type = this.fileOptions[id][name];\n if (name.startsWith(oldName)) {\n delete this.fileOptions[id][name];\n this.fileOptions[id][name.replace(oldName, newName)] = type;\n }\n });\n Object.keys(this.files[id]).forEach(name => {\n const data = this.files[id][name];\n if (name.startsWith(oldName)) {\n delete this.files[id][name];\n this.files[id][name.replace(oldName, newName)] = data;\n }\n });\n this._saveFileSettings(id, true);\n }\n\n // internal functionality\n _clone(obj) {\n if (obj === null || obj === undefined || !tools.isObject(obj)) {\n return obj;\n }\n\n const temp = obj.constructor(); // changed\n\n for (const key of Object.keys(obj)) {\n temp[key] = this._clone(obj[key]);\n }\n return temp;\n }\n\n _subscribeMeta(client, pattern) {\n this.handleSubscribe(client, 'meta', pattern);\n }\n\n // needed by server\n _subscribeConfigForClient(client, pattern) {\n this.handleSubscribe(client, 'objects', pattern);\n }\n\n // needed by server\n _unsubscribeConfigForClient(client, pattern) {\n this.handleUnsubscribe(client, 'objects', pattern); // ignore options => unsubscribe may everyone\n }\n\n // needed by server\n _subscribeFileForClient(client, id, pattern) {\n if (Array.isArray(pattern)) {\n pattern.forEach(pattern => this.handleSubscribe(client, 'files', `${id}$%$${pattern}`));\n } else {\n this.handleSubscribe(client, 'files', `${id}$%$${pattern}`);\n }\n }\n\n // needed by server\n _unsubscribeFileForClient(client, id, pattern) {\n if (Array.isArray(pattern)) {\n pattern.forEach(pattern => this.handleUnsubscribe(client, 'files', `${id}$%$${pattern}`));\n } else {\n this.handleUnsubscribe(client, 'files', `${id}$%$${pattern}`);\n }\n }\n\n // needed by server\n _getObject(id) {\n return this.dataset[id];\n }\n\n // needed by server\n _getKeys(pattern) {\n const r = new RegExp(tools.pattern2RegEx(pattern));\n const result = Object.keys(this.dataset).filter(id => r.test(id) && id !== this.META_ID);\n result.sort();\n return result;\n }\n\n // needed by server\n _getObjects(keys) {\n if (!keys) {\n throw new Error('no keys');\n }\n\n return keys.map(id => this.dataset[id]);\n }\n\n _ensureMetaDict() {\n let meta = this.dataset[this.META_ID];\n if (!meta) {\n meta = {};\n this.dataset[this.META_ID] = meta;\n }\n return meta;\n }\n\n /**\n * Get value of given meta id\n *\n * @param id\n * @returns\n */\n getMeta(id) {\n const meta = this._ensureMetaDict();\n return meta[id];\n }\n\n /**\n * Sets given value to id in metaNamespace\n *\n * @param id\n * @param value\n */\n setMeta(id, value) {\n const meta = this._ensureMetaDict();\n meta[id] = value;\n // Make sure the object gets re-written, especially when using an external DB\n this.dataset[this.META_ID] = meta;\n\n setImmediate(() => {\n // publish event in states\n this.log.silly(`${this.namespace} memory publish meta ${id} ${value}`);\n this.publishAll('meta', id, value);\n });\n\n if (!this.stateTimer) {\n this.stateTimer = setTimeout(() => this.saveState(), this.writeFileInterval);\n }\n }\n\n // needed by server\n _setObjectDirect(id, obj) {\n this.dataset[id] = obj;\n\n // object updated -> if type changed to meta -> cache\n if (obj.type === 'meta' && this.existingMetaObjects[id] === false) {\n this.existingMetaObjects[id] = true;\n }\n\n setImmediate(() => this.publishAll('objects', id, obj));\n\n this.stateTimer = this.stateTimer || setTimeout(() => this.saveState(), this.writeFileInterval);\n }\n\n /**\n * Delete the given object from the dataset\n *\n * @param id unique id of the object\n */\n _delObject(id) {\n const obj = this.dataset[id];\n if (!obj) {\n // Not existent, so goal reached :-)\n return;\n }\n\n if (obj.common?.dontDelete) {\n throw new Error('Object is marked as non deletable');\n }\n\n delete this.dataset[id];\n\n // object has been deleted -> remove from cached meta if there\n if (this.existingMetaObjects[id]) {\n this.existingMetaObjects[id] = false;\n }\n\n setImmediate(() => this.publishAll('objects', id, null));\n\n if (!this.stateTimer) {\n this.stateTimer = setTimeout(() => this.saveState(), this.writeFileInterval);\n }\n }\n\n // internal functionality\n _applyView(func, params) {\n const result = {\n rows: [],\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function _emit_(id, obj) {\n result.rows.push({ id: id, value: obj });\n }\n\n const f = eval(`(${func.map.replace(/emit/g, '_emit_')})`);\n\n for (const [id, obj] of Object.entries(this.dataset)) {\n if (params) {\n if (params.startkey && id < params.startkey) {\n continue;\n }\n if (params.endkey && id > params.endkey) {\n continue;\n }\n }\n\n if (obj) {\n try {\n f(obj);\n } catch (e) {\n this.log.warn(`${this.namespace} Cannot execute map: ${e.message}`);\n }\n }\n }\n // Calculate max\n if (func.reduce === '_stats') {\n let max = null;\n for (const row of result.rows) {\n if (max === null || row.value > max) {\n max = row.value;\n }\n }\n if (max !== null) {\n result.rows = [{ id: '_stats', value: { max: max } }];\n } else {\n result.rows = [];\n }\n }\n\n return result;\n }\n\n // needed by server\n _getObjectView(design, search, params) {\n const designObj = this.dataset[`_design/${design}`];\n if (!designObj) {\n this.log.error(`${this.namespace} Cannot find view \"${design}\"`);\n throw new Error(`Cannot find view \"${design}\"`);\n }\n if (!(designObj.views && designObj.views[search])) {\n this.log.warn(`${this.namespace} Cannot find search \"${search}\" in \"${design}\"`);\n throw new Error(`Cannot find search \"${search}\" in \"${design}\"`);\n }\n return this._applyView(designObj.views[search], params);\n }\n\n /**\n * Destructor of the class. Called by shutting down.\n */\n async destroy() {\n await super.destroy();\n\n this._saveFileSettings(true);\n if (this.stateTimer) {\n clearTimeout(this.stateTimer);\n this.stateTimer = null;\n }\n if (this.writeTimer) {\n clearTimeout(this.writeTimer);\n this.writeTimer = null;\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Object DB in memory - Server\n *\n * Copyright 2013-2026 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { InMemoryFileDB } from '@iobroker/db-base';\nimport { tools } from '@iobroker/db-base';\nimport { objectsUtils as utils } from '@iobroker/db-objects-redis';\nimport deepClone from 'deep-clone';\n\n/**\n * This class inherits InMemoryFileDB class and adds all relevant logic for objects\n * including the available methods for use by js-controller directly\n */\nexport class ObjectsInMemoryFileDB extends InMemoryFileDB {\n /**\n * @param settings Settings for the objects database\n */\n constructor(settings) {\n settings ||= {};\n settings.fileDB ||= {\n fileName: 'objects.json',\n backupDirName: 'backup-objects',\n };\n super(settings);\n\n if (!this.change) {\n this.change = id => {\n this.log.silly(`${this.namespace} objects change: ${id} ${JSON.stringify(this.change)}`);\n };\n }\n\n this.META_ID = '**META**';\n this.fileOptions = {};\n this.files = {};\n this.writeTimer = null;\n this.writeIds = [];\n this.preserveSettings = ['custom'];\n this.defaultNewAcl = this.settings.defaultNewAcl || null;\n this.namespace = this.settings.namespace || this.settings.hostname || '';\n this.writeFileInterval =\n this.settings.connection && typeof this.settings.connection.writeFileInterval === 'number'\n ? parseInt(this.settings.connection.writeFileInterval)\n : 5_000;\n if (!settings.jsonlDB) {\n this.log.silly(`${this.namespace} Objects DB uses file write interval of ${this.writeFileInterval} ms`);\n }\n\n this.objectsDir = path.join(this.dataDir, 'files');\n\n // cached meta information for file operations\n this.existingMetaObjects = {};\n\n // Handle some < js-controller 2.0 broken objects and correct them\n for (const obj of Object.values(this.dataset)) {\n if (tools.isObject(obj) && obj.acl && obj.acl.permissions && !obj.acl.object) {\n obj.acl.object = obj.acl.permissions;\n delete obj.acl.permissions;\n }\n }\n\n // init default new acl\n const configObj = this.dataset['system.config'];\n if (configObj && configObj.common && configObj.common.defaultNewAcl) {\n this.defaultNewAcl = deepClone(configObj.common.defaultNewAcl);\n }\n }\n\n /**\n * Normalize a file name by collapsing slashes and backslashes into a single forward slash\n *\n * @param name The file name to normalize\n */\n _normalizeFilename(name) {\n return name ? name.replace(/[/\\\\]+/g, '/') : name;\n }\n\n // -------------- FILE FUNCTIONS -------------------------------------------\n /**\n * Schedule writing the file settings (_data.json) to disk\n *\n * @param id The object ID whose file settings should be saved, or a boolean used as the force flag\n * @param force If true, write the settings immediately instead of debounced\n */\n _saveFileSettings(id, force) {\n if (typeof id === 'boolean') {\n force = id;\n id = undefined;\n }\n\n id !== undefined && !this.writeIds.includes(id) && this.writeIds.push(id);\n\n this.writeTimer && clearTimeout(this.writeTimer);\n\n // if store immediately\n if (force) {\n this.writeTimer = null;\n // Store dirs description\n for (const writeId of this.writeIds) {\n const location = path.join(this.objectsDir, writeId, '_data.json');\n try {\n if (fs.existsSync(path.join(this.objectsDir, writeId))) {\n fs.writeFileSync(location, JSON.stringify(this.fileOptions[writeId]));\n }\n } catch (e) {\n this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);\n }\n }\n this.writeIds = [];\n } else {\n this.writeTimer = setTimeout(() => {\n // Store dirs description\n for (const writeId of this.writeIds) {\n const location = path.join(this.objectsDir, writeId, '_data.json');\n try {\n fs.writeFileSync(location, JSON.stringify(this.fileOptions[writeId]));\n } catch (e) {\n this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);\n }\n }\n this.writeIds = [];\n }, 1_000);\n }\n }\n\n /**\n * Load the file settings (_data.json) for the given object ID into memory\n *\n * @param id The object ID whose file settings should be loaded\n */\n _loadFileSettings(id) {\n if (!this.fileOptions[id]) {\n const location = path.join(this.objectsDir, id, '_data.json');\n if (fs.existsSync(location)) {\n try {\n this.fileOptions[id] = fs.readJSONSync(location);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot parse ${location}: ${e.message}`);\n this.fileOptions[id] = {};\n }\n let corrected = false;\n Object.keys(this.fileOptions[id]).forEach(filename => {\n const normalized = this._normalizeFilename(filename);\n if (normalized !== filename) {\n const options = this.fileOptions[id][filename];\n delete this.fileOptions[id][filename];\n this.fileOptions[id][normalized] = options;\n corrected = true;\n }\n if (corrected) {\n try {\n fs.writeFileSync(location, JSON.stringify(this.fileOptions[id]));\n } catch (e) {\n this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);\n }\n }\n });\n } else {\n this.fileOptions[id] = {};\n }\n }\n }\n\n /**\n * Synchronize the in-memory file metadata with the files actually present on disk (server only)\n *\n * @param limitId Optional object ID to limit the synchronization to\n */\n syncFileDirectory(limitId) {\n const resNotifies = [];\n let resSynced = 0;\n\n function getAllFiles(dir) {\n let results = [];\n const list = fs.readdirSync(dir);\n list.forEach(file => {\n file = `${dir}/${file}`;\n const stat = fs.statSync(file);\n if (stat && stat.isDirectory()) {\n /* Recurse into a subdirectory */\n results = results.concat(getAllFiles(file));\n } else {\n /* Is a file */\n results.push(file);\n }\n });\n return results;\n }\n\n const res = this._getObjectView('system', 'meta', null);\n\n // collect meta ids to generate warning if non existing\n const metaIds = res.rows.map(obj => obj.id).filter(id => !limitId || limitId === id);\n\n if (!fs.existsSync(this.objectsDir)) {\n return {\n numberSuccess: resSynced,\n notifications: resNotifies,\n };\n }\n const baseDirs = fs.readdirSync(this.objectsDir);\n baseDirs.forEach(dir => {\n let dirSynced = 0;\n if (dir === '..' || dir === '.') {\n return;\n }\n const dirPath = path.join(this.objectsDir, dir);\n const stat = fs.statSync(dirPath);\n if (!stat.isDirectory()) {\n return;\n }\n if (limitId && dir !== limitId) {\n return;\n }\n if (!metaIds.includes(dir)) {\n resNotifies.push(\n `Ignoring Directory \"${dir}\" because officially not created as meta object. Please remove directory!`,\n );\n return;\n }\n this._loadFileSettings(dir);\n const files = getAllFiles(dirPath);\n files.forEach(file => {\n const localFile = file.substr(dirPath.length + 1);\n if (localFile === '_data.json') {\n return;\n }\n if (!this.fileOptions[dir][localFile]) {\n const fileStat = fs.statSync(file);\n const ext = path.extname(localFile);\n const mime = utils.getMimeType(ext);\n const _mimeType = mime.mimeType;\n const isBinary = mime.isBinary;\n\n this.fileOptions[dir][localFile] = {\n createdAt: fileStat.ctimeMs,\n acl: {\n owner: (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) ||\n utils.CONSTS.ACCESS_USER_RW |\n utils.CONSTS.ACCESS_GROUP_READ |\n utils.CONSTS.ACCESS_EVERY_READ, // 0x644\n },\n mimeType: _mimeType,\n binary: isBinary,\n modifiedAt: fileStat.mtimeMs,\n };\n dirSynced++;\n }\n });\n this._saveFileSettings(dir);\n resSynced += dirSynced;\n dirSynced && resNotifies.push(`Added ${dirSynced} Files in Directory \"${dir}\"`);\n });\n return {\n numberSuccess: resSynced,\n notifications: resNotifies,\n };\n }\n\n /**\n * Write a file into an object's file storage (used by the server)\n *\n * @param id The object ID owning the file\n * @param name The file name\n * @param data The file content\n * @param options Optional write options, or the mime type as a string\n */\n _writeFile(id, name, data, options) {\n if (typeof options === 'string') {\n options = { mimeType: options };\n }\n if (options && options.acl) {\n options.acl = null;\n }\n\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n\n options = options || {};\n\n this._loadFileSettings(id);\n\n this.files[id] = this.files[id] || {};\n\n try {\n if (!fs.existsSync(this.objectsDir)) {\n fs.mkdirSync(this.objectsDir);\n }\n if (!fs.existsSync(path.join(this.objectsDir, id))) {\n fs.mkdirSync(path.join(this.objectsDir, id));\n }\n } catch (e) {\n this.log.error(\n `${this.namespace} Cannot create directories: ${path.join(this.objectsDir, id)}: ${e.message}`,\n );\n this.log.error(\n `${this.namespace} Check the permissions! Or run installation fixer or \"iobroker fix\" command!`,\n );\n throw e;\n }\n\n const ext = path.extname(name);\n const mime = utils.getMimeType(ext);\n const _mimeType = mime.mimeType;\n const isBinary = mime.isBinary;\n\n this.fileOptions[id][name] = this.fileOptions[id][name] || { createdAt: Date.now() };\n this.fileOptions[id][name].acl = this.fileOptions[id][name].acl || {\n owner: options.user || (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup:\n options.group ||\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||\n utils.CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n options.mode ||\n (this.defaultNewAcl && this.defaultNewAcl.file) ||\n utils.CONSTS.ACCESS_USER_RW | utils.CONSTS.ACCESS_GROUP_READ | utils.CONSTS.ACCESS_EVERY_READ, // 0x644\n };\n\n this.fileOptions[id][name].mimeType = options.mimeType || _mimeType;\n this.fileOptions[id][name].binary = isBinary;\n this.fileOptions[id][name].acl.ownerGroup =\n this.fileOptions[id][name].acl.ownerGroup ||\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||\n utils.CONSTS.SYSTEM_ADMIN_GROUP;\n this.fileOptions[id][name].modifiedAt = Date.now();\n\n try {\n // Create directories if complex structure\n fs.ensureDirSync(path.join(this.objectsDir, id, path.dirname(name)));\n // Store file\n fs.writeFileSync(path.join(this.objectsDir, id, name), data, {\n flag: 'w',\n encoding: isBinary ? 'binary' : 'utf8',\n });\n\n if (isBinary) {\n // Reload by read\n delete this.files[id][name];\n } else {\n this.files[id][name] = data;\n }\n\n // Store dir description\n this._saveFileSettings(id);\n } catch (e) {\n this.log.error(\n `${this.namespace} Cannot write files: ${path.join(this.objectsDir, id, name)}: ${e.message}`,\n );\n throw e;\n }\n\n setImmediate(\n (name, size) => {\n // publish event in states\n this.log.silly(`${this.namespace} memory publish ${id} ${JSON.stringify({ name, file: true, size })}`);\n this.publishAll('files', `${id}$%$${name}`, size);\n },\n name,\n data.byteLength,\n );\n }\n\n /**\n * Read a file from an object's file storage (used by the server)\n *\n * @param id The object ID owning the file\n * @param name The file name\n * @param options Optional read options\n */\n _readFile(id, name, options) {\n if (options && options.acl) {\n options.acl = null;\n }\n\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n\n options = options || {};\n try {\n this._loadFileSettings(id);\n\n this.files[id] = this.files[id] || {};\n\n if (!this.files[id][name] || this.settings.connection.noFileCache || options.noFileCache) {\n const location = path.join(this.objectsDir, id, name);\n if (fs.existsSync(location)) {\n // Create description object if not exists\n this.fileOptions[id][name] = this.fileOptions[id][name] || {\n acl: {\n owner: (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 if (typeof this.fileOptions[id][name] !== 'object') {\n this.fileOptions[id][name] = {\n mimeType: this.fileOptions[id][name],\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\n this.files[id][name] = fs.readFileSync(location);\n if (this.fileOptions[id][name].binary === undefined) {\n const ext = path.extname(name);\n const mimeType = utils.getMimeType(ext);\n this.fileOptions[id][name].binary = mimeType.isBinary;\n this.fileOptions[id][name].mimeType = mimeType.mimeType;\n }\n\n if (!this.fileOptions[id][name].binary) {\n if (this.files[id][name]) {\n this.files[id][name] = this.files[id][name].toString();\n }\n }\n } else {\n if (this.fileOptions[id][name] !== undefined) {\n delete this.fileOptions[id][name];\n }\n if (this.files[id][name] !== undefined) {\n delete this.files[id][name];\n }\n }\n }\n\n if (this.fileOptions[id][name] && !this.fileOptions[id][name].acl) {\n // all files belong to admin by default, but everyone can edit it\n this.fileOptions[id][name].acl = {\n owner: (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup:\n (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) || utils.CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||\n utils.CONSTS.ACCESS_USER_ALL | utils.CONSTS.ACCESS_GROUP_ALL | utils.CONSTS.ACCESS_EVERY_RW, // 776\n };\n }\n\n if (this.fileOptions[id][name] !== null && this.fileOptions[id][name] !== undefined) {\n if (!this.fileOptions[id][name].mimeType) {\n const _ext = path.extname(name);\n const _mimeType = utils.getMimeType(_ext);\n this.fileOptions[id][name].mimeType = _mimeType.mimeType;\n }\n return {\n fileContent: this.files[id][name],\n fileMime: this.fileOptions[id][name].mimeType,\n };\n }\n } catch (e) {\n this.log.warn(`${this.namespace} Cannot read file ${id} / ${name}: ${e.message}`);\n throw e;\n }\n throw new Error(utils.ERRORS.ERROR_NOT_FOUND);\n }\n\n /**\n * Check if given object exists\n *\n * @param id id of the object\n * @returns if the object exists\n */\n // needed by server\n _objectExists(id) {\n if (!id || typeof id !== 'string') {\n throw new Error(`invalid id ${JSON.stringify(id)}`);\n }\n\n try {\n // check if the id exists\n return Object.prototype.hasOwnProperty.call(this.dataset, id);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot check object existence of \"${id}\": ${e.message}`);\n throw new Error(`Cannot check object existence of \"${id}\": ${e.message}`);\n }\n }\n\n /**\n * Check if given file exists\n *\n * @param id id of the namespace\n * @param [name] name of the file\n * @returns true if the file exists\n */\n // needed by server\n _fileExists(id, name) {\n if (typeof name !== 'string') {\n name = '';\n }\n\n const location = path.join(this.objectsDir, id, name);\n\n try {\n const stat = fs.statSync(location);\n return stat.isFile();\n } catch (e) {\n if (e.code !== 'ENOENT') {\n this.log.error(`${this.namespace} Cannot check file existence of \"${location}\": ${e.message}`);\n throw new Error(`Cannot check file existence of \"${location}\": ${e.message}`);\n }\n return false;\n }\n }\n\n /**\n * Check if given directory exists\n *\n * @param id id of the namespace\n * @param [name] name of the directory\n * @returns true if the directory exists\n */\n // special functionality only for Server (used together with SyncFileDirectory)\n dirExists(id, name) {\n if (typeof name !== 'string') {\n name = '';\n }\n\n const location = path.join(this.objectsDir, id, name);\n\n try {\n const stat = fs.statSync(location);\n return stat.isDirectory();\n } catch (e) {\n if (e.code !== 'ENOENT') {\n this.log.error(`${this.namespace} Cannot check directory existence of \"${location}\": ${e.message}`);\n throw new Error(`Cannot check directory existence of \"${location}\": ${e.message}`);\n }\n return false;\n }\n }\n\n /**\n * Delete a file or directory from an object's file storage (used by the server)\n *\n * @param id The object ID owning the file\n * @param name The file or directory name to delete\n */\n _unlink(id, name) {\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n\n this._loadFileSettings(id);\n\n const location = path.join(this.objectsDir, id, name);\n if (fs.existsSync(location)) {\n const stat = fs.statSync(location);\n\n if (stat.isDirectory()) {\n // read all entries and delete every one\n fs.readdirSync(location).forEach(dir => this._unlink(id, `${name}/${dir}`));\n\n this.log.debug(`Delete directory ${path.join(id, name)}`);\n try {\n fs.removeSync(location);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot delete directory \"${path.join(id, name)}\": ${e.message}`);\n throw e;\n }\n\n if (this.fileOptions[id]) {\n delete this.fileOptions[id];\n }\n if (this.files[id] && this.files[id]) {\n delete this.files[id];\n }\n } else {\n this.log.debug(`Delete file ${path.join(id, name)}`);\n try {\n fs.removeSync(location);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot delete file \"${path.join(id, name)}\": ${e.message}`);\n throw e;\n }\n\n if (this.fileOptions[id][name]) {\n delete this.fileOptions[id][name];\n }\n if (this.files[id] && this.files[id][name]) {\n delete this.files[id][name];\n }\n\n // Store dir description\n this._saveFileSettings(id, true);\n }\n\n setImmediate(\n (id, name) => {\n // publish event in states\n this.log.silly(\n `${this.namespace} memory publish ${id} ${JSON.stringify({ name, file: true, size: null })}`,\n );\n this.publishAll('files', `${id}$%$${name}`, null);\n },\n id,\n name,\n );\n }\n }\n\n /**\n * List the contents of a directory in an object's file storage (used by the server)\n *\n * @param id The object ID owning the files\n * @param name The directory name to list\n * @param options Optional read options\n */\n _readDir(id, name, options) {\n if (options && options.acl) {\n options.acl = null;\n }\n if ((id === '' || id === '/' || id === '*') && (name === '' || name === '*')) {\n // read root of xxx-data/files\n } else {\n const _path = utils.sanitizePath(id, name);\n id = _path.id;\n name = _path.name;\n }\n\n options = options || {};\n // Find all files and directories starts with name\n const _files = [];\n\n if (id && id === '*') {\n id = '';\n }\n if (name && name[name.length - 1] !== '/') {\n name += '/';\n }\n\n this._loadFileSettings(id);\n\n const len = name ? name.length : 0;\n for (const f of Object.keys(this.fileOptions[id])) {\n if (!name || f.substring(0, len) === name) {\n let rest = f.substring(len);\n rest = rest.split('/', 2);\n if (rest[0] && _files.indexOf(rest[0]) === -1) {\n _files.push(rest[0]);\n }\n }\n }\n\n const location = path.join(this.objectsDir, id, name);\n if (fs.existsSync(location) && fs.statSync(location).isDirectory()) {\n const dirFiles = fs.readdirSync(location);\n for (let i = 0; i < dirFiles.length; i++) {\n if (dirFiles[i] === '..' || dirFiles[i] === '.') {\n continue;\n }\n if (dirFiles[i] !== '_data.json' && _files.indexOf(dirFiles[i]) === -1) {\n _files.push(dirFiles[i]);\n }\n }\n } else {\n throw new Error(utils.ERRORS.ERROR_NOT_FOUND);\n }\n\n _files.sort();\n const res = [];\n for (const file of _files) {\n if (file === '..' || file === '.') {\n continue;\n }\n if (fs.existsSync(path.join(location, file))) {\n try {\n const stats = fs.statSync(path.join(location, file));\n const acl =\n this.fileOptions[id][name + file] && this.fileOptions[id][name + file].acl\n ? deepClone(this.fileOptions[id][name + file].acl) // copy settings\n : {\n read: true,\n write: true,\n owner:\n (this.defaultNewAcl && this.defaultNewAcl.owner) ||\n 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_RW |\n utils.CONSTS.ACCESS_GROUP_READ |\n utils.CONSTS.ACCESS_EVERY_READ,\n };\n\n // if filter for user\n if (options.filter && acl) {\n // If user may not write\n if (!options.acl.file.write) {\n // write\n acl.permissions &= ~(\n utils.CONSTS.ACCESS_USER_WRITE |\n utils.CONSTS.ACCESS_GROUP_WRITE |\n utils.CONSTS.ACCESS_EVERY_WRITE\n );\n }\n // If user may not read\n if (!options.acl.file.read) {\n // read\n acl.permissions &= ~(\n utils.CONSTS.ACCESS_USER_READ |\n utils.CONSTS.ACCESS_GROUP_READ |\n utils.CONSTS.ACCESS_EVERY_READ\n );\n }\n\n if (\n options.user !== utils.CONSTS.SYSTEM_ADMIN_USER &&\n options.groups.includes(utils.CONSTS.SYSTEM_ADMIN_GROUP)\n ) {\n if (acl.owner !== options.user) {\n // Check if the user is in the group\n if (options.groups.includes(acl.ownerGroup)) {\n // Check group rights\n if (!(acl.permissions & utils.CONSTS.ACCESS_GROUP_RW)) {\n continue;\n }\n acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_GROUP_READ);\n acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_GROUP_WRITE);\n } else {\n // everybody\n if (!(acl.permissions & utils.CONSTS.ACCESS_EVERY_RW)) {\n continue;\n }\n acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_EVERY_READ);\n acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_EVERY_WRITE);\n }\n } else {\n // Check user rights\n if (!(acl.permissions & utils.CONSTS.ACCESS_USER_RW)) {\n continue;\n }\n acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_USER_READ);\n acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_USER_WRITE);\n }\n } else {\n acl.read = true;\n acl.write = true;\n }\n }\n\n res.push({\n file,\n stats: stats,\n isDir: stats.isDirectory(),\n acl: acl,\n modifiedAt: this.fileOptions[id][name + file]\n ? this.fileOptions[id][name + file].modifiedAt\n : undefined,\n createdAt: this.fileOptions[id][name + file]\n ? this.fileOptions[id][name + file].createdAt\n : undefined,\n });\n } catch (e) {\n this.log.error(\n `${this.namespace} Cannot read permissions of ${path.join(this.objectsDir, id, name, file)}: ${\n e.message\n }`,\n );\n }\n }\n }\n\n return res;\n }\n\n /**\n * Rename a file or directory in an object's file storage (used by the server)\n *\n * @param id The object ID owning the file\n * @param oldName The current file or directory name\n * @param newName The new file or directory name\n */\n _rename(id, oldName, newName) {\n const _path = utils.sanitizePath(id, oldName);\n id = _path.id;\n oldName = _path.name;\n if (newName[0] === '/') {\n newName = newName.substring(1);\n }\n\n this._loadFileSettings(id);\n\n if (fs.existsSync(path.join(this.objectsDir, id, oldName))) {\n fs.renameSync(path.join(this.objectsDir, id, oldName), path.join(this.objectsDir, id, newName));\n } else {\n throw new Error(utils.ERRORS.ERROR_NOT_FOUND);\n }\n\n Object.keys(this.fileOptions[id]).forEach(name => {\n const type = this.fileOptions[id][name];\n if (name.startsWith(oldName)) {\n delete this.fileOptions[id][name];\n this.fileOptions[id][name.replace(oldName, newName)] = type;\n }\n });\n Object.keys(this.files[id]).forEach(name => {\n const data = this.files[id][name];\n if (name.startsWith(oldName)) {\n delete this.files[id][name];\n this.files[id][name.replace(oldName, newName)] = data;\n }\n });\n this._saveFileSettings(id, true);\n }\n\n /**\n * Create a deep clone of the given object\n *\n * @param obj The object to clone\n */\n _clone(obj) {\n if (obj === null || obj === undefined || !tools.isObject(obj)) {\n return obj;\n }\n\n const temp = obj.constructor(); // changed\n\n for (const key of Object.keys(obj)) {\n temp[key] = this._clone(obj[key]);\n }\n return temp;\n }\n\n /**\n * Subscribe a client to meta changes\n *\n * @param client The client to subscribe\n * @param pattern The pattern of meta IDs to subscribe to\n */\n _subscribeMeta(client, pattern) {\n this.handleSubscribe(client, 'meta', pattern);\n }\n\n /**\n * Subscribe a client to object changes (used by the server)\n *\n * @param client The client to subscribe\n * @param pattern The pattern of object IDs to subscribe to\n */\n _subscribeConfigForClient(client, pattern) {\n this.handleSubscribe(client, 'objects', pattern);\n }\n\n /**\n * Unsubscribe a client from object changes (used by the server)\n *\n * @param client The client to unsubscribe\n * @param pattern The pattern of object IDs to unsubscribe from\n */\n _unsubscribeConfigForClient(client, pattern) {\n this.handleUnsubscribe(client, 'objects', pattern); // ignore options => unsubscribe may everyone\n }\n\n /**\n * Subscribe a client to file changes of an object (used by the server)\n *\n * @param client The client to subscribe\n * @param id The object ID owning the files\n * @param pattern One or more file name patterns to subscribe to\n */\n _subscribeFileForClient(client, id, pattern) {\n if (Array.isArray(pattern)) {\n pattern.forEach(pattern => this.handleSubscribe(client, 'files', `${id}$%$${pattern}`));\n } else {\n this.handleSubscribe(client, 'files', `${id}$%$${pattern}`);\n }\n }\n\n /**\n * Unsubscribe a client from file changes of an object (used by the server)\n *\n * @param client The client to unsubscribe\n * @param id The object ID owning the files\n * @param pattern One or more file name patterns to unsubscribe from\n */\n _unsubscribeFileForClient(client, id, pattern) {\n if (Array.isArray(pattern)) {\n pattern.forEach(pattern => this.handleUnsubscribe(client, 'files', `${id}$%$${pattern}`));\n } else {\n this.handleUnsubscribe(client, 'files', `${id}$%$${pattern}`);\n }\n }\n\n /**\n * Get a single object by its ID (used by the server)\n *\n * @param id The object ID to read\n */\n _getObject(id) {\n return this.dataset[id];\n }\n\n /**\n * Get all object IDs matching the given pattern, sorted (used by the server)\n *\n * @param pattern The pattern to match object IDs against\n */\n _getKeys(pattern) {\n const r = new RegExp(tools.pattern2RegEx(pattern));\n const result = Object.keys(this.dataset).filter(id => r.test(id) && id !== this.META_ID);\n result.sort();\n return result;\n }\n\n /**\n * Get the values of the given object IDs (used by the server)\n *\n * @param keys The object IDs to read\n */\n _getObjects(keys) {\n if (!keys) {\n throw new Error('no keys');\n }\n\n return keys.map(id => this.dataset[id]);\n }\n\n /**\n * Get the meta dictionary, creating it if it does not exist yet\n */\n _ensureMetaDict() {\n let meta = this.dataset[this.META_ID];\n if (!meta) {\n meta = {};\n this.dataset[this.META_ID] = meta;\n }\n return meta;\n }\n\n /**\n * Get value of given meta id\n *\n * @param id The meta ID to read\n * @returns the stored meta value\n */\n getMeta(id) {\n const meta = this._ensureMetaDict();\n return meta[id];\n }\n\n /**\n * Sets given value to id in metaNamespace\n *\n * @param id The meta ID to write\n * @param value The value to store\n */\n setMeta(id, value) {\n const meta = this._ensureMetaDict();\n meta[id] = value;\n // Make sure the object gets re-written, especially when using an external DB\n this.dataset[this.META_ID] = meta;\n\n setImmediate(() => {\n // publish event in states\n this.log.silly(`${this.namespace} memory publish meta ${id} ${value}`);\n this.publishAll('meta', id, value);\n });\n\n if (!this.stateTimer) {\n this.stateTimer = setTimeout(() => this.saveState(), this.writeFileInterval);\n }\n }\n\n /**\n * Directly set an object value and publish the change (used by the server)\n *\n * @param id The object ID to set\n * @param obj The object to store\n */\n _setObjectDirect(id, obj) {\n this.dataset[id] = obj;\n\n // object updated -> if type changed to meta -> cache\n if (obj.type === 'meta' && this.existingMetaObjects[id] === false) {\n this.existingMetaObjects[id] = true;\n }\n\n setImmediate(() => this.publishAll('objects', id, obj));\n\n this.stateTimer = this.stateTimer || setTimeout(() => this.saveState(), this.writeFileInterval);\n }\n\n /**\n * Delete the given object from the dataset\n *\n * @param id unique id of the object\n */\n _delObject(id) {\n const obj = this.dataset[id];\n if (!obj) {\n // Not existent, so goal reached :-)\n return;\n }\n\n if (obj.common?.dontDelete) {\n throw new Error('Object is marked as non deletable');\n }\n\n delete this.dataset[id];\n\n // object has been deleted -> remove from cached meta if there\n if (this.existingMetaObjects[id]) {\n this.existingMetaObjects[id] = false;\n }\n\n setImmediate(() => this.publishAll('objects', id, null));\n\n if (!this.stateTimer) {\n this.stateTimer = setTimeout(() => this.saveState(), this.writeFileInterval);\n }\n }\n\n /**\n * Apply a view's map function over all objects and collect the matching rows\n *\n * @param func The view definition containing the map function\n * @param params Query parameters such as startkey and endkey\n */\n _applyView(func, params) {\n const result = {\n rows: [],\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function _emit_(id, obj) {\n result.rows.push({ id: id, value: obj });\n }\n\n const f = eval(`(${func.map.replace(/emit/g, '_emit_')})`);\n\n for (const [id, obj] of Object.entries(this.dataset)) {\n if (params) {\n if (params.startkey && id < params.startkey) {\n continue;\n }\n if (params.endkey && id > params.endkey) {\n continue;\n }\n }\n\n if (obj) {\n try {\n f(obj);\n } catch (e) {\n this.log.warn(`${this.namespace} Cannot execute map: ${e.message}`);\n }\n }\n }\n // Calculate max\n if (func.reduce === '_stats') {\n let max = null;\n for (const row of result.rows) {\n if (max === null || row.value > max) {\n max = row.value;\n }\n }\n if (max !== null) {\n result.rows = [{ id: '_stats', value: { max: max } }];\n } else {\n result.rows = [];\n }\n }\n\n return result;\n }\n\n /**\n * Run a predefined object view (design document) and return the matching rows (used by the server)\n *\n * @param design The design document name\n * @param search The view name within the design document\n * @param params Query parameters such as startkey and endkey\n */\n _getObjectView(design, search, params) {\n const designObj = this.dataset[`_design/${design}`];\n if (!designObj) {\n this.log.error(`${this.namespace} Cannot find view \"${design}\"`);\n throw new Error(`Cannot find view \"${design}\"`);\n }\n if (!(designObj.views && designObj.views[search])) {\n this.log.warn(`${this.namespace} Cannot find search \"${search}\" in \"${design}\"`);\n throw new Error(`Cannot find search \"${search}\" in \"${design}\"`);\n }\n return this._applyView(designObj.views[search], params);\n }\n\n /**\n * Destructor of the class. Called by shutting down.\n */\n async destroy() {\n await super.destroy();\n\n this._saveFileSettings(true);\n if (this.stateTimer) {\n clearTimeout(this.stateTimer);\n this.stateTimer = null;\n }\n if (this.writeTimer) {\n clearTimeout(this.writeTimer);\n this.writeTimer = null;\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_db_base", "path", "deepClone", "fs", "utils", "name", "id", "f", "pattern", "result", "params"]
7
7
  }
@@ -1,10 +1,27 @@
1
+ /**
2
+ * Objects database client that also starts an in-memory server speaking the Redis protocol
3
+ */
1
4
  export class ObjectsInMemoryServerClass extends ObjectsInRedisClient {
5
+ /**
6
+ * @param settings Settings for the objects client and the in-memory server
7
+ */
2
8
  constructor(settings: any);
3
9
  objectsServer: ObjectsInMemoryServer;
10
+ /**
11
+ * Synchronize the file directory of the in-memory server
12
+ *
13
+ * @param limitId Optional object ID to limit the synchronization to
14
+ */
4
15
  syncFileDirectory(limitId: any): {
5
16
  numberSuccess: number;
6
17
  notifications: any[];
7
18
  };
19
+ /**
20
+ * Check whether a directory exists in the in-memory server's file storage
21
+ *
22
+ * @param id The object ID owning the files
23
+ * @param name The directory path to check
24
+ */
8
25
  dirExists(id: any, name: any): boolean;
9
26
  }
10
27
  import { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';
@@ -24,6 +24,9 @@ module.exports = __toCommonJS(objectsInMemServerClass_exports);
24
24
  var import_db_objects_redis = require("@iobroker/db-objects-redis");
25
25
  var import_objectsInMemServerRedis = require("./objectsInMemServerRedis.js");
26
26
  class ObjectsInMemoryServerClass extends import_db_objects_redis.Client {
27
+ /**
28
+ * @param settings Settings for the objects client and the in-memory server
29
+ */
27
30
  constructor(settings) {
28
31
  settings.autoConnect = false;
29
32
  super(settings);
@@ -38,16 +41,33 @@ class ObjectsInMemoryServerClass extends import_db_objects_redis.Client {
38
41
  };
39
42
  this.objectsServer = new import_objectsInMemServerRedis.ObjectsInMemoryServer(serverSettings);
40
43
  }
44
+ /**
45
+ * Destroy the client first and the in-memory server afterwards
46
+ */
41
47
  async destroy() {
42
48
  await super.destroy();
43
49
  await this.objectsServer.destroy();
44
50
  }
51
+ /**
52
+ * Get the status as reported by the in-memory server
53
+ */
45
54
  getStatus() {
46
55
  return this.objectsServer.getStatus();
47
56
  }
57
+ /**
58
+ * Synchronize the file directory of the in-memory server
59
+ *
60
+ * @param limitId Optional object ID to limit the synchronization to
61
+ */
48
62
  syncFileDirectory(limitId) {
49
63
  return this.objectsServer.syncFileDirectory(limitId);
50
64
  }
65
+ /**
66
+ * Check whether a directory exists in the in-memory server's file storage
67
+ *
68
+ * @param id The object ID owning the files
69
+ * @param name The directory path to check
70
+ */
51
71
  dirExists(id, name) {
52
72
  return this.objectsServer.dirExists(id, name);
53
73
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/objects/objectsInMemServerClass.js"],
4
- "sourcesContent": ["/**\n * States DB in memory - Server with Redis protocol\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';\nimport { ObjectsInMemoryServer } from './objectsInMemServerRedis.js';\n\nexport class ObjectsInMemoryServerClass extends ObjectsInRedisClient {\n constructor(settings) {\n settings.autoConnect = false; // delay Client connection to when we need it\n super(settings);\n\n const serverSettings = {\n namespace: settings.namespace ? `${settings.namespace}-Server` : 'Server',\n connection: settings.connection,\n logger: settings.logger,\n hostname: settings.hostname,\n connected: () => {\n this.connectDb(); // now that server is connected also connect client\n },\n };\n this.objectsServer = new ObjectsInMemoryServer(serverSettings);\n }\n\n async destroy() {\n await super.destroy(); // destroy client first\n await this.objectsServer.destroy(); // server afterwards too\n }\n\n getStatus() {\n return this.objectsServer.getStatus(); // return Status as Server\n }\n\n syncFileDirectory(limitId) {\n return this.objectsServer.syncFileDirectory(limitId);\n }\n\n dirExists(id, name) {\n return this.objectsServer.dirExists(id, name);\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;AASA,8BAA+C;AAC/C,qCAAsC;AAEhC,MAAO,mCAAmC,wBAAAA,OAAoB;EAChE,YAAY,UAAQ;AAChB,aAAS,cAAc;AACvB,UAAM,QAAQ;AAEd,UAAM,iBAAiB;MACnB,WAAW,SAAS,YAAY,GAAG,SAAS,SAAS,YAAY;MACjE,YAAY,SAAS;MACrB,QAAQ,SAAS;MACjB,UAAU,SAAS;MACnB,WAAW,MAAK;AACZ,aAAK,UAAS;MAClB;;AAEJ,SAAK,gBAAgB,IAAI,qDAAsB,cAAc;EACjE;EAEA,MAAM,UAAO;AACT,UAAM,MAAM,QAAO;AACnB,UAAM,KAAK,cAAc,QAAO;EACpC;EAEA,YAAS;AACL,WAAO,KAAK,cAAc,UAAS;EACvC;EAEA,kBAAkB,SAAO;AACrB,WAAO,KAAK,cAAc,kBAAkB,OAAO;EACvD;EAEA,UAAU,IAAI,MAAI;AACd,WAAO,KAAK,cAAc,UAAU,IAAI,IAAI;EAChD;;",
4
+ "sourcesContent": ["/**\n * States DB in memory - Server with Redis protocol\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';\nimport { ObjectsInMemoryServer } from './objectsInMemServerRedis.js';\n\n/**\n * Objects database client that also starts an in-memory server speaking the Redis protocol\n */\nexport class ObjectsInMemoryServerClass extends ObjectsInRedisClient {\n /**\n * @param settings Settings for the objects client and the in-memory server\n */\n constructor(settings) {\n settings.autoConnect = false; // delay Client connection to when we need it\n super(settings);\n\n const serverSettings = {\n namespace: settings.namespace ? `${settings.namespace}-Server` : 'Server',\n connection: settings.connection,\n logger: settings.logger,\n hostname: settings.hostname,\n connected: () => {\n this.connectDb(); // now that server is connected also connect client\n },\n };\n this.objectsServer = new ObjectsInMemoryServer(serverSettings);\n }\n\n /**\n * Destroy the client first and the in-memory server afterwards\n */\n async destroy() {\n await super.destroy(); // destroy client first\n await this.objectsServer.destroy(); // server afterwards too\n }\n\n /**\n * Get the status as reported by the in-memory server\n */\n getStatus() {\n return this.objectsServer.getStatus(); // return Status as Server\n }\n\n /**\n * Synchronize the file directory of the in-memory server\n *\n * @param limitId Optional object ID to limit the synchronization to\n */\n syncFileDirectory(limitId) {\n return this.objectsServer.syncFileDirectory(limitId);\n }\n\n /**\n * Check whether a directory exists in the in-memory server's file storage\n *\n * @param id The object ID owning the files\n * @param name The directory path to check\n */\n dirExists(id, name) {\n return this.objectsServer.dirExists(id, name);\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;AASA,8BAA+C;AAC/C,qCAAsC;AAKhC,MAAO,mCAAmC,wBAAAA,OAAoB;;;;EAIhE,YAAY,UAAQ;AAChB,aAAS,cAAc;AACvB,UAAM,QAAQ;AAEd,UAAM,iBAAiB;MACnB,WAAW,SAAS,YAAY,GAAG,SAAS,SAAS,YAAY;MACjE,YAAY,SAAS;MACrB,QAAQ,SAAS;MACjB,UAAU,SAAS;MACnB,WAAW,MAAK;AACZ,aAAK,UAAS;MAClB;;AAEJ,SAAK,gBAAgB,IAAI,qDAAsB,cAAc;EACjE;;;;EAKA,MAAM,UAAO;AACT,UAAM,MAAM,QAAO;AACnB,UAAM,KAAK,cAAc,QAAO;EACpC;;;;EAKA,YAAS;AACL,WAAO,KAAK,cAAc,UAAS;EACvC;;;;;;EAOA,kBAAkB,SAAO;AACrB,WAAO,KAAK,cAAc,kBAAkB,OAAO;EACvD;;;;;;;EAQA,UAAU,IAAI,MAAI;AACd,WAAO,KAAK,cAAc,UAAU,IAAI,IAAI;EAChD;;",
6
6
  "names": ["ObjectsInRedisClient"]
7
7
  }
@@ -3,12 +3,6 @@
3
3
  * to access the methods via redis protocol
4
4
  */
5
5
  export class ObjectsInMemoryServer extends ObjectsInMemoryFileDB {
6
- /**
7
- * Constructor
8
- *
9
- * @param settings State and InMem-DB settings
10
- */
11
- constructor(settings: any);
12
6
  serverConnections: {};
13
7
  namespaceObjects: string;
14
8
  namespaceFile: string;
@@ -63,7 +57,7 @@ export class ObjectsInMemoryServer extends ObjectsInMemoryFileDB {
63
57
  /**
64
58
  * Return connected RedisHandlers/Connections
65
59
  *
66
- * @returns
60
+ * @returns the currently connected RedisHandlers/Connections
67
61
  */
68
62
  getClients(): {};
69
63
  /**
@@ -85,7 +79,7 @@ export class ObjectsInMemoryServer extends ObjectsInMemoryFileDB {
85
79
  * Initialize Redis Server
86
80
  *
87
81
  * @param settings Settings object
88
- * @returns
82
+ * @returns a promise that resolves once the Redis server is listening
89
83
  */
90
84
  _initRedisServer(settings: any): Promise<any>;
91
85
  server: net.Server | undefined;
@@ -659,7 +659,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
659
659
  /**
660
660
  * Return connected RedisHandlers/Connections
661
661
  *
662
- * @returns
662
+ * @returns the currently connected RedisHandlers/Connections
663
663
  */
664
664
  getClients() {
665
665
  return this.serverConnections;
@@ -785,7 +785,7 @@ class ObjectsInMemoryServer extends import_objectsInMemFileDB.ObjectsInMemoryFil
785
785
  * Initialize Redis Server
786
786
  *
787
787
  * @param settings Settings object
788
- * @returns
788
+ * @returns a promise that resolves once the Redis server is listening
789
789
  */
790
790
  _initRedisServer(settings) {
791
791
  return new Promise((resolve, reject) => {