@iobroker/js-controller-common 7.2.3-alpha.8-20260709-8d8c9c5ed → 7.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.js +5 -5
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/lib/common/notificationHandler.js +2 -6
- package/build/cjs/lib/common/notificationHandler.js.map +2 -2
- package/build/cjs/lib/common/objects.d.ts +0 -3
- package/build/cjs/lib/common/objects.js +0 -5
- package/build/cjs/lib/common/objects.js.map +2 -2
- package/build/cjs/lib/common/states.d.ts +0 -3
- package/build/cjs/lib/common/states.js +0 -5
- package/build/cjs/lib/common/states.js.map +2 -2
- package/build/cjs/lib/common/tools.d.ts +0 -5
- package/build/cjs/lib/common/tools.js +0 -4
- package/build/cjs/lib/common/tools.js.map +2 -2
- package/build/cjs/lib/common/zipFiles.d.ts +0 -36
- package/build/cjs/lib/common/zipFiles.js +0 -10
- package/build/cjs/lib/common/zipFiles.js.map +2 -2
- package/build/esm/lib/common/notificationHandler.js +3 -3
- package/build/esm/lib/common/notificationHandler.js.map +1 -1
- package/build/esm/lib/common/objects.d.ts +0 -3
- package/build/esm/lib/common/objects.d.ts.map +1 -1
- package/build/esm/lib/common/objects.js +0 -3
- package/build/esm/lib/common/objects.js.map +1 -1
- package/build/esm/lib/common/states.d.ts +0 -3
- package/build/esm/lib/common/states.d.ts.map +1 -1
- package/build/esm/lib/common/states.js +0 -3
- package/build/esm/lib/common/states.js.map +1 -1
- package/build/esm/lib/common/tools.d.ts +0 -5
- package/build/esm/lib/common/tools.d.ts.map +1 -1
- package/build/esm/lib/common/tools.js.map +1 -1
- package/build/esm/lib/common/zipFiles.d.ts +0 -36
- package/build/esm/lib/common/zipFiles.d.ts.map +1 -1
- package/build/esm/lib/common/zipFiles.js +2 -36
- package/build/esm/lib/common/zipFiles.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -13
package/build/cjs/index.js
CHANGED
|
@@ -27,8 +27,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
mod
|
|
28
28
|
));
|
|
29
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
-
var
|
|
31
|
-
__export(
|
|
30
|
+
var esm_exports = {};
|
|
31
|
+
__export(esm_exports, {
|
|
32
32
|
NotificationHandler: () => import_notificationHandler.NotificationHandler,
|
|
33
33
|
getObjectsConstructor: () => import_objects.getObjectsConstructor,
|
|
34
34
|
getStatesConstructor: () => import_states.getStatesConstructor,
|
|
@@ -41,13 +41,13 @@ __export(index_exports, {
|
|
|
41
41
|
statesDbHasServer: () => import_states.statesDbHasServer,
|
|
42
42
|
zipFiles: () => zipFiles
|
|
43
43
|
});
|
|
44
|
-
module.exports = __toCommonJS(
|
|
44
|
+
module.exports = __toCommonJS(esm_exports);
|
|
45
45
|
var import_states = require("./lib/common/states.js");
|
|
46
46
|
var import_objects = require("./lib/common/objects.js");
|
|
47
47
|
var import_notificationHandler = require("./lib/common/notificationHandler.js");
|
|
48
48
|
var zipFiles = __toESM(require("./lib/common/zipFiles.js"), 1);
|
|
49
|
-
__reExport(
|
|
50
|
-
__reExport(
|
|
49
|
+
__reExport(esm_exports, require("./lib/common/tools.js"), module.exports);
|
|
50
|
+
__reExport(esm_exports, require("@iobroker/js-controller-common-db"), module.exports);
|
|
51
51
|
const letsencrypt = true;
|
|
52
52
|
// Annotate the CommonJS export names for ESM import in node:
|
|
53
53
|
0 && (module.exports = {
|
package/build/cjs/index.js.map
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": ["/// <reference types=\"@iobroker/types-dev\" />\nexport {\n getStatesConstructor,\n statesDbHasServer,\n isLocalStatesDbServer,\n performStatesInterview,\n} from '@/lib/common/states.js';\nexport {\n getObjectsConstructor,\n objectsDbHasServer,\n isLocalObjectsDbServer,\n performObjectsInterview,\n} from '@/lib/common/objects.js';\nexport { NotificationHandler } from '@/lib/common/notificationHandler.js';\nexport type { SupportedFeature } from '@/lib/common/constants.js';\nexport * as zipFiles from '@/lib/common/zipFiles.js';\nexport * from '@/lib/common/tools.js';\nexport * from '@iobroker/js-controller-common-db';\n\n/** Shim until all adapters are using adapter-core 3.1.4 or higher */\nexport const letsencrypt = true;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;AACA,oBAKO;AACP,qBAKO;AACP,iCAAoC;AAEpC,eAA0B;AAC1B,
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;AACA,oBAKO;AACP,qBAKO;AACP,iCAAoC;AAEpC,eAA0B;AAC1B,wBAAc,kCAhBd;AAiBA,wBAAc,8CAjBd;AAoBO,MAAM,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,6 @@ 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 });
|
|
9
8
|
var __export = (target, all) => {
|
|
10
9
|
for (var name in all)
|
|
11
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -36,9 +35,6 @@ var import_fs_extra = __toESM(require("fs-extra"), 1);
|
|
|
36
35
|
var import_js_controller_common_db = require("@iobroker/js-controller-common-db");
|
|
37
36
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
38
37
|
class NotificationHandler {
|
|
39
|
-
static {
|
|
40
|
-
__name(this, "NotificationHandler");
|
|
41
|
-
}
|
|
42
38
|
states;
|
|
43
39
|
objects;
|
|
44
40
|
log;
|
|
@@ -102,10 +98,10 @@ class NotificationHandler {
|
|
|
102
98
|
endkey: "system.adapter.\u9999"
|
|
103
99
|
});
|
|
104
100
|
for (const entry of res.rows) {
|
|
105
|
-
if (entry.value
|
|
101
|
+
if (entry.value.notifications) {
|
|
106
102
|
await this.addConfig(entry.value.notifications);
|
|
107
103
|
}
|
|
108
|
-
if (entry.value
|
|
104
|
+
if (entry.value.common && entry.value.common.host === this.host) {
|
|
109
105
|
instancesOnHost.push(entry.id);
|
|
110
106
|
}
|
|
111
107
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/notificationHandler.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Notification handler class\n *\n * 2021-2024 foxriver76 <moritz.heusinger@gmail.com>\n */\n\nimport fs from 'fs-extra';\nimport { tools } from '@iobroker/js-controller-common-db';\nimport path from 'node:path';\nimport type { Client as StatesInRedisClient } from '@iobroker/db-states-redis';\nimport type { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';\nimport type Winston from 'winston';\n\ntype MultilingualObject = Exclude<ioBroker.StringOrTranslated, string>;\n\n/** Settings to configure an instance of NotificationHandler */\nexport interface NotificationHandlerSettings {\n /** Name of the host (not id - hence, without `system.host.` prefix) */\n host: string;\n /** States DB instance */\n states: StatesInRedisClient;\n /** Objects DB instance */\n objects: ObjectsInRedisClient;\n /** Logger instance */\n log: Winston.Logger | Console;\n /** Prefix for the log messages */\n logPrefix: string;\n}\n\n/** A notification config entry represents the top level of the notification structure */\nexport interface NotificationsConfigEntry {\n /** e.g. system */\n scope: string;\n /** multilingual name */\n name: MultilingualObject;\n /** multilingual description */\n description: MultilingualObject;\n /** The notification categories inside this scope */\n categories: CategoryConfigEntry[];\n}\n\nexport type Severity = 'info' | 'notify' | 'alert';\n\n/** A notification category entry represents one of the categories of a scope */\nexport interface CategoryConfigEntry {\n /** Id of the category */\n category: string;\n /** Name of the category */\n name: MultilingualObject;\n /** Allows defining the severity of the notification with `info` being the lowest, `notify` representing middle priority, `alert` representing high priority and often containing critical information */\n severity: Severity;\n /** Description of the category */\n description: MultilingualObject;\n /** Regex where `console.error` output is parsed against to check if a notification of this category should be generated */\n regex: string[];\n /** Restrict the maximum number of messages for this category */\n limit: number;\n}\n\ninterface NotificationMessageObject {\n message: string;\n ts: number;\n contextData?: ioBroker.NotificationContextData;\n}\n\ninterface NotificationsCategory {\n [category: string]: {\n [instance: string]: NotificationMessageObject[];\n };\n}\n\ninterface NotificationsObject {\n [scope: string]: NotificationsCategory;\n}\n\ninterface FilteredNotificationCategory {\n description: MultilingualObject;\n name: MultilingualObject;\n severity: Severity;\n instances: {\n [instance: string]: {\n messages: NotificationMessageObject[];\n };\n };\n}\n\ninterface FilteredNotificationScope {\n description: MultilingualObject;\n name: MultilingualObject;\n categories: {\n [category: string]: FilteredNotificationCategory;\n };\n}\n\n/** The filtered information as a response for `getFilteredInformation` */\nexport interface FilteredNotificationInformation {\n [scope: string]: FilteredNotificationScope;\n}\n\ninterface NotificationSetupCategory {\n regex: RegExp[];\n limit: number;\n name: MultilingualObject;\n severity: Severity;\n description: MultilingualObject;\n}\n\ninterface NotificationSetupObject {\n [scope: string]: {\n name: MultilingualObject;\n description: MultilingualObject;\n categories: {\n [category: string]: NotificationSetupCategory;\n };\n };\n}\n\ninterface ScopeStateValue {\n [category: string]: {\n count: number;\n };\n}\n\ninterface AddMessageOptions {\n /** Scope of the message */\n scope: string;\n /** Category of the message, if non we check against regex of scope */\n category?: string | null;\n /** Message to add */\n message: string;\n /** Instance e.g., hm-rpc.1 or hostname, if hostname it needs to be prefixed like system.host.rpi */\n instance: string;\n /** Additional context for the notification which can be used by notification processing adapters */\n contextData?: ioBroker.NotificationContextData;\n}\n\n/**\n * The Notification handler class provides an interface to manage the ioBroker notification system\n */\nexport class NotificationHandler {\n private states: StatesInRedisClient;\n private objects: ObjectsInRedisClient;\n private log: Winston.Logger | Console;\n private currentNotifications: NotificationsObject = {};\n // default data dir is relative to controllerDir\n private readonly dataDir = path.join(tools.getControllerDir(), tools.getDefaultDataDir());\n private readonly setup: NotificationSetupObject = {};\n private readonly logPrefix: string;\n private readonly host: string;\n\n /**\n * Creates a new instance of the notification handler class\n *\n * @param settings settings to configure the handler instance\n */\n constructor(settings: NotificationHandlerSettings) {\n this.states = settings.states;\n this.objects = settings.objects;\n this.log = settings.log;\n this.logPrefix = settings.logPrefix;\n this.host = settings.host;\n\n // load notifications file\n this._loadNotifications();\n }\n\n /**\n * Get all adapter instances on this host and store their notifications config - and clears up removed instances notifications - should be called once after init\n */\n async getSetupOfAllAdaptersFromHost(): Promise<void> {\n // create the initial notifications object\n let obj;\n try {\n obj = await this.objects.getObject(`system.host.${this.host}.notifications`);\n } catch {\n // ignore\n }\n\n if (!obj) {\n try {\n await this.objects.setObject(`system.host.${this.host}.notifications`, {\n type: 'folder',\n common: {\n name: {\n en: 'Notifications',\n de: 'Benachrichtigungen',\n ru: '\u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F',\n pt: 'Notifica\u00E7\u00F5es',\n nl: 'Meldingen',\n fr: 'Notifications',\n it: 'Notifiche',\n es: 'Notificaciones',\n pl: 'Powiadomienia',\n uk: '\u0421\u043F\u043E\u0432\u0456\u0449\u0435\u043D\u043D\u044F',\n 'zh-cn': '\u901A\u77E5\u4E8B\u9879',\n },\n },\n native: {},\n });\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not create notifications object: ${e.message}`);\n }\n }\n\n const instancesOnHost = [];\n // get all instances\n try {\n const res = await this.objects.getObjectViewAsync('system', 'instance', {\n startkey: 'system.adapter.',\n endkey: 'system.adapter.\\u9999',\n });\n\n for (const entry of res.rows) {\n if (entry.value?.notifications) {\n // check that instance has notification settings\n await this.addConfig(entry.value.notifications);\n }\n\n if (entry.value?.common.host === this.host) {\n // if it's on our current host\n instancesOnHost.push(entry.id);\n }\n }\n } catch (e) {\n throw new Error(`Could not get notifications setup from instances: ${e.message}`);\n }\n\n // now clear up all notifications that do not belong to our host anymore\n for (const notificationsCategory of Object.values(this.currentNotifications)) {\n for (const instancesInfo of Object.values(notificationsCategory)) {\n for (const instance of Object.keys(instancesInfo)) {\n if (!instancesOnHost.includes(instance) && instance !== `system.host.${this.host}`) {\n // instance no longer on host\n this.log.info(`${this.logPrefix} Instance ${instance} removed from host, clear notifications`);\n await this.clearNotifications(null, null, instance);\n }\n }\n }\n }\n\n // now sync RAM with state\n await this._updateScopeStates();\n }\n\n /**\n * Add a new category to the given scope with a provided optional list of regex\n *\n * @param notifications - Array with notifications\n */\n async addConfig(notifications: NotificationsConfigEntry[]): Promise<void> {\n // if valid attributes, store it\n if (Array.isArray(notifications)) {\n for (const scopeObj of notifications) {\n // create the state object for each scope if non-existing\n let obj;\n try {\n obj = await this.objects.getObject(`system.host.${this.host}.notifications.${scopeObj.scope}`);\n } catch {\n // ignore\n }\n\n if (!obj) {\n try {\n await this.objects.setObject(`system.host.${this.host}.notifications.${scopeObj.scope}`, {\n type: 'state',\n common: {\n type: 'object',\n role: 'value',\n read: true,\n write: false,\n name: scopeObj.name,\n desc: scopeObj.description,\n },\n native: {},\n });\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Could not create notifications object for scope \"${scopeObj.scope}\": ${e.message}`,\n );\n }\n }\n\n if (Array.isArray(scopeObj.categories) && scopeObj.categories.length) {\n const setupScope = this.setup[scopeObj.scope] || {\n name: scopeObj.name,\n description: scopeObj.description,\n categories: {},\n };\n\n // only if scope has at least one category\n this.setup[scopeObj.scope] = setupScope;\n\n for (const categoryObj of scopeObj.categories) {\n const setupCategory = setupScope.categories[categoryObj.category] || {\n regex: [],\n limit: categoryObj.limit,\n name: categoryObj.name,\n severity: categoryObj.severity,\n description: categoryObj.description,\n };\n setupScope.categories[categoryObj.category] = setupCategory;\n\n try {\n let regex: RegExp[] = [];\n if (Array.isArray(categoryObj.regex)) {\n for (const regexString of categoryObj.regex) {\n regex.push(new RegExp(regexString));\n }\n } else if (typeof categoryObj.regex === 'string') {\n // if someone passes a string, convert to a single entry array\n regex = [new RegExp(categoryObj.regex)];\n }\n\n setupCategory.regex = regex;\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Cannot store regex \"${JSON.stringify(categoryObj.regex)}\" for scope \"${\n scopeObj.scope\n }\", category \"${categoryObj.category}\": ${e.message}`,\n );\n }\n }\n }\n }\n }\n }\n\n /**\n * Add a message to the scope and category\n *\n * @param options The scope, category, message, instance and contextData information\n */\n async addMessage(options: AddMessageOptions): Promise<void> {\n const { message, scope, category, contextData } = options;\n let { instance } = options;\n\n if (typeof instance !== 'string') {\n this.log.error(\n `${this.logPrefix} [addMessage] Instance has to be of type \"string\", got \"${typeof instance}\"`,\n );\n return;\n }\n\n if (!instance.startsWith('system.adapter.') && !instance.startsWith('system.host.')) {\n instance = `system.adapter.${instance}`;\n }\n\n // get state of the scope\n let stateVal: ScopeStateValue = {};\n try {\n const state = await this.states.getStateAsync(`system.host.${this.host}.notifications.${scope}`);\n stateVal = state?.val ? JSON.parse(state.val as string) : {};\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not get state for scope \"${scope}\": ${e.message}`);\n }\n\n let categories = [category];\n\n if (!category) {\n // check regex - in parse text we can have multiple matches\n categories = this._parseText(scope, message);\n }\n\n const currentScopeObj = this.currentNotifications[scope] || {};\n this.currentNotifications[scope] = currentScopeObj;\n\n for (const _category of categories) {\n if (!_category) {\n continue;\n }\n\n const currentCategoryObj = currentScopeObj[_category] || {};\n currentScopeObj[_category] = currentCategoryObj;\n\n // array of all messages for instance/category\n const currentInstances = currentCategoryObj[instance] || [];\n currentCategoryObj[instance] = currentInstances;\n\n const setupCategory = this.setup[scope]?.categories[_category];\n\n if (!setupCategory) {\n // no setup for this instance/category combination found - so we have nothing to add\n this.log.warn(\n `${this.logPrefix} No configuration found for scope \"${scope}\" and category \"${_category}\"`,\n );\n continue;\n }\n\n // if limit exceeded, remove last element - use while if it somehow grew too big\n while (setupCategory.limit < currentInstances.length + 1) {\n currentInstances.pop();\n }\n\n // add a new element at the beginning\n currentInstances.unshift({ message, ts: Date.now(), contextData });\n }\n\n // now count all messages of this scope - if nothing matched it can be undefined, and we can skip\n if (tools.isObject(this.currentNotifications[scope])) {\n for (const [categoryName, category] of Object.entries(currentScopeObj)) {\n const categoryCounter = Object.keys(category).length;\n\n stateVal[categoryName] = { count: categoryCounter };\n }\n }\n\n // set updated scope state\n try {\n await this.states.setState(`system.host.${this.host}.notifications.${scope}`, {\n val: JSON.stringify(stateVal),\n ack: true,\n });\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not set notifications state for scope \"${scope}\": ${e.message}`);\n }\n }\n\n /**\n * Updates all scope states by current notifications in RAM\n */\n private async _updateScopeStates(): Promise<void> {\n for (const [scope, scopeObj] of Object.entries(this.currentNotifications)) {\n const stateVal: ScopeStateValue = {};\n\n for (const [category, categoryObj] of Object.entries(scopeObj)) {\n // count the number of instances with this error\n const catCounter = Object.keys(categoryObj).length;\n stateVal[category] = { count: catCounter };\n }\n\n // set updated scope state\n try {\n await this.states.setState(`system.host.${this.host}.notifications.${scope}`, {\n val: JSON.stringify(stateVal),\n ack: true,\n });\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Could not set notifications state for scope \"${scope}\": ${e.message}`,\n );\n }\n }\n }\n\n /**\n * Check the given message against all regular expressions of the given scope\n *\n * @param scope - scope of the message\n * @param message - message to check\n */\n private _parseText(scope: string, message: string): string[] {\n const categories: string[] = [];\n\n const scopeObj = this.setup[scope];\n\n if (!scopeObj) {\n return categories;\n }\n\n for (const [categoryId, categoryObj] of Object.entries(scopeObj.categories)) {\n // check all regular expressions for this category\n for (const regex of categoryObj.regex) {\n if (regex.test(message)) {\n // matching category\n categories.push(categoryId);\n // no further testing needed for this category\n break;\n }\n }\n }\n\n return categories;\n }\n\n /**\n * Load notifications from a file\n */\n private _loadNotifications(): void {\n try {\n this.currentNotifications = fs.readJSONSync(path.join(this.dataDir, 'notifications.json'));\n } catch (e) {\n // at first start its normal, that we cannot read notifications, so just info\n this.log.debug(`${this.logPrefix} Could not read notifications.json: ${e.message}`);\n }\n }\n\n /**\n * Save current notifications to file\n */\n storeNotifications(): void {\n try {\n fs.writeJSONSync(path.join(this.dataDir, 'notifications.json'), this.currentNotifications);\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not write notifications.json: ${e.message}`);\n }\n }\n\n /**\n * Returns the stored notifications matching the filters with description and name\n *\n * @param scopeFilter - scope of notifications\n * @param categoryFilter - category of notifications\n * @param instanceFilter - instance of notifications\n */\n getFilteredInformation(\n scopeFilter: string | null | undefined,\n categoryFilter: string | null | undefined,\n instanceFilter: string | null | undefined,\n ): FilteredNotificationInformation {\n const res: FilteredNotificationInformation = {};\n for (const [scope, currentNotification] of Object.entries(this.currentNotifications)) {\n if (scopeFilter && scopeFilter !== scope) {\n // scope filtered out\n continue;\n }\n\n const scopeObj = this.setup[scope];\n\n if (!scopeObj) {\n // no scope set up\n continue;\n }\n\n const scopeResult: FilteredNotificationScope = {\n categories: {},\n description: scopeObj.description,\n name: scopeObj.name,\n };\n\n res[scope] = scopeResult;\n\n for (const [category, currentCategoryObj] of Object.entries(currentNotification)) {\n if (categoryFilter && categoryFilter !== category) {\n // category filtered out\n continue;\n }\n\n const categoryObj = scopeObj.categories[category];\n\n if (!categoryObj) {\n // no category set up\n continue;\n }\n\n const resultCategories: FilteredNotificationCategory = {\n instances: {},\n description: categoryObj.description,\n name: categoryObj.name,\n severity: categoryObj.severity,\n };\n\n scopeResult.categories[category] = resultCategories;\n\n for (const [instance, instanceObj] of Object.entries(currentCategoryObj)) {\n if (instanceFilter && instanceFilter !== instance) {\n // instance filtered out\n continue;\n }\n\n resultCategories.instances[instance] = {\n messages: instanceObj,\n };\n }\n }\n }\n return res;\n }\n\n /**\n * Clears the stored notifications matching the filters\n *\n * @param scopeFilter - scope of notifications\n * @param categoryFilter - category of notifications\n * @param instanceFilter - instance of notifications\n */\n async clearNotifications(\n scopeFilter: string | null | undefined,\n categoryFilter: string | null | undefined,\n instanceFilter: string | null | undefined,\n ): Promise<void> {\n for (const scope of Object.keys(this.currentNotifications)) {\n const currentNotificationScope = this.currentNotifications[scope];\n\n if (!currentNotificationScope) {\n delete this.currentNotifications[scope];\n continue;\n }\n if (scopeFilter && scopeFilter !== scope) {\n // skip this, because not desired to be deleted\n continue;\n }\n\n let stateVal: ScopeStateValue = {};\n try {\n const state = await this.states.getStateAsync(`system.host.${this.host}.notifications.${scope}`);\n stateVal = state && state.val ? JSON.parse(state.val as string) : {};\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not get state for scope \"${scope}\": ${e.message}`);\n }\n\n for (const [category, categoryObj] of Object.entries(currentNotificationScope)) {\n if (categoryFilter && categoryFilter !== category) {\n // category filtered out\n continue;\n }\n\n let categoryCounter = 0;\n for (const instance of Object.keys(categoryObj)) {\n if (instanceFilter && instanceFilter !== instance) {\n // instance filtered out - message counter remains\n categoryCounter += 1;\n continue;\n }\n\n // not filtered out -> remove\n delete categoryObj[instance];\n }\n\n stateVal[category] = { count: categoryCounter };\n\n // check if all instances of this category deleted\n if (!Object.keys(categoryObj).length) {\n delete currentNotificationScope[category];\n delete stateVal[category];\n }\n }\n\n // check if all categories of this scope deleted\n if (!Object.keys(currentNotificationScope).length) {\n delete this.currentNotifications[scope];\n }\n\n // set updated state\n try {\n await this.states.setState(`system.host.${this.host}.notifications.${scope}`, {\n val: JSON.stringify(stateVal),\n ack: true,\n });\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Could not set notifications state for scope \"${scope}\": ${e.message}`,\n );\n }\n }\n }\n\n /**\n * Check if given scope exists in config\n *\n * @param scope - scope to be checked for\n */\n scopeExists(scope: string): boolean {\n return !!this.setup[scope];\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Notification handler class\n *\n * 2021-2024 foxriver76 <moritz.heusinger@gmail.com>\n */\n\nimport fs from 'fs-extra';\nimport { tools } from '@iobroker/js-controller-common-db';\nimport path from 'node:path';\nimport type { Client as StatesInRedisClient } from '@iobroker/db-states-redis';\nimport type { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';\nimport type Winston from 'winston';\n\ntype MultilingualObject = Exclude<ioBroker.StringOrTranslated, string>;\n\n/** Settings to configure an instance of NotificationHandler */\nexport interface NotificationHandlerSettings {\n /** Name of the host (not id - hence, without `system.host.` prefix) */\n host: string;\n /** States DB instance */\n states: StatesInRedisClient;\n /** Objects DB instance */\n objects: ObjectsInRedisClient;\n /** Logger instance */\n log: Winston.Logger | Console;\n /** Prefix for the log messages */\n logPrefix: string;\n}\n\n/** A notification config entry represents the top level of the notification structure */\nexport interface NotificationsConfigEntry {\n /** e.g. system */\n scope: string;\n /** multilingual name */\n name: MultilingualObject;\n /** multilingual description */\n description: MultilingualObject;\n /** The notification categories inside this scope */\n categories: CategoryConfigEntry[];\n}\n\nexport type Severity = 'info' | 'notify' | 'alert';\n\n/** A notification category entry represents one of the categories of a scope */\nexport interface CategoryConfigEntry {\n /** Id of the category */\n category: string;\n /** Name of the category */\n name: MultilingualObject;\n /** Allows defining the severity of the notification with `info` being the lowest, `notify` representing middle priority, `alert` representing high priority and often containing critical information */\n severity: Severity;\n /** Description of the category */\n description: MultilingualObject;\n /** Regex where `console.error` output is parsed against to check if a notification of this category should be generated */\n regex: string[];\n /** Restrict the maximum number of messages for this category */\n limit: number;\n}\n\ninterface NotificationMessageObject {\n message: string;\n ts: number;\n contextData?: ioBroker.NotificationContextData;\n}\n\ninterface NotificationsCategory {\n [category: string]: {\n [instance: string]: NotificationMessageObject[];\n };\n}\n\ninterface NotificationsObject {\n [scope: string]: NotificationsCategory;\n}\n\ninterface FilteredNotificationCategory {\n description: MultilingualObject;\n name: MultilingualObject;\n severity: Severity;\n instances: {\n [instance: string]: {\n messages: NotificationMessageObject[];\n };\n };\n}\n\ninterface FilteredNotificationScope {\n description: MultilingualObject;\n name: MultilingualObject;\n categories: {\n [category: string]: FilteredNotificationCategory;\n };\n}\n\n/** The filtered information as a response for `getFilteredInformation` */\nexport interface FilteredNotificationInformation {\n [scope: string]: FilteredNotificationScope;\n}\n\ninterface NotificationSetupCategory {\n regex: RegExp[];\n limit: number;\n name: MultilingualObject;\n severity: Severity;\n description: MultilingualObject;\n}\n\ninterface NotificationSetupObject {\n [scope: string]: {\n name: MultilingualObject;\n description: MultilingualObject;\n categories: {\n [category: string]: NotificationSetupCategory;\n };\n };\n}\n\ninterface ScopeStateValue {\n [category: string]: {\n count: number;\n };\n}\n\ninterface AddMessageOptions {\n /** Scope of the message */\n scope: string;\n /** Category of the message, if non we check against regex of scope */\n category?: string | null;\n /** Message to add */\n message: string;\n /** Instance e.g., hm-rpc.1 or hostname, if hostname it needs to be prefixed like system.host.rpi */\n instance: string;\n /** Additional context for the notification which can be used by notification processing adapters */\n contextData?: ioBroker.NotificationContextData;\n}\n\n/**\n * The Notification handler class provides an interface to manage the ioBroker notification system\n */\nexport class NotificationHandler {\n private states: StatesInRedisClient;\n private objects: ObjectsInRedisClient;\n private log: Winston.Logger | Console;\n private currentNotifications: NotificationsObject = {};\n // default data dir is relative to controllerDir\n private readonly dataDir = path.join(tools.getControllerDir(), tools.getDefaultDataDir());\n private readonly setup: NotificationSetupObject = {};\n private readonly logPrefix: string;\n private readonly host: string;\n\n /**\n * Creates a new instance of the notification handler class\n *\n * @param settings settings to configure the handler instance\n */\n constructor(settings: NotificationHandlerSettings) {\n this.states = settings.states;\n this.objects = settings.objects;\n this.log = settings.log;\n this.logPrefix = settings.logPrefix;\n this.host = settings.host;\n\n // load notifications file\n this._loadNotifications();\n }\n\n /**\n * Get all adapter instances on this host and store their notifications config - and clears up removed instances notifications - should be called once after init\n */\n async getSetupOfAllAdaptersFromHost(): Promise<void> {\n // create the initial notifications object\n let obj;\n try {\n obj = await this.objects.getObject(`system.host.${this.host}.notifications`);\n } catch {\n // ignore\n }\n\n if (!obj) {\n try {\n await this.objects.setObject(`system.host.${this.host}.notifications`, {\n type: 'folder',\n common: {\n name: {\n en: 'Notifications',\n de: 'Benachrichtigungen',\n ru: '\u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F',\n pt: 'Notifica\u00E7\u00F5es',\n nl: 'Meldingen',\n fr: 'Notifications',\n it: 'Notifiche',\n es: 'Notificaciones',\n pl: 'Powiadomienia',\n uk: '\u0421\u043F\u043E\u0432\u0456\u0449\u0435\u043D\u043D\u044F',\n 'zh-cn': '\u901A\u77E5\u4E8B\u9879',\n },\n },\n native: {},\n });\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not create notifications object: ${e.message}`);\n }\n }\n\n const instancesOnHost = [];\n // get all instances\n try {\n const res = await this.objects.getObjectViewAsync('system', 'instance', {\n startkey: 'system.adapter.',\n endkey: 'system.adapter.\\u9999',\n });\n\n for (const entry of res.rows) {\n // check that instance has notification settings\n if (entry.value.notifications) {\n await this.addConfig(entry.value.notifications);\n }\n\n if (entry.value.common && entry.value.common.host === this.host) {\n // if it's on our current host\n instancesOnHost.push(entry.id);\n }\n }\n } catch (e) {\n throw new Error(`Could not get notifications setup from instances: ${e.message}`);\n }\n\n // now clear up all notifications that do not belong to our host anymore\n for (const notificationsCategory of Object.values(this.currentNotifications)) {\n for (const instancesInfo of Object.values(notificationsCategory)) {\n for (const instance of Object.keys(instancesInfo)) {\n if (!instancesOnHost.includes(instance) && instance !== `system.host.${this.host}`) {\n // instance no longer on host\n this.log.info(`${this.logPrefix} Instance ${instance} removed from host, clear notifications`);\n await this.clearNotifications(null, null, instance);\n }\n }\n }\n }\n\n // now sync RAM with state\n await this._updateScopeStates();\n }\n\n /**\n * Add a new category to the given scope with a provided optional list of regex\n *\n * @param notifications - Array with notifications\n */\n async addConfig(notifications: NotificationsConfigEntry[]): Promise<void> {\n // if valid attributes, store it\n if (Array.isArray(notifications)) {\n for (const scopeObj of notifications) {\n // create the state object for each scope if non-existing\n let obj;\n try {\n obj = await this.objects.getObject(`system.host.${this.host}.notifications.${scopeObj.scope}`);\n } catch {\n // ignore\n }\n\n if (!obj) {\n try {\n await this.objects.setObject(`system.host.${this.host}.notifications.${scopeObj.scope}`, {\n type: 'state',\n common: {\n type: 'object',\n role: 'value',\n read: true,\n write: false,\n name: scopeObj.name,\n desc: scopeObj.description,\n },\n native: {},\n });\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Could not create notifications object for scope \"${scopeObj.scope}\": ${e.message}`,\n );\n }\n }\n\n if (Array.isArray(scopeObj.categories) && scopeObj.categories.length) {\n const setupScope = this.setup[scopeObj.scope] || {\n name: scopeObj.name,\n description: scopeObj.description,\n categories: {},\n };\n\n // only if scope has at least one category\n this.setup[scopeObj.scope] = setupScope;\n\n for (const categoryObj of scopeObj.categories) {\n const setupCategory = setupScope.categories[categoryObj.category] || {\n regex: [],\n limit: categoryObj.limit,\n name: categoryObj.name,\n severity: categoryObj.severity,\n description: categoryObj.description,\n };\n setupScope.categories[categoryObj.category] = setupCategory;\n\n try {\n let regex: RegExp[] = [];\n if (Array.isArray(categoryObj.regex)) {\n for (const regexString of categoryObj.regex) {\n regex.push(new RegExp(regexString));\n }\n } else if (typeof categoryObj.regex === 'string') {\n // if someone passes a string, convert to a single entry array\n regex = [new RegExp(categoryObj.regex)];\n }\n\n setupCategory.regex = regex;\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Cannot store regex \"${JSON.stringify(categoryObj.regex)}\" for scope \"${\n scopeObj.scope\n }\", category \"${categoryObj.category}\": ${e.message}`,\n );\n }\n }\n }\n }\n }\n }\n\n /**\n * Add a message to the scope and category\n *\n * @param options The scope, category, message, instance and contextData information\n */\n async addMessage(options: AddMessageOptions): Promise<void> {\n const { message, scope, category, contextData } = options;\n let { instance } = options;\n\n if (typeof instance !== 'string') {\n this.log.error(\n `${this.logPrefix} [addMessage] Instance has to be of type \"string\", got \"${typeof instance}\"`,\n );\n return;\n }\n\n if (!instance.startsWith('system.adapter.') && !instance.startsWith('system.host.')) {\n instance = `system.adapter.${instance}`;\n }\n\n // get state of the scope\n let stateVal: ScopeStateValue = {};\n try {\n const state = await this.states.getStateAsync(`system.host.${this.host}.notifications.${scope}`);\n stateVal = state?.val ? JSON.parse(state.val as string) : {};\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not get state for scope \"${scope}\": ${e.message}`);\n }\n\n let categories = [category];\n\n if (!category) {\n // check regex - in parse text we can have multiple matches\n categories = this._parseText(scope, message);\n }\n\n const currentScopeObj = this.currentNotifications[scope] || {};\n this.currentNotifications[scope] = currentScopeObj;\n\n for (const _category of categories) {\n if (!_category) {\n continue;\n }\n\n const currentCategoryObj = currentScopeObj[_category] || {};\n currentScopeObj[_category] = currentCategoryObj;\n\n // array of all messages for instance/category\n const currentInstances = currentCategoryObj[instance] || [];\n currentCategoryObj[instance] = currentInstances;\n\n const setupCategory = this.setup[scope]?.categories[_category];\n\n if (!setupCategory) {\n // no setup for this instance/category combination found - so we have nothing to add\n this.log.warn(\n `${this.logPrefix} No configuration found for scope \"${scope}\" and category \"${_category}\"`,\n );\n continue;\n }\n\n // if limit exceeded, remove last element - use while if it somehow grew too big\n while (setupCategory.limit < currentInstances.length + 1) {\n currentInstances.pop();\n }\n\n // add a new element at the beginning\n currentInstances.unshift({ message, ts: Date.now(), contextData });\n }\n\n // now count all messages of this scope - if nothing matched it can be undefined, and we can skip\n if (tools.isObject(this.currentNotifications[scope])) {\n for (const [categoryName, category] of Object.entries(currentScopeObj)) {\n const categoryCounter = Object.keys(category).length;\n\n stateVal[categoryName] = { count: categoryCounter };\n }\n }\n\n // set updated scope state\n try {\n await this.states.setState(`system.host.${this.host}.notifications.${scope}`, {\n val: JSON.stringify(stateVal),\n ack: true,\n });\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not set notifications state for scope \"${scope}\": ${e.message}`);\n }\n }\n\n /**\n * Updates all scope states by current notifications in RAM\n */\n private async _updateScopeStates(): Promise<void> {\n for (const [scope, scopeObj] of Object.entries(this.currentNotifications)) {\n const stateVal: ScopeStateValue = {};\n\n for (const [category, categoryObj] of Object.entries(scopeObj)) {\n // count the number of instances with this error\n const catCounter = Object.keys(categoryObj).length;\n stateVal[category] = { count: catCounter };\n }\n\n // set updated scope state\n try {\n await this.states.setState(`system.host.${this.host}.notifications.${scope}`, {\n val: JSON.stringify(stateVal),\n ack: true,\n });\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Could not set notifications state for scope \"${scope}\": ${e.message}`,\n );\n }\n }\n }\n\n /**\n * Check the given message against all regular expressions of the given scope\n *\n * @param scope - scope of the message\n * @param message - message to check\n */\n private _parseText(scope: string, message: string): string[] {\n const categories: string[] = [];\n\n const scopeObj = this.setup[scope];\n\n if (!scopeObj) {\n return categories;\n }\n\n for (const [categoryId, categoryObj] of Object.entries(scopeObj.categories)) {\n // check all regular expressions for this category\n for (const regex of categoryObj.regex) {\n if (regex.test(message)) {\n // matching category\n categories.push(categoryId);\n // no further testing needed for this category\n break;\n }\n }\n }\n\n return categories;\n }\n\n /**\n * Load notifications from a file\n */\n private _loadNotifications(): void {\n try {\n this.currentNotifications = fs.readJSONSync(path.join(this.dataDir, 'notifications.json'));\n } catch (e) {\n // at first start its normal, that we cannot read notifications, so just info\n this.log.debug(`${this.logPrefix} Could not read notifications.json: ${e.message}`);\n }\n }\n\n /**\n * Save current notifications to file\n */\n storeNotifications(): void {\n try {\n fs.writeJSONSync(path.join(this.dataDir, 'notifications.json'), this.currentNotifications);\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not write notifications.json: ${e.message}`);\n }\n }\n\n /**\n * Returns the stored notifications matching the filters with description and name\n *\n * @param scopeFilter - scope of notifications\n * @param categoryFilter - category of notifications\n * @param instanceFilter - instance of notifications\n */\n getFilteredInformation(\n scopeFilter: string | null | undefined,\n categoryFilter: string | null | undefined,\n instanceFilter: string | null | undefined,\n ): FilteredNotificationInformation {\n const res: FilteredNotificationInformation = {};\n for (const [scope, currentNotification] of Object.entries(this.currentNotifications)) {\n if (scopeFilter && scopeFilter !== scope) {\n // scope filtered out\n continue;\n }\n\n const scopeObj = this.setup[scope];\n\n if (!scopeObj) {\n // no scope set up\n continue;\n }\n\n const scopeResult: FilteredNotificationScope = {\n categories: {},\n description: scopeObj.description,\n name: scopeObj.name,\n };\n\n res[scope] = scopeResult;\n\n for (const [category, currentCategoryObj] of Object.entries(currentNotification)) {\n if (categoryFilter && categoryFilter !== category) {\n // category filtered out\n continue;\n }\n\n const categoryObj = scopeObj.categories[category];\n\n if (!categoryObj) {\n // no category set up\n continue;\n }\n\n const resultCategories: FilteredNotificationCategory = {\n instances: {},\n description: categoryObj.description,\n name: categoryObj.name,\n severity: categoryObj.severity,\n };\n\n scopeResult.categories[category] = resultCategories;\n\n for (const [instance, instanceObj] of Object.entries(currentCategoryObj)) {\n if (instanceFilter && instanceFilter !== instance) {\n // instance filtered out\n continue;\n }\n\n resultCategories.instances[instance] = {\n messages: instanceObj,\n };\n }\n }\n }\n return res;\n }\n\n /**\n * Clears the stored notifications matching the filters\n *\n * @param scopeFilter - scope of notifications\n * @param categoryFilter - category of notifications\n * @param instanceFilter - instance of notifications\n */\n async clearNotifications(\n scopeFilter: string | null | undefined,\n categoryFilter: string | null | undefined,\n instanceFilter: string | null | undefined,\n ): Promise<void> {\n for (const scope of Object.keys(this.currentNotifications)) {\n const currentNotificationScope = this.currentNotifications[scope];\n\n if (!currentNotificationScope) {\n delete this.currentNotifications[scope];\n continue;\n }\n if (scopeFilter && scopeFilter !== scope) {\n // skip this, because not desired to be deleted\n continue;\n }\n\n let stateVal: ScopeStateValue = {};\n try {\n const state = await this.states.getStateAsync(`system.host.${this.host}.notifications.${scope}`);\n stateVal = state && state.val ? JSON.parse(state.val as string) : {};\n } catch (e) {\n this.log.error(`${this.logPrefix} Could not get state for scope \"${scope}\": ${e.message}`);\n }\n\n for (const [category, categoryObj] of Object.entries(currentNotificationScope)) {\n if (categoryFilter && categoryFilter !== category) {\n // category filtered out\n continue;\n }\n\n let categoryCounter = 0;\n for (const instance of Object.keys(categoryObj)) {\n if (instanceFilter && instanceFilter !== instance) {\n // instance filtered out - message counter remains\n categoryCounter += 1;\n continue;\n }\n\n // not filtered out -> remove\n delete categoryObj[instance];\n }\n\n stateVal[category] = { count: categoryCounter };\n\n // check if all instances of this category deleted\n if (!Object.keys(categoryObj).length) {\n delete currentNotificationScope[category];\n delete stateVal[category];\n }\n }\n\n // check if all categories of this scope deleted\n if (!Object.keys(currentNotificationScope).length) {\n delete this.currentNotifications[scope];\n }\n\n // set updated state\n try {\n await this.states.setState(`system.host.${this.host}.notifications.${scope}`, {\n val: JSON.stringify(stateVal),\n ack: true,\n });\n } catch (e) {\n this.log.error(\n `${this.logPrefix} Could not set notifications state for scope \"${scope}\": ${e.message}`,\n );\n }\n }\n }\n\n /**\n * Check if given scope exists in config\n *\n * @param scope - scope to be checked for\n */\n scopeExists(scope: string): boolean {\n return !!this.setup[scope];\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["path", "category", "fs"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';
|
|
2
|
-
/**
|
|
3
|
-
* Get the objects database client constructor matching the configured objects DB type
|
|
4
|
-
*/
|
|
5
2
|
export declare function getObjectsConstructor(): Promise<typeof ObjectsClient>;
|
|
6
3
|
/**
|
|
7
4
|
* Allows to find out if a given objects dbType offers a server which runs on this host and listens (locally or globally/by IP)
|
|
@@ -5,7 +5,6 @@ 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 });
|
|
9
8
|
var __export = (target, all) => {
|
|
10
9
|
for (var name in all)
|
|
11
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -51,7 +50,6 @@ async function getObjectsConstructor() {
|
|
|
51
50
|
process.exit(101);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
|
-
__name(getObjectsConstructor, "getObjectsConstructor");
|
|
55
53
|
async function isLocalObjectsDbServer(dbType, host, checkIfLocalOnly = false) {
|
|
56
54
|
const hasServer = await objectsDbHasServer(dbType);
|
|
57
55
|
if (!hasServer) {
|
|
@@ -67,7 +65,6 @@ async function isLocalObjectsDbServer(dbType, host, checkIfLocalOnly = false) {
|
|
|
67
65
|
}
|
|
68
66
|
return result;
|
|
69
67
|
}
|
|
70
|
-
__name(isLocalObjectsDbServer, "isLocalObjectsDbServer");
|
|
71
68
|
async function objectsDbHasServer(dbType) {
|
|
72
69
|
try {
|
|
73
70
|
const objects = await import(`@iobroker/db-objects-${dbType}`);
|
|
@@ -77,7 +74,6 @@ async function objectsDbHasServer(dbType) {
|
|
|
77
74
|
throw new Error(`Installation error or unknown objects database type: ${dbType}`);
|
|
78
75
|
}
|
|
79
76
|
}
|
|
80
|
-
__name(objectsDbHasServer, "objectsDbHasServer");
|
|
81
77
|
async function performObjectsInterview(options) {
|
|
82
78
|
const { dbType, config } = options;
|
|
83
79
|
const objects = await import(`@iobroker/db-objects-${dbType}`);
|
|
@@ -86,7 +82,6 @@ async function performObjectsInterview(options) {
|
|
|
86
82
|
}
|
|
87
83
|
return objects.interview(config);
|
|
88
84
|
}
|
|
89
|
-
__name(performObjectsInterview, "performObjectsInterview");
|
|
90
85
|
// Annotate the CommonJS export names for ESM import in node:
|
|
91
86
|
0 && (module.exports = {
|
|
92
87
|
getObjectsConstructor,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/objects.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'fs-extra';\nimport { tools } from '@iobroker/js-controller-common';\nimport type { Client as ObjectsClient, interview } from '@iobroker/db-objects-redis';\n\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import fs from 'fs-extra';\nimport { tools } from '@iobroker/js-controller-common';\nimport type { Client as ObjectsClient, interview } from '@iobroker/db-objects-redis';\n\nexport async function getObjectsConstructor(): Promise<typeof ObjectsClient> {\n const config = fs.readJSONSync(tools.getConfigFileName());\n if (!config.objects) {\n config.objects = { type: 'jsonl' };\n }\n\n try {\n const Client = (await import(`@iobroker/db-objects-${config.objects.type}`)).Client;\n return Client;\n } catch (e) {\n console.error(e.stack);\n console.error(`Installation broken or unknown objects type: ${config.objects.type} configured`);\n process.exit(101);\n }\n}\n\n/**\n * Allows to find out if a given objects dbType offers a server which runs on this host and listens (locally or globally/by IP)\n *\n * @param dbType database type\n * @param host configured db host - multihost (array) will always return false\n * @param checkIfLocalOnly if true the method checks if the server listens to local connections only; else also external connection options are checked\n * @returns true if a server listens on this host (locally or globally/by IP)\n */\nexport async function isLocalObjectsDbServer(\n dbType: string,\n host: string | string[],\n checkIfLocalOnly: boolean = false,\n): Promise<boolean> {\n const hasServer = await objectsDbHasServer(dbType);\n if (!hasServer) {\n return false; // if no server it can not be a local server\n }\n\n if (Array.isArray(host)) {\n return false;\n }\n\n let result = host === 'localhost' || tools.isLocalAddress(host); // reachable locally only\n if (!checkIfLocalOnly) {\n const ownIps = tools.findIPs();\n result = result || tools.isListenAllAddress(host) || ownIps.includes(host);\n }\n\n return result;\n}\n\n/**\n * Allows to find out if a given objects dbType offers a server or not\n *\n * @param dbType database type\n * @returns true if a server class is available\n */\nexport async function objectsDbHasServer(dbType: string): Promise<boolean> {\n try {\n const objects = await import(`@iobroker/db-objects-${dbType}`);\n return !!objects.Server;\n } catch (e) {\n console.error(e);\n throw new Error(`Installation error or unknown objects database type: ${dbType}`);\n }\n}\n\ninterface PerformObjectsInterviewOptions {\n /** The partial states db options */\n config: ioBroker.ObjectsDatabaseOptions;\n /** Db type, like redis */\n dbType: string;\n}\n\n/**\n * Perform the objects interview if one has been provided\n *\n * @param options dbtype and the partial config\n * @returns the database options obtained by the answered questionnaire\n */\nexport async function performObjectsInterview(\n options: PerformObjectsInterviewOptions,\n): Promise<ioBroker.ObjectsDatabaseOptions> {\n const { dbType, config } = options;\n\n const objects = await import(`@iobroker/db-objects-${dbType}`);\n if (!objects.interview) {\n return config;\n }\n\n return objects.interview(config satisfies Parameters<typeof interview>[0]);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAAA,sBAAe;AACf,kCAAsB;AAGtB,eAAsB,wBAAqB;AACvC,QAAM,SAAS,gBAAAA,QAAG,aAAa,kCAAM,kBAAiB,CAAE;AACxD,MAAI,CAAC,OAAO,SAAS;AACjB,WAAO,UAAU,EAAE,MAAM,QAAO;EACpC;AAEA,MAAI;AACA,UAAM,UAAU,MAAM,OAAO,wBAAwB,OAAO,QAAQ,IAAI,KAAK;AAC7E,WAAO;EACX,SAAS,GAAG;AACR,YAAQ,MAAM,EAAE,KAAK;AACrB,YAAQ,MAAM,gDAAgD,OAAO,QAAQ,IAAI,aAAa;AAC9F,YAAQ,KAAK,GAAG;EACpB;AACJ;AAUA,eAAsB,uBAClB,QACA,MACA,mBAA4B,OAAK;AAEjC,QAAM,YAAY,MAAM,mBAAmB,MAAM;AACjD,MAAI,CAAC,WAAW;AACZ,WAAO;EACX;AAEA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACrB,WAAO;EACX;AAEA,MAAI,SAAS,SAAS,eAAe,kCAAM,eAAe,IAAI;AAC9D,MAAI,CAAC,kBAAkB;AACnB,UAAM,SAAS,kCAAM,QAAO;AAC5B,aAAS,UAAU,kCAAM,mBAAmB,IAAI,KAAK,OAAO,SAAS,IAAI;EAC7E;AAEA,SAAO;AACX;AAQA,eAAsB,mBAAmB,QAAc;AACnD,MAAI;AACA,UAAM,UAAU,MAAM,OAAO,wBAAwB,MAAM;AAC3D,WAAO,CAAC,CAAC,QAAQ;EACrB,SAAS,GAAG;AACR,YAAQ,MAAM,CAAC;AACf,UAAM,IAAI,MAAM,wDAAwD,MAAM,EAAE;EACpF;AACJ;AAeA,eAAsB,wBAClB,SAAuC;AAEvC,QAAM,EAAE,QAAQ,OAAM,IAAK;AAE3B,QAAM,UAAU,MAAM,OAAO,wBAAwB,MAAM;AAC3D,MAAI,CAAC,QAAQ,WAAW;AACpB,WAAO;EACX;AAEA,SAAO,QAAQ,UAAU,MAAgD;AAC7E;",
|
|
6
6
|
"names": ["fs"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import type { Client as StatesClient } from '@iobroker/db-states-redis';
|
|
2
|
-
/**
|
|
3
|
-
* Get the states database client constructor matching the configured states DB type
|
|
4
|
-
*/
|
|
5
2
|
export declare function getStatesConstructor(): Promise<typeof StatesClient>;
|
|
6
3
|
/**
|
|
7
4
|
* Allows to find out if a given states dbType offers a server or not
|
|
@@ -5,7 +5,6 @@ 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 });
|
|
9
8
|
var __export = (target, all) => {
|
|
10
9
|
for (var name in all)
|
|
11
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -51,7 +50,6 @@ async function getStatesConstructor() {
|
|
|
51
50
|
process.exit(101);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
|
-
__name(getStatesConstructor, "getStatesConstructor");
|
|
55
53
|
async function statesDbHasServer(dbType) {
|
|
56
54
|
try {
|
|
57
55
|
const states = await import(`@iobroker/db-states-${dbType}`);
|
|
@@ -60,7 +58,6 @@ async function statesDbHasServer(dbType) {
|
|
|
60
58
|
throw new Error(`Installation error or unknown states database type: ${dbType}`);
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
|
-
__name(statesDbHasServer, "statesDbHasServer");
|
|
64
61
|
async function isLocalStatesDbServer(dbType, host, checkIfLocalOnly = false) {
|
|
65
62
|
const hasServer = await statesDbHasServer(dbType);
|
|
66
63
|
if (!hasServer) {
|
|
@@ -76,7 +73,6 @@ async function isLocalStatesDbServer(dbType, host, checkIfLocalOnly = false) {
|
|
|
76
73
|
}
|
|
77
74
|
return result;
|
|
78
75
|
}
|
|
79
|
-
__name(isLocalStatesDbServer, "isLocalStatesDbServer");
|
|
80
76
|
async function performStatesInterview(options) {
|
|
81
77
|
const { dbType, config } = options;
|
|
82
78
|
const states = await import(`@iobroker/db-states-${dbType}`);
|
|
@@ -85,7 +81,6 @@ async function performStatesInterview(options) {
|
|
|
85
81
|
}
|
|
86
82
|
return states.interview(config);
|
|
87
83
|
}
|
|
88
|
-
__name(performStatesInterview, "performStatesInterview");
|
|
89
84
|
// Annotate the CommonJS export names for ESM import in node:
|
|
90
85
|
0 && (module.exports = {
|
|
91
86
|
getStatesConstructor,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/states.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'fs-extra';\nimport { tools } from '@iobroker/js-controller-common';\nimport type { Client as StatesClient, interview } from '@iobroker/db-states-redis';\n\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import fs from 'fs-extra';\nimport { tools } from '@iobroker/js-controller-common';\nimport type { Client as StatesClient, interview } from '@iobroker/db-states-redis';\n\nexport async function getStatesConstructor(): Promise<typeof StatesClient> {\n const config = fs.readJSONSync(tools.getConfigFileName());\n if (!config.states) {\n config.states = { type: 'jsonl' };\n }\n\n try {\n const Client = (await import(`@iobroker/db-states-${config.states.type}`)).Client;\n return Client;\n } catch (e) {\n console.error(e.stack);\n console.error(`Installation broken or unknown states type: ${config.states.type} configured.`);\n process.exit(101);\n }\n}\n\n/**\n * Allows to find out if a given states dbType offers a server or not\n *\n * @param dbType database type\n * @returns true if a server class is available\n */\nexport async function statesDbHasServer(dbType: string): Promise<boolean> {\n try {\n const states = await import(`@iobroker/db-states-${dbType}`);\n return !!states.Server;\n } catch {\n throw new Error(`Installation error or unknown states database type: ${dbType}`);\n }\n}\n\n/**\n * Allows to find out if a given states dbType offers a server which runs on this host and listens (locally or globally/by IP)\n *\n * @param dbType database type\n * @param host configured db host - multihost (array) will always return false\n * @param checkIfLocalOnly if true the method checks if the server listens to local connections only; else also external connection options are checked\n * @returns true if a server listens on this host (locally or globally/by IP)\n */\nexport async function isLocalStatesDbServer(\n dbType: string,\n host: string | string[],\n checkIfLocalOnly = false,\n): Promise<boolean> {\n const hasServer = await statesDbHasServer(dbType);\n if (!hasServer) {\n return false; // if no server it can not be a local server\n }\n\n if (Array.isArray(host)) {\n return false;\n }\n\n let result = host === 'localhost' || tools.isLocalAddress(host); // reachable locally only\n if (!checkIfLocalOnly && !Array.isArray(host)) {\n const ownIps = tools.findIPs();\n result = result || tools.isListenAllAddress(host) || ownIps.includes(host);\n }\n\n return result;\n}\n\ninterface PerformStatesInterviewOptions {\n /** The partial states db options */\n config: ioBroker.StatesDatabaseOptions;\n /** Db type, like redis */\n dbType: string;\n}\n\n/**\n * Perform the states interview if one has been provided\n *\n * @param options db type and partial config\n * @returns the database options obtained by the answered questionnaire\n */\nexport async function performStatesInterview(\n options: PerformStatesInterviewOptions,\n): Promise<ioBroker.StatesDatabaseOptions> {\n const { dbType, config } = options;\n\n const states = await import(`@iobroker/db-states-${dbType}`);\n if (!states.interview) {\n return config;\n }\n\n return states.interview(config satisfies Parameters<typeof interview>[0]);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAAA,sBAAe;AACf,kCAAsB;AAGtB,eAAsB,uBAAoB;AACtC,QAAM,SAAS,gBAAAA,QAAG,aAAa,kCAAM,kBAAiB,CAAE;AACxD,MAAI,CAAC,OAAO,QAAQ;AAChB,WAAO,SAAS,EAAE,MAAM,QAAO;EACnC;AAEA,MAAI;AACA,UAAM,UAAU,MAAM,OAAO,uBAAuB,OAAO,OAAO,IAAI,KAAK;AAC3E,WAAO;EACX,SAAS,GAAG;AACR,YAAQ,MAAM,EAAE,KAAK;AACrB,YAAQ,MAAM,+CAA+C,OAAO,OAAO,IAAI,cAAc;AAC7F,YAAQ,KAAK,GAAG;EACpB;AACJ;AAQA,eAAsB,kBAAkB,QAAc;AAClD,MAAI;AACA,UAAM,SAAS,MAAM,OAAO,uBAAuB,MAAM;AACzD,WAAO,CAAC,CAAC,OAAO;EACpB,QAAQ;AACJ,UAAM,IAAI,MAAM,uDAAuD,MAAM,EAAE;EACnF;AACJ;AAUA,eAAsB,sBAClB,QACA,MACA,mBAAmB,OAAK;AAExB,QAAM,YAAY,MAAM,kBAAkB,MAAM;AAChD,MAAI,CAAC,WAAW;AACZ,WAAO;EACX;AAEA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACrB,WAAO;EACX;AAEA,MAAI,SAAS,SAAS,eAAe,kCAAM,eAAe,IAAI;AAC9D,MAAI,CAAC,oBAAoB,CAAC,MAAM,QAAQ,IAAI,GAAG;AAC3C,UAAM,SAAS,kCAAM,QAAO;AAC5B,aAAS,UAAU,kCAAM,mBAAmB,IAAI,KAAK,OAAO,SAAS,IAAI;EAC7E;AAEA,SAAO;AACX;AAeA,eAAsB,uBAClB,SAAsC;AAEtC,QAAM,EAAE,QAAQ,OAAM,IAAK;AAE3B,QAAM,SAAS,MAAM,OAAO,uBAAuB,MAAM;AACzD,MAAI,CAAC,OAAO,WAAW;AACnB,WAAO;EACX;AAEA,SAAO,OAAO,UAAU,MAAgD;AAC5E;",
|
|
6
6
|
"names": ["fs"]
|
|
7
7
|
}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';
|
|
2
2
|
import type { InternalLogger } from '@iobroker/js-controller-common-db/tools';
|
|
3
3
|
import { type SupportedFeature } from './constants.js';
|
|
4
|
-
/** Instances grouped by their startup priority tier */
|
|
5
4
|
export interface OrderedInstancesObject {
|
|
6
|
-
/** Instances in tier 1, started first */
|
|
7
5
|
1: ioBroker.InstanceObject[];
|
|
8
|
-
/** Instances in tier 2, started after tier 1 */
|
|
9
6
|
2: ioBroker.InstanceObject[];
|
|
10
|
-
/** Instances in tier 3, started last */
|
|
11
7
|
3: ioBroker.InstanceObject[];
|
|
12
|
-
/** Admin instances, handled separately from the regular tiers */
|
|
13
8
|
admin: ioBroker.InstanceObject[];
|
|
14
9
|
}
|
|
15
10
|
/**
|
|
@@ -3,7 +3,6 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
6
|
var __export = (target, all) => {
|
|
8
7
|
for (var name in all)
|
|
9
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -62,7 +61,6 @@ async function getInstancesOrderedByStartPrio(objects, logger, logPrefix = "") {
|
|
|
62
61
|
}
|
|
63
62
|
return [...instances.admin, ...instances["1"], ...instances["2"], ...instances["3"]];
|
|
64
63
|
}
|
|
65
|
-
__name(getInstancesOrderedByStartPrio, "getInstancesOrderedByStartPrio");
|
|
66
64
|
function isInstalledFromNpm(options) {
|
|
67
65
|
const { adapterName, installedFrom } = options;
|
|
68
66
|
if (installedFrom === void 0) {
|
|
@@ -70,7 +68,6 @@ function isInstalledFromNpm(options) {
|
|
|
70
68
|
}
|
|
71
69
|
return installedFrom.startsWith(`${import_tools.appName.toLowerCase()}.${adapterName}`);
|
|
72
70
|
}
|
|
73
|
-
__name(isInstalledFromNpm, "isInstalledFromNpm");
|
|
74
71
|
function getSupportedFeatures() {
|
|
75
72
|
const features = [...import_constants.SUPPORTED_FEATURES];
|
|
76
73
|
if (!(0, import_tools.isControllerUiUpgradeSupported)()) {
|
|
@@ -81,7 +78,6 @@ function getSupportedFeatures() {
|
|
|
81
78
|
}
|
|
82
79
|
return features;
|
|
83
80
|
}
|
|
84
|
-
__name(getSupportedFeatures, "getSupportedFeatures");
|
|
85
81
|
// Annotate the CommonJS export names for ESM import in node:
|
|
86
82
|
0 && (module.exports = {
|
|
87
83
|
getInstancesOrderedByStartPrio,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/tools.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';\nimport { appName, isControllerUiUpgradeSupported } from '@iobroker/js-controller-common-db/tools';\nimport type { InternalLogger } from '@iobroker/js-controller-common-db/tools';\nimport { SUPPORTED_FEATURES, type SupportedFeature } from './constants.js';\n\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';\nimport { appName, isControllerUiUpgradeSupported } from '@iobroker/js-controller-common-db/tools';\nimport type { InternalLogger } from '@iobroker/js-controller-common-db/tools';\nimport { SUPPORTED_FEATURES, type SupportedFeature } from './constants.js';\n\nexport interface OrderedInstancesObject {\n 1: ioBroker.InstanceObject[];\n 2: ioBroker.InstanceObject[];\n 3: ioBroker.InstanceObject[];\n admin: ioBroker.InstanceObject[];\n}\n\n/**\n * Get ordered instances according to tier level\n *\n * @param objects - Objects DB\n * @param logger - logger object\n * @param logPrefix prefix for logging\n */\nexport async function getInstancesOrderedByStartPrio(\n objects: ObjectsClient,\n logger: InternalLogger | typeof console,\n logPrefix = '',\n): Promise<ioBroker.InstanceObject[]> {\n const instances: OrderedInstancesObject = { 1: [], 2: [], 3: [], admin: [] };\n const allowedTiers = [1, 2, 3];\n\n if (logPrefix) {\n // append space if we have a prefix\n logPrefix += ' ';\n }\n\n let doc: Awaited<ioBroker.GetObjectViewPromise<ioBroker.InstanceObject>> = { rows: [] };\n try {\n doc = await objects.getObjectViewAsync('system', 'instance', {\n startkey: 'system.adapter.',\n endkey: 'system.adapter.\\u9999',\n });\n } catch (e) {\n if (e.message?.startsWith('Cannot find ')) {\n logger.error(`${logPrefix} _design/system missing - call node ${appName}.js setup`);\n } else {\n logger.error(`${logPrefix} Can not get instances: ${e.message}`);\n }\n }\n\n if (!doc.rows || doc.rows.length === 0) {\n logger.info(`${logPrefix} no instances found`);\n } else {\n for (const row of doc.rows) {\n if (row?.value) {\n if (row.value._id.startsWith('system.adapter.admin')) {\n instances.admin.push(row.value);\n } else if (\n row.value.common?.tier !== undefined &&\n allowedTiers.includes(Math.round(row.value.common.tier))\n ) {\n instances[row.value.common.tier].push(row.value);\n } else {\n // no valid tier, so put it in the last one\n instances['3'].push(row.value);\n }\n }\n }\n }\n\n return [...instances.admin, ...instances['1'], ...instances['2'], ...instances['3']];\n}\n\ninterface IsInstalledFromNpmOptions {\n /** Installed from attribute of instance/adapter object */\n installedFrom?: ioBroker.InstalledFrom;\n /** Name of the adapter */\n adapterName: string;\n}\n\n/**\n * Check if the adapter has been installed from NPM\n *\n * @param options installedFrom and name information\n */\nexport function isInstalledFromNpm(options: IsInstalledFromNpmOptions): boolean {\n const { adapterName, installedFrom } = options;\n\n if (installedFrom === undefined) {\n return true;\n }\n\n return installedFrom.startsWith(`${appName.toLowerCase()}.${adapterName}`);\n}\n\n/**\n * Get the supported features for the current running controller\n */\nexport function getSupportedFeatures(): SupportedFeature[] {\n const features = [...SUPPORTED_FEATURES];\n\n if (!isControllerUiUpgradeSupported()) {\n const idx = features.indexOf('CONTROLLER_UI_UPGRADE');\n if (idx !== -1) {\n features.splice(idx, 1);\n }\n }\n\n return features;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AACA;;;;;;;AAAA,mBAAwD;AAExD,uBAA0D;AAgB1D,eAAsB,+BAClB,SACA,QACA,YAAY,IAAE;AAEd,QAAM,YAAoC,EAAE,GAAG,CAAA,GAAI,GAAG,CAAA,GAAI,GAAG,CAAA,GAAI,OAAO,CAAA,EAAE;AAC1E,QAAM,eAAe,CAAC,GAAG,GAAG,CAAC;AAE7B,MAAI,WAAW;AAEX,iBAAa;EACjB;AAEA,MAAI,MAAuE,EAAE,MAAM,CAAA,EAAE;AACrF,MAAI;AACA,UAAM,MAAM,QAAQ,mBAAmB,UAAU,YAAY;MACzD,UAAU;MACV,QAAQ;KACX;EACL,SAAS,GAAG;AACR,QAAI,EAAE,SAAS,WAAW,cAAc,GAAG;AACvC,aAAO,MAAM,GAAG,SAAS,uCAAuC,oBAAO,WAAW;IACtF,OAAO;AACH,aAAO,MAAM,GAAG,SAAS,2BAA2B,EAAE,OAAO,EAAE;IACnE;EACJ;AAEA,MAAI,CAAC,IAAI,QAAQ,IAAI,KAAK,WAAW,GAAG;AACpC,WAAO,KAAK,GAAG,SAAS,qBAAqB;EACjD,OAAO;AACH,eAAW,OAAO,IAAI,MAAM;AACxB,UAAI,KAAK,OAAO;AACZ,YAAI,IAAI,MAAM,IAAI,WAAW,sBAAsB,GAAG;AAClD,oBAAU,MAAM,KAAK,IAAI,KAAK;QAClC,WACI,IAAI,MAAM,QAAQ,SAAS,UAC3B,aAAa,SAAS,KAAK,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,GACzD;AACE,oBAAU,IAAI,MAAM,OAAO,IAAI,EAAE,KAAK,IAAI,KAAK;QACnD,OAAO;AAEH,oBAAU,GAAG,EAAE,KAAK,IAAI,KAAK;QACjC;MACJ;IACJ;EACJ;AAEA,SAAO,CAAC,GAAG,UAAU,OAAO,GAAG,UAAU,GAAG,GAAG,GAAG,UAAU,GAAG,GAAG,GAAG,UAAU,GAAG,CAAC;AACvF;AAcM,SAAU,mBAAmB,SAAkC;AACjE,QAAM,EAAE,aAAa,cAAa,IAAK;AAEvC,MAAI,kBAAkB,QAAW;AAC7B,WAAO;EACX;AAEA,SAAO,cAAc,WAAW,GAAG,qBAAQ,YAAW,CAAE,IAAI,WAAW,EAAE;AAC7E;AAKM,SAAU,uBAAoB;AAChC,QAAM,WAAW,CAAC,GAAG,mCAAkB;AAEvC,MAAI,KAAC,6CAA8B,GAAI;AACnC,UAAM,MAAM,SAAS,QAAQ,uBAAuB;AACpD,QAAI,QAAQ,IAAI;AACZ,eAAS,OAAO,KAAK,CAAC;IAC1B;EACJ;AAEA,SAAO;AACX;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,42 +1,6 @@
|
|
|
1
1
|
import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';
|
|
2
|
-
/**
|
|
3
|
-
* Pack all files of a directory into a zip archive
|
|
4
|
-
*
|
|
5
|
-
* @param objects The objects database client
|
|
6
|
-
* @param id The object ID owning the files
|
|
7
|
-
* @param name Path of the directory to read inside the object's file storage
|
|
8
|
-
* @param options Optional settings passed to the objects client, or the callback
|
|
9
|
-
* @param callback Called with the base64 encoded zip archive
|
|
10
|
-
*/
|
|
11
2
|
export declare function readDirAsZip(objects: ObjectsClient, id: string, name: string, options: any, callback: (err?: Error | null, base64?: string) => void): Promise<void>;
|
|
12
|
-
/**
|
|
13
|
-
* Unpack a zip archive and write all contained files into the object's file storage
|
|
14
|
-
*
|
|
15
|
-
* @param objects The objects database client
|
|
16
|
-
* @param id The object ID that should own the files
|
|
17
|
-
* @param name Target directory path inside the object's file storage
|
|
18
|
-
* @param data The zip archive as a buffer
|
|
19
|
-
* @param options Optional settings passed to the objects client
|
|
20
|
-
*/
|
|
21
3
|
export declare function writeDirAsZip(objects: ObjectsClient, id: string, name: string, data: Buffer, options: any): Promise<void>;
|
|
22
|
-
/**
|
|
23
|
-
* Read all objects below the given root ID and pack them into a zip archive
|
|
24
|
-
*
|
|
25
|
-
* @param objects The objects database client
|
|
26
|
-
* @param rootId The root object ID whose child objects should be exported
|
|
27
|
-
* @param adapter The adapter the objects belong to
|
|
28
|
-
* @param options Optional settings passed to the objects client
|
|
29
|
-
*/
|
|
30
4
|
export declare function readObjectsAsZip(objects: ObjectsClient, rootId: string, adapter: string, options?: any): Promise<string>;
|
|
31
|
-
/**
|
|
32
|
-
* Unpack a zip archive of objects and store them below the given root ID
|
|
33
|
-
*
|
|
34
|
-
* @param objects The objects database client
|
|
35
|
-
* @param rootId The root object ID the imported objects should be stored under
|
|
36
|
-
* @param adapter The adapter the objects belong to
|
|
37
|
-
* @param data The zip archive as a buffer
|
|
38
|
-
* @param options Optional settings passed to the objects client
|
|
39
|
-
* @param callback Called when the import has finished or failed
|
|
40
|
-
*/
|
|
41
5
|
export declare function writeObjectsAsZip(objects: ObjectsClient, rootId: string, adapter: string, data: Buffer, options: any, callback: (err?: Error | null) => void): Promise<void>;
|
|
42
6
|
//# sourceMappingURL=zipFiles.d.ts.map
|
|
@@ -5,7 +5,6 @@ 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 });
|
|
9
8
|
var __export = (target, all) => {
|
|
10
9
|
for (var name in all)
|
|
11
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -62,7 +61,6 @@ function _getAllFilesInDir(objects, id, name, options, callback, result) {
|
|
|
62
61
|
}
|
|
63
62
|
});
|
|
64
63
|
}
|
|
65
|
-
__name(_getAllFilesInDir, "_getAllFilesInDir");
|
|
66
64
|
function _addFile(objects, id, name, options, zip, callback) {
|
|
67
65
|
objects.readFile(id, name, options, (err, data, _mime) => {
|
|
68
66
|
if (err) {
|
|
@@ -89,7 +87,6 @@ function _addFile(objects, id, name, options, zip, callback) {
|
|
|
89
87
|
}
|
|
90
88
|
});
|
|
91
89
|
}
|
|
92
|
-
__name(_addFile, "_addFile");
|
|
93
90
|
async function readDirAsZip(objects, id, name, options, callback) {
|
|
94
91
|
if (typeof options === "function") {
|
|
95
92
|
callback = options;
|
|
@@ -130,7 +127,6 @@ async function readDirAsZip(objects, id, name, options, callback) {
|
|
|
130
127
|
}
|
|
131
128
|
});
|
|
132
129
|
}
|
|
133
|
-
__name(readDirAsZip, "readDirAsZip");
|
|
134
130
|
async function _checkDir(_options) {
|
|
135
131
|
const { parts, id, options, objects } = _options;
|
|
136
132
|
let { root } = _options;
|
|
@@ -147,7 +143,6 @@ async function _checkDir(_options) {
|
|
|
147
143
|
}
|
|
148
144
|
return _checkDir({ id, objects, options, root, parts });
|
|
149
145
|
}
|
|
150
|
-
__name(_checkDir, "_checkDir");
|
|
151
146
|
async function _writeOneFile(objects, zip, id, name, filename, options) {
|
|
152
147
|
const zipFile = zip.files[filename];
|
|
153
148
|
if (!zipFile) {
|
|
@@ -163,7 +158,6 @@ async function _writeOneFile(objects, zip, id, name, filename, options) {
|
|
|
163
158
|
await _checkDir({ objects, id, root: "", parts, options });
|
|
164
159
|
return objects.writeFileAsync(id, name + filename, data, options);
|
|
165
160
|
}
|
|
166
|
-
__name(_writeOneFile, "_writeOneFile");
|
|
167
161
|
async function writeDirAsZip(objects, id, name, data, options) {
|
|
168
162
|
const zip = new import_jszip.default();
|
|
169
163
|
options = options || {};
|
|
@@ -194,7 +188,6 @@ async function writeDirAsZip(objects, id, name, data, options) {
|
|
|
194
188
|
throw new Error(errors.join(", "));
|
|
195
189
|
}
|
|
196
190
|
}
|
|
197
|
-
__name(writeDirAsZip, "writeDirAsZip");
|
|
198
191
|
async function readObjectsAsZip(objects, rootId, adapter, options = {}) {
|
|
199
192
|
if (adapter) {
|
|
200
193
|
try {
|
|
@@ -228,7 +221,6 @@ async function readObjectsAsZip(objects, rootId, adapter, options = {}) {
|
|
|
228
221
|
const base64 = await zip.generateAsync({ type: "base64" });
|
|
229
222
|
return base64;
|
|
230
223
|
}
|
|
231
|
-
__name(readObjectsAsZip, "readObjectsAsZip");
|
|
232
224
|
async function _writeOneObject(objects, zip, rootId, filename, options) {
|
|
233
225
|
const zipFile = zip.files[filename];
|
|
234
226
|
if (!zipFile) {
|
|
@@ -262,7 +254,6 @@ async function _writeOneObject(objects, zip, rootId, filename, options) {
|
|
|
262
254
|
throw data.error;
|
|
263
255
|
}
|
|
264
256
|
}
|
|
265
|
-
__name(_writeOneObject, "_writeOneObject");
|
|
266
257
|
async function writeObjectsAsZip(objects, rootId, adapter, data, options, callback) {
|
|
267
258
|
options = options || {};
|
|
268
259
|
if (adapter) {
|
|
@@ -291,7 +282,6 @@ async function writeObjectsAsZip(objects, rootId, adapter, data, options, callba
|
|
|
291
282
|
}
|
|
292
283
|
callback(error.length ? new Error(error.join(", ")) : null);
|
|
293
284
|
}
|
|
294
|
-
__name(writeObjectsAsZip, "writeObjectsAsZip");
|
|
295
285
|
// Annotate the CommonJS export names for ESM import in node:
|
|
296
286
|
0 && (module.exports = {
|
|
297
287
|
readDirAsZip,
|