@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.
Files changed (175) hide show
  1. package/dist/cert.js +1 -1
  2. package/dist/cert.js.map +1 -1
  3. package/dist/cluster/cluster-labels.d.ts +3 -3
  4. package/dist/cluster/cluster-labels.js +2 -2
  5. package/dist/cluster/cluster-labels.js.map +1 -1
  6. package/dist/cluster/cluster-setup.d.ts +3 -3
  7. package/dist/cluster/cluster-setup.js +3 -3
  8. package/dist/cluster/cluster-setup.js.map +1 -1
  9. package/dist/db-types.d.ts +4 -4
  10. package/dist/db-types.js.map +1 -1
  11. package/dist/event-registry.d.ts +2 -2
  12. package/dist/event-registry.js +9 -7
  13. package/dist/event-registry.js.map +1 -1
  14. package/dist/fetch/index.d.ts +2 -2
  15. package/dist/fetch/index.js +3 -6
  16. package/dist/fetch/index.js.map +1 -1
  17. package/dist/http-interfaces.js +1 -1
  18. package/dist/http-interfaces.js.map +1 -1
  19. package/dist/infer-defaults.d.ts +4 -4
  20. package/dist/infer-defaults.js +8 -4
  21. package/dist/infer-defaults.js.map +1 -1
  22. package/dist/ip.js +2 -1
  23. package/dist/ip.js.map +1 -1
  24. package/dist/level.d.ts +3 -3
  25. package/dist/level.js +1 -0
  26. package/dist/level.js.map +1 -1
  27. package/dist/listen-zero.js.map +1 -1
  28. package/dist/mixin/mixin-cycle.js +6 -6
  29. package/dist/mixin/mixin-cycle.js.map +1 -1
  30. package/dist/plugin/acl.js.map +1 -1
  31. package/dist/plugin/cluster.js.map +1 -1
  32. package/dist/plugin/descriptor.js +1 -1
  33. package/dist/plugin/descriptor.js.map +1 -1
  34. package/dist/plugin/device.d.ts +6 -6
  35. package/dist/plugin/device.js.map +1 -1
  36. package/dist/plugin/endpoint.js.map +1 -1
  37. package/dist/plugin/media.js +19 -14
  38. package/dist/plugin/media.js.map +1 -1
  39. package/dist/plugin/mediaobject.d.ts +1 -1
  40. package/dist/plugin/mediaobject.js.map +1 -1
  41. package/dist/plugin/plugin-api.d.ts +6 -6
  42. package/dist/plugin/plugin-api.js +2 -2
  43. package/dist/plugin/plugin-api.js.map +1 -1
  44. package/dist/plugin/plugin-console.js +11 -10
  45. package/dist/plugin/plugin-console.js.map +1 -1
  46. package/dist/plugin/plugin-device.d.ts +3 -3
  47. package/dist/plugin/plugin-device.js +2 -0
  48. package/dist/plugin/plugin-device.js.map +1 -1
  49. package/dist/plugin/plugin-host-api.d.ts +1 -1
  50. package/dist/plugin/plugin-host-api.js +19 -5
  51. package/dist/plugin/plugin-host-api.js.map +1 -1
  52. package/dist/plugin/plugin-host.js +3 -2
  53. package/dist/plugin/plugin-host.js.map +1 -1
  54. package/dist/plugin/plugin-http.d.ts +1 -1
  55. package/dist/plugin/plugin-http.js +5 -1
  56. package/dist/plugin/plugin-http.js.map +1 -1
  57. package/dist/plugin/plugin-lazy-remote.js.map +1 -1
  58. package/dist/plugin/plugin-remote-websocket.js.map +1 -1
  59. package/dist/plugin/plugin-remote-worker.js +5 -2
  60. package/dist/plugin/plugin-remote-worker.js.map +1 -1
  61. package/dist/plugin/plugin-remote.js +1 -1
  62. package/dist/plugin/plugin-remote.js.map +1 -1
  63. package/dist/plugin/plugin-repl.js +6 -2
  64. package/dist/plugin/plugin-repl.js.map +1 -1
  65. package/dist/plugin/runtime/child-process-worker.d.ts +4 -4
  66. package/dist/plugin/runtime/child-process-worker.js +1 -2
  67. package/dist/plugin/runtime/child-process-worker.js.map +1 -1
  68. package/dist/plugin/runtime/cluster-fork-worker.d.ts +1 -1
  69. package/dist/plugin/runtime/cluster-fork-worker.js +2 -0
  70. package/dist/plugin/runtime/cluster-fork-worker.js.map +1 -1
  71. package/dist/plugin/runtime/custom-worker.js.map +1 -1
  72. package/dist/plugin/runtime/node-fork-worker.d.ts +1 -1
  73. package/dist/plugin/runtime/node-fork-worker.js.map +1 -1
  74. package/dist/plugin/runtime/node-thread-worker.js.map +1 -1
  75. package/dist/plugin/runtime/python-worker.js +1 -1
  76. package/dist/plugin/runtime/python-worker.js.map +1 -1
  77. package/dist/plugin/runtime/runtime-worker.d.ts +1 -1
  78. package/dist/plugin/system.d.ts +1 -1
  79. package/dist/plugin/system.js +1 -0
  80. package/dist/plugin/system.js.map +1 -1
  81. package/dist/promise-utils.d.ts +1 -1
  82. package/dist/promise-utils.js.map +1 -1
  83. package/dist/rpc-buffer-serializer.d.ts +1 -1
  84. package/dist/rpc-serializer.js.map +1 -1
  85. package/dist/rpc.d.ts +10 -9
  86. package/dist/rpc.js +15 -8
  87. package/dist/rpc.js.map +1 -1
  88. package/dist/runtime.d.ts +11 -11
  89. package/dist/runtime.js +17 -18
  90. package/dist/runtime.js.map +1 -1
  91. package/dist/scrypted-cluster-main.js +3 -2
  92. package/dist/scrypted-cluster-main.js.map +1 -1
  93. package/dist/scrypted-plugin-main.js +1 -1
  94. package/dist/scrypted-plugin-main.js.map +1 -1
  95. package/dist/scrypted-server-main.js +8 -5
  96. package/dist/scrypted-server-main.js.map +1 -1
  97. package/dist/server-settings.d.ts +1 -1
  98. package/dist/server-settings.js +4 -4
  99. package/dist/server-settings.js.map +1 -1
  100. package/dist/services/addresses.d.ts +1 -1
  101. package/dist/services/addresses.js +2 -2
  102. package/dist/services/addresses.js.map +1 -1
  103. package/dist/services/alerts.js +2 -2
  104. package/dist/services/alerts.js.map +1 -1
  105. package/dist/services/cluster-fork.js.map +1 -1
  106. package/dist/services/plugin.d.ts +5 -5
  107. package/dist/services/plugin.js.map +1 -1
  108. package/dist/services/service-control.js.map +1 -1
  109. package/dist/services/users.d.ts +2 -2
  110. package/dist/services/users.js.map +1 -1
  111. package/dist/state.d.ts +7 -7
  112. package/dist/state.js +4 -4
  113. package/dist/state.js.map +1 -1
  114. package/dist/threading.js.map +1 -1
  115. package/dist/usertoken.d.ts +2 -2
  116. package/dist/usertoken.js.map +1 -1
  117. package/package.json +2 -2
  118. package/python/cluster_setup.py +13 -4
  119. package/python/plugin_remote.py +22 -18
  120. package/python/rpc_reader.py +3 -5
  121. package/src/cert.ts +2 -2
  122. package/src/cluster/cluster-labels.ts +4 -4
  123. package/src/cluster/cluster-setup.ts +20 -20
  124. package/src/db-types.ts +16 -16
  125. package/src/event-registry.ts +13 -11
  126. package/src/fetch/index.ts +4 -7
  127. package/src/http-interfaces.ts +2 -2
  128. package/src/infer-defaults.ts +12 -8
  129. package/src/ip.ts +2 -1
  130. package/src/level.ts +10 -9
  131. package/src/listen-zero.ts +1 -1
  132. package/src/mixin/mixin-cycle.ts +6 -6
  133. package/src/plugin/acl.ts +1 -1
  134. package/src/plugin/cluster.ts +2 -2
  135. package/src/plugin/descriptor.ts +2 -2
  136. package/src/plugin/device.ts +16 -16
  137. package/src/plugin/endpoint.ts +4 -4
  138. package/src/plugin/media.ts +34 -29
  139. package/src/plugin/mediaobject.ts +3 -3
  140. package/src/plugin/plugin-api.ts +7 -7
  141. package/src/plugin/plugin-console.ts +13 -12
  142. package/src/plugin/plugin-device.ts +20 -18
  143. package/src/plugin/plugin-host-api.ts +27 -13
  144. package/src/plugin/plugin-host.ts +26 -25
  145. package/src/plugin/plugin-http.ts +9 -5
  146. package/src/plugin/plugin-lazy-remote.ts +1 -1
  147. package/src/plugin/plugin-remote-websocket.ts +1 -1
  148. package/src/plugin/plugin-remote-worker.ts +22 -20
  149. package/src/plugin/plugin-remote.ts +14 -14
  150. package/src/plugin/plugin-repl.ts +6 -2
  151. package/src/plugin/runtime/child-process-worker.ts +11 -12
  152. package/src/plugin/runtime/cluster-fork-worker.ts +2 -0
  153. package/src/plugin/runtime/custom-worker.ts +6 -6
  154. package/src/plugin/runtime/node-fork-worker.ts +3 -3
  155. package/src/plugin/runtime/node-thread-worker.ts +3 -3
  156. package/src/plugin/runtime/python-worker.ts +14 -14
  157. package/src/plugin/runtime/runtime-worker.ts +1 -1
  158. package/src/plugin/system.ts +24 -23
  159. package/src/promise-utils.ts +4 -4
  160. package/src/rpc-serializer.ts +3 -3
  161. package/src/rpc.ts +25 -17
  162. package/src/runtime.ts +59 -60
  163. package/src/scrypted-cluster-main.ts +19 -18
  164. package/src/scrypted-plugin-main.ts +2 -2
  165. package/src/scrypted-server-main.ts +17 -14
  166. package/src/server-settings.ts +5 -5
  167. package/src/services/addresses.ts +3 -3
  168. package/src/services/alerts.ts +2 -2
  169. package/src/services/cluster-fork.ts +9 -9
  170. package/src/services/plugin.ts +15 -15
  171. package/src/services/service-control.ts +1 -1
  172. package/src/services/users.ts +3 -3
  173. package/src/state.ts +21 -21
  174. package/src/threading.ts +5 -5
  175. 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, workerInspectAddress);
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
- return listenSet.check(socket.localAddress, net.isIPv4(socket.localAddress) ? 'ipv4' : 'ipv6');
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, tag);
455
+ const plugin = (await scrypted.installNpm(endpoint!, tag))!;
454
456
  res.send({
455
- id: scrypted.findPluginDevice(plugin.pluginId)._id,
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) {
@@ -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) {
@@ -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(null, 'Logger' as any, undefined);
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(null, 'Logger' as any, undefined);
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, runtimeWorkerOptions, peerLiveness, getZip);
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');
@@ -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)._id,
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].consoleServer;
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].consoleServer;
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].consoleServer;
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].remote.getServicePort(name, ...args);
185
+ return this.scrypted.plugins[pluginId]!.remote.getServicePort(name, ...args);
186
186
  }
187
187
  }
@@ -20,7 +20,7 @@ export class ServiceControl {
20
20
  await httpFetch({
21
21
  url: webhookUpdate,
22
22
  headers: {
23
- Authorization: webhookUpdateAuthorization,
23
+ Authorization: webhookUpdateAuthorization!,
24
24
  }
25
25
  });
26
26
  }
@@ -5,9 +5,9 @@ import crypto from 'crypto';
5
5
 
6
6
  export class UsersService {
7
7
  users = new Map<string, ScryptedUser>();
8
- usersPromise: Promise<ScryptedUser[]>;
8
+ usersPromise!: Promise<ScryptedUser[]>;
9
9
 
10
- static async addUserToDatabase(db: WrappedLevel, username: string, password: string, aclId: string) {
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: string) {
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: ScryptedInterface, mixinId: string) {
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).log('i', `${property}: ${value} (mixin)`);
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?: ScryptedInterface) {
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).log('i', `${property}: ${value}`);
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, false)
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 cb = (eventDetails: EventDetails, eventData: any) => {
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
- callback?.(eventDetails, eventData);
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
- callback = undefined;
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.tailRefresh)
224
+ if (!rt!.tailRefresh)
225
225
  return;
226
- await device[RefreshSymbol](rt.refreshInterface, rt.userInitiated);
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.postMessage(thread_v8.serialize(message));
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.on('message', (message: any) => mainPeer.handleMessage(thread_v8.deserialize(message)));
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: string, public timestamp = Date.now(), public duration = ONE_DAY_MILLISECONDS) {
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 {