@scrypted/server 0.144.0 → 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 +19 -14
- 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 +34 -29
- 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
|
@@ -62,12 +62,12 @@ installSourceMapSupport({
|
|
|
62
62
|
environment: 'node',
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
let workerInspectPort: number = undefined;
|
|
66
|
-
let workerInspectAddress: string = undefined;
|
|
65
|
+
let workerInspectPort: number | undefined = undefined;
|
|
66
|
+
let workerInspectAddress: string | undefined = undefined;
|
|
67
67
|
|
|
68
68
|
async function doconnect(): Promise<net.Socket> {
|
|
69
69
|
return new Promise((resolve, reject) => {
|
|
70
|
-
const target = net.connect(workerInspectPort
|
|
70
|
+
const target = net.connect(workerInspectPort!, workerInspectAddress!);
|
|
71
71
|
target.once('error', reject)
|
|
72
72
|
target.once('connect', () => resolve(target))
|
|
73
73
|
})
|
|
@@ -123,7 +123,8 @@ app.use(bodyParser.json());
|
|
|
123
123
|
app.use(bodyParser.raw({ type: 'application/*', limit: 100000000 }) as any);
|
|
124
124
|
|
|
125
125
|
function checkListenSet(socket: net.Socket) {
|
|
126
|
-
|
|
126
|
+
const localAddress = socket.localAddress!;
|
|
127
|
+
return listenSet.check(localAddress, net.isIPv4(localAddress) ? 'ipv4' : 'ipv6');
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
if (listenSet.rules.length) {
|
|
@@ -236,7 +237,7 @@ async function start(mainFilename: string, options?: {
|
|
|
236
237
|
};
|
|
237
238
|
}
|
|
238
239
|
|
|
239
|
-
const getDefaultAuthentication = (req: Request) => {
|
|
240
|
+
const getDefaultAuthentication = (req: Request): ScryptedUser | undefined => {
|
|
240
241
|
const defaultAuthentication = !req.query.disableDefaultAuthentication && process.env.SCRYPTED_DEFAULT_AUTHENTICATION;
|
|
241
242
|
if (defaultAuthentication) {
|
|
242
243
|
const referer = req.headers.referer;
|
|
@@ -244,7 +245,7 @@ async function start(mainFilename: string, options?: {
|
|
|
244
245
|
try {
|
|
245
246
|
const u = new URL(referer);
|
|
246
247
|
if (u.searchParams.has('disableDefaultAuthentication'))
|
|
247
|
-
return;
|
|
248
|
+
return undefined;
|
|
248
249
|
}
|
|
249
250
|
catch (e) {
|
|
250
251
|
// no/invalid referer, allow the default auth
|
|
@@ -252,6 +253,7 @@ async function start(mainFilename: string, options?: {
|
|
|
252
253
|
}
|
|
253
254
|
return scrypted.usersService.users.get(defaultAuthentication);
|
|
254
255
|
}
|
|
256
|
+
return undefined;
|
|
255
257
|
}
|
|
256
258
|
|
|
257
259
|
app.use(async (req, res, next) => {
|
|
@@ -358,7 +360,7 @@ async function start(mainFilename: string, options?: {
|
|
|
358
360
|
if (req.protocol === 'https' && req.headers.authorization && req.headers.authorization.toLowerCase()?.indexOf('basic') !== -1) {
|
|
359
361
|
const basicChecker = basicAuth.check(async (req) => {
|
|
360
362
|
try {
|
|
361
|
-
const user = await db.tryGet(ScryptedUser, req.user)
|
|
363
|
+
const user = (await db.tryGet(ScryptedUser, req.user))!;
|
|
362
364
|
res.locals.username = user._id;
|
|
363
365
|
res.locals.aclId = user.aclId;
|
|
364
366
|
}
|
|
@@ -435,7 +437,7 @@ async function start(mainFilename: string, options?: {
|
|
|
435
437
|
if (owner)
|
|
436
438
|
endpoint = `@${owner}/${endpoint}`;
|
|
437
439
|
try {
|
|
438
|
-
const json = await getNpmPackageInfo(endpoint);
|
|
440
|
+
const json = await getNpmPackageInfo(endpoint!);
|
|
439
441
|
res.send(json);
|
|
440
442
|
}
|
|
441
443
|
catch (e) {
|
|
@@ -450,9 +452,9 @@ async function start(mainFilename: string, options?: {
|
|
|
450
452
|
if (owner)
|
|
451
453
|
endpoint = `@${owner}/${endpoint}`;
|
|
452
454
|
try {
|
|
453
|
-
const plugin = await scrypted.installNpm(endpoint
|
|
455
|
+
const plugin = (await scrypted.installNpm(endpoint!, tag))!;
|
|
454
456
|
res.send({
|
|
455
|
-
id: scrypted.findPluginDevice(plugin.pluginId)
|
|
457
|
+
id: scrypted.findPluginDevice(plugin.pluginId)!._id,
|
|
456
458
|
});
|
|
457
459
|
}
|
|
458
460
|
catch (e) {
|
|
@@ -527,7 +529,7 @@ async function start(mainFilename: string, options?: {
|
|
|
527
529
|
}
|
|
528
530
|
}
|
|
529
531
|
}
|
|
530
|
-
catch (e) {
|
|
532
|
+
catch (e: any) {
|
|
531
533
|
res.header('Content-Type', 'text/plain');
|
|
532
534
|
res.status(500);
|
|
533
535
|
res.send(e.toString());
|
|
@@ -544,9 +546,9 @@ async function start(mainFilename: string, options?: {
|
|
|
544
546
|
return req.secure ? 'login_user_token' : 'login_user_token_insecure';
|
|
545
547
|
};
|
|
546
548
|
|
|
547
|
-
const checkValidUserToken = (token: string) => {
|
|
549
|
+
const checkValidUserToken = (token: string): UserToken | undefined => {
|
|
548
550
|
if (!token)
|
|
549
|
-
return;
|
|
551
|
+
return undefined;
|
|
550
552
|
try {
|
|
551
553
|
const userToken = UserToken.validateToken(token);
|
|
552
554
|
if (scrypted.usersService.users.has(userToken.username))
|
|
@@ -555,6 +557,7 @@ async function start(mainFilename: string, options?: {
|
|
|
555
557
|
catch (e) {
|
|
556
558
|
// console.warn('invalid token', e.message);
|
|
557
559
|
}
|
|
560
|
+
return undefined;
|
|
558
561
|
}
|
|
559
562
|
|
|
560
563
|
const getSignedLoginUserToken = (req: Request<any>) => {
|
|
@@ -751,7 +754,7 @@ async function start(mainFilename: string, options?: {
|
|
|
751
754
|
hostname,
|
|
752
755
|
})
|
|
753
756
|
}
|
|
754
|
-
catch (e) {
|
|
757
|
+
catch (e: any) {
|
|
755
758
|
// env based anon user login
|
|
756
759
|
const defaultAuthentication = getDefaultAuthentication(req);
|
|
757
760
|
if (defaultAuthentication) {
|
package/src/server-settings.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getUsableNetworkAddresses } from './ip';
|
|
2
2
|
|
|
3
|
-
export const SCRYPTED_INSECURE_PORT = parseInt(process.env.SCRYPTED_INSECURE_PORT) || 11080;
|
|
4
|
-
export const SCRYPTED_SECURE_PORT = parseInt(process.env.SCRYPTED_SECURE_PORT) || 10443;
|
|
5
|
-
export const SCRYPTED_DEBUG_PORT = parseInt(process.env.SCRYPTED_DEBUG_PORT) || 10081;
|
|
6
|
-
export const SCRYPTED_CLUSTER_WORKERS = parseInt(process.env.SCRYPTED_CLUSTER_WORKERS) || 32;
|
|
3
|
+
export const SCRYPTED_INSECURE_PORT = parseInt(process.env.SCRYPTED_INSECURE_PORT ?? '') || 11080;
|
|
4
|
+
export const SCRYPTED_SECURE_PORT = parseInt(process.env.SCRYPTED_SECURE_PORT ?? '') || 10443;
|
|
5
|
+
export const SCRYPTED_DEBUG_PORT = parseInt(process.env.SCRYPTED_DEBUG_PORT ?? '') || 10081;
|
|
6
|
+
export const SCRYPTED_CLUSTER_WORKERS = parseInt(process.env.SCRYPTED_CLUSTER_WORKERS ?? '') || 32;
|
|
7
7
|
|
|
8
|
-
export function getIpAddress(): string {
|
|
8
|
+
export function getIpAddress(): string | undefined {
|
|
9
9
|
return getUsableNetworkAddresses()[0];
|
|
10
10
|
}
|
|
@@ -25,16 +25,16 @@ export class AddressSettings {
|
|
|
25
25
|
await this.scrypted.datastore.upsert(localAddresses);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
async getLocalAddresses(raw?: boolean): Promise<string[]> {
|
|
28
|
+
async getLocalAddresses(raw?: boolean): Promise<string[] | undefined> {
|
|
29
29
|
const settings = await this.scrypted.datastore.tryGet(Settings, 'localAddresses');
|
|
30
30
|
|
|
31
31
|
if (!settings?.value?.[0])
|
|
32
|
-
return;
|
|
32
|
+
return undefined;
|
|
33
33
|
|
|
34
34
|
const ret: string[] = [];
|
|
35
35
|
const networkInterfaces = os.networkInterfaces();
|
|
36
36
|
const allAddresses = new Set(Object.values(networkInterfaces)
|
|
37
|
-
.flat().map(ni => ni.address));
|
|
37
|
+
.flat().filter((ni): ni is os.NetworkInterfaceInfo => ni !== undefined).map(ni => ni.address));
|
|
38
38
|
for (const addressOrInterface of settings.value) {
|
|
39
39
|
const nif = networkInterfaces[addressOrInterface];
|
|
40
40
|
if (raw) {
|
package/src/services/alerts.ts
CHANGED
|
@@ -14,10 +14,10 @@ export class Alerts {
|
|
|
14
14
|
}
|
|
15
15
|
async removeAlert(alert: ScryptedAlert) {
|
|
16
16
|
await this.scrypted.datastore.removeId(ScryptedAlert, alert._id);
|
|
17
|
-
this.scrypted.stateManager.notifyInterfaceEvent(
|
|
17
|
+
this.scrypted.stateManager.notifyInterfaceEvent(undefined, 'Logger' as any, undefined);
|
|
18
18
|
}
|
|
19
19
|
async clearAlerts() {
|
|
20
20
|
await this.scrypted.datastore.removeAll(ScryptedAlert);
|
|
21
|
-
this.scrypted.stateManager.notifyInterfaceEvent(
|
|
21
|
+
this.scrypted.stateManager.notifyInterfaceEvent(undefined, 'Logger' as any, undefined);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -9,7 +9,7 @@ import { removeIPv4EmbeddedIPv6 } from "../ip";
|
|
|
9
9
|
|
|
10
10
|
class WrappedForkResult implements ClusterForkResultInterface {
|
|
11
11
|
[RpcPeer.PROPERTY_PROXY_PROPERTIES] = {
|
|
12
|
-
clusterWorkerId: undefined as string,
|
|
12
|
+
clusterWorkerId: undefined as unknown as string,
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
constructor(public clusterWorkerId: string, public forkResult: Promise<ClusterForkResultInterface>) {
|
|
@@ -48,7 +48,7 @@ export class ClusterForkService {
|
|
|
48
48
|
return matches && (!options.clusterWorkerId || worker.id === options.clusterWorkerId);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
let worker: RunningClusterWorker;
|
|
51
|
+
let worker: RunningClusterWorker | undefined;
|
|
52
52
|
|
|
53
53
|
// try to keep fork id affinity to single worker if present. this presents the opportunity for
|
|
54
54
|
// IPC.
|
|
@@ -73,7 +73,7 @@ export class ClusterForkService {
|
|
|
73
73
|
// sort by number of forks, to distribute load.
|
|
74
74
|
.sort((a, b) => a.worker.forks.size * a.worker.weight - b.worker.forks.size * b.worker.weight);
|
|
75
75
|
|
|
76
|
-
worker = matchingWorkers[0]?.worker
|
|
76
|
+
worker = matchingWorkers[0]?.worker!;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
console.log('forking to worker', worker.id, options);
|
|
@@ -81,7 +81,7 @@ export class ClusterForkService {
|
|
|
81
81
|
worker.fork ||= worker.peer.getParam('fork');
|
|
82
82
|
const fork: ClusterForkParam = await worker.fork;
|
|
83
83
|
|
|
84
|
-
const forkResultPromise = fork(options.runtime
|
|
84
|
+
const forkResultPromise = fork(options.runtime!, runtimeWorkerOptions, peerLiveness, getZip);
|
|
85
85
|
options.id ||= this.runtime.findPluginDevice(runtimeWorkerOptions.packageJson.name)?._id;
|
|
86
86
|
|
|
87
87
|
// the server is responsible for killing the forked process when the requestor is killed.
|
|
@@ -117,12 +117,12 @@ export class ClusterForkService {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
async getParam(clusterWorkerId: string, key: string) {
|
|
120
|
-
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)
|
|
120
|
+
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)!;
|
|
121
121
|
return clusterWorker.peer.getParam(key);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
async getFsPromises(clusterWorkerId: string) {
|
|
125
|
-
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)
|
|
125
|
+
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)!;
|
|
126
126
|
if (clusterWorker.mode === 'server') {
|
|
127
127
|
return {
|
|
128
128
|
[RpcPeer.PROPERTY_JSON_COPY_SERIALIZE_CHILDREN]: true,
|
|
@@ -133,21 +133,21 @@ export class ClusterForkService {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
async getEnvControl(clusterWorkerId: string) {
|
|
136
|
-
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)
|
|
136
|
+
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)!;
|
|
137
137
|
if (clusterWorker.mode === 'server')
|
|
138
138
|
return this.runtime.envControl;
|
|
139
139
|
return clusterWorker.peer.getParam('env-control');
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
async getServiceControl(clusterWorkerId: string) {
|
|
143
|
-
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)
|
|
143
|
+
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)!;
|
|
144
144
|
if (clusterWorker.mode === 'server')
|
|
145
145
|
return this.runtime.serviceControl;
|
|
146
146
|
return clusterWorker.peer.getParam('service-control');
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
async getInfo(clusterWorkerId: string) {
|
|
150
|
-
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)
|
|
150
|
+
const clusterWorker = this.runtime.clusterWorkers.get(clusterWorkerId)!;
|
|
151
151
|
if (clusterWorker.mode === 'server')
|
|
152
152
|
return this.runtime.info;
|
|
153
153
|
return clusterWorker.peer.getParam('info');
|
package/src/services/plugin.ts
CHANGED
|
@@ -25,7 +25,7 @@ export class PluginComponent {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async renameDeviceId(id: string, newId: string) {
|
|
28
|
-
const pluginDevice = this.scrypted.findPluginDeviceById(id)
|
|
28
|
+
const pluginDevice = this.scrypted.findPluginDeviceById(id)!;
|
|
29
29
|
await this.kill(pluginDevice.pluginId);
|
|
30
30
|
// wait for everything to settle.
|
|
31
31
|
await sleep(2000);
|
|
@@ -45,7 +45,7 @@ export class PluginComponent {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
async setStorage(id: string, storage: { [key: string]: string }) {
|
|
48
|
-
const pluginDevice = this.scrypted.findPluginDeviceById(id)
|
|
48
|
+
const pluginDevice = this.scrypted.findPluginDeviceById(id)!;
|
|
49
49
|
pluginDevice.storage = storage;
|
|
50
50
|
await this.scrypted.datastore.upsert(pluginDevice);
|
|
51
51
|
const host = this.scrypted.getPluginHostForDeviceId(id);
|
|
@@ -58,7 +58,7 @@ export class PluginComponent {
|
|
|
58
58
|
console.warn(message);
|
|
59
59
|
throw new Error(message);
|
|
60
60
|
}
|
|
61
|
-
const pluginDevice = this.scrypted.findPluginDeviceById(id)
|
|
61
|
+
const pluginDevice = this.scrypted.findPluginDeviceById(id)!;
|
|
62
62
|
this.scrypted.stateManager.setPluginDeviceState(pluginDevice, ScryptedInterfaceProperty.mixins, [...new Set(mixins)]);
|
|
63
63
|
this.scrypted.stateManager.updateDescriptor(pluginDevice);
|
|
64
64
|
await this.scrypted.datastore.upsert(pluginDevice);
|
|
@@ -75,7 +75,7 @@ export class PluginComponent {
|
|
|
75
75
|
}
|
|
76
76
|
async reload(pluginId: string) {
|
|
77
77
|
const plugin = await this.scrypted.datastore.tryGet(Plugin, pluginId);
|
|
78
|
-
await this.scrypted.runPlugin(plugin);
|
|
78
|
+
await this.scrypted.runPlugin(plugin!);
|
|
79
79
|
}
|
|
80
80
|
async kill(pluginId: string) {
|
|
81
81
|
return this.scrypted.plugins[pluginId]?.kill();
|
|
@@ -98,7 +98,7 @@ export class PluginComponent {
|
|
|
98
98
|
}
|
|
99
99
|
async getPluginInfo(pluginId: string) {
|
|
100
100
|
const packageJson = await this.getPackageJson(pluginId);
|
|
101
|
-
const host = this.scrypted.plugins[pluginId]
|
|
101
|
+
const host = this.scrypted.plugins[pluginId]!;
|
|
102
102
|
let rpcObjects = 0;
|
|
103
103
|
let pendingResults = 0;
|
|
104
104
|
const pendingResultMethods: {
|
|
@@ -108,7 +108,7 @@ export class PluginComponent {
|
|
|
108
108
|
rpcObjects = host.peer.localProxied.size + Object.keys(host.peer.remoteWeakProxies).length;
|
|
109
109
|
pendingResults = Object.keys(host.peer.pendingResults).length;
|
|
110
110
|
for (const deferred of Object.values(host.peer.pendingResults)) {
|
|
111
|
-
pendingResultMethods[deferred.method] = (pendingResultMethods[deferred.method] || 0) + 1;
|
|
111
|
+
pendingResultMethods[deferred.method!] = (pendingResultMethods[deferred.method!] || 0) + 1;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
return {
|
|
@@ -118,7 +118,7 @@ export class PluginComponent {
|
|
|
118
118
|
packageJson,
|
|
119
119
|
pendingResults,
|
|
120
120
|
pendingResultCounts: pendingResultMethods,
|
|
121
|
-
id: this.scrypted.findPluginDevice(pluginId)
|
|
121
|
+
id: this.scrypted.findPluginDevice(pluginId)!._id,
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -148,7 +148,7 @@ export class PluginComponent {
|
|
|
148
148
|
const version = registry['dist-tags'].latest;
|
|
149
149
|
if (registry?.versions?.[version]?.deprecated) {
|
|
150
150
|
console.log('plugin deprecated, uninstalling:', plugin);
|
|
151
|
-
await this.scrypted.removeDevice(this.scrypted.findPluginDevice(plugin));
|
|
151
|
+
await this.scrypted.removeDevice(this.scrypted.findPluginDevice(plugin)!);
|
|
152
152
|
continue;
|
|
153
153
|
}
|
|
154
154
|
if (!semver.gt(version, host.packageJson.version)) {
|
|
@@ -167,21 +167,21 @@ export class PluginComponent {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
async clearConsole(id: string) {
|
|
170
|
-
const pluginDevice = this.scrypted.findPluginDeviceById(id)
|
|
171
|
-
const consoleServer = await this.scrypted.plugins[pluginDevice.pluginId]
|
|
170
|
+
const pluginDevice = this.scrypted.findPluginDeviceById(id)!;
|
|
171
|
+
const consoleServer = await this.scrypted.plugins[pluginDevice.pluginId]!.consoleServer;
|
|
172
172
|
consoleServer.clear(pluginDevice.nativeId);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
async getRemoteServicePort(pluginId: string, name: string, ...args: any[]): Promise<[number, string]> {
|
|
176
176
|
if (name === 'console') {
|
|
177
|
-
const consoleServer = await this.scrypted.plugins[pluginId]
|
|
178
|
-
return [consoleServer.readPort, process.env.SCRYPTED_CLUSTER_ADDRESS];
|
|
177
|
+
const consoleServer = await this.scrypted.plugins[pluginId]!.consoleServer;
|
|
178
|
+
return [consoleServer.readPort, process.env.SCRYPTED_CLUSTER_ADDRESS!];
|
|
179
179
|
}
|
|
180
180
|
if (name === 'console-writer') {
|
|
181
|
-
const consoleServer = await this.scrypted.plugins[pluginId]
|
|
182
|
-
return [consoleServer.writePort, process.env.SCRYPTED_CLUSTER_ADDRESS];
|
|
181
|
+
const consoleServer = await this.scrypted.plugins[pluginId]!.consoleServer;
|
|
182
|
+
return [consoleServer.writePort, process.env.SCRYPTED_CLUSTER_ADDRESS!];
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
return this.scrypted.plugins[pluginId]
|
|
185
|
+
return this.scrypted.plugins[pluginId]!.remote.getServicePort(name, ...args);
|
|
186
186
|
}
|
|
187
187
|
}
|
package/src/services/users.ts
CHANGED
|
@@ -5,9 +5,9 @@ import crypto from 'crypto';
|
|
|
5
5
|
|
|
6
6
|
export class UsersService {
|
|
7
7
|
users = new Map<string, ScryptedUser>();
|
|
8
|
-
usersPromise
|
|
8
|
+
usersPromise!: Promise<ScryptedUser[]>;
|
|
9
9
|
|
|
10
|
-
static async addUserToDatabase(db: WrappedLevel, username: string, password: string, aclId
|
|
10
|
+
static async addUserToDatabase(db: WrappedLevel, username: string, password: string, aclId?: string) {
|
|
11
11
|
const user = new ScryptedUser();
|
|
12
12
|
user._id = username;
|
|
13
13
|
user.aclId = aclId;
|
|
@@ -63,7 +63,7 @@ export class UsersService {
|
|
|
63
63
|
this.updateUsersPromise();
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
async addUserInternal(username: string, password: string, aclId
|
|
66
|
+
async addUserInternal(username: string, password: string, aclId?: string) {
|
|
67
67
|
await this.ensureUsersPromise();
|
|
68
68
|
|
|
69
69
|
const user = await UsersService.addUserToDatabase(this.scrypted.datastore, username, password, aclId);
|
package/src/state.ts
CHANGED
|
@@ -34,7 +34,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
34
34
|
this.scrypted = scrypted;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
async getImplementerId(pluginDevice: PluginDevice, eventInterface: ScryptedInterface | string) {
|
|
37
|
+
async getImplementerId(pluginDevice: PluginDevice, eventInterface: ScryptedInterface | string | undefined) {
|
|
38
38
|
if (!eventInterface)
|
|
39
39
|
throw new Error(`ScryptedInterface is required`);
|
|
40
40
|
|
|
@@ -62,7 +62,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
this.notifyEventDetails(pluginDevice._id, {
|
|
65
|
-
eventId: undefined
|
|
65
|
+
eventId: undefined!,
|
|
66
66
|
eventInterface,
|
|
67
67
|
eventTime: Date.now(),
|
|
68
68
|
mixinId,
|
|
@@ -75,8 +75,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
75
75
|
this.notify(pluginDevice?._id, Date.now(), eventInterface, undefined, value);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
async setPluginDeviceStateFromMixin(pluginDevice: PluginDevice, property: string, value: any, eventInterface:
|
|
79
|
-
// TODO: crashing here. send descriptor from python too.
|
|
78
|
+
async setPluginDeviceStateFromMixin(pluginDevice: PluginDevice, property: string, value: any, eventInterface: string | undefined, mixinId: string) {
|
|
80
79
|
eventInterface = eventInterface || propertyInterfaces[property];
|
|
81
80
|
|
|
82
81
|
const implementerId = await this.getImplementerId(pluginDevice, eventInterface);
|
|
@@ -85,9 +84,9 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
85
84
|
event: eventInterface,
|
|
86
85
|
mixinId,
|
|
87
86
|
});
|
|
88
|
-
this.scrypted.getDeviceLogger(pluginDevice)
|
|
87
|
+
this.scrypted.getDeviceLogger(pluginDevice)!.log('i', `${property}: ${value} (mixin)`);
|
|
89
88
|
this.notifyEventDetails(pluginDevice._id, {
|
|
90
|
-
eventId: undefined
|
|
89
|
+
eventId: undefined!,
|
|
91
90
|
eventInterface,
|
|
92
91
|
eventTime: Date.now(),
|
|
93
92
|
mixinId,
|
|
@@ -99,7 +98,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
99
98
|
return this.setPluginDeviceState(pluginDevice, property, value, eventInterface);
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
setPluginDeviceState(device: PluginDevice, property: string, value: any, eventInterface?:
|
|
101
|
+
setPluginDeviceState(device: PluginDevice, property: string, value: any, eventInterface?: string) {
|
|
103
102
|
eventInterface = eventInterface || propertyInterfaces[property];
|
|
104
103
|
if (!eventInterface)
|
|
105
104
|
throw new Error(`eventInterface must be provided`);
|
|
@@ -108,7 +107,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
108
107
|
|
|
109
108
|
if (eventInterface !== ScryptedInterface.ScryptedDevice) {
|
|
110
109
|
if (this.notify(device?._id, Date.now(), eventInterface, property, value, { changed }) && device) {
|
|
111
|
-
this.scrypted.getDeviceLogger(device)
|
|
110
|
+
this.scrypted.getDeviceLogger(device)!.log('i', `${property}: ${value}`);
|
|
112
111
|
}
|
|
113
112
|
}
|
|
114
113
|
|
|
@@ -126,7 +125,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
126
125
|
this.notify(undefined, undefined, ScryptedInterface.ScryptedDevice, ScryptedInterfaceProperty.id, id, { changed: true });
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
notifyInterfaceEvent(device: PluginDevice, eventInterface: ScryptedInterface | string, value: any, mixinId?: string) {
|
|
128
|
+
notifyInterfaceEvent(device: PluginDevice | undefined, eventInterface: ScryptedInterface | string, value: any, mixinId?: string) {
|
|
130
129
|
this.notify(device?._id, Date.now(), eventInterface, undefined, value, {
|
|
131
130
|
changed: true,
|
|
132
131
|
mixinId,
|
|
@@ -149,7 +148,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
149
148
|
return systemState;
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
listenDevice(id: string, options: string | EventListenerOptions, callback: (eventDetails: EventDetails, eventData: any) => void): EventListenerRegister {
|
|
151
|
+
override listenDevice(id: string, options: string | EventListenerOptions, callback: (eventDetails: EventDetails, eventData: any) => void): EventListenerRegister {
|
|
153
152
|
let { denoise, event, watch } = (options || {}) as EventListenerOptions;
|
|
154
153
|
if (!event && typeof options === 'string')
|
|
155
154
|
event = options as string;
|
|
@@ -163,7 +162,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
163
162
|
while (polling && !watch) {
|
|
164
163
|
// listen is not user initiated. an explicit refresh call would be.
|
|
165
164
|
try {
|
|
166
|
-
await this.refresh(id, event
|
|
165
|
+
await this.refresh(id, event!, false)
|
|
167
166
|
}
|
|
168
167
|
catch (e) {
|
|
169
168
|
console.error('refresh ended by exception', e);
|
|
@@ -174,10 +173,11 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
let lastData: any = undefined;
|
|
177
|
-
let
|
|
176
|
+
let callbackWrapper: typeof callback | undefined = callback;
|
|
177
|
+
let cb: typeof callback | undefined = (eventDetails, eventData) => {
|
|
178
178
|
if (denoise && lastData === eventData)
|
|
179
179
|
return;
|
|
180
|
-
|
|
180
|
+
callbackWrapper?.(eventDetails, eventData);
|
|
181
181
|
};
|
|
182
182
|
|
|
183
183
|
const wrappedRegister = super.listenDevice(id, options, cb);
|
|
@@ -185,7 +185,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
185
185
|
return new EventListenerRegisterImpl(() => {
|
|
186
186
|
wrappedRegister.removeListener();
|
|
187
187
|
cb = undefined;
|
|
188
|
-
|
|
188
|
+
callbackWrapper = undefined;
|
|
189
189
|
polling = false;
|
|
190
190
|
});
|
|
191
191
|
}
|
|
@@ -203,7 +203,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
const device: any = this.scrypted.getDevice<Refresh>(id);
|
|
206
|
-
const logger = this.scrypted.getDeviceLogger(this.scrypted.findPluginDeviceById(id))
|
|
206
|
+
const logger = this.scrypted.getDeviceLogger(this.scrypted.findPluginDeviceById(id))!;
|
|
207
207
|
|
|
208
208
|
if (!device.interfaces.includes(ScryptedInterface.Refresh))
|
|
209
209
|
throw new Error('device does not implement refresh');
|
|
@@ -221,13 +221,13 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
221
221
|
await sleep(timeout);
|
|
222
222
|
try {
|
|
223
223
|
const rt = this.refreshThrottles[id];
|
|
224
|
-
if (!rt
|
|
224
|
+
if (!rt!.tailRefresh)
|
|
225
225
|
return;
|
|
226
|
-
await device[RefreshSymbol](rt
|
|
226
|
+
await device[RefreshSymbol](rt!.refreshInterface, rt!.userInitiated);
|
|
227
227
|
}
|
|
228
228
|
catch (e) {
|
|
229
229
|
logger.log('e', 'Refresh failed');
|
|
230
|
-
logger.log('e', e.toString());
|
|
230
|
+
logger.log('e', (e as Error).toString());
|
|
231
231
|
}
|
|
232
232
|
finally {
|
|
233
233
|
delete this.refreshThrottles[id];
|
|
@@ -257,7 +257,7 @@ export class ScryptedStateManager extends EventRegistry {
|
|
|
257
257
|
|
|
258
258
|
interface RefreshThrottle {
|
|
259
259
|
promise: Promise<void>;
|
|
260
|
-
refreshInterface: string;
|
|
260
|
+
refreshInterface: string | undefined;
|
|
261
261
|
userInitiated: boolean;
|
|
262
262
|
tailRefresh: boolean;
|
|
263
263
|
}
|
|
@@ -266,10 +266,10 @@ function isSameValue(value1: any, value2: any) {
|
|
|
266
266
|
return value1 === value2 || JSON.stringify(value1) === JSON.stringify(value2);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
export function setState(pluginDevice: PluginDevice, property: string, value: any): boolean {
|
|
269
|
+
export function setState(pluginDevice: PluginDevice, property: string, value: any): boolean | undefined {
|
|
270
270
|
// device may have been deleted.
|
|
271
271
|
if (!pluginDevice.state)
|
|
272
|
-
return;
|
|
272
|
+
return undefined;
|
|
273
273
|
if (!pluginDevice.state[property])
|
|
274
274
|
pluginDevice.state[property] = {};
|
|
275
275
|
const state = pluginDevice.state[property];
|
package/src/threading.ts
CHANGED
|
@@ -36,15 +36,15 @@ export async function newThread<T>(...args: any[]): Promise<T> {
|
|
|
36
36
|
const thread_vm: typeof vm = global.require('vm');
|
|
37
37
|
const mainPeer: RpcPeer = new RpcPeer('thread', 'main', (message: any, reject: any) => {
|
|
38
38
|
try {
|
|
39
|
-
thread_worker_threads.parentPort
|
|
39
|
+
thread_worker_threads.parentPort!.postMessage(thread_v8.serialize(message));
|
|
40
40
|
}
|
|
41
41
|
catch (e) {
|
|
42
|
-
reject?.(e);
|
|
42
|
+
reject?.(e as Error);
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
45
|
mainPeer.transportSafeArgumentTypes.add(Buffer.name);
|
|
46
46
|
mainPeer.transportSafeArgumentTypes.add(Uint8Array.name);
|
|
47
|
-
thread_worker_threads.parentPort
|
|
47
|
+
thread_worker_threads.parentPort!.on('message', (message: any) => mainPeer.handleMessage(thread_v8.deserialize(message)));
|
|
48
48
|
|
|
49
49
|
mainPeer.params.eval = async (script: string, moduleNames: string[], paramNames: string[], ...paramValues: any[]) => {
|
|
50
50
|
const f = thread_vm.compileFunction(`return (${script})`, paramNames, {
|
|
@@ -55,7 +55,7 @@ export async function newThread<T>(...args: any[]): Promise<T> {
|
|
|
55
55
|
params[module] = global.require(module);
|
|
56
56
|
}
|
|
57
57
|
for (let i = 0; i < paramNames.length; i++) {
|
|
58
|
-
params[paramNames[i]] = paramValues[i];
|
|
58
|
+
params[paramNames[i]!] = paramValues[i];
|
|
59
59
|
}
|
|
60
60
|
const c = await f(...paramValues);
|
|
61
61
|
return await c(params);
|
|
@@ -79,7 +79,7 @@ export async function newThread<T>(...args: any[]): Promise<T> {
|
|
|
79
79
|
worker.postMessage(v8.serialize(message));
|
|
80
80
|
}
|
|
81
81
|
catch (e) {
|
|
82
|
-
reject?.(e);
|
|
82
|
+
reject?.(e as Error);
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
threadPeer.transportSafeArgumentTypes.add(Buffer.name);
|
package/src/usertoken.ts
CHANGED
|
@@ -2,7 +2,7 @@ export const ONE_DAY_MILLISECONDS = 86400000;
|
|
|
2
2
|
export const ONE_YEAR_MILLISECONDS = ONE_DAY_MILLISECONDS * 365;
|
|
3
3
|
|
|
4
4
|
export class UserToken {
|
|
5
|
-
constructor(public username: string, public aclId
|
|
5
|
+
constructor(public username: string, public aclId?: string, public timestamp = Date.now(), public duration = ONE_DAY_MILLISECONDS) {
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
static validateToken(token: string): UserToken {
|