@scrypted/server 0.144.1 → 0.144.2
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/dist/cert.js +1 -1
- package/dist/cert.js.map +1 -1
- package/dist/cluster/cluster-labels.d.ts +3 -3
- package/dist/cluster/cluster-labels.js +2 -2
- package/dist/cluster/cluster-labels.js.map +1 -1
- package/dist/cluster/cluster-setup.d.ts +3 -3
- package/dist/cluster/cluster-setup.js +3 -3
- package/dist/cluster/cluster-setup.js.map +1 -1
- package/dist/db-types.d.ts +4 -4
- package/dist/db-types.js.map +1 -1
- package/dist/event-registry.d.ts +2 -2
- package/dist/event-registry.js +9 -7
- package/dist/event-registry.js.map +1 -1
- package/dist/fetch/index.d.ts +2 -2
- package/dist/fetch/index.js +3 -6
- package/dist/fetch/index.js.map +1 -1
- package/dist/http-interfaces.js +1 -1
- package/dist/http-interfaces.js.map +1 -1
- package/dist/infer-defaults.d.ts +4 -4
- package/dist/infer-defaults.js +8 -4
- package/dist/infer-defaults.js.map +1 -1
- package/dist/ip.js +2 -1
- package/dist/ip.js.map +1 -1
- package/dist/level.d.ts +3 -3
- package/dist/level.js +1 -0
- package/dist/level.js.map +1 -1
- package/dist/listen-zero.js.map +1 -1
- package/dist/mixin/mixin-cycle.js +6 -6
- package/dist/mixin/mixin-cycle.js.map +1 -1
- package/dist/plugin/acl.js.map +1 -1
- package/dist/plugin/cluster.js.map +1 -1
- package/dist/plugin/descriptor.js +1 -1
- package/dist/plugin/descriptor.js.map +1 -1
- package/dist/plugin/device.d.ts +6 -6
- package/dist/plugin/device.js.map +1 -1
- package/dist/plugin/endpoint.js.map +1 -1
- package/dist/plugin/media.js.map +1 -1
- package/dist/plugin/mediaobject.d.ts +1 -1
- package/dist/plugin/mediaobject.js.map +1 -1
- package/dist/plugin/plugin-api.d.ts +6 -6
- package/dist/plugin/plugin-api.js +2 -2
- package/dist/plugin/plugin-api.js.map +1 -1
- package/dist/plugin/plugin-console.js +11 -10
- package/dist/plugin/plugin-console.js.map +1 -1
- package/dist/plugin/plugin-device.d.ts +3 -3
- package/dist/plugin/plugin-device.js +2 -0
- package/dist/plugin/plugin-device.js.map +1 -1
- package/dist/plugin/plugin-host-api.d.ts +1 -1
- package/dist/plugin/plugin-host-api.js +19 -5
- package/dist/plugin/plugin-host-api.js.map +1 -1
- package/dist/plugin/plugin-host.js +3 -2
- package/dist/plugin/plugin-host.js.map +1 -1
- package/dist/plugin/plugin-http.d.ts +1 -1
- package/dist/plugin/plugin-http.js +5 -1
- package/dist/plugin/plugin-http.js.map +1 -1
- package/dist/plugin/plugin-lazy-remote.js.map +1 -1
- package/dist/plugin/plugin-remote-websocket.js.map +1 -1
- package/dist/plugin/plugin-remote-worker.js +5 -2
- package/dist/plugin/plugin-remote-worker.js.map +1 -1
- package/dist/plugin/plugin-remote.js +1 -1
- package/dist/plugin/plugin-remote.js.map +1 -1
- package/dist/plugin/plugin-repl.js +6 -2
- package/dist/plugin/plugin-repl.js.map +1 -1
- package/dist/plugin/runtime/child-process-worker.d.ts +4 -4
- package/dist/plugin/runtime/child-process-worker.js +1 -2
- package/dist/plugin/runtime/child-process-worker.js.map +1 -1
- package/dist/plugin/runtime/cluster-fork-worker.d.ts +1 -1
- package/dist/plugin/runtime/cluster-fork-worker.js +2 -0
- package/dist/plugin/runtime/cluster-fork-worker.js.map +1 -1
- package/dist/plugin/runtime/custom-worker.js.map +1 -1
- package/dist/plugin/runtime/node-fork-worker.d.ts +1 -1
- package/dist/plugin/runtime/node-fork-worker.js.map +1 -1
- package/dist/plugin/runtime/node-thread-worker.js.map +1 -1
- package/dist/plugin/runtime/python-worker.js +1 -1
- package/dist/plugin/runtime/python-worker.js.map +1 -1
- package/dist/plugin/runtime/runtime-worker.d.ts +1 -1
- package/dist/plugin/system.d.ts +1 -1
- package/dist/plugin/system.js +1 -0
- package/dist/plugin/system.js.map +1 -1
- package/dist/promise-utils.d.ts +1 -1
- package/dist/promise-utils.js.map +1 -1
- package/dist/rpc-buffer-serializer.d.ts +1 -1
- package/dist/rpc-serializer.js.map +1 -1
- package/dist/rpc.d.ts +10 -9
- package/dist/rpc.js +15 -8
- package/dist/rpc.js.map +1 -1
- package/dist/runtime.d.ts +11 -11
- package/dist/runtime.js +17 -18
- package/dist/runtime.js.map +1 -1
- package/dist/scrypted-cluster-main.js +3 -2
- package/dist/scrypted-cluster-main.js.map +1 -1
- package/dist/scrypted-plugin-main.js +1 -1
- package/dist/scrypted-plugin-main.js.map +1 -1
- package/dist/scrypted-server-main.js +8 -5
- package/dist/scrypted-server-main.js.map +1 -1
- package/dist/server-settings.d.ts +1 -1
- package/dist/server-settings.js +4 -4
- package/dist/server-settings.js.map +1 -1
- package/dist/services/addresses.d.ts +1 -1
- package/dist/services/addresses.js +2 -2
- package/dist/services/addresses.js.map +1 -1
- package/dist/services/alerts.js +2 -2
- package/dist/services/alerts.js.map +1 -1
- package/dist/services/cluster-fork.js.map +1 -1
- package/dist/services/plugin.d.ts +5 -5
- package/dist/services/plugin.js.map +1 -1
- package/dist/services/service-control.js.map +1 -1
- package/dist/services/users.d.ts +2 -2
- package/dist/services/users.js.map +1 -1
- package/dist/state.d.ts +7 -7
- package/dist/state.js +4 -4
- package/dist/state.js.map +1 -1
- package/dist/threading.js.map +1 -1
- package/dist/usertoken.d.ts +2 -2
- package/dist/usertoken.js.map +1 -1
- package/package.json +2 -2
- package/python/cluster_setup.py +13 -4
- package/python/plugin_remote.py +22 -18
- package/python/rpc_reader.py +3 -5
- package/src/cert.ts +2 -2
- package/src/cluster/cluster-labels.ts +4 -4
- package/src/cluster/cluster-setup.ts +20 -20
- package/src/db-types.ts +16 -16
- package/src/event-registry.ts +13 -11
- package/src/fetch/index.ts +4 -7
- package/src/http-interfaces.ts +2 -2
- package/src/infer-defaults.ts +12 -8
- package/src/ip.ts +2 -1
- package/src/level.ts +10 -9
- package/src/listen-zero.ts +1 -1
- package/src/mixin/mixin-cycle.ts +6 -6
- package/src/plugin/acl.ts +1 -1
- package/src/plugin/cluster.ts +2 -2
- package/src/plugin/descriptor.ts +2 -2
- package/src/plugin/device.ts +16 -16
- package/src/plugin/endpoint.ts +4 -4
- package/src/plugin/media.ts +15 -15
- package/src/plugin/mediaobject.ts +3 -3
- package/src/plugin/plugin-api.ts +7 -7
- package/src/plugin/plugin-console.ts +13 -12
- package/src/plugin/plugin-device.ts +20 -18
- package/src/plugin/plugin-host-api.ts +27 -13
- package/src/plugin/plugin-host.ts +26 -25
- package/src/plugin/plugin-http.ts +9 -5
- package/src/plugin/plugin-lazy-remote.ts +1 -1
- package/src/plugin/plugin-remote-websocket.ts +1 -1
- package/src/plugin/plugin-remote-worker.ts +22 -20
- package/src/plugin/plugin-remote.ts +14 -14
- package/src/plugin/plugin-repl.ts +6 -2
- package/src/plugin/runtime/child-process-worker.ts +11 -12
- package/src/plugin/runtime/cluster-fork-worker.ts +2 -0
- package/src/plugin/runtime/custom-worker.ts +6 -6
- package/src/plugin/runtime/node-fork-worker.ts +3 -3
- package/src/plugin/runtime/node-thread-worker.ts +3 -3
- package/src/plugin/runtime/python-worker.ts +14 -14
- package/src/plugin/runtime/runtime-worker.ts +1 -1
- package/src/plugin/system.ts +24 -23
- package/src/promise-utils.ts +4 -4
- package/src/rpc-serializer.ts +3 -3
- package/src/rpc.ts +25 -17
- package/src/runtime.ts +59 -60
- package/src/scrypted-cluster-main.ts +19 -18
- package/src/scrypted-plugin-main.ts +2 -2
- package/src/scrypted-server-main.ts +17 -14
- package/src/server-settings.ts +5 -5
- package/src/services/addresses.ts +3 -3
- package/src/services/alerts.ts +2 -2
- package/src/services/cluster-fork.ts +9 -9
- package/src/services/plugin.ts +15 -15
- package/src/services/service-control.ts +1 -1
- package/src/services/users.ts +3 -3
- package/src/state.ts +21 -21
- package/src/threading.ts +5 -5
- package/src/usertoken.ts +1 -1
package/src/db-types.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { LevelDocument } from "./level";
|
|
|
2
2
|
import { ScryptedNativeId, SystemDeviceState } from "@scrypted/types";
|
|
3
3
|
|
|
4
4
|
export class ScryptedDocument implements LevelDocument {
|
|
5
|
-
_id
|
|
6
|
-
_documentType
|
|
5
|
+
_id!: string;
|
|
6
|
+
_documentType!: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export class Settings extends ScryptedDocument {
|
|
@@ -16,28 +16,28 @@ export class Plugin extends ScryptedDocument {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export class ScryptedUser extends ScryptedDocument {
|
|
19
|
-
passwordDate
|
|
20
|
-
passwordHash
|
|
21
|
-
token
|
|
22
|
-
salt
|
|
23
|
-
aclId
|
|
19
|
+
passwordDate!: number;
|
|
20
|
+
passwordHash!: string;
|
|
21
|
+
token!: string;
|
|
22
|
+
salt!: string;
|
|
23
|
+
aclId?: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export class ScryptedAlert extends ScryptedDocument {
|
|
27
|
-
timestamp
|
|
28
|
-
title
|
|
29
|
-
path
|
|
30
|
-
message
|
|
27
|
+
timestamp!: number;
|
|
28
|
+
title!: string;
|
|
29
|
+
path!: string;
|
|
30
|
+
message!: string;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export class PluginDevice extends ScryptedDocument {
|
|
34
|
-
constructor(id
|
|
34
|
+
constructor(id: string) {
|
|
35
35
|
super();
|
|
36
36
|
this._id = id;
|
|
37
37
|
}
|
|
38
38
|
nativeId: ScryptedNativeId;
|
|
39
|
-
pluginId
|
|
40
|
-
state
|
|
41
|
-
stateVersion
|
|
42
|
-
storage
|
|
39
|
+
pluginId!: string;
|
|
40
|
+
state!: { [property: string]: SystemDeviceState };
|
|
41
|
+
stateVersion!: number;
|
|
42
|
+
storage!: { [key: string]: string };
|
|
43
43
|
}
|
package/src/event-registry.ts
CHANGED
|
@@ -29,10 +29,11 @@ export class EventRegistry {
|
|
|
29
29
|
|
|
30
30
|
listen(callback: (id: string, eventDetails: EventDetails, eventData: any) => void): EventListenerRegister {
|
|
31
31
|
const events = this.systemListeners;
|
|
32
|
-
|
|
32
|
+
let cb: typeof callback | undefined = callback;
|
|
33
|
+
events.add(cb);
|
|
33
34
|
return new EventListenerRegisterImpl(() => {
|
|
34
|
-
events.delete(
|
|
35
|
-
|
|
35
|
+
events.delete(cb!);
|
|
36
|
+
cb = undefined;
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
|
|
@@ -45,14 +46,15 @@ export class EventRegistry {
|
|
|
45
46
|
this.listeners[token] = events;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
let cb: typeof callback | undefined = callback;
|
|
50
|
+
events.add(cb);
|
|
49
51
|
return new EventListenerRegisterImpl(() => {
|
|
50
|
-
events.delete(
|
|
51
|
-
|
|
52
|
+
events.delete(cb!);
|
|
53
|
+
cb = undefined;
|
|
52
54
|
});
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
notify(id: string | undefined, eventTime: number, eventInterface: string, property: string | undefined, value: any, options?: {
|
|
57
|
+
notify(id: string | undefined, eventTime: number | undefined, eventInterface: string, property: string | undefined, value: any, options?: {
|
|
56
58
|
changed?: boolean;
|
|
57
59
|
mixinId?: string;
|
|
58
60
|
}): boolean {
|
|
@@ -62,9 +64,9 @@ export class EventRegistry {
|
|
|
62
64
|
return false;
|
|
63
65
|
|
|
64
66
|
const eventDetails: EventDetails = {
|
|
65
|
-
eventId: undefined
|
|
67
|
+
eventId: undefined!,
|
|
66
68
|
eventInterface,
|
|
67
|
-
eventTime
|
|
69
|
+
eventTime: eventTime!,
|
|
68
70
|
property,
|
|
69
71
|
mixinId,
|
|
70
72
|
};
|
|
@@ -79,9 +81,9 @@ export class EventRegistry {
|
|
|
79
81
|
// system listeners only get state changes.
|
|
80
82
|
// there are many potentially noisy stateless events, like
|
|
81
83
|
// object detection and settings changes.
|
|
82
|
-
if ((eventDetails.property && !eventDetails.mixinId) || allowedEventInterfaces.has(eventInterface)) {
|
|
84
|
+
if ((eventDetails.property && !eventDetails.mixinId) || allowedEventInterfaces.has(eventInterface!)) {
|
|
83
85
|
for (const event of this.systemListeners) {
|
|
84
|
-
event(id
|
|
86
|
+
event(id!, eventDetails, value);
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
|
package/src/fetch/index.ts
CHANGED
|
@@ -66,14 +66,14 @@ export type fetcher<B, M> = <T extends HttpFetchOptions<B>>(options: T) => Promi
|
|
|
66
66
|
>>;
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
export function getHttpFetchAccept(responseType: HttpFetchResponseType | undefined) {
|
|
69
|
+
export function getHttpFetchAccept(responseType: HttpFetchResponseType | undefined): string | undefined {
|
|
70
70
|
switch (responseType) {
|
|
71
71
|
case 'json':
|
|
72
72
|
return 'application/json';
|
|
73
73
|
case 'text':
|
|
74
74
|
return 'text/plain';
|
|
75
75
|
}
|
|
76
|
-
return;
|
|
76
|
+
return undefined;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export function hasHeader(headers: [string, string][], key: string) {
|
|
@@ -119,10 +119,7 @@ export function createHeadersArray(headers: HeadersInit | undefined): [string, s
|
|
|
119
119
|
return headersArray;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
const v = headers[k];
|
|
124
|
-
headersArray.push([k, v]);
|
|
125
|
-
}
|
|
122
|
+
headersArray.push(...Object.entries(headers));
|
|
126
123
|
|
|
127
124
|
return headersArray;
|
|
128
125
|
}
|
|
@@ -135,7 +132,7 @@ export function createHeadersArray(headers: HeadersInit | undefined): [string, s
|
|
|
135
132
|
*/
|
|
136
133
|
export function createStringOrBufferBody(headers: [string, string][], body: any) {
|
|
137
134
|
let contentType: string | undefined;
|
|
138
|
-
if (typeof body === 'object') {
|
|
135
|
+
if (typeof body === 'object' && !ArrayBuffer.isView(body)) {
|
|
139
136
|
body = JSON.stringify(body);
|
|
140
137
|
contentType = 'application/json';
|
|
141
138
|
}
|
package/src/http-interfaces.ts
CHANGED
|
@@ -63,7 +63,7 @@ export class HttpResponseImpl implements HttpResponse {
|
|
|
63
63
|
|
|
64
64
|
// prefer etag
|
|
65
65
|
this.res.sendFile(filePath, {
|
|
66
|
-
root:
|
|
66
|
+
root: undefined,
|
|
67
67
|
dotfiles: 'allow',
|
|
68
68
|
cacheControl: false,
|
|
69
69
|
});
|
|
@@ -110,7 +110,7 @@ export class HttpResponseImpl implements HttpResponse {
|
|
|
110
110
|
this.res.end();
|
|
111
111
|
}
|
|
112
112
|
catch (e) {
|
|
113
|
-
this.res.destroy(e);
|
|
113
|
+
this.res.destroy(e as Error);
|
|
114
114
|
}
|
|
115
115
|
finally {
|
|
116
116
|
peer.kill();
|
package/src/infer-defaults.ts
CHANGED
|
@@ -36,12 +36,16 @@ addType(ScryptedInterface.HttpRequestHandler, ScryptedDeviceType.DataSource);
|
|
|
36
36
|
addType(ScryptedInterface.BufferConverter, ScryptedDeviceType.API);
|
|
37
37
|
addType(ScryptedInterface.DeviceProvider, ScryptedDeviceType.DeviceProvider);
|
|
38
38
|
|
|
39
|
-
export function inferTypeFromInterfaces(interfaces: ScryptedInterface[]): ScryptedDeviceType {
|
|
39
|
+
export function inferTypeFromInterfaces(interfaces: ScryptedInterface[]): ScryptedDeviceType | undefined {
|
|
40
40
|
return inferTypesFromInterfaces(interfaces)[0];
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export function inferTypesFromInterfaces(interfaces: ScryptedInterface[]): ScryptedDeviceType[] {
|
|
44
|
-
const types = Object.keys(inferenceTable)
|
|
44
|
+
const types = Object.keys(inferenceTable)
|
|
45
|
+
.filter(iface => interfaces.includes(iface as ScryptedInterface))
|
|
46
|
+
.map(iface => inferenceTable[iface])
|
|
47
|
+
.filter((types): types is ScryptedDeviceType[] => types !== undefined)
|
|
48
|
+
.flat();
|
|
45
49
|
return types;
|
|
46
50
|
}
|
|
47
51
|
|
|
@@ -96,24 +100,24 @@ const roomHints: { [hint: string]: string } = {
|
|
|
96
100
|
'Laundry': 'Laundry Room',
|
|
97
101
|
}
|
|
98
102
|
|
|
99
|
-
export function inferRoomFromName(name: string): string {
|
|
103
|
+
export function inferRoomFromName(name: string): string | undefined {
|
|
100
104
|
if (!name)
|
|
101
|
-
return;
|
|
105
|
+
return undefined;
|
|
102
106
|
for (const hint of Object.keys(roomHints)) {
|
|
103
107
|
if (name.includes(hint))
|
|
104
108
|
return roomHints[hint];
|
|
105
109
|
}
|
|
110
|
+
return undefined;
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
export function getProvidedRoomOrDefault(pluginDevice: PluginDevice): string {
|
|
113
|
+
export function getProvidedRoomOrDefault(pluginDevice: PluginDevice): string | undefined {
|
|
109
114
|
const providedRoom = getState(pluginDevice, ScryptedInterfaceProperty.providedRoom);
|
|
110
115
|
if (providedRoom)
|
|
111
116
|
return providedRoom;
|
|
112
|
-
|
|
113
|
-
return room;
|
|
117
|
+
return inferRoomFromName(getDisplayName(pluginDevice));
|
|
114
118
|
}
|
|
115
119
|
|
|
116
|
-
export function getDisplayRoom(pluginDevice: PluginDevice): string {
|
|
120
|
+
export function getDisplayRoom(pluginDevice: PluginDevice): string | undefined {
|
|
117
121
|
const room = getState(pluginDevice, ScryptedInterfaceProperty.room);
|
|
118
122
|
if (room)
|
|
119
123
|
return room;
|
package/src/ip.ts
CHANGED
|
@@ -70,6 +70,7 @@ export function getUsableNetworkAddresses() {
|
|
|
70
70
|
const getUsable = (family: string | number) => {
|
|
71
71
|
const usable = Object.values(nis)
|
|
72
72
|
.flat()
|
|
73
|
+
.filter((details): details is os.NetworkInterfaceInfo => !!details)
|
|
73
74
|
.filter((details) => details.family === family)
|
|
74
75
|
.filter(details => isUsableNetworkAddress(details.address));
|
|
75
76
|
return usable;
|
|
@@ -84,7 +85,7 @@ export function getUsableNetworkAddresses() {
|
|
|
84
85
|
const fixedAddresses = ipv6.filter(details => details.address.includes('::'));
|
|
85
86
|
const fixedRanges = fixedAddresses.map(details => {
|
|
86
87
|
const block = new net.BlockList();
|
|
87
|
-
const cidr = parseInt(details.address.split('/')[1]) || 1;
|
|
88
|
+
const cidr = parseInt(details.address.split('/')[1] ?? '') || 1;
|
|
88
89
|
block.addSubnet(details.address, cidr, 'ipv6');
|
|
89
90
|
return block;
|
|
90
91
|
});
|
package/src/level.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GetOptions, Level, OpenOptions, PutOptions } from 'level';
|
|
2
2
|
|
|
3
3
|
export interface LevelDocument {
|
|
4
|
-
_id
|
|
5
|
-
_documentType
|
|
4
|
+
_id: any;
|
|
5
|
+
_documentType: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export interface LevelDocumentConstructor<T extends LevelDocument> {
|
|
@@ -16,11 +16,11 @@ function createLevelDocument(documentConstructor: any, json: any) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export class WrappedLevel extends Level<string, string | number> {
|
|
19
|
-
curId
|
|
19
|
+
curId!: number;
|
|
20
20
|
|
|
21
|
-
async open(): Promise<void>;
|
|
22
|
-
async open(options?: OpenOptions): Promise<void> {
|
|
23
|
-
await super.open(options);
|
|
21
|
+
override async open(): Promise<void>;
|
|
22
|
+
override async open(options?: OpenOptions): Promise<void> {
|
|
23
|
+
await super.open(options!);
|
|
24
24
|
try {
|
|
25
25
|
this.curId = parseInt(await this.get('_id') as string);
|
|
26
26
|
}
|
|
@@ -31,14 +31,15 @@ export class WrappedLevel extends Level<string, string | number> {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
async tryGet<T>(documentConstructor: new () => T, _id: any, options?: GetOptions<string, string | number>): Promise<T> {
|
|
34
|
+
async tryGet<T>(documentConstructor: new () => T, _id: any, options?: GetOptions<string, string | number>): Promise<T | undefined> {
|
|
35
35
|
try {
|
|
36
36
|
const _documentType = documentConstructor.name;
|
|
37
37
|
const key = `${_documentType}/${_id}`;
|
|
38
|
-
const json = await this.get(key, options)
|
|
38
|
+
const json = await this.get(key, options!)
|
|
39
39
|
return createLevelDocument(documentConstructor, json);
|
|
40
40
|
}
|
|
41
41
|
catch (e) {
|
|
42
|
+
return undefined;
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -82,7 +83,7 @@ export class WrappedLevel extends Level<string, string | number> {
|
|
|
82
83
|
|
|
83
84
|
value._documentType = _documentType;
|
|
84
85
|
const key = `${_documentType}/${value._id}`;
|
|
85
|
-
await this.put(key, JSON.stringify(value), options);
|
|
86
|
+
await this.put(key, JSON.stringify(value), options!);
|
|
86
87
|
return value;
|
|
87
88
|
};
|
|
88
89
|
|
package/src/listen-zero.ts
CHANGED
|
@@ -18,7 +18,7 @@ export async function listenZeroSingleClient(hostname: string, options?: net.Ser
|
|
|
18
18
|
const server = options?.tls ? new tls.Server(options) : new net.Server(options);
|
|
19
19
|
const port = await listenZero(server, hostname);
|
|
20
20
|
|
|
21
|
-
let cancel
|
|
21
|
+
let cancel!: () => void;
|
|
22
22
|
const clientPromise = new Promise<net.Socket>((resolve, reject) => {
|
|
23
23
|
const timeout = setTimeout(() => {
|
|
24
24
|
server.close();
|
package/src/mixin/mixin-cycle.ts
CHANGED
|
@@ -10,22 +10,22 @@ export function getMixins(scrypted: ScryptedRuntime, id: string) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function hasMixinCycle(scrypted: ScryptedRuntime, id: string, mixins?: string[]) {
|
|
13
|
-
|
|
13
|
+
let mixinsList = mixins || getMixins(scrypted, id);
|
|
14
14
|
|
|
15
15
|
// given the mixins for a device, find all the mixins for those mixins,
|
|
16
16
|
// and create a visited graph.
|
|
17
17
|
// if the visited graphs includes the original device, that indicates
|
|
18
18
|
// a cyclical dependency for that device.
|
|
19
|
-
const visitedMixins = new Set(
|
|
19
|
+
const visitedMixins = new Set(mixinsList);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
while (
|
|
23
|
-
const mixin =
|
|
21
|
+
mixinsList = mixinsList.slice();
|
|
22
|
+
while (mixinsList.length) {
|
|
23
|
+
const mixin = mixinsList.pop()!;
|
|
24
24
|
if (visitedMixins.has(mixin))
|
|
25
25
|
continue;
|
|
26
26
|
visitedMixins.add(mixin);
|
|
27
27
|
const providerMixins = getMixins(scrypted, mixin);
|
|
28
|
-
|
|
28
|
+
mixinsList.push(...providerMixins);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
return visitedMixins.has(id);
|
package/src/plugin/acl.ts
CHANGED
|
@@ -61,7 +61,7 @@ export class AccessControls {
|
|
|
61
61
|
const { eventInterface } = eventDetails;
|
|
62
62
|
|
|
63
63
|
for (const dacl of dacls) {
|
|
64
|
-
if (!dacl.interfaces || dacl.interfaces.includes(eventInterface))
|
|
64
|
+
if (!dacl.interfaces || dacl.interfaces.includes(eventInterface!))
|
|
65
65
|
return false;
|
|
66
66
|
}
|
|
67
67
|
|
package/src/plugin/cluster.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface ClusterForkServiceInterface {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export class ClusterManagerImpl implements ClusterManager {
|
|
9
|
-
private clusterServicePromise
|
|
9
|
+
private clusterServicePromise!: Promise<ClusterForkServiceInterface>;
|
|
10
10
|
|
|
11
11
|
constructor(public clusterMode: undefined | 'client' | 'server', private api: PluginAPI, private clusterWorkerId: string) {
|
|
12
12
|
}
|
|
@@ -16,7 +16,7 @@ export class ClusterManagerImpl implements ClusterManager {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
getClusterAddress(): string {
|
|
19
|
-
return process.env.SCRYPTED_CLUSTER_ADDRESS
|
|
19
|
+
return process.env.SCRYPTED_CLUSTER_ADDRESS!;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
getClusterMode(): 'server' | 'client' | undefined {
|
package/src/plugin/descriptor.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ScryptedInterface, ScryptedInterfaceDescriptor, ScryptedInterfaceDescriptors } from "@scrypted/types";
|
|
2
2
|
|
|
3
|
-
export const allInterfaceProperties: string[] =
|
|
3
|
+
export const allInterfaceProperties: string[] = Object.values(ScryptedInterfaceDescriptors).map(type => type.properties).flat();
|
|
4
4
|
|
|
5
5
|
export function getPropertyInterfaces(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }) {
|
|
6
6
|
const propertyInterfaces: { [property: string]: ScryptedInterface } = {};
|
|
@@ -26,7 +26,7 @@ export function getInterfaceProperties(descriptors: { [scryptedInterface: string
|
|
|
26
26
|
|
|
27
27
|
export function isValidInterfaceMethod(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }, interfaces: Set<string>, method: string) {
|
|
28
28
|
const availableMethods = getInterfaceMethods(descriptors, interfaces);
|
|
29
|
-
return availableMethods.includes(method) || descriptors[ScryptedInterface.ScryptedDevice]
|
|
29
|
+
return availableMethods.includes(method) || descriptors[ScryptedInterface.ScryptedDevice]!.methods.includes(method);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export function isValidInterfaceProperty(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }, interfaces: string[], property: string): boolean {
|
package/src/plugin/device.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { SystemManagerImpl } from './system';
|
|
|
7
7
|
class DeviceLogger implements Logger {
|
|
8
8
|
nativeId: ScryptedNativeId;
|
|
9
9
|
api: PluginAPI;
|
|
10
|
-
logger
|
|
10
|
+
logger!: Promise<PluginLogger>;
|
|
11
11
|
|
|
12
12
|
constructor(api: PluginAPI, nativeId: ScryptedNativeId, public console: any) {
|
|
13
13
|
this.api = api;
|
|
@@ -65,12 +65,12 @@ export class DeviceStateProxyHandler implements ProxyHandler<any> {
|
|
|
65
65
|
return { id: this.id }
|
|
66
66
|
if (p === 'setState')
|
|
67
67
|
return this.setState;
|
|
68
|
-
return this.deviceManager.systemManager.state[this.id][p as string]?.value;
|
|
68
|
+
return this.deviceManager.systemManager.state[this.id]![p as string]?.value;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
set?(target: any, p: PropertyKey, value: any, receiver: any) {
|
|
72
72
|
checkProperty(p.toString(), value);
|
|
73
|
-
this.deviceManager.systemManager.state[this.id][p as string] = {
|
|
73
|
+
this.deviceManager.systemManager.state[this.id]![p as string] = {
|
|
74
74
|
value,
|
|
75
75
|
};
|
|
76
76
|
this.setState(p.toString(), value);
|
|
@@ -84,10 +84,10 @@ interface DeviceManagerDevice {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
export class DeviceManagerImpl implements DeviceManager {
|
|
87
|
-
api
|
|
88
|
-
nativeIds = new Map<
|
|
89
|
-
deviceStorage = new Map<
|
|
90
|
-
mixinStorage = new Map<
|
|
87
|
+
api!: PluginAPI;
|
|
88
|
+
nativeIds = new Map<ScryptedNativeId, DeviceManagerDevice>();
|
|
89
|
+
deviceStorage = new Map<ScryptedNativeId, StorageImpl>();
|
|
90
|
+
mixinStorage = new Map<ScryptedNativeId, Map<string, StorageImpl>>();
|
|
91
91
|
|
|
92
92
|
constructor(public systemManager: SystemManagerImpl,
|
|
93
93
|
public getDeviceConsole: (nativeId?: ScryptedNativeId) => Console,
|
|
@@ -103,7 +103,7 @@ export class DeviceManagerImpl implements DeviceManager {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
getDeviceState(nativeId?: any): DeviceState {
|
|
106
|
-
const handler = new DeviceStateProxyHandler(this, this.nativeIds.get(nativeId)
|
|
106
|
+
const handler = new DeviceStateProxyHandler(this, this.nativeIds.get(nativeId)!.id,
|
|
107
107
|
(property, value) => this.api.setState(nativeId, property, value));
|
|
108
108
|
return new Proxy(handler, handler);
|
|
109
109
|
}
|
|
@@ -136,7 +136,7 @@ export class DeviceManagerImpl implements DeviceManager {
|
|
|
136
136
|
}
|
|
137
137
|
pruneMixinStorage() {
|
|
138
138
|
for (const nativeId of this.nativeIds.keys()) {
|
|
139
|
-
const storage = this.nativeIds.get(nativeId)
|
|
139
|
+
const storage = this.nativeIds.get(nativeId)!.storage;
|
|
140
140
|
for (const key of Object.keys(storage)) {
|
|
141
141
|
if (!key.startsWith('mixin:'))
|
|
142
142
|
continue;
|
|
@@ -152,7 +152,7 @@ export class DeviceManagerImpl implements DeviceManager {
|
|
|
152
152
|
async onMixinEvent(id: string, nativeId: ScryptedNativeId, eventInterface: string, eventData: any) {
|
|
153
153
|
return this.api.onMixinEvent(id, nativeId, eventInterface, eventData);
|
|
154
154
|
}
|
|
155
|
-
getNativeIds():
|
|
155
|
+
getNativeIds(): ScryptedNativeId[] {
|
|
156
156
|
return Array.from(this.nativeIds.keys());
|
|
157
157
|
}
|
|
158
158
|
async onDeviceDiscovered(device: Device) {
|
|
@@ -219,20 +219,20 @@ export class StorageImpl implements Storage {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
get storage(): { [key: string]: any } {
|
|
222
|
-
return this.deviceManager.nativeIds.get(this.nativeId)
|
|
222
|
+
return this.deviceManager.nativeIds.get(this.nativeId)!.storage;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
get length(): number {
|
|
226
|
-
return Object.keys(this.storage).filter(key => key.startsWith(this.prefix)).length;
|
|
226
|
+
return Object.keys(this.storage).filter(key => key.startsWith(this.prefix!)).length;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
clear(): void {
|
|
230
230
|
if (!this.prefix) {
|
|
231
|
-
this.deviceManager.nativeIds.get(this.nativeId)
|
|
231
|
+
this.deviceManager.nativeIds.get(this.nativeId)!.storage = {};
|
|
232
232
|
}
|
|
233
233
|
else {
|
|
234
234
|
const storage = this.storage;
|
|
235
|
-
Object.keys(this.storage).filter(key => key.startsWith(this.prefix)).forEach(key => delete storage[key]);
|
|
235
|
+
Object.keys(this.storage).filter(key => key.startsWith(this.prefix!)).forEach(key => delete storage[key]);
|
|
236
236
|
}
|
|
237
237
|
this.api.setStorage(this.nativeId, this.storage);
|
|
238
238
|
}
|
|
@@ -242,9 +242,9 @@ export class StorageImpl implements Storage {
|
|
|
242
242
|
}
|
|
243
243
|
key(index: number): string {
|
|
244
244
|
if (!this.prefix) {
|
|
245
|
-
return Object.keys(this.storage)[index]
|
|
245
|
+
return Object.keys(this.storage)[index]!;
|
|
246
246
|
}
|
|
247
|
-
return Object.keys(this.storage).filter(key => key.startsWith(this.prefix))[index]
|
|
247
|
+
return Object.keys(this.storage).filter(key => key.startsWith(this.prefix!))[index]!.substring(this.prefix!.length);
|
|
248
248
|
}
|
|
249
249
|
removeItem(key: string): void {
|
|
250
250
|
delete this.storage[this.prefix + key];
|
package/src/plugin/endpoint.ts
CHANGED
|
@@ -3,10 +3,10 @@ import type { DeviceManagerImpl } from "./device";
|
|
|
3
3
|
import type { PluginAPI } from "./plugin-api";
|
|
4
4
|
|
|
5
5
|
export class EndpointManagerImpl implements EndpointManager {
|
|
6
|
-
deviceManager
|
|
7
|
-
api
|
|
8
|
-
pluginId
|
|
9
|
-
mediaManager
|
|
6
|
+
deviceManager!: DeviceManagerImpl;
|
|
7
|
+
api!: PluginAPI;
|
|
8
|
+
pluginId!: string;
|
|
9
|
+
mediaManager!: MediaManager;
|
|
10
10
|
|
|
11
11
|
getEndpoint(nativeId?: ScryptedNativeId) {
|
|
12
12
|
if (!nativeId)
|
package/src/plugin/media.ts
CHANGED
|
@@ -348,7 +348,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
|
348
348
|
fromMimeType: mediaObject.mimeType,
|
|
349
349
|
toMimeType,
|
|
350
350
|
convert: async (data, fromMimeType, toMimeType) => {
|
|
351
|
-
return mediaObject.convert(toMimeType);
|
|
351
|
+
return mediaObject.convert!(toMimeType);
|
|
352
352
|
}
|
|
353
353
|
});
|
|
354
354
|
|
|
@@ -366,10 +366,10 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
|
366
366
|
// connect the intrinsic converter to other converters
|
|
367
367
|
for (const candidate of converters) {
|
|
368
368
|
try {
|
|
369
|
-
const candidateMime = new MimeType(candidate.fromMimeType);
|
|
369
|
+
const candidateMime = new MimeType(candidate.fromMimeType!);
|
|
370
370
|
if (!mimeMatches(convertedMime, candidateMime))
|
|
371
371
|
continue;
|
|
372
|
-
const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')) || (candidateMime.essence === '*/*' ? 1000 : 1);
|
|
372
|
+
const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')!) || (candidateMime.essence === '*/*' ? 1000 : 1);
|
|
373
373
|
const candidateId = candidate.id;
|
|
374
374
|
node[candidateId] = outputWeight;
|
|
375
375
|
}
|
|
@@ -381,10 +381,10 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
|
381
381
|
|
|
382
382
|
for (const converter of converters) {
|
|
383
383
|
try {
|
|
384
|
-
const inputMime = new MimeType(converter.fromMimeType);
|
|
385
|
-
const convertedMime = new MimeType(converter.toMimeType);
|
|
384
|
+
const inputMime = new MimeType(converter.fromMimeType!);
|
|
385
|
+
const convertedMime = new MimeType(converter.toMimeType!);
|
|
386
386
|
// catch all converters should be heavily weighted so as not to use them.
|
|
387
|
-
const inputWeight = parseFloat(inputMime.parameters.get('converter-weight')) || (inputMime.essence === '*/*' ? 1000 : 1);
|
|
387
|
+
const inputWeight = parseFloat(inputMime.parameters.get('converter-weight')!) || (inputMime.essence === '*/*' ? 1000 : 1);
|
|
388
388
|
// const convertedWeight = parseFloat(convertedMime.parameters.get('converter-weight')) || (convertedMime.essence === ScryptedMimeTypes.MediaObject ? 1000 : 1);
|
|
389
389
|
// const conversionWeight = inputWeight + convertedWeight;
|
|
390
390
|
const targetId = converter.id;
|
|
@@ -393,10 +393,10 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
|
393
393
|
// edge matches
|
|
394
394
|
for (const candidate of converters) {
|
|
395
395
|
try {
|
|
396
|
-
const candidateMime = new MimeType(candidate.fromMimeType);
|
|
396
|
+
const candidateMime = new MimeType(candidate.fromMimeType!);
|
|
397
397
|
if (!mimeMatches(convertedMime, candidateMime))
|
|
398
398
|
continue;
|
|
399
|
-
const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')) || (candidateMime.essence === '*/*' ? 1000 : 1);
|
|
399
|
+
const outputWeight = parseFloat(candidateMime.parameters.get('converter-weight')!) || (candidateMime.essence === '*/*' ? 1000 : 1);
|
|
400
400
|
const candidateId = candidate.id;
|
|
401
401
|
node[candidateId] = inputWeight + outputWeight;
|
|
402
402
|
}
|
|
@@ -436,23 +436,23 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
|
436
436
|
let valueMime = new MimeType(mediaObject.mimeType);
|
|
437
437
|
|
|
438
438
|
while (route.length) {
|
|
439
|
-
const node = route.shift()
|
|
440
|
-
const converter = converterMap.get(node)
|
|
441
|
-
const converterToMimeType = new MimeType(converter.toMimeType);
|
|
442
|
-
const converterFromMimeType = new MimeType(converter.fromMimeType);
|
|
439
|
+
const node = route.shift()!;
|
|
440
|
+
const converter = converterMap.get(node)!;
|
|
441
|
+
const converterToMimeType = new MimeType(converter.toMimeType!);
|
|
442
|
+
const converterFromMimeType = new MimeType(converter.fromMimeType!);
|
|
443
443
|
const type = converterToMimeType.type === '*' ? valueMime.type : converterToMimeType.type;
|
|
444
444
|
const subtype = converterToMimeType.subtype === '*' ? valueMime.subtype : converterToMimeType.subtype;
|
|
445
445
|
let targetMimeType = `${type}/${subtype}`;
|
|
446
446
|
if (!route.length && outputMime.parameters.size) {
|
|
447
447
|
const withParameters = new MimeType(targetMimeType);
|
|
448
448
|
for (const k of outputMime.parameters.keys()) {
|
|
449
|
-
withParameters.parameters.set(k, outputMime.parameters.get(k));
|
|
449
|
+
withParameters.parameters.set(k, outputMime.parameters.get(k)!);
|
|
450
450
|
}
|
|
451
451
|
targetMimeType = outputMime.toString();
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
if (converter.toMimeType === ScryptedMimeTypes.MediaObject) {
|
|
455
|
-
const mo = await converter.convert(value, valueMime.essence, toMimeType, { sourceId }) as MediaObjectInterface;
|
|
455
|
+
const mo = await converter.convert!(value, valueMime.essence, toMimeType, { sourceId }) as MediaObjectInterface;
|
|
456
456
|
const found = await this.convertMediaObject(mo, toMimeType);
|
|
457
457
|
return {
|
|
458
458
|
data: found,
|
|
@@ -460,7 +460,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
|
460
460
|
};
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
-
value = await converter.convert(value, valueMime.essence, targetMimeType, { sourceId }) as string | Buffer;
|
|
463
|
+
value = await converter.convert!(value, valueMime.essence, targetMimeType, { sourceId }) as string | Buffer;
|
|
464
464
|
valueMime = new MimeType(targetMimeType);
|
|
465
465
|
}
|
|
466
466
|
|
|
@@ -5,12 +5,12 @@ import { MediaObjectRemote } from "./plugin-api";
|
|
|
5
5
|
export class MediaObject implements MediaObjectRemote {
|
|
6
6
|
__proxy_props: any;
|
|
7
7
|
|
|
8
|
-
constructor(public mimeType: string, public data: any, options
|
|
8
|
+
constructor(public mimeType: string, public data: any, options?: MediaObjectCreateOptions) {
|
|
9
9
|
this.__proxy_props = {}
|
|
10
10
|
options ||= {};
|
|
11
11
|
options.mimeType = mimeType;
|
|
12
|
-
options
|
|
13
|
-
options
|
|
12
|
+
options!.convert ||= null!;
|
|
13
|
+
options!.toMimeTypes ||= null!;
|
|
14
14
|
|
|
15
15
|
for (const [key, value] of Object.entries(options)) {
|
|
16
16
|
if (RpcPeer.isTransportSafe(value))
|
package/src/plugin/plugin-api.ts
CHANGED
|
@@ -19,9 +19,9 @@ export interface PluginAPI {
|
|
|
19
19
|
onDeviceEvent(nativeId: ScryptedNativeId, eventInterface: string, eventData?: any): Promise<void>;
|
|
20
20
|
onMixinEvent(id: string, nativeId: ScryptedNativeId, eventInterface: string, eventData?: any): Promise<void>;
|
|
21
21
|
onDeviceRemoved(nativeId: string): Promise<void>;
|
|
22
|
-
setStorage(nativeId:
|
|
22
|
+
setStorage(nativeId: ScryptedNativeId, storage: { [key: string]: any }): Promise<void>;
|
|
23
23
|
|
|
24
|
-
getDeviceById(id: string): Promise<ScryptedDevice>;
|
|
24
|
+
getDeviceById(id: string): Promise<ScryptedDevice | undefined>;
|
|
25
25
|
setDeviceProperty(id: string, property: ScryptedInterfaceProperty, value: any): Promise<void>;
|
|
26
26
|
removeDevice(id: string): Promise<void>;
|
|
27
27
|
listen(EventListener: (id: string, eventDetails: EventDetails, eventData: any) => void): Promise<EventListenerRegister>;
|
|
@@ -69,7 +69,7 @@ export class PluginAPIManagedListeners {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export class PluginAPIProxy extends PluginAPIManagedListeners implements PluginAPI {
|
|
72
|
-
acl
|
|
72
|
+
acl!: AccessControls;
|
|
73
73
|
|
|
74
74
|
constructor(public api: PluginAPI, public mediaManager?: MediaManager) {
|
|
75
75
|
super();
|
|
@@ -108,9 +108,9 @@ export class PluginAPIProxy extends PluginAPIManagedListeners implements PluginA
|
|
|
108
108
|
this.acl?.deny();
|
|
109
109
|
return this.api.setStorage(nativeId, storage);
|
|
110
110
|
}
|
|
111
|
-
getDeviceById(id: string): Promise<ScryptedDevice> {
|
|
111
|
+
async getDeviceById(id: string): Promise<ScryptedDevice | undefined> {
|
|
112
112
|
if (this.acl?.shouldRejectDevice(id))
|
|
113
|
-
return;
|
|
113
|
+
return undefined;
|
|
114
114
|
return this.api.getDeviceById(id);
|
|
115
115
|
}
|
|
116
116
|
setDeviceProperty(id: string, property: ScryptedInterfaceProperty, value: any): Promise<void> {
|
|
@@ -148,7 +148,7 @@ export class PluginAPIProxy extends PluginAPIManagedListeners implements PluginA
|
|
|
148
148
|
return this.api.getComponent(id);
|
|
149
149
|
}
|
|
150
150
|
async getMediaManager(): Promise<MediaManager> {
|
|
151
|
-
return this.mediaManager
|
|
151
|
+
return this.mediaManager!;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
async requestRestart() {
|
|
@@ -176,7 +176,7 @@ export class PluginZipAPI {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
export interface PluginRemote {
|
|
179
|
-
loadZip(packageJson: any, zipAPI: PluginZipAPI, options
|
|
179
|
+
loadZip(packageJson: any, zipAPI: PluginZipAPI, options?: PluginRemoteLoadZipOptions): Promise<any>;
|
|
180
180
|
setSystemState(state: { [id: string]: { [property: string]: SystemDeviceState } }): Promise<void>;
|
|
181
181
|
setNativeId(nativeId: ScryptedNativeId, id: string, storage: { [key: string]: any }): Promise<void>;
|
|
182
182
|
updateDeviceState(id: string, state: { [property: string]: SystemDeviceState }): Promise<void>;
|