iobroker.js-controller 7.0.2 → 7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/compactgroupController.js.map +1 -1
- package/build/cjs/lib/adapter.js +0 -2
- package/build/cjs/lib/adapterAutoUpgradeManager.js +33 -0
- package/build/cjs/lib/adapterAutoUpgradeManager.js.map +1 -1
- package/build/cjs/lib/adapterUpgradeManager.d.ts +0 -2
- package/build/cjs/lib/adapterUpgradeManager.js +86 -0
- package/build/cjs/lib/adapterUpgradeManager.js.map +1 -1
- package/build/cjs/lib/blocklistManager.js +22 -0
- package/build/cjs/lib/blocklistManager.js.map +1 -1
- package/build/cjs/lib/exitCodes.js +0 -2
- package/build/cjs/lib/multihostServer.js +7 -3
- package/build/cjs/lib/multihostServer.js.map +1 -1
- package/build/cjs/lib/objects/objectsInMemClient.js +0 -2
- package/build/cjs/lib/objects/objectsInMemServer.js +0 -2
- package/build/cjs/lib/objects.d.ts +0 -1
- package/build/cjs/lib/objects.js +4 -0
- package/build/cjs/lib/objects.js.map +1 -1
- package/build/cjs/lib/password.js +0 -2
- package/build/cjs/lib/password.js.map +1 -1
- package/build/cjs/lib/preinstallCheck.js +4 -0
- package/build/cjs/lib/preinstallCheck.js.map +1 -1
- package/build/cjs/lib/restart.js +6 -4
- package/build/cjs/lib/restart.js.map +3 -3
- package/build/cjs/lib/states/statesInMemClient.js +0 -2
- package/build/cjs/lib/states/statesInMemServer.js +0 -2
- package/build/cjs/lib/tools.js +0 -2
- package/build/cjs/lib/upgradeManager.js +90 -2
- package/build/cjs/lib/upgradeManager.js.map +3 -3
- package/build/cjs/lib/utils.d.ts +0 -1
- package/build/cjs/lib/utils.js.map +1 -1
- package/build/cjs/lib/vis/states.js.map +1 -1
- package/build/cjs/lib/vis/visUtils.js +1 -0
- package/build/cjs/lib/vis/visUtils.js.map +1 -1
- package/build/cjs/main.d.ts +0 -10
- package/build/cjs/main.js +61 -17
- package/build/cjs/main.js.map +3 -3
- package/build/esm/lib/adapterUpgradeManager.d.ts +0 -2
- package/build/esm/lib/adapterUpgradeManager.d.ts.map +1 -1
- package/build/esm/lib/objects.d.ts +0 -1
- package/build/esm/lib/objects.d.ts.map +1 -1
- package/build/esm/lib/utils.d.ts +0 -1
- package/build/esm/lib/utils.d.ts.map +1 -1
- package/build/esm/main.d.ts +0 -10
- package/build/esm/main.d.ts.map +1 -1
- package/build/esm/main.js +1 -10
- package/build/esm/main.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/io-package.json +2 -2
- package/package.json +12 -12
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/compactgroupController.ts"],
|
|
4
4
|
"sourcesContent": ["/**\n * Controller process for Compact Groups\n *\n * Copyright 2018-2024 bluefox <dogafox@gmail.com>,\n * MIT License\n *\n */\nimport { init } from '@/main.js';\n\nconst compactGroup = parseInt(process.argv[2], 10);\nif (isNaN(compactGroup) || compactGroup < 1) {\n console.log(`Invalid compact group (${compactGroup}) as first parameter. Exit.`);\n process.exit();\n}\n\ninit(compactGroup);\n"],
|
|
5
|
-
"mappings": ";AAOA,kBAAqB;AAErB,MAAM,eAAe,SAAS,QAAQ,KAAK,
|
|
5
|
+
"mappings": ";AAOA,kBAAqB;AAErB,MAAM,eAAe,SAAS,QAAQ,KAAK,CAAC,GAAG,EAAE;AACjD,IAAI,MAAM,YAAY,KAAK,eAAe,GAAG;AACzC,UAAQ,IAAI,0BAA0B,YAAY,6BAA6B;AAC/E,UAAQ,KAAI;AAChB;IAEA,kBAAK,YAAY;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/cjs/lib/adapter.js
CHANGED
|
@@ -23,6 +23,4 @@ __export(adapter_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(adapter_exports);
|
|
24
24
|
var import_js_controller_adapter = require("@iobroker/js-controller-adapter");
|
|
25
25
|
var adapter_default = import_js_controller_adapter.Adapter;
|
|
26
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
27
|
-
0 && (module.exports = {});
|
|
28
26
|
//# sourceMappingURL=adapter.js.map
|
|
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
20
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
26
|
mod
|
|
23
27
|
));
|
|
@@ -32,13 +36,16 @@ var import_semver = __toESM(require("semver"), 1);
|
|
|
32
36
|
class AdapterAutoUpgradeManager {
|
|
33
37
|
objects;
|
|
34
38
|
states;
|
|
39
|
+
/** Mapping from semver range to range identifier */
|
|
35
40
|
SEMVER_RANGE_MAPPING = {
|
|
36
41
|
none: "",
|
|
37
42
|
patch: "~",
|
|
38
43
|
minor: "^",
|
|
39
44
|
major: ">"
|
|
40
45
|
};
|
|
46
|
+
/** Prefix for log messages */
|
|
41
47
|
logPrefix;
|
|
48
|
+
/** Logger which needs to be prefixed */
|
|
42
49
|
logger;
|
|
43
50
|
constructor(options) {
|
|
44
51
|
this.objects = options.objects;
|
|
@@ -46,6 +53,9 @@ class AdapterAutoUpgradeManager {
|
|
|
46
53
|
this.logger = options.logger;
|
|
47
54
|
this.logPrefix = options.logPrefix;
|
|
48
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Checks if auto upgrade is enabled for the current configured repository
|
|
58
|
+
*/
|
|
49
59
|
async isAutoUpgradeEnabled() {
|
|
50
60
|
let sysConf;
|
|
51
61
|
try {
|
|
@@ -58,6 +68,9 @@ class AdapterAutoUpgradeManager {
|
|
|
58
68
|
const activeRepo = sysConf.common.activeRepo[0];
|
|
59
69
|
return sysConf.common.adapterAutoUpgrade.repositories[activeRepo];
|
|
60
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Checks the current `system.repositories` object and checks if one needs to be performed according to the adapter configuration
|
|
73
|
+
*/
|
|
61
74
|
async upgradeAdapters() {
|
|
62
75
|
this.logger.info(`${this.logPrefix} Check for available automatic adapter upgrades`);
|
|
63
76
|
const upgradedAdapters = [];
|
|
@@ -94,6 +107,11 @@ class AdapterAutoUpgradeManager {
|
|
|
94
107
|
}
|
|
95
108
|
return { upgradedAdapters, failedAdapters };
|
|
96
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Upgrade specified adapter to given version
|
|
112
|
+
*
|
|
113
|
+
* @param options information of the adapter to install, e.g. version and name, sa well as active repo
|
|
114
|
+
*/
|
|
97
115
|
async upgradeAdapter(options) {
|
|
98
116
|
const { repoName, name, version } = options;
|
|
99
117
|
this.logger.info(`${this.logPrefix} Upgrade adapter "${name}" to ${version}`);
|
|
@@ -105,6 +123,9 @@ class AdapterAutoUpgradeManager {
|
|
|
105
123
|
});
|
|
106
124
|
await upgrade.upgradeAdapter(repoName, `${name}@${version}`, false, true, false);
|
|
107
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Get the current active repository name
|
|
128
|
+
*/
|
|
108
129
|
async getConfiguredRepositoryName() {
|
|
109
130
|
const obj = await this.objects.getObjectAsync("system.config");
|
|
110
131
|
if (!obj?.common?.activeRepo?.length) {
|
|
@@ -112,6 +133,11 @@ class AdapterAutoUpgradeManager {
|
|
|
112
133
|
}
|
|
113
134
|
return obj.common.activeRepo[0];
|
|
114
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Get the repository information for the given repository
|
|
138
|
+
*
|
|
139
|
+
* @param name Name of the repository
|
|
140
|
+
*/
|
|
115
141
|
async getRepository(name) {
|
|
116
142
|
const obj = await this.objects.getObjectAsync("system.repositories");
|
|
117
143
|
const jsonContent = obj?.native?.repositories?.[name]?.json;
|
|
@@ -121,6 +147,9 @@ class AdapterAutoUpgradeManager {
|
|
|
121
147
|
delete jsonContent._repoInfo;
|
|
122
148
|
return jsonContent;
|
|
123
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Get the auto upgrade configuration of all adapters
|
|
152
|
+
*/
|
|
124
153
|
async getAutoUpdateConfiguration() {
|
|
125
154
|
const res = await this.objects.getObjectViewAsync("system", "adapter", {
|
|
126
155
|
startkey: "system.adapter.",
|
|
@@ -132,12 +161,16 @@ class AdapterAutoUpgradeManager {
|
|
|
132
161
|
const defaultPolicy = await this.getDefaultUpgradePolicy();
|
|
133
162
|
return res.rows.filter((row) => defaultPolicy && defaultPolicy !== "none" || row.value?.common.automaticUpgrade && row.value.common.automaticUpgrade !== "none").map((row) => {
|
|
134
163
|
return {
|
|
164
|
+
// ts can not infer, that we filtered out falsy row.value entries
|
|
135
165
|
name: row.value.common.name,
|
|
136
166
|
version: row.value.common.version,
|
|
137
167
|
upgradePolicy: row.value.common.automaticUpgrade || defaultPolicy
|
|
138
168
|
};
|
|
139
169
|
});
|
|
140
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Get the default upgrade policy from the system config
|
|
173
|
+
*/
|
|
141
174
|
async getDefaultUpgradePolicy() {
|
|
142
175
|
let sysConf;
|
|
143
176
|
try {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/adapterAutoUpgradeManager.ts"],
|
|
4
4
|
"sourcesContent": ["import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';\nimport type { Client as StatesClient } from '@iobroker/db-states-redis';\nimport type { logger } from '@iobroker/js-controller-common';\nimport { Upgrade } from '@iobroker/js-controller-cli';\nimport semver from 'semver';\n\ninterface AdapterAutoUpgradeOptions {\n /** The objects DB client */\n objects: ObjectsClient;\n /** The states DB client */\n states: StatesClient;\n /** Logger which needs to be prefixed */\n logger: ReturnType<typeof logger>;\n /** Prefix for log messages */\n logPrefix: string;\n}\n\ninterface UpgradeAdapterOptions extends ioBroker.RepositoryJsonAdapterContent {\n /** Current active repository */\n repoName: string;\n}\n\ninterface UpgradedAdapter {\n /** Name of the adapter */\n name: string;\n /** Version before upgrade */\n oldVersion: string;\n /** Newly installed version */\n newVersion: string;\n}\n\ninterface UpgradeAdaptersResult {\n /** Adapters which were successfully upgraded */\n upgradedAdapters: UpgradedAdapter[];\n /** Adapters which were failed to upgrade */\n failedAdapters: UpgradedAdapter[];\n}\n\ninterface AdapterUpgradeConfiguration {\n /** Name of the adapter */\n name: string;\n /** Current installed version */\n version: string;\n /** Configured upgrade policy */\n upgradePolicy: ioBroker.AutoUpgradePolicy;\n}\n\nexport class AdapterAutoUpgradeManager {\n private readonly objects: ObjectsClient;\n private readonly states: StatesClient;\n /** Mapping from semver range to range identifier */\n private SEMVER_RANGE_MAPPING = {\n none: '',\n patch: '~',\n minor: '^',\n major: '>',\n } as const;\n /** Prefix for log messages */\n private readonly logPrefix: string;\n /** Logger which needs to be prefixed */\n private logger: ReturnType<typeof logger>;\n\n constructor(options: AdapterAutoUpgradeOptions) {\n this.objects = options.objects;\n this.states = options.states;\n this.logger = options.logger;\n this.logPrefix = options.logPrefix;\n }\n\n /**\n * Checks if auto upgrade is enabled for the current configured repository\n */\n async isAutoUpgradeEnabled(): Promise<boolean> {\n let sysConf: ioBroker.SystemConfigObject | null | undefined;\n\n try {\n sysConf = await this.objects.getObjectAsync('system.config');\n } catch {\n // ignore\n }\n\n if (!sysConf?.common.activeRepo?.length || !sysConf.common.adapterAutoUpgrade) {\n return false;\n }\n\n const activeRepo = sysConf.common.activeRepo[0];\n\n return sysConf.common.adapterAutoUpgrade.repositories[activeRepo];\n }\n\n /**\n * Checks the current `system.repositories` object and checks if one needs to be performed according to the adapter configuration\n */\n async upgradeAdapters(): Promise<UpgradeAdaptersResult> {\n this.logger.info(`${this.logPrefix} Check for available automatic adapter upgrades`);\n const upgradedAdapters: UpgradedAdapter[] = [];\n const failedAdapters: UpgradedAdapter[] = [];\n const repoName = await this.getConfiguredRepositoryName();\n const repoInformation = await this.getRepository(repoName);\n\n const installedAdaptersConfig = await this.getAutoUpdateConfiguration();\n\n for (const adapterConfig of installedAdaptersConfig) {\n const repoAdapterInfo = repoInformation[adapterConfig.name];\n if (!repoAdapterInfo) {\n continue;\n }\n\n if (semver.gte(adapterConfig.version, repoAdapterInfo.version)) {\n continue;\n }\n\n if (\n semver.satisfies(\n repoAdapterInfo.version,\n `${this.SEMVER_RANGE_MAPPING[adapterConfig.upgradePolicy]}${adapterConfig.version}`,\n { includePrerelease: true },\n )\n ) {\n try {\n await this.upgradeAdapter({ ...repoAdapterInfo, repoName });\n upgradedAdapters.push({\n name: repoAdapterInfo.name,\n newVersion: repoAdapterInfo.version,\n oldVersion: adapterConfig.version,\n });\n this.logger.info(\n `${this.logPrefix} Successfully upgraded adapter \"${repoAdapterInfo.name}\" to ${repoAdapterInfo.version}`,\n );\n } catch (e) {\n this.logger.error(\n `${this.logPrefix} Could not upgrade adapter \"${repoAdapterInfo.name}\" to ${repoAdapterInfo.version}: ${e.message}`,\n );\n failedAdapters.push({\n name: repoAdapterInfo.name,\n newVersion: repoAdapterInfo.version,\n oldVersion: adapterConfig.version,\n });\n }\n }\n }\n\n return { upgradedAdapters, failedAdapters };\n }\n\n /**\n * Upgrade specified adapter to given version\n *\n * @param options information of the adapter to install, e.g. version and name, sa well as active repo\n */\n private async upgradeAdapter(options: UpgradeAdapterOptions): Promise<void> {\n const { repoName, name, version } = options;\n\n this.logger.info(`${this.logPrefix} Upgrade adapter \"${name}\" to ${version}`);\n\n const upgrade = new Upgrade({\n objects: this.objects,\n states: this.states,\n params: {},\n processExit: () => undefined,\n });\n\n await upgrade.upgradeAdapter(repoName, `${name}@${version}`, false, true, false);\n }\n\n /**\n * Get the current active repository name\n */\n private async getConfiguredRepositoryName(): Promise<string> {\n const obj = await this.objects.getObjectAsync('system.config');\n\n if (!obj?.common?.activeRepo?.length) {\n throw new Error('Could not find an active repository');\n }\n\n return obj.common.activeRepo[0];\n }\n\n /**\n * Get the repository information for the given repository\n *\n * @param name Name of the repository\n */\n private async getRepository(name: string): Promise<Record<string, ioBroker.RepositoryJsonAdapterContent>> {\n const obj = await this.objects.getObjectAsync('system.repositories');\n\n const jsonContent:\n | (ioBroker.RepositoryJson & {\n _repoInfo?: any;\n })\n | null\n | undefined = obj?.native?.repositories?.[name]?.json;\n\n if (!jsonContent) {\n throw new Error(`Could not get repository information for \"${name}\"`);\n }\n\n delete jsonContent._repoInfo;\n return jsonContent as Record<string, ioBroker.RepositoryJsonAdapterContent>;\n }\n\n /**\n * Get the auto upgrade configuration of all adapters\n */\n private async getAutoUpdateConfiguration(): Promise<AdapterUpgradeConfiguration[]> {\n const res = await this.objects.getObjectViewAsync('system', 'adapter', {\n startkey: 'system.adapter.',\n endkey: 'system.adapter.\\u9999',\n });\n\n if (!res) {\n throw new Error('Did not get information about installed adapters');\n }\n\n const defaultPolicy = await this.getDefaultUpgradePolicy();\n\n return res.rows\n .filter(\n row =>\n (defaultPolicy && defaultPolicy !== 'none') ||\n (row.value?.common.automaticUpgrade && row.value.common.automaticUpgrade !== 'none'),\n )\n .map(row => {\n return {\n // ts can not infer, that we filtered out falsy row.value entries\n name: row.value.common.name,\n version: row.value.common.version,\n upgradePolicy: row.value.common.automaticUpgrade! || defaultPolicy,\n };\n });\n }\n\n /**\n * Get the default upgrade policy from the system config\n */\n private async getDefaultUpgradePolicy(): Promise<ioBroker.AutoUpgradePolicy | undefined> {\n let sysConf: ioBroker.SystemConfigObject | null | undefined;\n\n try {\n sysConf = await this.objects.getObjectAsync('system.config');\n } catch {\n // ignore\n }\n\n return sysConf?.common.adapterAutoUpgrade?.defaultPolicy;\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["semver"]
|
|
7
7
|
}
|
|
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
20
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
26
|
mod
|
|
23
27
|
));
|
|
@@ -33,26 +37,43 @@ var import_node_https = __toESM(require("node:https"), 1);
|
|
|
33
37
|
var import_promises = require("node:timers/promises");
|
|
34
38
|
var import_js_controller_cli = require("@iobroker/js-controller-cli");
|
|
35
39
|
class AdapterUpgradeManager {
|
|
40
|
+
/** Wait ms until adapter is stopped */
|
|
36
41
|
STOP_TIMEOUT_MS = 3e3;
|
|
42
|
+
/** Wait ms for delivery of final response */
|
|
37
43
|
SHUTDOWN_TIMEOUT = 1e4;
|
|
44
|
+
/** Name of the adapter to upgrade */
|
|
38
45
|
adapterName;
|
|
46
|
+
/** Desired adapter version */
|
|
39
47
|
version;
|
|
48
|
+
/** Response send by webserver */
|
|
40
49
|
response = {
|
|
41
50
|
running: true,
|
|
42
51
|
stderr: [],
|
|
43
52
|
stdout: []
|
|
44
53
|
};
|
|
54
|
+
/** Used to stop the stop shutdown timeout */
|
|
45
55
|
shutdownAbortController;
|
|
56
|
+
/** Logger to log to file and other transports */
|
|
46
57
|
logger;
|
|
58
|
+
/** The server used for communicating upgrade status */
|
|
47
59
|
server;
|
|
60
|
+
/** All socket connections of the webserver */
|
|
48
61
|
sockets = /* @__PURE__ */ new Set();
|
|
62
|
+
/** Name of the host for logging purposes */
|
|
49
63
|
hostname = import_js_controller_common.tools.getHostName();
|
|
64
|
+
/** The objects DB client */
|
|
50
65
|
objects;
|
|
66
|
+
/** The states DB client */
|
|
51
67
|
states;
|
|
68
|
+
/** List of instances which have been stopped */
|
|
52
69
|
stoppedInstances = [];
|
|
70
|
+
/** If webserver should be started with https */
|
|
53
71
|
useHttps;
|
|
72
|
+
/** Public certificate name if https is desired */
|
|
54
73
|
certPublicName;
|
|
74
|
+
/** Private certificate name if https is desired */
|
|
55
75
|
certPrivateName;
|
|
76
|
+
/** Port where the webserver should be running */
|
|
56
77
|
port;
|
|
57
78
|
constructor(options) {
|
|
58
79
|
this.adapterName = options.adapterName;
|
|
@@ -67,14 +88,26 @@ class AdapterUpgradeManager {
|
|
|
67
88
|
this.certPrivateName = options.certPrivateName;
|
|
68
89
|
}
|
|
69
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Stops the adapter and returns ids of stopped instances
|
|
93
|
+
*/
|
|
70
94
|
async stopAdapter() {
|
|
71
95
|
this.stoppedInstances = await this.getAllEnabledInstances();
|
|
72
96
|
await this.enableInstances(this.stoppedInstances, false);
|
|
73
97
|
await (0, import_promises.setTimeout)(this.STOP_TIMEOUT_MS);
|
|
74
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Start all instances which were enabled before the upgrade
|
|
101
|
+
*/
|
|
75
102
|
async startAdapter() {
|
|
76
103
|
await this.enableInstances(this.stoppedInstances, true);
|
|
77
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Start or stop given instances
|
|
107
|
+
*
|
|
108
|
+
* @param instances id of instances which will be stopped
|
|
109
|
+
* @param enabled if enable or disable instances
|
|
110
|
+
*/
|
|
78
111
|
async enableInstances(instances, enabled) {
|
|
79
112
|
const ts = Date.now();
|
|
80
113
|
for (const instance of instances) {
|
|
@@ -88,6 +121,9 @@ class AdapterUpgradeManager {
|
|
|
88
121
|
await this.objects.extendObjectAsync(instance, updatedObj);
|
|
89
122
|
}
|
|
90
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Install given version of adapter
|
|
126
|
+
*/
|
|
91
127
|
async performUpgrade() {
|
|
92
128
|
const processExitHandler = (exitCode) => {
|
|
93
129
|
this.log(`Upgrade process exited with code: ${exitCode}`, true);
|
|
@@ -108,6 +144,9 @@ class AdapterUpgradeManager {
|
|
|
108
144
|
}
|
|
109
145
|
await this.setFinished();
|
|
110
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Starts the web server for admin communication either secure or insecure
|
|
149
|
+
*/
|
|
111
150
|
async startWebServer() {
|
|
112
151
|
if (this.useHttps && this.certPublicName && this.certPrivateName) {
|
|
113
152
|
await this.startSecureWebServer({
|
|
@@ -120,6 +159,9 @@ class AdapterUpgradeManager {
|
|
|
120
159
|
this.startInsecureWebServer({ port: this.port, useHttps: false });
|
|
121
160
|
}
|
|
122
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Shuts down the server, restarts the adapter
|
|
164
|
+
*/
|
|
123
165
|
shutdownServer() {
|
|
124
166
|
if (this.shutdownAbortController) {
|
|
125
167
|
this.shutdownAbortController.abort();
|
|
@@ -133,12 +175,21 @@ class AdapterUpgradeManager {
|
|
|
133
175
|
this.log("Successfully started adapter");
|
|
134
176
|
});
|
|
135
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Destroy all sockets, to prevent requests from keeping server alive
|
|
180
|
+
*/
|
|
136
181
|
destroySockets() {
|
|
137
182
|
for (const socket of this.sockets) {
|
|
138
183
|
socket.destroy();
|
|
139
184
|
this.sockets.delete(socket);
|
|
140
185
|
}
|
|
141
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* This function is called when the webserver receives a message
|
|
189
|
+
*
|
|
190
|
+
* @param req received message
|
|
191
|
+
* @param res server response
|
|
192
|
+
*/
|
|
142
193
|
webServerCallback(req, res) {
|
|
143
194
|
res.writeHead(200);
|
|
144
195
|
res.end(JSON.stringify(this.response));
|
|
@@ -147,6 +198,9 @@ class AdapterUpgradeManager {
|
|
|
147
198
|
this.shutdownServer();
|
|
148
199
|
}
|
|
149
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Get all instances of the adapter
|
|
203
|
+
*/
|
|
150
204
|
async getAllEnabledInstances() {
|
|
151
205
|
const res = await this.objects.getObjectListAsync({
|
|
152
206
|
startkey: `system.adapter.${this.adapterName}.`,
|
|
@@ -156,6 +210,12 @@ class AdapterUpgradeManager {
|
|
|
156
210
|
enabledInstances = res.rows.filter((row) => row.value.common.enabled && this.hostname === row.value.common.host).map((row) => row.value._id);
|
|
157
211
|
return enabledInstances;
|
|
158
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Log via logger and provide the logs for the server too
|
|
215
|
+
*
|
|
216
|
+
* @param message the message which will be logged
|
|
217
|
+
* @param error if it is an error
|
|
218
|
+
*/
|
|
159
219
|
log(message, error = false) {
|
|
160
220
|
if (error) {
|
|
161
221
|
this.logger.error(`host.${this.hostname} ${message}`);
|
|
@@ -165,6 +225,11 @@ class AdapterUpgradeManager {
|
|
|
165
225
|
this.logger.info(`host.${this.hostname} [WEBSERVER_UPGRADE] (${this.adapterName}) ${message}`);
|
|
166
226
|
this.response.stdout.push(message);
|
|
167
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Start an insecure web server for admin communication
|
|
230
|
+
*
|
|
231
|
+
* @param params Web server configuration
|
|
232
|
+
*/
|
|
168
233
|
startInsecureWebServer(params) {
|
|
169
234
|
const { port } = params;
|
|
170
235
|
this.server = import_node_http.default.createServer((req, res) => {
|
|
@@ -175,6 +240,11 @@ class AdapterUpgradeManager {
|
|
|
175
240
|
this.log(`Server is running on http://localhost:${port}`);
|
|
176
241
|
});
|
|
177
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Start a secure web server for admin communication
|
|
245
|
+
*
|
|
246
|
+
* @param params Web server configuration
|
|
247
|
+
*/
|
|
178
248
|
async startSecureWebServer(params) {
|
|
179
249
|
const { port, certPublicName, certPrivateName } = params;
|
|
180
250
|
const { certPublic, certPrivate } = await this.getCertificates({ certPublicName, certPrivateName });
|
|
@@ -186,6 +256,11 @@ class AdapterUpgradeManager {
|
|
|
186
256
|
this.log(`Server is running on http://localhost:${port}`);
|
|
187
257
|
});
|
|
188
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Keep track of all existing sockets
|
|
261
|
+
*
|
|
262
|
+
* @param server the webserver
|
|
263
|
+
*/
|
|
189
264
|
monitorSockets(server) {
|
|
190
265
|
server.on("connection", (socket) => {
|
|
191
266
|
this.sockets.add(socket);
|
|
@@ -194,6 +269,11 @@ class AdapterUpgradeManager {
|
|
|
194
269
|
});
|
|
195
270
|
});
|
|
196
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Get certificates from the DB
|
|
274
|
+
*
|
|
275
|
+
* @param params certificate information
|
|
276
|
+
*/
|
|
197
277
|
async getCertificates(params) {
|
|
198
278
|
const { certPublicName, certPrivateName } = params;
|
|
199
279
|
const obj = await this.objects.getObjectAsync("system.certificates");
|
|
@@ -203,10 +283,16 @@ class AdapterUpgradeManager {
|
|
|
203
283
|
const certs = obj.native.certificates;
|
|
204
284
|
return { certPrivate: certs[certPrivateName], certPublic: certs[certPublicName] };
|
|
205
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Tells the upgrade manager, that server can be shut down on next response or on timeout
|
|
288
|
+
*/
|
|
206
289
|
async setFinished() {
|
|
207
290
|
this.response.running = false;
|
|
208
291
|
await this.startShutdownTimeout();
|
|
209
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Start a timeout which starts adapter and shuts down the server if expired
|
|
295
|
+
*/
|
|
210
296
|
async startShutdownTimeout() {
|
|
211
297
|
this.shutdownAbortController = new AbortController();
|
|
212
298
|
try {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/adapterUpgradeManager.ts"],
|
|
4
4
|
"sourcesContent": ["import { tools } from '@iobroker/js-controller-common';\nimport http from 'node:http';\nimport https from 'node:https';\nimport type { Client as ObjectsClient } from '@iobroker/db-objects-redis';\nimport type { Client as StatesClient } from '@iobroker/db-states-redis';\nimport { setTimeout as wait } from 'node:timers/promises';\nimport type { Logger } from 'winston';\nimport { Upgrade, type ProcessExitCallback } from '@iobroker/js-controller-cli';\nimport type { Socket } from 'node:net';\nimport type { Duplex } from 'node:stream';\n\ninterface Certificates {\n /** Public certificate */\n certPublic: string;\n /** Private certificate */\n certPrivate: string;\n}\n\ninterface InsecureWebServerParameters {\n /** if https should be used for the webserver */\n useHttps: false;\n /** port of the web server */\n port: number;\n}\n\ntype SecureWebServerParameters = Omit<InsecureWebServerParameters, 'useHttps'> & {\n useHttps: true;\n certPrivateName: string;\n certPublicName: string;\n};\ntype WebServerParameters = InsecureWebServerParameters | SecureWebServerParameters;\n\nexport type AdapterUpgradeManagerOptions = {\n /** Version of adapter to upgrade too */\n version: string;\n /** Name of the adapter to upgrade */\n adapterName: string;\n /** The objects DB client */\n objects: ObjectsClient;\n /** The states DB client */\n states: StatesClient;\n /** A logger instance */\n logger: Logger;\n} & WebServerParameters;\n\ninterface GetCertificatesParams {\n /** Name of the public certificate */\n certPublicName: string;\n /** Name of the private certificate */\n certPrivateName: string;\n}\n\ninterface ServerResponse {\n /** If the update is still running */\n running: boolean;\n stderr: string[];\n stdout: string[];\n /** if installation process succeeded */\n success?: boolean;\n}\n\nexport class AdapterUpgradeManager {\n /** Wait ms until adapter is stopped */\n private readonly STOP_TIMEOUT_MS = 3_000;\n /** Wait ms for delivery of final response */\n private readonly SHUTDOWN_TIMEOUT = 10_000;\n /** Name of the adapter to upgrade */\n private readonly adapterName: string;\n /** Desired adapter version */\n private readonly version: string;\n /** Response send by webserver */\n private readonly response: ServerResponse = {\n running: true,\n stderr: [],\n stdout: [],\n };\n /** Used to stop the stop shutdown timeout */\n private shutdownAbortController?: AbortController;\n /** Logger to log to file and other transports */\n private readonly logger: Logger;\n\n /** The server used for communicating upgrade status */\n private server?: https.Server | http.Server;\n /** All socket connections of the webserver */\n private sockets = new Set<Socket | Duplex>();\n /** Name of the host for logging purposes */\n private readonly hostname = tools.getHostName();\n /** The objects DB client */\n private readonly objects: ObjectsClient;\n /** The states DB client */\n private readonly states: StatesClient;\n /** List of instances which have been stopped */\n private stoppedInstances: string[] = [];\n /** If webserver should be started with https */\n private readonly useHttps: boolean;\n /** Public certificate name if https is desired */\n private readonly certPublicName?: string;\n /** Private certificate name if https is desired */\n private readonly certPrivateName?: string;\n /** Port where the webserver should be running */\n private readonly port: number;\n\n constructor(options: AdapterUpgradeManagerOptions) {\n this.adapterName = options.adapterName;\n this.version = options.version;\n this.logger = options.logger;\n this.objects = options.objects;\n this.states = options.states;\n this.useHttps = options.useHttps;\n this.port = options.port;\n\n if (options.useHttps) {\n this.certPublicName = options.certPublicName;\n this.certPrivateName = options.certPrivateName;\n }\n }\n\n /**\n * Stops the adapter and returns ids of stopped instances\n */\n async stopAdapter(): Promise<void> {\n this.stoppedInstances = await this.getAllEnabledInstances();\n await this.enableInstances(this.stoppedInstances, false);\n await wait(this.STOP_TIMEOUT_MS);\n }\n\n /**\n * Start all instances which were enabled before the upgrade\n */\n async startAdapter(): Promise<void> {\n await this.enableInstances(this.stoppedInstances, true);\n }\n\n /**\n * Start or stop given instances\n *\n * @param instances id of instances which will be stopped\n * @param enabled if enable or disable instances\n */\n async enableInstances(instances: string[], enabled: boolean): Promise<void> {\n const ts = Date.now();\n for (const instance of instances) {\n const updatedObj = {\n common: {\n enabled,\n },\n from: `system.host.${this.hostname}`,\n ts,\n } as Partial<ioBroker.InstanceObject>;\n\n await this.objects.extendObjectAsync(instance, updatedObj);\n }\n }\n\n /**\n * Install given version of adapter\n */\n async performUpgrade(): Promise<void> {\n const processExitHandler: ProcessExitCallback = exitCode => {\n this.log(`Upgrade process exited with code: ${exitCode}`, true);\n };\n\n const upgrade = new Upgrade({\n objects: this.objects,\n processExit: processExitHandler,\n states: this.states,\n params: {},\n });\n\n try {\n await upgrade.upgradeAdapter(undefined, `${this.adapterName}@${this.version}`, true, true, false);\n this.response.success = true;\n this.log(`Successfully upgraded ${this.adapterName} to version ${this.version}`);\n } catch (e) {\n this.log(e.message, true);\n this.response.success = false;\n }\n\n await this.setFinished();\n }\n\n /**\n * Starts the web server for admin communication either secure or insecure\n */\n async startWebServer(): Promise<void> {\n if (this.useHttps && this.certPublicName && this.certPrivateName) {\n await this.startSecureWebServer({\n certPublicName: this.certPublicName,\n certPrivateName: this.certPrivateName,\n port: this.port,\n useHttps: true,\n });\n } else {\n this.startInsecureWebServer({ port: this.port, useHttps: false });\n }\n }\n\n /**\n * Shuts down the server, restarts the adapter\n */\n shutdownServer(): void {\n if (this.shutdownAbortController) {\n this.shutdownAbortController.abort();\n }\n\n if (!this.server) {\n return;\n }\n\n this.destroySockets();\n\n this.server.close(async () => {\n await this.startAdapter();\n this.log('Successfully started adapter');\n });\n }\n\n /**\n * Destroy all sockets, to prevent requests from keeping server alive\n */\n destroySockets(): void {\n for (const socket of this.sockets) {\n socket.destroy();\n this.sockets.delete(socket);\n }\n }\n\n /**\n * This function is called when the webserver receives a message\n *\n * @param req received message\n * @param res server response\n */\n webServerCallback(req: http.IncomingMessage, res: http.ServerResponse): void {\n res.writeHead(200);\n res.end(JSON.stringify(this.response));\n\n if (!this.response.running) {\n this.log('Final information delivered');\n this.shutdownServer();\n }\n }\n\n /**\n * Get all instances of the adapter\n */\n async getAllEnabledInstances(): Promise<string[]> {\n const res = await this.objects.getObjectListAsync({\n startkey: `system.adapter.${this.adapterName}.`,\n endkey: `system.adapter.${this.adapterName}.\\u9999`,\n });\n\n let enabledInstances: string[] = [];\n\n enabledInstances = res.rows\n .filter(row => row.value.common.enabled && this.hostname === row.value.common.host)\n .map(row => row.value._id);\n\n return enabledInstances;\n }\n\n /**\n * Log via logger and provide the logs for the server too\n *\n * @param message the message which will be logged\n * @param error if it is an error\n */\n log(message: string, error = false): void {\n if (error) {\n this.logger.error(`host.${this.hostname} ${message}`);\n this.response.stderr.push(message);\n return;\n }\n\n this.logger.info(`host.${this.hostname} [WEBSERVER_UPGRADE] (${this.adapterName}) ${message}`);\n this.response.stdout.push(message);\n }\n\n /**\n * Start an insecure web server for admin communication\n *\n * @param params Web server configuration\n */\n startInsecureWebServer(params: InsecureWebServerParameters): void {\n const { port } = params;\n\n this.server = http.createServer((req, res) => {\n this.webServerCallback(req, res);\n });\n\n this.monitorSockets(this.server);\n\n this.server.listen(port, () => {\n this.log(`Server is running on http://localhost:${port}`);\n });\n }\n\n /**\n * Start a secure web server for admin communication\n *\n * @param params Web server configuration\n */\n async startSecureWebServer(params: SecureWebServerParameters): Promise<void> {\n const { port, certPublicName, certPrivateName } = params;\n\n const { certPublic, certPrivate } = await this.getCertificates({ certPublicName, certPrivateName });\n\n this.server = https.createServer({ key: certPrivate, cert: certPublic }, (req, res) => {\n this.webServerCallback(req, res);\n });\n\n this.monitorSockets(this.server);\n\n this.server.listen(port, () => {\n this.log(`Server is running on http://localhost:${port}`);\n });\n }\n\n /**\n * Keep track of all existing sockets\n *\n * @param server the webserver\n */\n monitorSockets(server: http.Server | https.Server): void {\n server.on('connection', socket => {\n this.sockets.add(socket);\n\n server.once('close', () => {\n this.sockets.delete(socket);\n });\n });\n }\n\n /**\n * Get certificates from the DB\n *\n * @param params certificate information\n */\n async getCertificates(params: GetCertificatesParams): Promise<Certificates> {\n const { certPublicName, certPrivateName } = params;\n\n const obj = await this.objects.getObjectAsync('system.certificates');\n\n if (!obj) {\n throw new Error('No certificates found');\n }\n\n const certs = obj.native.certificates;\n\n return { certPrivate: certs[certPrivateName], certPublic: certs[certPublicName] };\n }\n\n /**\n * Tells the upgrade manager, that server can be shut down on next response or on timeout\n */\n private async setFinished(): Promise<void> {\n this.response.running = false;\n\n await this.startShutdownTimeout();\n }\n\n /**\n * Start a timeout which starts adapter and shuts down the server if expired\n */\n async startShutdownTimeout(): Promise<void> {\n this.shutdownAbortController = new AbortController();\n try {\n await wait(this.SHUTDOWN_TIMEOUT, null, { signal: this.shutdownAbortController.signal });\n\n this.log('Timeout expired, initializing shutdown');\n this.shutdownServer();\n } catch (e) {\n if (e.code !== 'ABORT_ERR') {\n this.log(e.message, true);\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,kCAAsB;AACtB,uBAAiB;AACjB,wBAAkB;AAGlB,sBAAmC;AAEnC,+BAAkD;AAsD5C,MAAO,sBAAqB;;EAEb,kBAAkB;;EAElB,mBAAmB;;EAEnB;;EAEA;;EAEA,WAA2B;IACxC,SAAS;IACT,QAAQ,CAAA;IACR,QAAQ,CAAA;;;EAGJ;;EAES;;EAGT;;EAEA,UAAU,oBAAI,IAAG;;EAER,WAAW,kCAAM,YAAW;;EAE5B;;EAEA;;EAET,mBAA6B,CAAA;;EAEpB;;EAEA;;EAEA;;EAEA;EAEjB,YAAY,SAAqC;AAC7C,SAAK,cAAc,QAAQ;AAC3B,SAAK,UAAU,QAAQ;AACvB,SAAK,SAAS,QAAQ;AACtB,SAAK,UAAU,QAAQ;AACvB,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ;AACxB,SAAK,OAAO,QAAQ;AAEpB,QAAI,QAAQ,UAAU;AAClB,WAAK,iBAAiB,QAAQ;AAC9B,WAAK,kBAAkB,QAAQ;IACnC;EACJ;;;;EAKA,MAAM,cAAW;AACb,SAAK,mBAAmB,MAAM,KAAK,uBAAsB;AACzD,UAAM,KAAK,gBAAgB,KAAK,kBAAkB,KAAK;AACvD,cAAM,gBAAAA,YAAK,KAAK,eAAe;EACnC;;;;EAKA,MAAM,eAAY;AACd,UAAM,KAAK,gBAAgB,KAAK,kBAAkB,IAAI;EAC1D;;;;;;;EAQA,MAAM,gBAAgB,WAAqB,SAAgB;AACvD,UAAM,KAAK,KAAK,IAAG;AACnB,eAAW,YAAY,WAAW;AAC9B,YAAM,aAAa;QACf,QAAQ;UACJ;;QAEJ,MAAM,eAAe,KAAK,QAAQ;QAClC;;AAGJ,YAAM,KAAK,QAAQ,kBAAkB,UAAU,UAAU;IAC7D;EACJ;;;;EAKA,MAAM,iBAAc;AAChB,UAAM,qBAA0C,cAAW;AACvD,WAAK,IAAI,qCAAqC,QAAQ,IAAI,IAAI;IAClE;AAEA,UAAM,UAAU,IAAI,iCAAQ;MACxB,SAAS,KAAK;MACd,aAAa;MACb,QAAQ,KAAK;MACb,QAAQ,CAAA;KACX;AAED,QAAI;AACA,YAAM,QAAQ,eAAe,QAAW,GAAG,KAAK,WAAW,IAAI,KAAK,OAAO,IAAI,MAAM,MAAM,KAAK;AAChG,WAAK,SAAS,UAAU;AACxB,WAAK,IAAI,yBAAyB,KAAK,WAAW,eAAe,KAAK,OAAO,EAAE;IACnF,SAAS,GAAG;AACR,WAAK,IAAI,EAAE,SAAS,IAAI;AACxB,WAAK,SAAS,UAAU;IAC5B;AAEA,UAAM,KAAK,YAAW;EAC1B;;;;EAKA,MAAM,iBAAc;AAChB,QAAI,KAAK,YAAY,KAAK,kBAAkB,KAAK,iBAAiB;AAC9D,YAAM,KAAK,qBAAqB;QAC5B,gBAAgB,KAAK;QACrB,iBAAiB,KAAK;QACtB,MAAM,KAAK;QACX,UAAU;OACb;IACL,OAAO;AACH,WAAK,uBAAuB,EAAE,MAAM,KAAK,MAAM,UAAU,MAAK,CAAE;IACpE;EACJ;;;;EAKA,iBAAc;AACV,QAAI,KAAK,yBAAyB;AAC9B,WAAK,wBAAwB,MAAK;IACtC;AAEA,QAAI,CAAC,KAAK,QAAQ;AACd;IACJ;AAEA,SAAK,eAAc;AAEnB,SAAK,OAAO,MAAM,YAAW;AACzB,YAAM,KAAK,aAAY;AACvB,WAAK,IAAI,8BAA8B;IAC3C,CAAC;EACL;;;;EAKA,iBAAc;AACV,eAAW,UAAU,KAAK,SAAS;AAC/B,aAAO,QAAO;AACd,WAAK,QAAQ,OAAO,MAAM;IAC9B;EACJ;;;;;;;EAQA,kBAAkB,KAA2B,KAAwB;AACjE,QAAI,UAAU,GAAG;AACjB,QAAI,IAAI,KAAK,UAAU,KAAK,QAAQ,CAAC;AAErC,QAAI,CAAC,KAAK,SAAS,SAAS;AACxB,WAAK,IAAI,6BAA6B;AACtC,WAAK,eAAc;IACvB;EACJ;;;;EAKA,MAAM,yBAAsB;AACxB,UAAM,MAAM,MAAM,KAAK,QAAQ,mBAAmB;MAC9C,UAAU,kBAAkB,KAAK,WAAW;MAC5C,QAAQ,kBAAkB,KAAK,WAAW;KAC7C;AAED,QAAI,mBAA6B,CAAA;AAEjC,uBAAmB,IAAI,KAClB,OAAO,SAAO,IAAI,MAAM,OAAO,WAAW,KAAK,aAAa,IAAI,MAAM,OAAO,IAAI,EACjF,IAAI,SAAO,IAAI,MAAM,GAAG;AAE7B,WAAO;EACX;;;;;;;EAQA,IAAI,SAAiB,QAAQ,OAAK;AAC9B,QAAI,OAAO;AACP,WAAK,OAAO,MAAM,QAAQ,KAAK,QAAQ,IAAI,OAAO,EAAE;AACpD,WAAK,SAAS,OAAO,KAAK,OAAO;AACjC;IACJ;AAEA,SAAK,OAAO,KAAK,QAAQ,KAAK,QAAQ,yBAAyB,KAAK,WAAW,KAAK,OAAO,EAAE;AAC7F,SAAK,SAAS,OAAO,KAAK,OAAO;EACrC;;;;;;EAOA,uBAAuB,QAAmC;AACtD,UAAM,EAAE,KAAI,IAAK;AAEjB,SAAK,SAAS,iBAAAC,QAAK,aAAa,CAAC,KAAK,QAAO;AACzC,WAAK,kBAAkB,KAAK,GAAG;IACnC,CAAC;AAED,SAAK,eAAe,KAAK,MAAM;AAE/B,SAAK,OAAO,OAAO,MAAM,MAAK;AAC1B,WAAK,IAAI,yCAAyC,IAAI,EAAE;IAC5D,CAAC;EACL;;;;;;EAOA,MAAM,qBAAqB,QAAiC;AACxD,UAAM,EAAE,MAAM,gBAAgB,gBAAe,IAAK;AAElD,UAAM,EAAE,YAAY,YAAW,IAAK,MAAM,KAAK,gBAAgB,EAAE,gBAAgB,gBAAe,CAAE;AAElG,SAAK,SAAS,kBAAAC,QAAM,aAAa,EAAE,KAAK,aAAa,MAAM,WAAU,GAAI,CAAC,KAAK,QAAO;AAClF,WAAK,kBAAkB,KAAK,GAAG;IACnC,CAAC;AAED,SAAK,eAAe,KAAK,MAAM;AAE/B,SAAK,OAAO,OAAO,MAAM,MAAK;AAC1B,WAAK,IAAI,yCAAyC,IAAI,EAAE;IAC5D,CAAC;EACL;;;;;;EAOA,eAAe,QAAkC;AAC7C,WAAO,GAAG,cAAc,YAAS;AAC7B,WAAK,QAAQ,IAAI,MAAM;AAEvB,aAAO,KAAK,SAAS,MAAK;AACtB,aAAK,QAAQ,OAAO,MAAM;MAC9B,CAAC;IACL,CAAC;EACL;;;;;;EAOA,MAAM,gBAAgB,QAA6B;AAC/C,UAAM,EAAE,gBAAgB,gBAAe,IAAK;AAE5C,UAAM,MAAM,MAAM,KAAK,QAAQ,eAAe,qBAAqB;AAEnE,QAAI,CAAC,KAAK;AACN,YAAM,IAAI,MAAM,uBAAuB;IAC3C;AAEA,UAAM,QAAQ,IAAI,OAAO;AAEzB,WAAO,EAAE,aAAa,MAAM,eAAe,GAAG,YAAY,MAAM,cAAc,EAAC;EACnF;;;;EAKQ,MAAM,cAAW;AACrB,SAAK,SAAS,UAAU;AAExB,UAAM,KAAK,qBAAoB;EACnC;;;;EAKA,MAAM,uBAAoB;AACtB,SAAK,0BAA0B,IAAI,gBAAe;AAClD,QAAI;AACA,gBAAM,gBAAAF,YAAK,KAAK,kBAAkB,MAAM,EAAE,QAAQ,KAAK,wBAAwB,OAAM,CAAE;AAEvF,WAAK,IAAI,wCAAwC;AACjD,WAAK,eAAc;IACvB,SAAS,GAAG;AACR,UAAI,EAAE,SAAS,aAAa;AACxB,aAAK,IAAI,EAAE,SAAS,IAAI;MAC5B;IACJ;EACJ;;",
|
|
6
6
|
"names": ["wait", "http", "https"]
|
|
7
7
|
}
|
|
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
20
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
26
|
mod
|
|
23
27
|
));
|
|
@@ -30,10 +34,16 @@ module.exports = __toCommonJS(blocklistManager_exports);
|
|
|
30
34
|
var import_constants = require("@iobroker/js-controller-common-db/constants");
|
|
31
35
|
var import_semver = __toESM(require("semver"), 1);
|
|
32
36
|
class BlocklistManager {
|
|
37
|
+
/** The objects client */
|
|
33
38
|
objects;
|
|
34
39
|
constructor(options) {
|
|
35
40
|
this.objects = options.objects;
|
|
36
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Iterates over all instances, disables blocklisted once if enabled
|
|
44
|
+
*
|
|
45
|
+
* @returns A list of disabled instances
|
|
46
|
+
*/
|
|
37
47
|
async disableAllBlocklistedInstances() {
|
|
38
48
|
const disabledList = [];
|
|
39
49
|
const systemRepoObj = await this.objects.getObject(import_constants.SYSTEM_REPOSITORIES_ID);
|
|
@@ -65,6 +75,12 @@ class BlocklistManager {
|
|
|
65
75
|
}
|
|
66
76
|
return disabledList;
|
|
67
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if version of a specific adapter is blocked
|
|
80
|
+
*
|
|
81
|
+
* @param options adapter version and name information
|
|
82
|
+
* @returns A boolean indicating if the adapter version is blocked
|
|
83
|
+
*/
|
|
68
84
|
async isAdapterVersionBlocked(options) {
|
|
69
85
|
const systemRepoObj = await this.objects.getObject(import_constants.SYSTEM_REPOSITORIES_ID);
|
|
70
86
|
const systemConfigObj = await this.objects.getObject(import_constants.SYSTEM_CONFIG_ID);
|
|
@@ -73,6 +89,12 @@ class BlocklistManager {
|
|
|
73
89
|
}
|
|
74
90
|
return this.internalIsAdapterVersionBlocked({ ...options, systemRepoObj, systemConfigObj });
|
|
75
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if version of a specific adapter is blocked
|
|
94
|
+
*
|
|
95
|
+
* @param options information about adapter, version and cached objects
|
|
96
|
+
* @returns A boolean indicating if the adapter version is blocked
|
|
97
|
+
*/
|
|
76
98
|
internalIsAdapterVersionBlocked(options) {
|
|
77
99
|
const { adapterName, version, systemRepoObj, systemConfigObj } = options;
|
|
78
100
|
for (const activeRepoName of systemConfigObj.common.activeRepo) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/blocklistManager.ts"],
|
|
4
4
|
"sourcesContent": ["import type { Client as ObjectsClient } from '@iobroker/db-objects-redis';\nimport {\n HIGHEST_UNICODE_SYMBOL,\n SYSTEM_ADAPTER_PREFIX,\n SYSTEM_CONFIG_ID,\n SYSTEM_REPOSITORIES_ID,\n} from '@iobroker/js-controller-common-db/constants';\nimport semver from 'semver';\n\ninterface BlocklistManagerOptions {\n /** The objects client */\n objects: ObjectsClient;\n}\n\ninterface AdapterVersionBlockedOptions {\n /** The version of the adapter instance */\n version: string;\n /** Name of the adapter */\n adapterName: string;\n}\n\ninterface InternalAdapterVersionBlockedOptions extends AdapterVersionBlockedOptions {\n /** The system repository object */\n systemRepoObj: ioBroker.RepositoryObject;\n /** The system config object */\n systemConfigObj: ioBroker.SystemConfigObject;\n}\n\nexport class BlocklistManager {\n /** The objects client */\n private readonly objects: ObjectsClient;\n\n constructor(options: BlocklistManagerOptions) {\n this.objects = options.objects;\n }\n\n /**\n * Iterates over all instances, disables blocklisted once if enabled\n *\n * @returns A list of disabled instances\n */\n async disableAllBlocklistedInstances(): Promise<ioBroker.InstanceObject[]> {\n /** List of instances which we have disabled */\n const disabledList: ioBroker.InstanceObject[] = [];\n\n const systemRepoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const systemConfigObj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n\n if (!systemConfigObj || !systemRepoObj) {\n return disabledList;\n }\n\n const instancesView = await this.objects.getObjectViewAsync('system', 'instance', {\n startkey: SYSTEM_ADAPTER_PREFIX,\n endkey: SYSTEM_ADAPTER_PREFIX + HIGHEST_UNICODE_SYMBOL,\n });\n\n for (const row of instancesView.rows) {\n const obj = row.value;\n\n if (!obj.common.enabled) {\n continue;\n }\n\n const isBlocked = this.internalIsAdapterVersionBlocked({\n systemConfigObj,\n systemRepoObj,\n adapterName: obj.common.name,\n version: obj.common.version,\n });\n\n if (!isBlocked) {\n continue;\n }\n\n obj.common.enabled = false;\n\n await this.objects.setObject(obj._id, obj);\n disabledList.push(row.value);\n }\n\n return disabledList;\n }\n\n /**\n * Check if version of a specific adapter is blocked\n *\n * @param options adapter version and name information\n * @returns A boolean indicating if the adapter version is blocked\n */\n async isAdapterVersionBlocked(options: AdapterVersionBlockedOptions): Promise<boolean> {\n const systemRepoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const systemConfigObj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n\n if (!systemConfigObj || !systemRepoObj) {\n return false;\n }\n\n return this.internalIsAdapterVersionBlocked({ ...options, systemRepoObj, systemConfigObj });\n }\n\n /**\n * Check if version of a specific adapter is blocked\n *\n * @param options information about adapter, version and cached objects\n * @returns A boolean indicating if the adapter version is blocked\n */\n private internalIsAdapterVersionBlocked(options: InternalAdapterVersionBlockedOptions): boolean {\n const { adapterName, version, systemRepoObj, systemConfigObj } = options;\n\n for (const activeRepoName of systemConfigObj.common.activeRepo) {\n if (!(activeRepoName in systemRepoObj.native.repositories)) {\n return false;\n }\n\n const repo = systemRepoObj.native.repositories[activeRepoName];\n const adapterEntry = repo.json?.[adapterName];\n\n if (!adapterEntry || !('blockedVersions' in adapterEntry)) {\n return false;\n }\n\n for (const blockedVersion of adapterEntry.blockedVersions) {\n if (semver.satisfies(version, blockedVersion, { includePrerelease: true })) {\n return true;\n }\n }\n }\n\n return false;\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;;;;;AAAA,uBAKO;AACP,oBAAmB;AAqBb,MAAO,iBAAgB;;EAER;EAEjB,YAAY,SAAgC;AACxC,SAAK,UAAU,QAAQ;EAC3B;;;;;;EAOA,MAAM,iCAA8B;AAEhC,UAAM,eAA0C,CAAA;AAEhD,UAAM,gBAAgB,MAAM,KAAK,QAAQ,UAAU,uCAAsB;AACzE,UAAM,kBAAkB,MAAM,KAAK,QAAQ,UAAU,iCAAgB;AAErE,QAAI,CAAC,mBAAmB,CAAC,eAAe;AACpC,aAAO;IACX;AAEA,UAAM,gBAAgB,MAAM,KAAK,QAAQ,mBAAmB,UAAU,YAAY;MAC9E,UAAU;MACV,QAAQ,yCAAwB;KACnC;AAED,eAAW,OAAO,cAAc,MAAM;AAClC,YAAM,MAAM,IAAI;AAEhB,UAAI,CAAC,IAAI,OAAO,SAAS;AACrB;MACJ;AAEA,YAAM,YAAY,KAAK,gCAAgC;QACnD;QACA;QACA,aAAa,IAAI,OAAO;QACxB,SAAS,IAAI,OAAO;OACvB;AAED,UAAI,CAAC,WAAW;AACZ;MACJ;AAEA,UAAI,OAAO,UAAU;AAErB,YAAM,KAAK,QAAQ,UAAU,IAAI,KAAK,GAAG;AACzC,mBAAa,KAAK,IAAI,KAAK;IAC/B;AAEA,WAAO;EACX;;;;;;;EAQA,MAAM,wBAAwB,SAAqC;AAC/D,UAAM,gBAAgB,MAAM,KAAK,QAAQ,UAAU,uCAAsB;AACzE,UAAM,kBAAkB,MAAM,KAAK,QAAQ,UAAU,iCAAgB;AAErE,QAAI,CAAC,mBAAmB,CAAC,eAAe;AACpC,aAAO;IACX;AAEA,WAAO,KAAK,gCAAgC,EAAE,GAAG,SAAS,eAAe,gBAAe,CAAE;EAC9F;;;;;;;EAQQ,gCAAgC,SAA6C;AACjF,UAAM,EAAE,aAAa,SAAS,eAAe,gBAAe,IAAK;AAEjE,eAAW,kBAAkB,gBAAgB,OAAO,YAAY;AAC5D,UAAI,EAAE,kBAAkB,cAAc,OAAO,eAAe;AACxD,eAAO;MACX;AAEA,YAAM,OAAO,cAAc,OAAO,aAAa,cAAc;AAC7D,YAAM,eAAe,KAAK,OAAO,WAAW;AAE5C,UAAI,CAAC,gBAAgB,EAAE,qBAAqB,eAAe;AACvD,eAAO;MACX;AAEA,iBAAW,kBAAkB,aAAa,iBAAiB;AACvD,YAAI,cAAAA,QAAO,UAAU,SAAS,gBAAgB,EAAE,mBAAmB,KAAI,CAAE,GAAG;AACxE,iBAAO;QACX;MACJ;IACJ;AAEA,WAAO;EACX;;",
|
|
6
6
|
"names": ["semver"]
|
|
7
7
|
}
|
|
@@ -23,6 +23,4 @@ __export(exitCodes_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(exitCodes_exports);
|
|
24
24
|
var import_js_controller_common = require("@iobroker/js-controller-common");
|
|
25
25
|
var exitCodes_default = import_js_controller_common.EXIT_CODES;
|
|
26
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
27
|
-
0 && (module.exports = {});
|
|
28
26
|
//# sourceMappingURL=exitCodes.js.map
|
|
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
20
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
26
|
mod
|
|
23
27
|
));
|
|
@@ -76,7 +80,7 @@ function MHServer(hostname, logger, config, info, ips, secret) {
|
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
82
|
function checkAuthList(ts) {
|
|
79
|
-
ts = ts || new Date().getTime();
|
|
83
|
+
ts = ts || (/* @__PURE__ */ new Date()).getTime();
|
|
80
84
|
for (const id of Object.keys(authList)) {
|
|
81
85
|
if (!authList[id]) {
|
|
82
86
|
delete authList[id];
|
|
@@ -101,7 +105,7 @@ function MHServer(hostname, logger, config, info, ips, secret) {
|
|
|
101
105
|
if (!msg) {
|
|
102
106
|
return;
|
|
103
107
|
}
|
|
104
|
-
const ts = new Date().getTime();
|
|
108
|
+
const ts = (/* @__PURE__ */ new Date()).getTime();
|
|
105
109
|
checkAuthList(ts);
|
|
106
110
|
const id = `${rinfo.address}:${rinfo.port}`;
|
|
107
111
|
switch (msg.cmd) {
|
|
@@ -200,7 +204,7 @@ function MHServer(hostname, logger, config, info, ips, secret) {
|
|
|
200
204
|
});
|
|
201
205
|
server.on("message", (msg, rinfo) => {
|
|
202
206
|
const text = msg.toString();
|
|
203
|
-
const now = new Date().getTime();
|
|
207
|
+
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
204
208
|
const id = `${rinfo.address}:${rinfo.port}`;
|
|
205
209
|
for (const ids in buffer) {
|
|
206
210
|
if (!lastFrame[ids]) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/multihostServer.js"],
|
|
4
4
|
"sourcesContent": ["/**\n * Multihost server\n *\n * Master multihost functionality\n *\n * Copyright 2014-2024 bluefox <dogafox@gmail.com>,\n * MIT License\n *\n */\n\nimport dgram from 'node:dgram';\nimport { tools as dbTools } from '@iobroker/js-controller-common-db';\nconst PORT = 50005;\nconst MULTICAST_ADDR = '239.255.255.250';\n\n/**\n * The Multihost Server allows connection from other ioBroker hosts\n *\n * @param hostname\n * @param logger\n * @param config\n * @param info\n * @param ips\n * @param secret\n */\nexport function MHServer(hostname, logger, config, info, ips, secret) {\n const count = 0;\n const buffer = {};\n const lastFrame = {};\n const authList = {};\n\n let server = null;\n let initTimer = null;\n let stopped = false;\n let crypto;\n\n config = Object.assign({}, config); // make a copy\n\n if (config.objects) {\n config.objects = {\n type: config.objects.type,\n host: config.objects.host,\n port: config.objects.port,\n user: config.objects.user,\n pass: config.objects.pass,\n options: config.objects.options,\n maxQueue: config.objects.maxQueue,\n };\n }\n\n if (config.states) {\n config.states = {\n type: config.states.type,\n host: config.states.host,\n port: config.states.port,\n user: config.states.user,\n pass: config.states.pass,\n options: config.states.options,\n maxQueue: config.states.maxQueue,\n };\n }\n\n function send(msg, rinfo) {\n if (server) {\n setImmediate(() => {\n const text = JSON.stringify(msg);\n try {\n server.send(text, 0, text.length, rinfo.port, rinfo.address);\n } catch (e) {\n logger.warn(\n `host.${hostname} Multi-host discovery server: cannot send answer to ${rinfo.address}:${rinfo.port}: ${e}`,\n );\n }\n });\n }\n }\n\n // delete all old connections\n function checkAuthList(ts) {\n ts = ts || new Date().getTime();\n for (const id of Object.keys(authList)) {\n if (!authList[id]) {\n delete authList[id];\n } else if (ts - authList[id].ts > 31000) {\n delete authList[id];\n }\n }\n }\n\n async function sha(secret, salt, callback) {\n // calculate sha256\n crypto = crypto || (await import('node:crypto'));\n const hash = crypto.createHash('sha256');\n\n hash.on('readable', () => {\n const data = hash.read();\n if (data) {\n callback(data.toString('hex'));\n }\n });\n\n hash.write(secret + salt);\n hash.end();\n }\n\n // hello => auth => browse\n function process(msg, rinfo) {\n if (!msg) {\n return;\n }\n\n const ts = new Date().getTime();\n checkAuthList(ts);\n\n const id = `${rinfo.address}:${rinfo.port}`;\n\n switch (msg.cmd) {\n case 'browse':\n if (secret && msg.password && authList[id]) {\n return sha(secret, authList[id].salt, shaText => {\n if (shaText !== msg.password) {\n send(\n {\n auth: config.multihostService.secure,\n cmd: msg.cmd,\n id: msg.id,\n result: 'invalid password',\n },\n rinfo,\n );\n } else {\n authList[id].auth = true;\n send(\n {\n auth: config.multihostService.secure,\n cmd: msg.cmd,\n id: msg.id,\n objects: config.objects,\n states: config.states,\n info: info,\n hostname: hostname,\n slave: !dbTools.isLocalObjectsDbServer(config.objects.type, config.objects.host),\n result: 'ok',\n },\n rinfo,\n );\n }\n });\n }\n\n if (!config.multihostService.secure || (authList[id] && authList[id].auth)) {\n send(\n {\n auth: config.multihostService.secure,\n cmd: msg.cmd,\n id: msg.id,\n objects: config.objects,\n states: config.states,\n info: info,\n hostname: hostname,\n slave: !dbTools.isLocalObjectsDbServer(config.objects.type, config.objects.host),\n result: 'ok',\n },\n rinfo,\n );\n } else {\n authList[id] = {\n time: ts,\n salt: (Math.random() * 1000000 + ts).toString().substring(0, 16),\n auth: false,\n };\n // padding\n if (authList[id].salt.length < 16) {\n authList[id].salt += new Array(16 - authList[id].salt.length).join('_');\n }\n send(\n {\n auth: config.multihostService.secure,\n cmd: msg.cmd,\n id: msg.id,\n result: 'not authenticated',\n salt: authList[id].salt,\n },\n rinfo,\n );\n }\n break;\n\n default:\n send(\n {\n cmd: msg.cmd,\n id: msg.id,\n result: 'unknown command',\n },\n rinfo,\n );\n break;\n }\n }\n\n this.init = function () {\n stopped = false;\n if (initTimer) {\n clearTimeout(initTimer);\n initTimer = null;\n }\n\n if (count > 10) {\n return logger.warn(\n `host.${hostname} Multi-host discovery server: Port ${PORT} is occupied. Service stopped.`,\n );\n }\n\n server = dgram.createSocket({ type: 'udp4', reuseAddr: true });\n\n server.on('error', err => {\n logger.error(`host.${hostname} Multi-host discovery server: error: ${err.stack}`);\n server.close();\n server = null;\n\n initTimer =\n initTimer ||\n setTimeout(() => {\n initTimer = null;\n this.init();\n }, 5000);\n });\n\n server.on('close', () => {\n server = null;\n\n if (!initTimer && !stopped) {\n initTimer = setTimeout(() => {\n initTimer = null;\n this.init();\n }, 5000);\n }\n });\n\n server.on('message', (msg, rinfo) => {\n // following messages are allowed\n const text = msg.toString();\n const now = new Date().getTime();\n const id = `${rinfo.address}:${rinfo.port}`;\n\n for (const ids in buffer) {\n if (!lastFrame[ids]) {\n delete buffer[ids];\n } else if (now - lastFrame[ids] > 1000) {\n delete buffer[ids];\n delete lastFrame[ids];\n }\n }\n\n if (lastFrame[id] && now - lastFrame[id] > 1000) {\n buffer[id] = '';\n }\n\n lastFrame[id] = now;\n\n if (!buffer[id] && text[0] !== '{') {\n // ignore message\n logger.debug(\n `host.${hostname} Multi-host discovery server: Message from ${rinfo.address} ignored: ${text}`,\n );\n } else {\n buffer[id] = (buffer[id] || '') + msg.toString();\n if (buffer[id] && buffer[id][buffer[id].length - 1] === '}') {\n try {\n const data = JSON.parse(buffer[id]);\n buffer[id] = '';\n if (data) {\n process(data, rinfo);\n }\n } catch {\n // may be not yet complete.\n }\n }\n }\n });\n\n server.on('listening', () => {\n try {\n server.addMembership(MULTICAST_ADDR);\n } catch {\n logger.warn(`host.${hostname} Multi-host discovery server: Multicast membership could not be added.`);\n }\n const address = server.address();\n logger.info(\n `host.${hostname} Multi-host discovery server: service started on ${address.address}:${address.port}`,\n );\n });\n\n server.bind(PORT);\n };\n\n this.close = function (callback) {\n stopped = true;\n if (initTimer) {\n clearTimeout(initTimer);\n initTimer = null;\n }\n if (server) {\n try {\n server.close(callback);\n server = null;\n } catch {\n server = null;\n if (callback) {\n callback();\n }\n }\n } else if (callback) {\n callback();\n }\n };\n\n this.init();\n\n return this;\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["secret", "dbTools", "dgram"]
|
|
7
7
|
}
|
|
@@ -24,6 +24,4 @@ module.exports = __toCommonJS(objectsInMemClient_exports);
|
|
|
24
24
|
var import_db_objects_redis = require("@iobroker/db-objects-redis");
|
|
25
25
|
console.warn('Deprecated! Please use require("@iobroker/db-objects-redis").Client library in tests!');
|
|
26
26
|
var objectsInMemClient_default = import_db_objects_redis.Client;
|
|
27
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
-
0 && (module.exports = {});
|
|
29
27
|
//# sourceMappingURL=objectsInMemClient.js.map
|
|
@@ -24,6 +24,4 @@ module.exports = __toCommonJS(objectsInMemServer_exports);
|
|
|
24
24
|
var import_db_objects_file = require("@iobroker/db-objects-file");
|
|
25
25
|
console.warn('Deprecated! Please use require("@iobroker/db-objects-file").Server in tests to start a server and then use require("@iobroker/db-objects-file").Client to connect with a client against this server!');
|
|
26
26
|
var objectsInMemServer_default = import_db_objects_file.Server;
|
|
27
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
-
0 && (module.exports = {});
|
|
29
27
|
//# sourceMappingURL=objectsInMemServer.js.map
|