@iobroker/js-controller-adapter 7.2.4 → 7.2.5
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/lib/_Types.d.ts +3 -0
- package/build/cjs/lib/adapter/adapter.d.ts +2 -2
- package/build/cjs/lib/adapter/adapter.js +72 -6
- package/build/cjs/lib/adapter/adapter.js.map +2 -2
- package/build/esm/lib/_Types.d.ts +3 -0
- package/build/esm/lib/_Types.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.d.ts +2 -2
- package/build/esm/lib/adapter/adapter.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.js +74 -8
- package/build/esm/lib/adapter/adapter.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -10
|
@@ -388,6 +388,8 @@ export interface InternalAddChannelToEnumOptions {
|
|
|
388
388
|
export interface SendToOptions {
|
|
389
389
|
/** Method throws or calls error cb, if callback not called in time, works for single targets only */
|
|
390
390
|
timeout?: number;
|
|
391
|
+
/** The user on whose behalf the message is sent */
|
|
392
|
+
user?: ioBroker.ObjectIDs.User;
|
|
391
393
|
}
|
|
392
394
|
export interface InternalSendToOptions {
|
|
393
395
|
instanceName: string;
|
|
@@ -411,6 +413,7 @@ export interface InternalSendToHostOptions {
|
|
|
411
413
|
command: string;
|
|
412
414
|
message: any;
|
|
413
415
|
callback?: ioBroker.MessageCallback | ioBroker.MessageCallbackInfo;
|
|
416
|
+
options?: SendToOptions;
|
|
414
417
|
}
|
|
415
418
|
export interface InternalGetStateOptions {
|
|
416
419
|
id: string;
|
|
@@ -162,7 +162,7 @@ export interface AdapterClass {
|
|
|
162
162
|
* Sends a message to a specific host or all hosts.
|
|
163
163
|
*/
|
|
164
164
|
sendToHostAsync(hostName: string, message: ioBroker.MessagePayload): Promise<ioBroker.Message | undefined>;
|
|
165
|
-
sendToHostAsync(hostName: string, command: string, message: ioBroker.MessagePayload): Promise<ioBroker.Message | undefined>;
|
|
165
|
+
sendToHostAsync(hostName: string, command: string, message: ioBroker.MessagePayload, options?: SendToOptions): Promise<ioBroker.Message | undefined>;
|
|
166
166
|
/**
|
|
167
167
|
* Sends a message to a specific instance or all instances of some specific adapter.
|
|
168
168
|
*/
|
|
@@ -722,7 +722,7 @@ export declare class AdapterClass extends EventEmitter {
|
|
|
722
722
|
sendTo(instanceName: string, command: string, message: any, callback?: ioBroker.MessageCallback | ioBroker.MessageCallbackInfo, options?: SendToOptions): void;
|
|
723
723
|
private _sendTo;
|
|
724
724
|
sendToHost(hostName: string | null, message: any, callback?: ioBroker.MessageCallback | ioBroker.MessageCallbackInfo): void;
|
|
725
|
-
sendToHost(hostName: string | null, command: string, message: any, callback?: ioBroker.MessageCallback | ioBroker.MessageCallbackInfo): void;
|
|
725
|
+
sendToHost(hostName: string | null, command: string, message: any, callback?: ioBroker.MessageCallback | ioBroker.MessageCallbackInfo, options?: SendToOptions): void;
|
|
726
726
|
private _sendToHost;
|
|
727
727
|
sendToUI(options: SendToUserInterfaceClientOptions): Promise<void>;
|
|
728
728
|
registerNotification<Scope extends keyof ioBroker.NotificationScopes>(scope: Scope, category: ioBroker.NotificationScopes[Scope] | null, message: string, options?: NotificationOptions): Promise<void>;
|
|
@@ -363,7 +363,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
363
363
|
this.readFileAsync = import_js_controller_common.tools.promisify(this.readFile, this, ["file", "mimeType"]);
|
|
364
364
|
this.writeFileAsync = import_js_controller_common.tools.promisify(this.writeFile, this);
|
|
365
365
|
this.fileExistsAsync = import_js_controller_common.tools.promisify(this.fileExists, this);
|
|
366
|
-
this.sendToHostAsync = import_js_controller_common.tools.promisifyNoError(this.sendToHost, this);
|
|
367
366
|
this.setStateAsync = import_js_controller_common.tools.promisify(this.setState, this);
|
|
368
367
|
this.setStateChangedAsync = import_js_controller_common.tools.promisify(this.setStateChanged, this, ["id", "notChanged"]);
|
|
369
368
|
this.setForeignStateAsync = import_js_controller_common.tools.promisify(this.setForeignState, this);
|
|
@@ -4711,13 +4710,27 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4711
4710
|
this.sendTo(instanceName, command, message, callback, options);
|
|
4712
4711
|
});
|
|
4713
4712
|
}
|
|
4713
|
+
/**
|
|
4714
|
+
* The `user` field of an outbound message, from the `user` of the send options.
|
|
4715
|
+
*
|
|
4716
|
+
* Spread into the envelope, so a send without a user leaves the field out entirely instead of
|
|
4717
|
+
* putting an empty one in: a receiver that checks `obj.user` must be able to tell "nobody named a
|
|
4718
|
+
* user" from "the user is known", and an empty string is neither.
|
|
4719
|
+
*
|
|
4720
|
+
* @param options the send options the caller passed, if any
|
|
4721
|
+
*/
|
|
4722
|
+
#userOf(options) {
|
|
4723
|
+
const user = options?.user;
|
|
4724
|
+
return typeof user === "string" && user ? { user } : {};
|
|
4725
|
+
}
|
|
4714
4726
|
async _sendTo(_options) {
|
|
4715
4727
|
const { command, message, callback, options } = _options;
|
|
4716
4728
|
let { instanceName } = _options;
|
|
4717
4729
|
const obj = {
|
|
4718
4730
|
command,
|
|
4719
4731
|
message,
|
|
4720
|
-
from: `system.adapter.${this.namespace}
|
|
4732
|
+
from: `system.adapter.${this.namespace}`,
|
|
4733
|
+
...this.#userOf(options)
|
|
4721
4734
|
};
|
|
4722
4735
|
if (!instanceName) {
|
|
4723
4736
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, "No instanceName provided or not a string");
|
|
@@ -4817,8 +4830,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4817
4830
|
* if (!result) adapter.log.error('No response received');
|
|
4818
4831
|
* }
|
|
4819
4832
|
* ```
|
|
4833
|
+
* @param options optional send options: a `timeout` for the answer, or the `user` this message is
|
|
4834
|
+
* sent on behalf of - the host sees it as `obj.user`
|
|
4820
4835
|
*/
|
|
4821
|
-
sendToHost(hostName, command, message, callback) {
|
|
4836
|
+
sendToHost(hostName, command, message, callback, options) {
|
|
4822
4837
|
if (typeof message === "undefined") {
|
|
4823
4838
|
message = command;
|
|
4824
4839
|
command = "send";
|
|
@@ -4830,17 +4845,57 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4830
4845
|
if (!import_js_controller_common.tools.isObject(callback)) {
|
|
4831
4846
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
4832
4847
|
}
|
|
4848
|
+
if (options !== void 0) {
|
|
4849
|
+
import_validator.Validator.assertObject(options, "options");
|
|
4850
|
+
}
|
|
4833
4851
|
return this._sendToHost({
|
|
4834
4852
|
hostName,
|
|
4835
4853
|
command,
|
|
4836
4854
|
message,
|
|
4855
|
+
options,
|
|
4837
4856
|
callback
|
|
4838
4857
|
});
|
|
4839
4858
|
}
|
|
4859
|
+
/**
|
|
4860
|
+
* Async version of sendToHost
|
|
4861
|
+
*
|
|
4862
|
+
* Resolves with whatever the host answered - like the promisified version it replaces, an error
|
|
4863
|
+
* of the host reaches the caller as the resolved value, and that is left alone: an adapter that
|
|
4864
|
+
* awaits this today must not start seeing rejections.
|
|
4865
|
+
*
|
|
4866
|
+
* It rejects in one case: a `timeout` was asked for in the send options and elapsed, which is
|
|
4867
|
+
* how `sendToAsync` reports the same thing. Whoever passes that option is writing against an
|
|
4868
|
+
* option that did not exist before and can expect it; whoever passes none keeps the old
|
|
4869
|
+
* behaviour, including a host that never answers and a caller that waits for ever.
|
|
4870
|
+
*
|
|
4871
|
+
* @param hostName name of the host where the message must be sent to. E.g. "myPC" or "system.host.myPC". If argument is null, the message will be sent to all hosts.
|
|
4872
|
+
* @param command command name. One of: "cmdExec", "getRepository", "getInstalled", ...
|
|
4873
|
+
* @param message object that will be given as argument for request
|
|
4874
|
+
* @param options optional send options: a `timeout` for the answer, or the `user` the message is sent for
|
|
4875
|
+
*/
|
|
4876
|
+
sendToHostAsync(hostName, command, message, options) {
|
|
4877
|
+
const timeout = options?.timeout;
|
|
4878
|
+
return new Promise((resolve, reject) => {
|
|
4879
|
+
this.sendToHost(
|
|
4880
|
+
hostName,
|
|
4881
|
+
command,
|
|
4882
|
+
message,
|
|
4883
|
+
// The answer of a host travels through the states database and is therefore never an
|
|
4884
|
+
// `Error` instance; one can only come from here, and only where a budget was named.
|
|
4885
|
+
(result) => timeout && result instanceof Error ? reject(result) : resolve(result),
|
|
4886
|
+
options
|
|
4887
|
+
);
|
|
4888
|
+
});
|
|
4889
|
+
}
|
|
4840
4890
|
async _sendToHost(_options) {
|
|
4841
|
-
const { command, message, callback } = _options;
|
|
4891
|
+
const { command, message, callback, options } = _options;
|
|
4842
4892
|
let { hostName } = _options;
|
|
4843
|
-
const obj = {
|
|
4893
|
+
const obj = {
|
|
4894
|
+
command,
|
|
4895
|
+
message,
|
|
4896
|
+
from: `system.adapter.${this.namespace}`,
|
|
4897
|
+
...this.#userOf(options)
|
|
4898
|
+
};
|
|
4844
4899
|
if (!this.#states) {
|
|
4845
4900
|
this._logger.info(`${this.namespaceLog} sendToHost not processed because States database not connected`);
|
|
4846
4901
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
@@ -4889,7 +4944,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4889
4944
|
if (this._callbackId >= 4294967295) {
|
|
4890
4945
|
this._callbackId = 1;
|
|
4891
4946
|
}
|
|
4892
|
-
|
|
4947
|
+
const callbackId = obj.callback.id;
|
|
4948
|
+
let timer;
|
|
4949
|
+
if (options?.timeout) {
|
|
4950
|
+
timer = setTimeout(() => {
|
|
4951
|
+
const callbackObj = this.messageCallbacks.get(callbackId);
|
|
4952
|
+
if (callbackObj) {
|
|
4953
|
+
callbackObj.cb(new Error("Timeout exceeded"));
|
|
4954
|
+
this.messageCallbacks.delete(callbackId);
|
|
4955
|
+
}
|
|
4956
|
+
}, options.timeout);
|
|
4957
|
+
}
|
|
4958
|
+
this.messageCallbacks.set(callbackId, { cb: callback, time: Date.now(), timer });
|
|
4893
4959
|
} else {
|
|
4894
4960
|
obj.callback = callback;
|
|
4895
4961
|
obj.callback.ack = true;
|