mirror of
https://github.com/koush/scrypted.git
synced 2026-02-06 07:22:19 +00:00
Compare commits
347 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd3e7fe238 | ||
|
|
b02c17e185 | ||
|
|
6dee9b04df | ||
|
|
378fb41908 | ||
|
|
48f7208d55 | ||
|
|
d1bfed3019 | ||
|
|
6bf10d4aff | ||
|
|
3ceef8ff87 | ||
|
|
df1155cf82 | ||
|
|
453469ed98 | ||
|
|
2e4dbceb0e | ||
|
|
c620a4e126 | ||
|
|
5698551b7e | ||
|
|
9e655c0a53 | ||
|
|
35dadaab93 | ||
|
|
71a93805ef | ||
|
|
76487091da | ||
|
|
3c5b8bc940 | ||
|
|
37e5c49729 | ||
|
|
16fc4407c1 | ||
|
|
3e76c1b1d3 | ||
|
|
4880c18c48 | ||
|
|
198d4808cb | ||
|
|
ef8f4ba9b8 | ||
|
|
d6c6e3c594 | ||
|
|
6c904da49b | ||
|
|
6ac790f824 | ||
|
|
3638f80cef | ||
|
|
809b632417 | ||
|
|
f53330c861 | ||
|
|
66455c8f01 | ||
|
|
e6eb61f04f | ||
|
|
adeb3d837e | ||
|
|
3da3f85513 | ||
|
|
cbe251e345 | ||
|
|
dfa2dacde4 | ||
|
|
9395253b50 | ||
|
|
e020ee1517 | ||
|
|
a7ecb9b5e5 | ||
|
|
24f9b0fca3 | ||
|
|
a78ad99f50 | ||
|
|
c26c5e94a4 | ||
|
|
2d93a69c91 | ||
|
|
1c52297e74 | ||
|
|
5bc76642cc | ||
|
|
15fa27029d | ||
|
|
553678ed1a | ||
|
|
b3b7265263 | ||
|
|
d87d9bb751 | ||
|
|
301213fc5f | ||
|
|
da393ae4e0 | ||
|
|
9376fc4ba6 | ||
|
|
51d4aa7b3e | ||
|
|
30334e5bd0 | ||
|
|
dffc05d165 | ||
|
|
172e5b3ccb | ||
|
|
cad60e7730 | ||
|
|
131458576c | ||
|
|
0d7b47e1e9 | ||
|
|
1a33384115 | ||
|
|
1fa5f66b44 | ||
|
|
1032d444fb | ||
|
|
2883824690 | ||
|
|
a505394852 | ||
|
|
1240f401d7 | ||
|
|
b49faaa033 | ||
|
|
cbb1d4533a | ||
|
|
a5a027bd6d | ||
|
|
94acd0e800 | ||
|
|
cabdd91a92 | ||
|
|
93c9b62e87 | ||
|
|
21c771d50f | ||
|
|
bb2ecd7bd8 | ||
|
|
6c0864b883 | ||
|
|
3c8ef7a2cf | ||
|
|
6afecc8185 | ||
|
|
ea16381b7a | ||
|
|
09d3ac587f | ||
|
|
3872cb391a | ||
|
|
7d985937ca | ||
|
|
cef8482b93 | ||
|
|
f729c76346 | ||
|
|
9aa9498aae | ||
|
|
afe832a32a | ||
|
|
be6a81c9a2 | ||
|
|
964bb27d48 | ||
|
|
6bca83b338 | ||
|
|
11860409f1 | ||
|
|
6743f76e09 | ||
|
|
771d90ea73 | ||
|
|
ba28899dc3 | ||
|
|
3e57c90208 | ||
|
|
e155584373 | ||
|
|
4a3968956e | ||
|
|
78c259d14e | ||
|
|
6f4b360d2a | ||
|
|
642795dd9d | ||
|
|
4b3d37b628 | ||
|
|
8e28e6d19e | ||
|
|
d13171551d | ||
|
|
ea1474c21e | ||
|
|
7abff3a91b | ||
|
|
40f11a0053 | ||
|
|
1d3450455b | ||
|
|
bd3b4ac387 | ||
|
|
6787153c30 | ||
|
|
7024daba53 | ||
|
|
28a2e0d898 | ||
|
|
a7757a9a54 | ||
|
|
84fc40e1e5 | ||
|
|
b3b8f6bc70 | ||
|
|
7962606a2b | ||
|
|
9c2ea7d2bc | ||
|
|
4e653a9942 | ||
|
|
167db0f11a | ||
|
|
49064de767 | ||
|
|
51836ca59f | ||
|
|
d64ed629b0 | ||
|
|
83a9ad2250 | ||
|
|
7f9358a3b5 | ||
|
|
9cf3d6c912 | ||
|
|
5e3d1c423c | ||
|
|
64fa68f2d0 | ||
|
|
45cc859636 | ||
|
|
1984bb44ba | ||
|
|
1164e4b15b | ||
|
|
9e5fbc5251 | ||
|
|
6f52390067 | ||
|
|
d34afab6a4 | ||
|
|
2edc74f75b | ||
|
|
e913131f90 | ||
|
|
bca752addb | ||
|
|
43fc6c9fc9 | ||
|
|
448e2c4e6e | ||
|
|
625ea7981e | ||
|
|
1be806eb8e | ||
|
|
e4b71ffbd4 | ||
|
|
16f4cafea3 | ||
|
|
f78df27341 | ||
|
|
57d4e4b9bd | ||
|
|
cb1c062b5e | ||
|
|
e3b996562c | ||
|
|
c96bf237b5 | ||
|
|
5bde86fd15 | ||
|
|
5075920308 | ||
|
|
9e4845b868 | ||
|
|
0cab8f2faf | ||
|
|
510321b7d6 | ||
|
|
efb0a39e52 | ||
|
|
467d89ccaf | ||
|
|
19832c9537 | ||
|
|
0b24e57262 | ||
|
|
f406969140 | ||
|
|
4db26a1779 | ||
|
|
bfc82d0010 | ||
|
|
df3a3d279c | ||
|
|
bb7f2a0c9b | ||
|
|
3f83d4b8f7 | ||
|
|
779fa1df9c | ||
|
|
1c08313e8b | ||
|
|
64e8dc2cc9 | ||
|
|
1914fa60ea | ||
|
|
8073a80bae | ||
|
|
cd7d45155f | ||
|
|
6f6ccff5b1 | ||
|
|
4ea8049d22 | ||
|
|
8354564157 | ||
|
|
26518f0693 | ||
|
|
72df40c422 | ||
|
|
fe1b677381 | ||
|
|
16a9abeb9e | ||
|
|
ba07aa7765 | ||
|
|
35e508a01e | ||
|
|
1e709a058d | ||
|
|
f5a4bab0a8 | ||
|
|
e373a3935e | ||
|
|
f9f9762046 | ||
|
|
4b6751785c | ||
|
|
133cbcf5f5 | ||
|
|
817c171757 | ||
|
|
9af9359b26 | ||
|
|
b684ced629 | ||
|
|
977db49f87 | ||
|
|
992fe98f5e | ||
|
|
a74157168e | ||
|
|
0eed5241f0 | ||
|
|
c0680736e7 | ||
|
|
c345f173d2 | ||
|
|
1ed10cd1cb | ||
|
|
9426db12aa | ||
|
|
a35e821f79 | ||
|
|
983794d5d0 | ||
|
|
cd3e2340b8 | ||
|
|
bb82eb6bde | ||
|
|
5006bb90fc | ||
|
|
7134ef114a | ||
|
|
2f5b1f6526 | ||
|
|
f88f0a25db | ||
|
|
d2810b09ed | ||
|
|
f103ddf660 | ||
|
|
47edffa56d | ||
|
|
86a5a73276 | ||
|
|
1a47015558 | ||
|
|
0de9812760 | ||
|
|
10d16dab21 | ||
|
|
f3f4bbc77f | ||
|
|
029f788407 | ||
|
|
89b93eb2f4 | ||
|
|
6fd35e54e6 | ||
|
|
118c404525 | ||
|
|
833ecb721f | ||
|
|
a8f1e74278 | ||
|
|
1075fb4491 | ||
|
|
f09a797ebf | ||
|
|
1e0fdee7b6 | ||
|
|
be6375e9f4 | ||
|
|
e5ba39f886 | ||
|
|
6841b74a26 | ||
|
|
a3f45e2c49 | ||
|
|
b664ccd24f | ||
|
|
3f244b586f | ||
|
|
9f828739de | ||
|
|
b2cef35bc0 | ||
|
|
3e54540db7 | ||
|
|
debd7f2c40 | ||
|
|
adbc2aaed9 | ||
|
|
6024b4ceaf | ||
|
|
3a065febb5 | ||
|
|
1e2c3e0ca7 | ||
|
|
61dfddeab2 | ||
|
|
b902873d44 | ||
|
|
a38d803b86 | ||
|
|
9c3dab18da | ||
|
|
2ceb2cd9c3 | ||
|
|
a5fd1c0278 | ||
|
|
2c717cb4fc | ||
|
|
df10c4e5f2 | ||
|
|
7c51bb420e | ||
|
|
367eafff5c | ||
|
|
adcdd18497 | ||
|
|
a95b77fe26 | ||
|
|
3ff75f0fde | ||
|
|
eecd38d271 | ||
|
|
7128af20af | ||
|
|
c651c2164b | ||
|
|
6caafd73f5 | ||
|
|
05cb505783 | ||
|
|
07baddc9c3 | ||
|
|
76ac260bf7 | ||
|
|
dfee7c6b09 | ||
|
|
b3ce6a2af3 | ||
|
|
933c0cac0f | ||
|
|
1fb1334a00 | ||
|
|
cb45a00c25 | ||
|
|
fec59af263 | ||
|
|
5d213a4c51 | ||
|
|
d444c4ab7c | ||
|
|
590f955ca9 | ||
|
|
7df4bf2723 | ||
|
|
3416347a1f | ||
|
|
c669bb8902 | ||
|
|
ce5fd2d4fd | ||
|
|
fa8a756059 | ||
|
|
73b85e1cd0 | ||
|
|
1300073712 | ||
|
|
3e296e12a5 | ||
|
|
bf98060a08 | ||
|
|
d1cd380123 | ||
|
|
1a2aadfb52 | ||
|
|
60c854a477 | ||
|
|
0790b60122 | ||
|
|
a3caa09df4 | ||
|
|
02ca8bd765 | ||
|
|
f9e1a94ab3 | ||
|
|
dd0da26df3 | ||
|
|
890f2e8daf | ||
|
|
2c8babe3ce | ||
|
|
8e31b5f970 | ||
|
|
0873a72848 | ||
|
|
145c66e1c8 | ||
|
|
2b60b45113 | ||
|
|
6f63927e2f | ||
|
|
528eabdfc0 | ||
|
|
e201ea1fc1 | ||
|
|
7790810b86 | ||
|
|
e9ec78909b | ||
|
|
26245e17ca | ||
|
|
5d87a1b2dd | ||
|
|
e1efde3868 | ||
|
|
525eb028c6 | ||
|
|
520c6a62a1 | ||
|
|
6e6898ce33 | ||
|
|
1344c9112c | ||
|
|
f2148ce26a | ||
|
|
81b00195d6 | ||
|
|
8f71778f05 | ||
|
|
2e5b8d90aa | ||
|
|
780182b94a | ||
|
|
57480f7606 | ||
|
|
1478684120 | ||
|
|
223b302bed | ||
|
|
f56cef1b50 | ||
|
|
83bfa30d4b | ||
|
|
611674af46 | ||
|
|
941ea7f346 | ||
|
|
2b9c2956d6 | ||
|
|
266d5bf8a3 | ||
|
|
d0007fc7bb | ||
|
|
75f90b78eb | ||
|
|
1e8959413e | ||
|
|
1301247ea3 | ||
|
|
2798fe4d3d | ||
|
|
55a76a86dc | ||
|
|
cebd49fadb | ||
|
|
90adb11f27 | ||
|
|
cea5c95c82 | ||
|
|
0405e13181 | ||
|
|
5659499c16 | ||
|
|
d272a4b86f | ||
|
|
f8a8ed4241 | ||
|
|
892b978065 | ||
|
|
c81c55c12e | ||
|
|
bb9d98921b | ||
|
|
4c66efc4af | ||
|
|
0547ed9a32 | ||
|
|
b046822282 | ||
|
|
b033d24451 | ||
|
|
15464229ad | ||
|
|
93ad50db73 | ||
|
|
427139e8df | ||
|
|
b1100398ec | ||
|
|
b40a2eaf6e | ||
|
|
17c9440fd9 | ||
|
|
ea63a96444 | ||
|
|
0f02f96b89 | ||
|
|
6ce538bb23 | ||
|
|
29ab0e79de | ||
|
|
e07cd13ef3 | ||
|
|
0cbb26051c | ||
|
|
fcb8d938ee | ||
|
|
98fe1d412a | ||
|
|
c19ec63f98 | ||
|
|
a41e915f69 | ||
|
|
f0db59f6d2 | ||
|
|
8e691ff2ee | ||
|
|
42e0810bc0 | ||
|
|
68e91ad996 |
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -27,6 +27,11 @@ Created issues that do not meet these requirements or are improperly filled out
|
||||
1. Delete this section and everything above it.
|
||||
2. Fill out the sections below.
|
||||
|
||||
** Before You Submit**
|
||||
|
||||
- [ ] I checked that my issue isn't already filed: [Search open issues](https://github.com/koush/scrypted/issues).
|
||||
- [ ] I checked the relevant camera/device and/or plugin `Log` in the `Management Console` for errors or warnings that may help identify and resolve the issue myself.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is. The issue tracker is only for reporting bugs in Scrypted, for general support check Discord. Hardrware support requests or assistance requests will be immediately closed.
|
||||
|
||||
@@ -43,6 +48,9 @@ A clear and concise description of what you expected to happen.
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Logs**
|
||||
Include a `Log` from the device/camera in the management console (and if applicable, the affacted plugin, like HomeKit).
|
||||
|
||||
**Server (please complete the following information):**
|
||||
- OS: [e.g. Ubuntu]
|
||||
- Installation Method: [e.g. Desktop App, Docker, Local]
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
2
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# disable blank issue creation
|
||||
blank_issues_enabled: false
|
||||
2
.github/workflows/docker-common.yml
vendored
2
.github/workflows/docker-common.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: self-hosted
|
||||
env:
|
||||
NODE_VERSION: '20'
|
||||
NODE_VERSION: '22'
|
||||
strategy:
|
||||
matrix:
|
||||
BASE: ["noble"]
|
||||
|
||||
27
.github/workflows/docker.yml
vendored
27
.github/workflows/docker.yml
vendored
@@ -20,9 +20,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
BASE: [
|
||||
["noble-nvidia", ".s6"],
|
||||
["noble-full", ".s6"],
|
||||
["noble-lite", ""],
|
||||
["noble-nvidia", ".s6", "noble-nvidia"],
|
||||
["noble-full", ".s6", "noble-full"],
|
||||
["noble-lite", "", "noble-lite"],
|
||||
# ["noble-lite", ".router", "noble-router"],
|
||||
]
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
@@ -94,16 +95,18 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
${{ format('koush/scrypted:v{1}-{0}', matrix.BASE[0], github.event.inputs.publish_tag || steps.package-version.outputs.NPM_VERSION) }}
|
||||
${{ matrix.BASE[0] == 'noble-full' && format('koush/scrypted:{0}', github.event.inputs.tag) || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[0] == 'noble-nvidia' && 'koush/scrypted:nvidia' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[0] == 'noble-full' && 'koush/scrypted:full' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[0] == 'noble-lite' && 'koush/scrypted:lite' || '' }}
|
||||
${{ format('koush/scrypted:v{1}-{0}', matrix.BASE[2], github.event.inputs.publish_tag || steps.package-version.outputs.NPM_VERSION) }}
|
||||
${{ matrix.BASE[2] == 'noble-full' && format('koush/scrypted:{0}', github.event.inputs.tag) || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-nvidia' && 'koush/scrypted:nvidia' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-full' && 'koush/scrypted:full' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-lite' && matrix.BASE[1] == '' && 'koush/scrypted:lite' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-router' && 'koush/scrypted:router' || '' }}
|
||||
|
||||
${{ format('ghcr.io/koush/scrypted:v{1}-{0}', matrix.BASE[0], github.event.inputs.publish_tag || steps.package-version.outputs.NPM_VERSION) }}
|
||||
${{ matrix.BASE[0] == 'noble-full' && format('ghcr.io/koush/scrypted:{0}', github.event.inputs.tag) || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[0] == 'noble-nvidia' && 'ghcr.io/koush/scrypted:nvidia' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[0] == 'noble-full' && 'ghcr.io/koush/scrypted:full' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[0] == 'noble-lite' && 'ghcr.io/koush/scrypted:lite' || '' }}
|
||||
${{ matrix.BASE[2] == 'noble-full' && format('ghcr.io/koush/scrypted:{0}', github.event.inputs.tag) || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-nvidia' && 'ghcr.io/koush/scrypted:nvidia' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-full' && 'ghcr.io/koush/scrypted:full' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-lite' && matrix.BASE[1] == '' && 'ghcr.io/koush/scrypted:lite' || '' }}
|
||||
${{ github.event.inputs.tag == 'latest' && matrix.BASE[2] == 'noble-lite' && 'ghcr.io/koush/scrypted:router' || '' }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: [ubuntu-latest, macos-14, macos-13, windows-latest]
|
||||
runner: [ubuntu-latest, ubuntu-24.04-arm, macos-14, macos-13, windows-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
||||
3630
common/package-lock.json
generated
3630
common/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -123,6 +123,9 @@ export function createAsyncQueue<T>() {
|
||||
}
|
||||
|
||||
return {
|
||||
[Symbol.dispose]() {
|
||||
end(new Error('async queue disposed'));
|
||||
},
|
||||
get ended() {
|
||||
return ended;
|
||||
},
|
||||
|
||||
@@ -7,7 +7,6 @@ const { systemManager } = sdk;
|
||||
export abstract class AutoenableMixinProvider extends ScryptedDeviceBase {
|
||||
hasEnabledMixin: { [id: string]: string } = {};
|
||||
pluginsComponent: Promise<any>;
|
||||
unshiftMixin = false;
|
||||
|
||||
constructor(nativeId?: string, public autoIncludeToken = 'v4') {
|
||||
super(nativeId);
|
||||
@@ -45,6 +44,10 @@ export abstract class AutoenableMixinProvider extends ScryptedDeviceBase {
|
||||
return this.hasEnabledMixin[device.id] === this.autoIncludeToken;
|
||||
}
|
||||
|
||||
shouldUnshiftMixin(device: ScryptedDevice) {
|
||||
return false;
|
||||
}
|
||||
|
||||
async maybeEnableMixin(device: ScryptedDevice) {
|
||||
if (!device || device.mixins?.includes(this.id))
|
||||
return;
|
||||
@@ -61,7 +64,7 @@ export abstract class AutoenableMixinProvider extends ScryptedDeviceBase {
|
||||
|
||||
this.log.i('auto enabling mixin for ' + device.name)
|
||||
const mixins = (device.mixins || []).slice();
|
||||
if (this.unshiftMixin)
|
||||
if (this.shouldUnshiftMixin(device))
|
||||
mixins.unshift(this.id);
|
||||
else
|
||||
mixins.push(this.id);
|
||||
@@ -77,5 +80,5 @@ export abstract class AutoenableMixinProvider extends ScryptedDeviceBase {
|
||||
this.storage.setItem('hasEnabledMixin', JSON.stringify(this.hasEnabledMixin));
|
||||
}
|
||||
|
||||
abstract canMixin(type: ScryptedDeviceType, interfaces: string[]): Promise<string[] | null | undefined | void>;
|
||||
abstract canMixin(type: ScryptedDeviceType | string, interfaces: string[]): Promise<string[] | null | undefined | void>;
|
||||
}
|
||||
|
||||
@@ -70,11 +70,7 @@ export function getH264DecoderArgs(): CodecArgs {
|
||||
],
|
||||
};
|
||||
|
||||
if (isRaspberryPi()) {
|
||||
ret['Raspberry Pi'] = ['-c:v', 'h264_mmal'];
|
||||
ret[V4L2] = ['-c:v', 'h264_v4l2m2m'];
|
||||
}
|
||||
else if (os.platform() === 'linux') {
|
||||
if (os.platform() === 'linux') {
|
||||
ret[V4L2] = ['-c:v', 'h264_v4l2m2m'];
|
||||
}
|
||||
else if (os.platform() === 'win32') {
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
export interface RefreshPromise<T> {
|
||||
promise: Promise<T>;
|
||||
cacheDuration: number;
|
||||
}
|
||||
|
||||
export function singletonPromise<T>(rp: undefined | RefreshPromise<T>, method: () => Promise<T>, cacheDuration = 0) {
|
||||
if (rp?.promise)
|
||||
return rp;
|
||||
|
||||
const promise = method();
|
||||
if (!rp) {
|
||||
rp = {
|
||||
promise,
|
||||
cacheDuration,
|
||||
}
|
||||
}
|
||||
else {
|
||||
rp.promise = promise;
|
||||
}
|
||||
promise.finally(() => setTimeout(() => rp.promise = undefined, rp.cacheDuration));
|
||||
return rp;
|
||||
}
|
||||
|
||||
export class TimeoutError<T> extends Error {
|
||||
constructor(public promise: Promise<T>) {
|
||||
super('Operation Timed Out');
|
||||
}
|
||||
}
|
||||
|
||||
export function timeoutPromise<T>(timeout: number, promise: Promise<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const t = setTimeout(() => reject(new TimeoutError(promise)), timeout);
|
||||
|
||||
promise
|
||||
.then(v => {
|
||||
clearTimeout(t);
|
||||
resolve(v);
|
||||
})
|
||||
.catch(e => {
|
||||
clearTimeout(t);
|
||||
reject(e);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export function timeoutFunction<T>(timeout: number, f: (isTimedOut: () => boolean) => Promise<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
let isTimedOut = false;
|
||||
const promise = f(() => isTimedOut);
|
||||
|
||||
const t = setTimeout(() => {
|
||||
isTimedOut = true;
|
||||
reject(new TimeoutError(promise));
|
||||
}, timeout);
|
||||
|
||||
promise
|
||||
.then(v => {
|
||||
clearTimeout(t);
|
||||
resolve(v);
|
||||
})
|
||||
.catch(e => {
|
||||
clearTimeout(t);
|
||||
reject(e);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export function createPromiseDebouncer<T>() {
|
||||
let current: Promise<T>;
|
||||
|
||||
return (func: () => Promise<T>): Promise<T> => {
|
||||
if (!current)
|
||||
current = func().finally(() => current = undefined);
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
export function createMapPromiseDebouncer<T>() {
|
||||
const map = new Map<string, Promise<T>>();
|
||||
|
||||
return (key: any, debounce: number, func: () => Promise<T>): Promise<T> => {
|
||||
const keyStr = JSON.stringify(key);
|
||||
let value = map.get(keyStr);
|
||||
if (!value) {
|
||||
value = func().finally(() => {
|
||||
if (!debounce) {
|
||||
map.delete(keyStr);
|
||||
return;
|
||||
}
|
||||
setTimeout(() => map.delete(keyStr), debounce);
|
||||
});
|
||||
map.set(keyStr, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
1
common/src/promise-utils.ts
Symbolic link
1
common/src/promise-utils.ts
Symbolic link
@@ -0,0 +1 @@
|
||||
../../server/src/promise-utils.ts
|
||||
@@ -95,6 +95,9 @@ export const H265_NAL_TYPE_SPS = 33;
|
||||
export const H265_NAL_TYPE_PPS = 34;
|
||||
export const H265_NAL_TYPE_IDR_N = 19;
|
||||
export const H265_NAL_TYPE_IDR_W = 20;
|
||||
export const H265_NAL_TYPE_FU = 49;
|
||||
export const H265_NAL_TYPE_SEI_PREFIX = 39;
|
||||
export const H265_NAL_TYPE_SEI_SUFFIX = 40;
|
||||
|
||||
export function findH264NaluType(streamChunk: StreamChunk, naluType: number) {
|
||||
if (streamChunk.type !== 'h264')
|
||||
@@ -161,10 +164,10 @@ export function findH265NaluTypeInNalu(nalu: Buffer, naluType: number) {
|
||||
return;
|
||||
}
|
||||
|
||||
export function getNaluTypes(streamChunk: StreamChunk) {
|
||||
export function getStartedH264NaluTypes(streamChunk: StreamChunk) {
|
||||
if (streamChunk.type !== 'h264')
|
||||
return new Set<number>();
|
||||
return getNaluTypesInNalu(streamChunk.chunks[streamChunk.chunks.length - 1].subarray(12))
|
||||
return getNaluTypesInNalu(streamChunk.chunks[streamChunk.chunks.length - 1].subarray(12), true)
|
||||
}
|
||||
|
||||
export function getNaluTypesInNalu(nalu: Buffer, fuaRequireStart = false, fuaRequireEnd = false) {
|
||||
@@ -205,10 +208,10 @@ export function getNaluTypesInNalu(nalu: Buffer, fuaRequireStart = false, fuaReq
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getH265NaluTypes(streamChunk: StreamChunk) {
|
||||
export function getStartedH265NaluTypes(streamChunk: StreamChunk) {
|
||||
if (streamChunk.type !== 'h265')
|
||||
return new Set<number>();
|
||||
return getNaluTypesInH265Nalu(streamChunk.chunks[streamChunk.chunks.length - 1].subarray(12))
|
||||
return getNaluTypesInH265Nalu(streamChunk.chunks[streamChunk.chunks.length - 1].subarray(12), true)
|
||||
}
|
||||
|
||||
export function getNaluTypesInH265Nalu(nalu: Buffer, fuaRequireStart = false, fuaRequireEnd = false) {
|
||||
@@ -216,7 +219,7 @@ export function getNaluTypesInH265Nalu(nalu: Buffer, fuaRequireStart = false, fu
|
||||
const naluType = parseH265NaluType(nalu[0]);
|
||||
if (naluType === H265_NAL_TYPE_AGG) {
|
||||
ret.add(H265_NAL_TYPE_AGG);
|
||||
let pos = 1;
|
||||
let pos = 2;
|
||||
while (pos < nalu.length) {
|
||||
const naluLength = nalu.readUInt16BE(pos);
|
||||
pos += 2;
|
||||
@@ -225,6 +228,23 @@ export function getNaluTypesInH265Nalu(nalu: Buffer, fuaRequireStart = false, fu
|
||||
pos += naluLength;
|
||||
}
|
||||
}
|
||||
else if (naluType === H265_NAL_TYPE_FU) {
|
||||
ret.add(H265_NAL_TYPE_FU);
|
||||
const fuaType = nalu[2] & 0x3F; // 6 bits
|
||||
if (fuaRequireStart) {
|
||||
const isFuStart = !!(nalu[2] & 0x80);
|
||||
if (isFuStart)
|
||||
ret.add(fuaType);
|
||||
}
|
||||
else if (fuaRequireEnd) {
|
||||
const isFuEnd = !!(nalu[2] & 0x40);
|
||||
if (isFuEnd)
|
||||
ret.add(fuaType);
|
||||
}
|
||||
else {
|
||||
ret.add(fuaType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret.add(naluType);
|
||||
}
|
||||
@@ -247,19 +267,21 @@ export function createRtspParser(options?: StreamParserOptions): RtspStreamParse
|
||||
'tcp',
|
||||
...(options?.vcodec || []),
|
||||
...(options?.acodec || []),
|
||||
// linux and windows seem to support 64000 but darwin is 32000?
|
||||
'-pkt_size', '32000',
|
||||
'-f', 'rtsp',
|
||||
],
|
||||
findSyncFrame(streamChunks: StreamChunk[]) {
|
||||
for (let prebufferIndex = 0; prebufferIndex < streamChunks.length; prebufferIndex++) {
|
||||
const streamChunk = streamChunks[prebufferIndex];
|
||||
if (streamChunk.type === 'h264') {
|
||||
const naluTypes = getNaluTypes(streamChunk);
|
||||
const naluTypes = getStartedH264NaluTypes(streamChunk);
|
||||
if (naluTypes.has(H264_NAL_TYPE_SPS) || naluTypes.has(H264_NAL_TYPE_IDR)) {
|
||||
return streamChunks.slice(prebufferIndex);
|
||||
}
|
||||
}
|
||||
else if (streamChunk.type === 'h265') {
|
||||
const naluTypes = getH265NaluTypes(streamChunk);
|
||||
const naluTypes = getStartedH265NaluTypes(streamChunk);
|
||||
|
||||
if (naluTypes.has(H265_NAL_TYPE_VPS)
|
||||
|| naluTypes.has(H265_NAL_TYPE_SPS)
|
||||
@@ -394,7 +416,7 @@ export class RtspClient extends RtspBase {
|
||||
hasGetParameter = true;
|
||||
contentBase: string;
|
||||
|
||||
constructor(public url: string) {
|
||||
constructor(public readonly url: string) {
|
||||
super();
|
||||
const u = new URL(url);
|
||||
const port = parseInt(u.port) || 554;
|
||||
@@ -511,6 +533,42 @@ export class RtspClient extends RtspBase {
|
||||
}
|
||||
}
|
||||
|
||||
async *handleStream(): AsyncGenerator<{
|
||||
rtcp: boolean,
|
||||
header: Buffer,
|
||||
packet: Buffer,
|
||||
channel: number,
|
||||
}> {
|
||||
while (true) {
|
||||
const header = await readLength(this.client, 4);
|
||||
// can this even happen? since the RTSP request method isn't a fixed
|
||||
// value like the "RTSP" in the RTSP response, I don't think so?
|
||||
if (header[0] !== RTSP_FRAME_MAGIC) {
|
||||
if (header.toString() !== 'RTSP')
|
||||
throw this.createBadHeader(header);
|
||||
|
||||
this.client.unshift(header);
|
||||
|
||||
// do what with this?
|
||||
const message = await super.readMessage();
|
||||
const body = await this.readBody(parseHeaders(message));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const length = header.readUInt16BE(2);
|
||||
const packet = await readLength(this.client, length);
|
||||
const id = header.readUInt8(1);
|
||||
|
||||
yield {
|
||||
channel: id,
|
||||
rtcp: id % 2 === 1,
|
||||
header,
|
||||
packet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async readLoop() {
|
||||
const deferred = new Deferred<void>();
|
||||
|
||||
@@ -613,7 +671,8 @@ export class RtspClient extends RtspBase {
|
||||
const { parseHTTPHeadersQuotedKeyValueSet } = await import('http-auth-utils/dist/utils');
|
||||
|
||||
if (this.wwwAuthenticate.includes('Basic')) {
|
||||
const hash = BASIC.computeHash(url);
|
||||
const parsedUrl = new URL(this.url);
|
||||
const hash = BASIC.computeHash({ username: parsedUrl.username, password: parsedUrl.password });
|
||||
return `Basic ${hash}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,3 +359,33 @@ export function getSpsPps(
|
||||
pps: Buffer.from(pps, 'base64'),
|
||||
}
|
||||
}
|
||||
|
||||
export function getSpsPpsVps(
|
||||
section: {
|
||||
fmtp: {
|
||||
payloadType: number;
|
||||
parameters: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}[]
|
||||
}
|
||||
) {
|
||||
const parameters = section?.fmtp?.[0]?.parameters;
|
||||
if (!parameters) {
|
||||
return {
|
||||
sps: undefined,
|
||||
pps: undefined,
|
||||
vps: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const sps = parameters['sprop-sps'];
|
||||
const pps = parameters['sprop-pps'];
|
||||
const vps = parameters['sprop-vps'];
|
||||
|
||||
return {
|
||||
sps: sps ? Buffer.from(sps, 'base64') : undefined,
|
||||
pps: pps ? Buffer.from(pps, 'base64') : undefined,
|
||||
vps: vps ? Buffer.from(vps, 'base64') : undefined,
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,9 @@ export function createService<T, V>(options: ForkOptions, create: (t: Promise<T>
|
||||
currentFork = sdk.fork<T>(options);
|
||||
currentFork.worker.on('exit', () => currentResult = undefined);
|
||||
currentResult = create(currentFork.result);
|
||||
currentResult.catch(() => currentResult = undefined);
|
||||
currentResult.catch(() => {
|
||||
currentResult = undefined;
|
||||
});
|
||||
return currentResult;
|
||||
},
|
||||
|
||||
|
||||
2
external/werift
vendored
2
external/werift
vendored
Submodule external/werift updated: e379126007...c317c6eb30
@@ -1,6 +1,6 @@
|
||||
# Home Assistant Addon Configuration
|
||||
name: Scrypted
|
||||
version: "v0.120.0-jammy-full"
|
||||
version: "v0.130.1-noble-full"
|
||||
slug: scrypted
|
||||
description: Scrypted is a high performance home video integration and automation platform
|
||||
url: "https://github.com/koush/scrypted"
|
||||
|
||||
@@ -16,6 +16,6 @@ ENV NODE_OPTIONS="--dns-result-order=ipv4first"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20240321"
|
||||
ENV SCRYPTED_BASE_VERSION="20250101"
|
||||
|
||||
CMD ["/bin/sh", "-c", "ulimit -c 0; exec npm --prefix /server exec scrypted-serve"]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# This common file will be used by both Docker and the linux
|
||||
# install script.
|
||||
################################################################
|
||||
ARG BASE="jammy"
|
||||
ARG BASE="noble"
|
||||
FROM ubuntu:${BASE} as header
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
@@ -19,7 +19,7 @@ RUN apt-get update && apt-get -y install \
|
||||
apt-get -y update && \
|
||||
apt-get -y upgrade
|
||||
|
||||
ARG NODE_VERSION=20
|
||||
ARG NODE_VERSION=22
|
||||
RUN apt-get install -y ca-certificates curl gnupg
|
||||
RUN mkdir -p /etc/apt/keyrings
|
||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor --yes -o /etc/apt/keyrings/nodesource.gpg
|
||||
|
||||
@@ -10,7 +10,7 @@ RUN apt-get update && apt-get -y install \
|
||||
apt-get -y update && \
|
||||
apt-get -y upgrade
|
||||
|
||||
ARG NODE_VERSION=20
|
||||
ARG NODE_VERSION=22
|
||||
RUN apt-get install -y ca-certificates curl gnupg
|
||||
RUN mkdir -p /etc/apt/keyrings
|
||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor --yes -o /etc/apt/keyrings/nodesource.gpg
|
||||
@@ -21,6 +21,7 @@ ENV SCRYPTED_INSTALL_ENVIRONMENT="docker"
|
||||
ENV SCRYPTED_CAN_RESTART="true"
|
||||
ENV SCRYPTED_VOLUME="/server/volume"
|
||||
ENV SCRYPTED_INSTALL_PATH="/server"
|
||||
ENV SHELL="/bin/bash"
|
||||
|
||||
RUN test -f "/usr/bin/python3" && test -f "/usr/bin/python3.12"
|
||||
ENV SCRYPTED_PYTHON_PATH="/usr/bin/python3"
|
||||
|
||||
50
install/docker/Dockerfile.router
Normal file
50
install/docker/Dockerfile.router
Normal file
@@ -0,0 +1,50 @@
|
||||
ARG BASE="noble-lite"
|
||||
FROM ghcr.io/koush/scrypted-common:${BASE}
|
||||
|
||||
# tools
|
||||
RUN apt -y update && apt -y install nano net-tools dnsutils dnsmasq vlan bridge-utils netplan.io nftables isc-dhcp-client
|
||||
RUN rm -f /etc/systemd/system/multi-user.target.wants/dnsmasq.service
|
||||
RUN rm -f /etc/systemd/system/sysinit.target.wants/systemd-resolved.service
|
||||
|
||||
# go + caddy
|
||||
RUN apt -y install golang-go
|
||||
RUN apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
||||
RUN curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
|
||||
RUN curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-xcaddy.list
|
||||
RUN apt -y update
|
||||
RUN apt -y install xcaddy
|
||||
RUN xcaddy build --with github.com/caddy-dns/cloudflare --output /usr/local/bin/caddy
|
||||
|
||||
# nftables
|
||||
COPY ./router/scrypted-nftables.service /etc/systemd/system
|
||||
RUN systemctl enable scrypted-nftables
|
||||
RUN bash -c 'echo include \"/etc/nftables.d/*.conf\"\; > /etc/nftables.conf'
|
||||
RUN mkdir -p /etc/nftables.d
|
||||
COPY ./router/01-scrypted.conf /etc/nftables.d
|
||||
|
||||
# ipv6 forwarding
|
||||
COPY ./router/scrypted-ip-forwarding.service /etc/systemd/system
|
||||
RUN systemctl enable scrypted-ip-forwarding
|
||||
|
||||
# install turn server, but disable it too set it up on a per interface basis.
|
||||
RUN apt -y update && apt -y install coturn && systemctl disable coturn && rm /usr/lib/systemd/system/coturn.service
|
||||
|
||||
# install usbmuxd for iphone tethering
|
||||
# ensure the pairing info stays in persistent storage
|
||||
RUN apt -y update && apt -y install usbmuxd && rm /usr/lib/systemd/system/usbmuxd.service && ln -sf /server/volume/plugins/\@scrypted/router/usbmuxd /var/lib/lockdown
|
||||
|
||||
WORKDIR /
|
||||
# cache bust
|
||||
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
|
||||
ARG SCRYPTED_INSTALL_VERSION="latest"
|
||||
RUN test -n "$SCRYPTED_INSTALL_VERSION"
|
||||
RUN npx -y scrypted@latest install-server ${SCRYPTED_INSTALL_VERSION}
|
||||
|
||||
COPY ./router/scrypted-dhcp-watcher.service /etc/systemd/system/scrypted-dhcp-watcher.service
|
||||
RUN systemctl enable scrypted-dhcp-watcher
|
||||
|
||||
COPY ./router/scrypted.service /etc/systemd/system/scrypted.service
|
||||
RUN systemctl enable scrypted
|
||||
|
||||
WORKDIR /
|
||||
CMD ["/sbin/init"]
|
||||
@@ -46,6 +46,6 @@ ENV NODE_OPTIONS="--dns-result-order=ipv4first"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20240321"
|
||||
ENV SCRYPTED_BASE_VERSION="20250101"
|
||||
|
||||
CMD ["/bin/sh", "-c", "ulimit -c 0; exec npm --prefix /server exec scrypted-serve"]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -x
|
||||
|
||||
NODE_VERSION=20
|
||||
NODE_VERSION=22
|
||||
SCRYPTED_INSTALL_VERSION=beta
|
||||
IMAGE_BASE=jammy
|
||||
FLAVOR=full
|
||||
|
||||
@@ -55,7 +55,7 @@ services:
|
||||
# Scrypted NVR Storage (Part 3 of 3)
|
||||
|
||||
# Modify to add the additional volume for Scrypted NVR.
|
||||
# The following example would mount the /mnt/sda/video path on the host
|
||||
# The following example would mount the /mnt/media/video path on the host
|
||||
# to the /nvr path inside the docker container.
|
||||
# - /mnt/media/video:/nvr
|
||||
|
||||
|
||||
@@ -34,8 +34,10 @@ set -e
|
||||
mkdir -p /tmp/amd
|
||||
cd /tmp/amd
|
||||
curl -O -L http://repo.radeon.com/amdgpu-install/latest/ubuntu/$distro/$FILENAME
|
||||
apt -y update
|
||||
apt -y install rsync
|
||||
dpkg -i $FILENAME
|
||||
apt -y update
|
||||
amdgpu-install --usecase=opencl --no-dkms -y --accept-eula
|
||||
cd /tmp
|
||||
rm -rf /tmp/amd
|
||||
|
||||
@@ -4,6 +4,25 @@ then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
UBUNTU_22_04=$(lsb_release -r | grep "22.04")
|
||||
UBUNTU_24_04=$(lsb_release -r | grep "24.04")
|
||||
|
||||
# needs either ubuntu 22.0.4 or 24.04
|
||||
if [ -z "$UBUNTU_22_04" ] && [ -z "$UBUNTU_24_04" ]
|
||||
then
|
||||
echo "Intel graphics package can not be installed. Ubuntu version could not be detected when checking lsb-release and /etc/os-release."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$UBUNTU_22_04" ]
|
||||
then
|
||||
distro="jammy"
|
||||
|
||||
else
|
||||
distro="noble"
|
||||
fi
|
||||
|
||||
# no errors beyond this point
|
||||
set -e
|
||||
|
||||
@@ -21,13 +40,26 @@ set -e
|
||||
|
||||
# need intel-media-va-driver-non-free, but all the other intel packages are installed from Intel github.
|
||||
echo "Installing Intel graphics packages."
|
||||
apt-get update && apt-get install -y gpg-agent &&
|
||||
rm -f /usr/share/keyrings/intel-graphics.gpg &&
|
||||
curl -L https://repositories.intel.com/graphics/intel-graphics.key | gpg --dearmor --yes --output /usr/share/keyrings/intel-graphics.gpg &&
|
||||
echo 'deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/graphics/ubuntu jammy arc' | tee /etc/apt/sources.list.d/intel.gpu.jammy.list &&
|
||||
apt-get -y update &&
|
||||
apt-get -y install intel-media-va-driver-non-free &&
|
||||
apt-get -y dist-upgrade;
|
||||
|
||||
if [ "$distro" == "jammy" ]
|
||||
then
|
||||
apt-get update && apt-get install -y gpg-agent &&
|
||||
rm -f /usr/share/keyrings/intel-graphics.gpg &&
|
||||
curl -L https://repositories.intel.com/graphics/intel-graphics.key | gpg --dearmor --yes --output /usr/share/keyrings/intel-graphics.gpg &&
|
||||
echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/graphics/ubuntu $distro arc" | tee /etc/apt/sources.list.d/intel.gpu.$distro.list &&
|
||||
apt-get -y update &&
|
||||
apt-get -y install intel-media-va-driver-non-free &&
|
||||
apt-get -y dist-upgrade;
|
||||
else
|
||||
apt-get update && apt-get install -y gpg-agent &&
|
||||
rm -f /usr/share/keyrings/intel-graphics.gpg &&
|
||||
curl -L https://repositories.intel.com/gpu/intel-graphics.key | gpg --dearmor --yes --output /usr/share/keyrings/intel-graphics.gpg &&
|
||||
echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu $distro unified" | tee /etc/apt/sources.list.d/intel-gpu-$distro.list &&
|
||||
apt-get -y update &&
|
||||
apt-get -y install intel-media-va-driver-non-free &&
|
||||
apt-get -y dist-upgrade;
|
||||
fi
|
||||
|
||||
|
||||
rm -rf /tmp/gpu && mkdir -p /tmp/gpu && cd /tmp/gpu
|
||||
|
||||
@@ -55,12 +87,13 @@ rm -f *.deb
|
||||
|
||||
# https://github.com/intel/compute-runtime/releases/tag/24.45.31740.9
|
||||
# note that at time of commit, IGC supports ubuntu 24.04 only possibly due to their builder being on 24.04.
|
||||
IGC_VERSION=2_2.1.12+18087_amd64
|
||||
COMPUTE_VERSION=24.45.31740.9
|
||||
ZERO_GPU_VERSION=1.6.31740.9_amd64
|
||||
LIBIGDGMM_VERSION=22.5.2_amd64
|
||||
curl -O -L https://github.com/intel/intel-graphics-compiler/releases/download/v2.1.12/intel-igc-core-$IGC_VERSION.deb
|
||||
curl -O -L https://github.com/intel/intel-graphics-compiler/releases/download/v2.1.12/intel-igc-opencl-$IGC_VERSION.deb
|
||||
IGC_BASE_VERSION=2.5.6
|
||||
IGC_VERSION=2_$IGC_BASE_VERSION+18417_amd64
|
||||
COMPUTE_VERSION=24.52.32224.5
|
||||
ZERO_GPU_VERSION=1.6.32224.5_amd64
|
||||
LIBIGDGMM_VERSION=22.5.5_amd64
|
||||
curl -O -L https://github.com/intel/intel-graphics-compiler/releases/download/v$IGC_BASE_VERSION/intel-igc-core-$IGC_VERSION.deb
|
||||
curl -O -L https://github.com/intel/intel-graphics-compiler/releases/download/v$IGC_BASE_VERSION/intel-igc-opencl-$IGC_VERSION.deb
|
||||
curl -O -L https://github.com/intel/compute-runtime/releases/download/$COMPUTE_VERSION/intel-level-zero-gpu-dbgsym_$ZERO_GPU_VERSION.ddeb
|
||||
curl -O -L https://github.com/intel/compute-runtime/releases/download/$COMPUTE_VERSION/intel-level-zero-gpu_$ZERO_GPU_VERSION.deb
|
||||
curl -O -L https://github.com/intel/compute-runtime/releases/download/$COMPUTE_VERSION/intel-opencl-icd-dbgsym_"$COMPUTE_VERSION"_amd64.ddeb
|
||||
|
||||
@@ -45,8 +45,8 @@ curl -O -L https://github.com/oneapi-src/level-zero/releases/download/v"$LEVEL_Z
|
||||
|
||||
# npu driver
|
||||
# https://github.com/intel/linux-npu-driver
|
||||
NPU_VERSION=1.10.0
|
||||
NPU_VERSION_DATE=20241107-11729849322
|
||||
NPU_VERSION=1.13.0
|
||||
NPU_VERSION_DATE=20250131-13074932693
|
||||
curl -O -L https://github.com/intel/linux-npu-driver/releases/download/v"$NPU_VERSION"/intel-driver-compiler-npu_$NPU_VERSION."$NPU_VERSION_DATE"_ubuntu$distro.deb
|
||||
# firmware can only be installed on host. will cause problems inside container.
|
||||
if [ -n "$INTEL_FW_NPU" ]
|
||||
|
||||
@@ -36,9 +36,8 @@ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --yes --dea
|
||||
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
||||
apt -y update
|
||||
# is there a way to get a versioned package automatically?
|
||||
apt -y install nvidia-utils-560
|
||||
apt -y install cuda-drivers
|
||||
apt -y install nvidia-container-toolkit
|
||||
|
||||
nvidia-ctk runtime configure --runtime=docker
|
||||
nvidia-ctk config --set nvidia-container-cli.no-cgroups --in-place
|
||||
systemctl restart docker
|
||||
|
||||
55
install/docker/router/01-scrypted.conf
Normal file
55
install/docker/router/01-scrypted.conf
Normal file
@@ -0,0 +1,55 @@
|
||||
table ip nat {
|
||||
chain POSTROUTING {
|
||||
type nat hook postrouting priority srcnat; policy accept;
|
||||
jump postrouting_scrypted
|
||||
}
|
||||
|
||||
chain postrouting_scrypted {
|
||||
}
|
||||
|
||||
chain PREROUTING {
|
||||
type nat hook prerouting priority dstnat; policy accept;
|
||||
jump prerouting_scrypted;
|
||||
}
|
||||
|
||||
chain prerouting_scrypted {
|
||||
}
|
||||
}
|
||||
|
||||
table ip filter {
|
||||
chain FORWARD {
|
||||
type filter hook forward priority filter; policy drop;
|
||||
jump forward_scrypted
|
||||
}
|
||||
|
||||
chain forward_scrypted {
|
||||
}
|
||||
}
|
||||
|
||||
table ip6 nat {
|
||||
chain POSTROUTING {
|
||||
type nat hook postrouting priority srcnat; policy accept;
|
||||
jump postrouting_scrypted
|
||||
}
|
||||
|
||||
chain postrouting_scrypted {
|
||||
}
|
||||
|
||||
chain PREROUTING {
|
||||
type nat hook prerouting priority dstnat; policy accept;
|
||||
jump prerouting_scrypted;
|
||||
}
|
||||
|
||||
chain prerouting_scrypted {
|
||||
}
|
||||
}
|
||||
|
||||
table ip6 filter {
|
||||
chain FORWARD {
|
||||
type filter hook forward priority filter; policy drop;
|
||||
jump forward_scrypted
|
||||
}
|
||||
|
||||
chain forward_scrypted {
|
||||
}
|
||||
}
|
||||
11
install/docker/router/scrypted-dhcp-watcher.service
Normal file
11
install/docker/router/scrypted-dhcp-watcher.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Scrypted DHCP Watcher
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/etc/dhcp/scrypted-dhcp-watcher
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
17
install/docker/router/scrypted-ip-forwarding.service
Normal file
17
install/docker/router/scrypted-ip-forwarding.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=ipv6 forwarding
|
||||
After=network.target
|
||||
Conflicts=shutdown.target
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
StandardInput=null
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
ExecStart=bash -c "sysctl -w net.ipv4.ip_forward=1 && sysctl -w net.ipv6.conf.all.forwarding=1 && sysctl -w net.ipv6.conf.default.forwarding=1"
|
||||
ExecReload=bash -c "sysctl -w net.ipv4.ip_forward=1 && sysctl -w net.ipv6.conf.all.forwarding=1 && sysctl -w net.ipv6.conf.default.forwarding=1"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
18
install/docker/router/scrypted-nftables.service
Normal file
18
install/docker/router/scrypted-nftables.service
Normal file
@@ -0,0 +1,18 @@
|
||||
[Unit]
|
||||
Description=nftables
|
||||
Documentation=man:nft(8) http://wiki.nftables.org
|
||||
After=network.target
|
||||
Conflicts=shutdown.target
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
StandardInput=null
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
ExecStart=/usr/sbin/nft -f /etc/nftables.conf
|
||||
ExecReload=/usr/sbin/nft -f /etc/nftables.conf
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
24
install/docker/router/scrypted.service
Normal file
24
install/docker/router/scrypted.service
Normal file
@@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=Scrypted
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/server
|
||||
ExecStart=/bin/sh -c "ulimit -c 0; exec npm exec scrypted-serve"
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
Environment="SCRYPTED_INSTALL_ENVIRONMENT=docker"
|
||||
Environment="SCRYPTED_CAN_RESTART=true"
|
||||
Environment="SCRYPTED_VOLUME=/server/volume"
|
||||
Environment="SCRYPTED_INSTALL_PATH=/server"
|
||||
Environment="SCRYPTED_PYTHON_PATH=/usr/bin/python3"
|
||||
Environment="SCRYPTED_PYTHON312_PATH=/usr/bin/python3.12"
|
||||
Environment="SCRYPTED_DOCKER_FLAVOR=lite"
|
||||
Environment="DEBIAN_FRONTEND=noninteractive"
|
||||
Environment="NODE_OPTIONS=--dns-result-order=ipv4first"
|
||||
Environment="SCRYPTED_BASE_VERSION=20250101"
|
||||
Environment="SHELL=/bin/bash"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -3,7 +3,7 @@
|
||||
# This common file will be used by both Docker and the linux
|
||||
# install script.
|
||||
################################################################
|
||||
ARG BASE="jammy"
|
||||
ARG BASE="noble"
|
||||
FROM ubuntu:${BASE} as header
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
@@ -16,7 +16,7 @@ RUN apt-get update && apt-get -y install \
|
||||
apt-get -y update && \
|
||||
apt-get -y upgrade
|
||||
|
||||
ARG NODE_VERSION=20
|
||||
ARG NODE_VERSION=22
|
||||
RUN apt-get install -y ca-certificates curl gnupg
|
||||
RUN mkdir -p /etc/apt/keyrings
|
||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor --yes -o /etc/apt/keyrings/nodesource.gpg
|
||||
|
||||
@@ -39,12 +39,16 @@ launchctl unload ~/Library/LaunchAgents/app.scrypted.server.plist || echo ""
|
||||
echo "Installing Scrypted dependencies..."
|
||||
RUN_IGNORE xcode-select --install
|
||||
RUN brew update
|
||||
RUN_IGNORE brew install node@20
|
||||
# dlib
|
||||
RUN brew install cmake
|
||||
|
||||
# seems to be necessary for python-codecs' pycairo dependency or something?
|
||||
RUN_IGNORE gobject-introspection libffi pkg-config
|
||||
# in sequoia, brew node is unusable because it is not signed and can't access local network unless run as root.
|
||||
# https://developer.apple.com/forums/thread/766270
|
||||
# RUN_IGNORE brew install node@20
|
||||
# NODE_PATH=$(brew --prefix node@20)
|
||||
# NODE_BIN_PATH=$NODE_PATH/bin
|
||||
RUN_IGNORE curl -L https://nodejs.org/dist/v22.14.0/node-v22.14.0.pkg -o /tmp/node.pkg
|
||||
RUN_IGNORE sudo installer -pkg /tmp/node.pkg -target /
|
||||
NODE_PATH=/usr/local # used to pass var test
|
||||
NODE_BIN_PATH=/usr/local/bin
|
||||
|
||||
# gstreamer plugins
|
||||
RUN_IGNORE brew install gstreamer
|
||||
@@ -82,14 +86,12 @@ echo "Installing Scrypted Launch Agent..."
|
||||
|
||||
RUN mkdir -p ~/Library/LaunchAgents
|
||||
|
||||
NODE_PATH=$(brew --prefix node@20)
|
||||
if [ ! -d "$NODE_PATH" ]
|
||||
then
|
||||
echo "Unable to determine node@20 path."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NODE_BIN_PATH=$NODE_PATH/bin
|
||||
if [ ! -d "$NODE_BIN_PATH" ]
|
||||
then
|
||||
echo "Unable to determine node@20 bin path."
|
||||
@@ -155,7 +157,7 @@ cat > ~/Library/LaunchAgents/app.scrypted.server.plist <<EOT
|
||||
<key>NODE_OPTIONS</key>
|
||||
<string>$NODE_OPTIONS</string>
|
||||
<key>PATH</key>
|
||||
<string>$NODE_BIN_PATH:$PYTHON_BIN_PATH:$BREW_PREFIX/bin:$BREW_PREFIX/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
||||
<string>$PYTHON_BIN_PATH:$NODE_BIN_PATH:$BREW_PREFIX/bin:$BREW_PREFIX/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
||||
<key>HOME</key>
|
||||
<string>/Users/$USER</string>
|
||||
<key>SCRYPTED_PYTHON_PATH</key>
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
#Requires -RunAsAdministrator
|
||||
# Check if the script is running as administrator
|
||||
$IsAdmin = [System.Security.Principal.WindowsPrincipal] [System.Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$AdminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
|
||||
|
||||
if (-not $IsAdmin.IsInRole($AdminRole)) {
|
||||
# If not, relaunch the script with elevated privileges
|
||||
$ScriptPath = $PSCommandPath
|
||||
Start-Process powershell -ArgumentList "-File `"$ScriptPath`"" -Verb RunAs
|
||||
exit
|
||||
}
|
||||
|
||||
# Set-PSDebug -Trace 1
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ function readyn() {
|
||||
}
|
||||
|
||||
cd /tmp
|
||||
SCRYPTED_VERSION=v0.120.0
|
||||
SCRYPTED_VERSION=v0.137.0
|
||||
SCRYPTED_TAR_ZST=scrypted-$SCRYPTED_VERSION.tar.zst
|
||||
if [ -z "$VMID" ]
|
||||
then
|
||||
@@ -139,7 +139,12 @@ then
|
||||
echo "#############################################################################"
|
||||
echo -e "\033[32mPaste the following command into this shell to install to local-lvm instead:\033[0m"
|
||||
echo ""
|
||||
echo "bash $0 --storage local-lvm"
|
||||
if [ -n "$SCRYPTED_RESTORE" ]
|
||||
then
|
||||
echo "bash $0 --storage local-lvm"
|
||||
else
|
||||
echo "SCRYPTED_RESTORE=true bash $0 --storage local-lvm"
|
||||
fi
|
||||
echo "#############################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
@@ -27,7 +27,7 @@ echo "external/werift > npm install"
|
||||
npm install
|
||||
popd
|
||||
|
||||
for directory in rtsp amcrest onvif hikvision reolink unifi-protect webrtc homekit
|
||||
for directory in rtsp ffmpeg-camera amcrest onvif hikvision reolink unifi-protect webrtc homekit
|
||||
do
|
||||
echo "$directory > npm install"
|
||||
pushd plugins/$directory
|
||||
|
||||
312
packages/cli/package-lock.json
generated
312
packages/cli/package-lock.json
generated
@@ -9,23 +9,23 @@
|
||||
"version": "1.3.20",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/client": "^1.3.3",
|
||||
"@scrypted/types": "^0.3.30",
|
||||
"engine.io-client": "^6.5.3",
|
||||
"@scrypted/client": "^1.3.13",
|
||||
"@scrypted/types": "^0.5.9",
|
||||
"engine.io-client": "^6.6.3",
|
||||
"readline-sync": "^1.4.10",
|
||||
"semver": "^7.5.4",
|
||||
"tslib": "^2.6.2"
|
||||
"semver": "^7.7.1",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted": "dist/packages/cli/src/main.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.9.4",
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/readline-sync": "^1.4.8",
|
||||
"@types/semver": "^7.5.6",
|
||||
"rimraf": "^5.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.3.2"
|
||||
"@types/semver": "^7.5.8",
|
||||
"rimraf": "^6.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.8.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
@@ -44,6 +44,7 @@
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
@@ -81,30 +82,24 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/client": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/client/-/client-1.3.3.tgz",
|
||||
"integrity": "sha512-Wuy7x02TCRy1buaDNX8NOIaL1j4ZXu4dqTTJsKHlPe3+umsBvpwbylD+YyyU8ghQJC6a40Bs5UMsvnCvNa/1fg==",
|
||||
"version": "1.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/client/-/client-1.3.13.tgz",
|
||||
"integrity": "sha512-jxXnGCoHIwuB7PobPJyqYy9THljR2UJOILxO++HiNq/i0nqRUECYvVfU5frN/ZnP6nmQoiRKrl8ErGWVBT7ecg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/types": "^0.3.4",
|
||||
"engine.io-client": "^6.5.3",
|
||||
"follow-redirects": "^1.15.4",
|
||||
"rimraf": "^5.0.5"
|
||||
"engine.io-client": "^6.6.3",
|
||||
"follow-redirects": "^1.15.9",
|
||||
"rimraf": "^6.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@scrypted/types": "^0.5.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/types": {
|
||||
"version": "0.3.30",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.3.30.tgz",
|
||||
"integrity": "sha512-1k+JVSR6WSNmE/5mLdqfrTmV3uRbvZp0OwKb8ikNi39ysBuC000tQGcEdXZqhYqRgWdhDTWtxXe9XsYoAZGKmA==",
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.5.9.tgz",
|
||||
"integrity": "sha512-Qt/gLdzDqYwgOArpLrEErPb91mhAOmN0NFFOFwX9G/5vSV5Xvm6ixQhPWF4f+up3G9ecPVPMPtZCsWmhxAD1hA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
@@ -137,12 +132,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.4.tgz",
|
||||
"integrity": "sha512-wmyg8HUhcn6ACjsn8oKYjkN/zUzQeNtMy44weTJSM6p4MMzEOuKbA3OjJ267uPCOW7Xex9dyrNTful8XTQYoDA==",
|
||||
"version": "22.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
|
||||
"integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/readline-sync": {
|
||||
@@ -152,10 +148,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
|
||||
"integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==",
|
||||
"dev": true
|
||||
"version": "7.5.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
|
||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.8.2",
|
||||
@@ -179,9 +176,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -193,6 +191,7 @@
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -209,12 +208,14 @@
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -223,6 +224,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -233,7 +235,8 @@
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
@@ -242,9 +245,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -282,23 +286,26 @@
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/engine.io-client": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
|
||||
"integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
|
||||
"version": "6.6.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz",
|
||||
"integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.2.1",
|
||||
"ws": "~8.11.0",
|
||||
"xmlhttprequest-ssl": "~2.0.0"
|
||||
"ws": "~8.17.1",
|
||||
"xmlhttprequest-ssl": "~2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-parser": {
|
||||
@@ -310,15 +317,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
@@ -329,11 +337,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
|
||||
"integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
"cross-spawn": "^7.0.6",
|
||||
"signal-exit": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -344,21 +353,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "10.3.10",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
|
||||
"integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
|
||||
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^2.3.5",
|
||||
"minimatch": "^9.0.1",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
|
||||
"path-scurry": "^1.10.1"
|
||||
"jackspeak": "^4.0.1",
|
||||
"minimatch": "^10.0.0",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
@@ -368,6 +379,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -375,34 +387,31 @@
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
|
||||
"integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz",
|
||||
"integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
|
||||
"integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
@@ -412,23 +421,25 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
|
||||
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
|
||||
"integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
@@ -438,37 +449,37 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
|
||||
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^9.1.1 || ^10.0.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
"lru-cache": "^11.0.0",
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/path-scurry/node_modules/lru-cache": {
|
||||
"version": "10.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.3.tgz",
|
||||
"integrity": "sha512-B7gr+F6MkqB3uzINHXNctGieGsRTMwIBgxkp0yq/5BwcuDzD4A8wQpHQW6vDAm1uKSLQghmRdD9sKqf2vJ1cEg==",
|
||||
"engines": {
|
||||
"node": "14 || >=16.14"
|
||||
}
|
||||
},
|
||||
"node_modules/readline-sync": {
|
||||
"version": "1.4.10",
|
||||
"resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
|
||||
@@ -478,29 +489,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
|
||||
"integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
|
||||
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^10.3.7"
|
||||
"glob": "^11.0.0",
|
||||
"package-json-from-dist": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -512,6 +523,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
@@ -523,6 +535,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -531,6 +544,7 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
@@ -542,6 +556,7 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
@@ -559,6 +574,7 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -572,6 +588,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -579,12 +596,14 @@
|
||||
"node_modules/string-width-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/string-width-cjs/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -596,6 +615,7 @@
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
@@ -611,6 +631,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -622,15 +643,17 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
@@ -670,15 +693,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz",
|
||||
"integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==",
|
||||
"version": "5.8.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
|
||||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -688,10 +713,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
@@ -703,6 +729,7 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
@@ -717,6 +744,7 @@
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
@@ -734,6 +762,7 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
@@ -750,6 +779,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -758,6 +788,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -771,12 +802,14 @@
|
||||
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -790,6 +823,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -798,15 +832,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
@@ -818,18 +853,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/xmlhttprequest-ssl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
|
||||
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
|
||||
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
|
||||
@@ -16,19 +16,19 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/client": "^1.3.3",
|
||||
"@scrypted/types": "^0.3.30",
|
||||
"engine.io-client": "^6.5.3",
|
||||
"@scrypted/client": "^1.3.13",
|
||||
"@scrypted/types": "^0.5.9",
|
||||
"engine.io-client": "^6.6.3",
|
||||
"readline-sync": "^1.4.10",
|
||||
"semver": "^7.5.4",
|
||||
"tslib": "^2.6.2"
|
||||
"semver": "^7.7.1",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.9.4",
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/readline-sync": "^1.4.8",
|
||||
"@types/semver": "^7.5.6",
|
||||
"rimraf": "^5.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.3.2"
|
||||
"@types/semver": "^7.5.8",
|
||||
"rimraf": "^6.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,8 +166,6 @@ async function main() {
|
||||
}
|
||||
}
|
||||
const args = ffmpegInput.inputArguments ? [...ffmpegInput.inputArguments] : [];
|
||||
if (ffmpegInput.h264FilterArguments)
|
||||
args.push(...ffmpegInput.h264FilterArguments);
|
||||
console.log('ffplay', ...args);
|
||||
child_process.spawn('ffplay', args, {
|
||||
stdio: 'inherit',
|
||||
|
||||
@@ -7,7 +7,7 @@ export async function connectShell(sdk: ScryptedStatic, ...cmd: string[]) {
|
||||
throw Error("@scrypted/core does not provide a Terminal Service");
|
||||
}
|
||||
|
||||
const termSvcDirect = await sdk.connectRPCObject<StreamService>(termSvc);
|
||||
const termSvcDirect = await sdk.connectRPCObject<StreamService<Buffer|string, Buffer>>(termSvc);
|
||||
const dataQueue = createAsyncQueue<Buffer>();
|
||||
const ctrlQueue = createAsyncQueue<any>();
|
||||
|
||||
|
||||
252
packages/client/package-lock.json
generated
252
packages/client/package-lock.json
generated
@@ -1,25 +1,27 @@
|
||||
{
|
||||
"name": "@scrypted/client",
|
||||
"version": "1.3.9",
|
||||
"version": "1.3.13",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/client",
|
||||
"version": "1.3.9",
|
||||
"version": "1.3.13",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/types": "^0.3.92",
|
||||
"engine.io-client": "^6.6.1",
|
||||
"engine.io-client": "^6.6.3",
|
||||
"follow-redirects": "^1.15.9",
|
||||
"rimraf": "^6.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/node": "^22.7.4",
|
||||
"@types/ws": "^8.5.13",
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/ws": "^8.18.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@scrypted/types": "^0.5.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
@@ -27,6 +29,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
@@ -38,6 +41,7 @@
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
@@ -51,87 +55,98 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
|
||||
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"dev": true
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/types": {
|
||||
"version": "0.3.92",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.3.92.tgz",
|
||||
"integrity": "sha512-/M1Lg42/yoFWusj5+Lyp2S0JCiWDDWcmsjiUnTf1DahZ6/M2oZ3bwR/0KX3D9vJE79owWST1Gm0+Rdvpxuil9A==",
|
||||
"license": "ISC"
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.5.12.tgz",
|
||||
"integrity": "sha512-nTwcMHZyH3nXThL22eNcVw7OjSyL5qoTgUay6K7y43HKz1mBnFEmIUkW8eLdyP4nbpwwA0b60MOPDKZVnssB0Q==",
|
||||
"license": "ISC",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
"dev": true
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ip": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/ip/-/ip-1.1.3.tgz",
|
||||
"integrity": "sha512-64waoJgkXFTYnCYDUWgSATJ/dXEBanVkaP5d4Sbk7P6U7cTTMhxVyROTckc6JKdwCrgnAjZMn0k3177aQxtDEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
|
||||
"integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
|
||||
"version": "22.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
|
||||
"integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
|
||||
"integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==",
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -139,10 +154,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -151,10 +167,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz",
|
||||
"integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==",
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -163,6 +183,7 @@
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -174,6 +195,7 @@
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -185,17 +207,20 @@
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -204,6 +229,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -214,13 +240,15 @@
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
@@ -237,11 +265,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
@@ -257,6 +286,7 @@
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
@@ -264,17 +294,20 @@
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/engine.io-client": {
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.1.tgz",
|
||||
"integrity": "sha512-aYuoak7I+R83M/BBPIOs2to51BmFIpC1wZe6zZzMrT2llVsHy5cvcmdsJgP2Qz6smHu+sD9oexiSUAVd8OfBPw==",
|
||||
"version": "6.6.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz",
|
||||
"integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1",
|
||||
@@ -284,9 +317,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-parser": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
|
||||
"integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
@@ -301,6 +335,7 @@
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
@@ -311,11 +346,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
|
||||
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
"cross-spawn": "^7.0.6",
|
||||
"signal-exit": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -326,9 +362,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz",
|
||||
"integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
|
||||
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^4.0.1",
|
||||
@@ -351,6 +388,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -358,12 +396,14 @@
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
|
||||
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz",
|
||||
"integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
@@ -375,9 +415,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz",
|
||||
"integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==",
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
|
||||
"integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
@@ -386,12 +427,14 @@
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
|
||||
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
@@ -406,24 +449,28 @@
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -432,6 +479,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^11.0.0",
|
||||
"minipass": "^7.1.2"
|
||||
@@ -447,6 +495,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
|
||||
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^11.0.0",
|
||||
"package-json-from-dist": "^1.0.0"
|
||||
@@ -465,6 +514,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
@@ -476,6 +526,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -484,6 +535,7 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
@@ -495,6 +547,7 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
@@ -512,6 +565,7 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -525,6 +579,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -532,12 +587,14 @@
|
||||
"node_modules/string-width-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/string-width-cjs/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -549,6 +606,7 @@
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
@@ -564,6 +622,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -575,6 +634,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -584,6 +644,7 @@
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
@@ -623,10 +684,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
|
||||
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
|
||||
"version": "5.8.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
|
||||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -636,21 +698,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
@@ -665,6 +730,7 @@
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
@@ -682,6 +748,7 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
@@ -698,6 +765,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -706,6 +774,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -719,12 +788,14 @@
|
||||
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -738,6 +809,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -749,6 +821,7 @@
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
@@ -766,9 +839,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/xmlhttprequest-ssl": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.1.tgz",
|
||||
"integrity": "sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
|
||||
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -778,6 +851,7 @@
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/client",
|
||||
"version": "1.3.9",
|
||||
"version": "1.3.13",
|
||||
"description": "",
|
||||
"main": "dist/packages/client/src/index.js",
|
||||
"scripts": {
|
||||
@@ -13,14 +13,16 @@
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/node": "^22.7.4",
|
||||
"@types/ws": "^8.5.13",
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/ws": "^8.18.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@scrypted/types": "^0.5.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scrypted/types": "^0.3.92",
|
||||
"engine.io-client": "^6.6.1",
|
||||
"engine.io-client": "^6.6.3",
|
||||
"follow-redirects": "^1.15.9",
|
||||
"rimraf": "^6.0.1"
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ export async function connectScryptedClient(options: ScryptedClientOptions): Pro
|
||||
|
||||
check.on('message', data => {
|
||||
if (data.constructor === Buffer || data.constructor === ArrayBuffer) {
|
||||
serializer.onMessageBuffer(Buffer.from(data));
|
||||
serializer.onMessageBuffer(Buffer.from(data as string));
|
||||
}
|
||||
else {
|
||||
serializer.onMessageFinish(JSON.parse(data as string));
|
||||
@@ -683,7 +683,7 @@ export async function connectScryptedClient(options: ScryptedClientOptions): Pro
|
||||
});
|
||||
socket.on('message', data => {
|
||||
if (data.constructor === Buffer || data.constructor === ArrayBuffer) {
|
||||
serializer.onMessageBuffer(Buffer.from(data));
|
||||
serializer.onMessageBuffer(Buffer.from(data as string));
|
||||
}
|
||||
else {
|
||||
serializer.onMessageFinish(JSON.parse(data as string));
|
||||
|
||||
2
plugins/alexa/.vscode/settings.json
vendored
2
plugins/alexa/.vscode/settings.json
vendored
@@ -1,4 +1,4 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
"scrypted.debugHost": "scrypted-server",
|
||||
}
|
||||
@@ -1,6 +1,21 @@
|
||||
<details>
|
||||
<summary>Changelog</summary>
|
||||
|
||||
### 0.3.6
|
||||
|
||||
alexa: maybe fix alexa when no detection types are available
|
||||
|
||||
|
||||
### 0.3.4
|
||||
|
||||
Alexa: add option to not auto enable devices (#1615)
|
||||
|
||||
|
||||
### 0.3.3
|
||||
|
||||
google-home/alexa: republish with new sdk for media converter
|
||||
|
||||
|
||||
### 0.3.2
|
||||
|
||||
alexa: fix syncedDevices being undefined
|
||||
|
||||
70
plugins/alexa/package-lock.json
generated
70
plugins/alexa/package-lock.json
generated
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/alexa",
|
||||
"version": "0.3.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/alexa",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.7",
|
||||
"dependencies": {
|
||||
"axios": "^1.3.4",
|
||||
"uuid": "^9.0.0"
|
||||
@@ -14,7 +15,7 @@
|
||||
"@scrypted/common": "../../common",
|
||||
"@scrypted/sdk": "../../sdk",
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/node": "^18.4.2"
|
||||
"@types/node": "^22.13.11"
|
||||
}
|
||||
},
|
||||
"../../common": {
|
||||
@@ -24,35 +25,41 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.5",
|
||||
"version": "0.5.10",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-changelog": "bin/scrypted-changelog.js",
|
||||
@@ -64,11 +71,9 @@
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21"
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.26.11"
|
||||
}
|
||||
},
|
||||
"../common": {
|
||||
@@ -98,10 +103,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz",
|
||||
"integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==",
|
||||
"dev": true
|
||||
"version": "22.13.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz",
|
||||
"integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
@@ -193,6 +202,13 @@
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||
@@ -202,4 +218,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/alexa",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.7",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
"prescrypted-setup-project": "scrypted-package-json",
|
||||
@@ -42,6 +42,6 @@
|
||||
"@scrypted/common": "../../common",
|
||||
"@scrypted/sdk": "../../sdk",
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/node": "^18.4.2"
|
||||
"@types/node": "^22.13.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,17 +660,26 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
|
||||
|
||||
const deviceHandler = alexaDeviceHandlers.get(mapName);
|
||||
|
||||
if (deviceHandler) {
|
||||
const getDevice = () => {
|
||||
const device = systemManager.getDeviceById(directive.endpoint.endpointId);
|
||||
if (!device) {
|
||||
response.send(deviceErrorResponse("NO_SUCH_ENDPOINT", "The device doesn't exist in Scrypted", directive));
|
||||
if (!device || !device.mixins.includes(this.id)) {
|
||||
response.send(deviceErrorResponse("NO_SUCH_ENDPOINT", "The device doesn't exist in Scrypted or was removed from the Alexa Plugin", directive));
|
||||
this.deleteEndpoints(directive.endpoint.endpointId).catch(() => { });
|
||||
return;
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
if (deviceHandler) {
|
||||
const device = getDevice();
|
||||
if (!device)
|
||||
return;
|
||||
await deviceHandler.apply(this, [request, response, directive, device]);
|
||||
return;
|
||||
} else {
|
||||
this.console.error(`no handler for: ${mapName}`);
|
||||
if (!getDevice())
|
||||
return;
|
||||
}
|
||||
|
||||
// it is better to send a non-specific response than an error, as the API might get rate throttled
|
||||
@@ -718,6 +727,9 @@ class HttpResponseLoggingImpl implements AlexaHttpResponse {
|
||||
sendSocket(socket: any, options: HttpResponseOptions): void {
|
||||
this.response.sendSocket(socket, options);
|
||||
}
|
||||
sendStream(stream: AsyncGenerator<Buffer, void>, options?: HttpResponseOptions): void {
|
||||
this.response.sendStream(stream, options);
|
||||
}
|
||||
}
|
||||
|
||||
export default AlexaPlugin;
|
||||
|
||||
@@ -126,68 +126,69 @@ export async function getCameraCapabilities(device: ScryptedDevice): Promise<Dis
|
||||
];
|
||||
|
||||
if (device.interfaces.includes(ScryptedInterface.ObjectDetector)) {
|
||||
const detectionTypes = await (device as any as ObjectDetector).getObjectTypes();
|
||||
const classNames = detectionTypes.classes.filter(t => t !== 'ring' && t !== 'motion').map(type => type.toLowerCase());
|
||||
|
||||
capabilities.push(
|
||||
{
|
||||
"type": "AlexaInterface",
|
||||
"interface": "Alexa.SmartVision.ObjectDetectionSensor",
|
||||
"version": "1.0",
|
||||
"properties": {
|
||||
"supported": [{
|
||||
"name": "objectDetectionClasses"
|
||||
}],
|
||||
"proactivelyReported": true,
|
||||
"retrievable": true
|
||||
},
|
||||
"configuration": {
|
||||
"objectDetectionConfiguration": classNames.map(type => ({
|
||||
"imageNetClass": type
|
||||
}))
|
||||
}
|
||||
} as DiscoveryCapability
|
||||
);
|
||||
|
||||
capabilities.push(
|
||||
{
|
||||
"type": "AlexaInterface",
|
||||
"interface": "Alexa.DataController",
|
||||
"instance": "Camera.SmartVisionData",
|
||||
"version": "1.0",
|
||||
"properties": undefined,
|
||||
"configuration": {
|
||||
"targetCapability": {
|
||||
"name": "Alexa.SmartVision.ObjectDetectionSensor",
|
||||
"version": "1.0"
|
||||
const detectionTypes = await (device as any as ObjectDetector).getObjectTypes().catch(() => {}) || undefined;
|
||||
const classNames = detectionTypes?.classes?.filter(t => t !== 'ring' && t !== 'motion').map(type => type.toLowerCase()).filter(c => !!c);
|
||||
if (classNames?.length) {
|
||||
capabilities.push(
|
||||
{
|
||||
"type": "AlexaInterface",
|
||||
"interface": "Alexa.SmartVision.ObjectDetectionSensor",
|
||||
"version": "1.0",
|
||||
"properties": {
|
||||
"supported": [{
|
||||
"name": "objectDetectionClasses"
|
||||
}],
|
||||
"proactivelyReported": true,
|
||||
"retrievable": true
|
||||
},
|
||||
"dataRetrievalSchema": {
|
||||
"type": "JSON",
|
||||
"schema": "SmartVisionData"
|
||||
},
|
||||
"supportedAccess": ["BY_IDENTIFIER", "BY_TIMESTAMP_RANGE"]
|
||||
}
|
||||
} as DiscoveryCapability
|
||||
);
|
||||
}
|
||||
|
||||
if (device.interfaces.includes(ScryptedInterface.MotionSensor)) {
|
||||
capabilities.push(
|
||||
{
|
||||
"type": "AlexaInterface",
|
||||
"interface": "Alexa.MotionSensor",
|
||||
"version": "3",
|
||||
"properties": {
|
||||
"supported": [
|
||||
{
|
||||
"name": "detectionState"
|
||||
}
|
||||
],
|
||||
"proactivelyReported": true,
|
||||
"retrievable": true
|
||||
}
|
||||
} as DiscoveryCapability
|
||||
);
|
||||
"configuration": {
|
||||
"objectDetectionConfiguration": classNames.map(type => ({
|
||||
"imageNetClass": type
|
||||
}))
|
||||
}
|
||||
} as DiscoveryCapability
|
||||
);
|
||||
|
||||
capabilities.push(
|
||||
{
|
||||
"type": "AlexaInterface",
|
||||
"interface": "Alexa.DataController",
|
||||
"instance": "Camera.SmartVisionData",
|
||||
"version": "1.0",
|
||||
"properties": undefined,
|
||||
"configuration": {
|
||||
"targetCapability": {
|
||||
"name": "Alexa.SmartVision.ObjectDetectionSensor",
|
||||
"version": "1.0"
|
||||
},
|
||||
"dataRetrievalSchema": {
|
||||
"type": "JSON",
|
||||
"schema": "SmartVisionData"
|
||||
},
|
||||
"supportedAccess": ["BY_IDENTIFIER", "BY_TIMESTAMP_RANGE"]
|
||||
}
|
||||
} as DiscoveryCapability
|
||||
);
|
||||
}
|
||||
|
||||
if (device.interfaces.includes(ScryptedInterface.MotionSensor)) {
|
||||
capabilities.push(
|
||||
{
|
||||
"type": "AlexaInterface",
|
||||
"interface": "Alexa.MotionSensor",
|
||||
"version": "3",
|
||||
"properties": {
|
||||
"supported": [
|
||||
{
|
||||
"name": "detectionState"
|
||||
}
|
||||
],
|
||||
"proactivelyReported": true,
|
||||
"retrievable": true
|
||||
}
|
||||
} as DiscoveryCapability
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface SupportedType {
|
||||
setState?(device: ScryptedDevice, payload: any): Promise<Partial<Report>>;
|
||||
}
|
||||
|
||||
export const supportedTypes = new Map<ScryptedDeviceType, SupportedType>();
|
||||
export const supportedTypes = new Map<ScryptedDeviceType | string, SupportedType>();
|
||||
|
||||
import '../handlers';
|
||||
import './camera';
|
||||
|
||||
2
plugins/amcrest/.vscode/settings.json
vendored
2
plugins/amcrest/.vscode/settings.json
vendored
@@ -1,4 +1,4 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
"scrypted.debugHost": "scrypted-nvr",
|
||||
}
|
||||
92
plugins/amcrest/package-lock.json
generated
92
plugins/amcrest/package-lock.json
generated
@@ -1,21 +1,23 @@
|
||||
{
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.164",
|
||||
"version": "0.0.165",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.164",
|
||||
"version": "0.0.165",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"content-type": "^1.0.5"
|
||||
"content-type": "^1.0.5",
|
||||
"xml2js": "^0.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/content-type": "^1.1.8",
|
||||
"@types/node": "^20.11.30"
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/xml2js": "^0.4.14"
|
||||
}
|
||||
},
|
||||
"../../common": {
|
||||
@@ -24,34 +26,40 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.29",
|
||||
"version": "0.3.114",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-changelog": "bin/scrypted-changelog.js",
|
||||
@@ -63,11 +71,9 @@
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21"
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.26.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/common": {
|
||||
@@ -93,6 +99,16 @@
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/xml2js": {
|
||||
"version": "0.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz",
|
||||
"integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/content-type": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||
@@ -101,11 +117,39 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/xml2js": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
|
||||
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.164",
|
||||
"version": "0.0.165",
|
||||
"description": "Amcrest Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
@@ -39,10 +39,12 @@
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"content-type": "^1.0.5"
|
||||
"content-type": "^1.0.5",
|
||||
"xml2js": "^0.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/content-type": "^1.1.8",
|
||||
"@types/node": "^20.11.30"
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/xml2js": "^0.4.14"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { automaticallyConfigureSettings, checkPluginNeedsAutoConfigure } from "@scrypted/common/src/autoconfigure-codecs";
|
||||
import { ffmpegLogInitialOutput } from '@scrypted/common/src/media-helpers';
|
||||
import { readLength } from "@scrypted/common/src/read-stream";
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, Lock, MediaObject, MediaStreamOptions, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, Reboot, RequestPictureOptions, RequestRecordingStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, VideoCameraConfiguration, VideoRecorder } from "@scrypted/sdk";
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, Lock, MediaObject, MediaStreamOptions, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, Reboot, RequestPictureOptions, RequestRecordingStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, VideoCameraConfiguration, VideoRecorder, VideoTextOverlay, VideoTextOverlays } from "@scrypted/sdk";
|
||||
import child_process, { ChildProcess } from 'child_process';
|
||||
import { PassThrough, Readable, Stream } from "stream";
|
||||
import { OnvifIntercom } from "../../onvif/src/onvif-intercom";
|
||||
import { createRtspMediaStreamOptions, RtspProvider, RtspSmartCamera, UrlMediaStreamOptions } from "../../rtsp/src/rtsp";
|
||||
import { AmcrestCameraClient, AmcrestEvent, AmcrestEventData } from "./amcrest-api";
|
||||
import { amcrestAutoConfigureSettings, autoconfigureSettings } from "./amcrest-configure";
|
||||
import { group } from "console";
|
||||
|
||||
const { mediaManager } = sdk;
|
||||
|
||||
@@ -23,7 +22,7 @@ const rtspChannelSetting: Setting = {
|
||||
placeholder: '1',
|
||||
};
|
||||
|
||||
class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration, Camera, Intercom, Lock, VideoRecorder, Reboot, ObjectDetector {
|
||||
class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration, Camera, Intercom, Lock, VideoRecorder, Reboot, ObjectDetector, VideoTextOverlays {
|
||||
eventStream: Stream;
|
||||
cp: ChildProcess;
|
||||
client: AmcrestCameraClient;
|
||||
@@ -43,6 +42,92 @@ class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration,
|
||||
this.updateDeviceInfo();
|
||||
}
|
||||
|
||||
async getVideoTextOverlays(): Promise<Record<string, VideoTextOverlay>> {
|
||||
const client = this.getClient();
|
||||
const response = await client.request({
|
||||
method: "GET",
|
||||
url: `http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=getConfig&name=VideoWidget`,
|
||||
responseType: "text",
|
||||
headers: {
|
||||
"Content-Type": "application/xml",
|
||||
},
|
||||
});
|
||||
const body: string = response.body;
|
||||
if (!body.startsWith("<")) {
|
||||
const encodeBlend = '.EncodeBlend';
|
||||
const config: Record<string, VideoTextOverlay> = {};
|
||||
|
||||
for (const line of body.split(/\r?\n/).filter(l => l.includes(encodeBlend + '='))) {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed) continue;
|
||||
const splitIndex = trimmed.indexOf("=");
|
||||
if (splitIndex === -1) continue;
|
||||
// remove encodeBlend
|
||||
let key = trimmed.substring(0, splitIndex);
|
||||
key = key.substring(0, key.length - encodeBlend.length);
|
||||
config[key] = {
|
||||
readonly: true,
|
||||
};
|
||||
}
|
||||
|
||||
const textValue = '.Text';
|
||||
|
||||
for (const line of body.split(/\r?\n/).filter(l => l.includes(textValue + '='))) {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed) continue;
|
||||
const splitIndex = trimmed.indexOf("=");
|
||||
if (splitIndex === -1) continue;
|
||||
// remove encodeBlend
|
||||
let key = trimmed.substring(0, splitIndex);
|
||||
key = key.substring(0, key.length - textValue.length);
|
||||
const text = trimmed.substring(splitIndex + 1).trim();
|
||||
const c = config[key];
|
||||
if (!c)
|
||||
continue;
|
||||
delete c.readonly;
|
||||
c.text = text;
|
||||
}
|
||||
|
||||
return config;
|
||||
} else {
|
||||
throw new Error('invalid response');
|
||||
// const json = await xml2js.parseStringPromise(body);
|
||||
// return { json, xml: body };
|
||||
}
|
||||
}
|
||||
|
||||
async setVideoTextOverlay(id: string, value: VideoTextOverlay): Promise<void> {
|
||||
// trim the table. off id
|
||||
if (id.startsWith('table.'))
|
||||
id = id.substring('table.'.length);
|
||||
const client = this.getClient();
|
||||
if (value.text) {
|
||||
const enableUrl = `http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=setConfig&${id}.EncodeBlend=true&${id}.PreviewBlend=true`;
|
||||
await client.request({
|
||||
method: "GET",
|
||||
url: enableUrl,
|
||||
responseType: "text",
|
||||
});
|
||||
|
||||
const textUrl = `http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=setConfig&${id}.Text=${encodeURIComponent(
|
||||
value.text
|
||||
)}`;
|
||||
await client.request({
|
||||
method: "GET",
|
||||
url: textUrl,
|
||||
responseType: "text",
|
||||
});
|
||||
}
|
||||
else {
|
||||
const disableUrl = `http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=setConfig&${id}.EncodeBlend=false&${id}.PreviewBlend=false`;
|
||||
await client.request({
|
||||
method: "GET",
|
||||
url: disableUrl,
|
||||
responseType: "text",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async reboot() {
|
||||
const client = this.getClient();
|
||||
await client.reboot();
|
||||
@@ -631,6 +716,7 @@ class AmcrestProvider extends RtspProvider {
|
||||
ScryptedInterface.Camera,
|
||||
ScryptedInterface.AudioSensor,
|
||||
ScryptedInterface.MotionSensor,
|
||||
ScryptedInterface.VideoTextOverlays,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
4
plugins/cloud/package-lock.json
generated
4
plugins/cloud/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/cloud",
|
||||
"version": "0.2.48",
|
||||
"version": "0.2.49",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/cloud",
|
||||
"version": "0.2.48",
|
||||
"version": "0.2.49",
|
||||
"dependencies": {
|
||||
"@eneris/push-receiver": "^4.3.0",
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -52,5 +52,5 @@
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2"
|
||||
},
|
||||
"version": "0.2.48"
|
||||
"version": "0.2.49"
|
||||
}
|
||||
|
||||
@@ -1046,12 +1046,16 @@ class ScryptedCloud extends ScryptedDeviceBase implements OauthClient, Settings,
|
||||
args['--url'] = tunnelUrl;
|
||||
}
|
||||
|
||||
// if error messages are detected after 10 minutes from tunnel attempt start,
|
||||
// kill the tunnel.
|
||||
const tenMinutesMs = 10 * 60 * 1000;
|
||||
const tunnelStart = Date.now();
|
||||
const deferred = new Deferred<string>();
|
||||
|
||||
const cloudflareTunnel = cloudflared.tunnel(args);
|
||||
deferred.resolvePromise(cloudflareTunnel.url);
|
||||
|
||||
const processData = (string: string) => {
|
||||
this.console.error(string);
|
||||
|
||||
const lines = string.split('\n');
|
||||
for (const line of lines) {
|
||||
if ((line.includes('Unregistered tunnel connection')
|
||||
@@ -1059,12 +1063,10 @@ class ScryptedCloud extends ScryptedDeviceBase implements OauthClient, Settings,
|
||||
|| line.includes('Register tunnel error')
|
||||
|| line.includes('Failed to serve tunnel')
|
||||
|| line.includes('Failed to get tunnel'))
|
||||
&& deferred.finished) {
|
||||
this.console.warn('Cloudflare registration failed after tunnel started. The old tunnel may be invalid. Terminating.');
|
||||
&& (deferred.finished || Date.now() - tunnelStart > tenMinutesMs)) {
|
||||
this.console.warn('Cloudflare registration failure detected. Terminating.');
|
||||
cloudflareTunnel.child.kill();
|
||||
}
|
||||
if (line.includes('hostname'))
|
||||
this.console.log(line);
|
||||
const match = /config=(".*?}")/gm.exec(line)
|
||||
if (match) {
|
||||
const json = match[1];
|
||||
@@ -1109,7 +1111,10 @@ class ScryptedCloud extends ScryptedDeviceBase implements OauthClient, Settings,
|
||||
throw e;
|
||||
}
|
||||
this.console.log(`cloudflare url mapped ${this.cloudflareTunnel} to ${tunnelUrl}`);
|
||||
return cloudflareTunnel;
|
||||
return {
|
||||
url: deferred.promise,
|
||||
child: cloudflareTunnel.child,
|
||||
};
|
||||
}, {
|
||||
startingDelay: 60000,
|
||||
timeMultiple: 1.2,
|
||||
|
||||
4
plugins/core/package-lock.json
generated
4
plugins/core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.3.102",
|
||||
"version": "0.3.120",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.3.102",
|
||||
"version": "0.3.120",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.3.102",
|
||||
"version": "0.3.120",
|
||||
"description": "Scrypted Core plugin. Provides the UI, websocket, and engine.io APIs.",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache-2.0",
|
||||
@@ -33,10 +33,6 @@
|
||||
"ScryptedSettings",
|
||||
"SystemSettings",
|
||||
"Settings"
|
||||
],
|
||||
"pluginDependencies": [
|
||||
"@scrypted/snapshot",
|
||||
"@scrypted/webrtc"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -72,7 +72,6 @@ function createVideoCamera(devices: VideoCamera[], console: Console): VideoCamer
|
||||
container: 'rawvideo',
|
||||
mediaStreamOptions: (await createVideoStreamOptions())?.[0],
|
||||
inputArguments: [],
|
||||
h264FilterArguments: [],
|
||||
};
|
||||
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
@@ -102,7 +101,7 @@ function createVideoCamera(devices: VideoCamera[], console: Console): VideoCamer
|
||||
let i = dim * dim - 1;
|
||||
filter.push(`[${prev}][pos${i}] overlay=shortest=1:x=${curx % 1920}:y=${cury % 1080}`);
|
||||
|
||||
ffmpegInput.h264FilterArguments.push(
|
||||
ffmpegInput.inputArguments.push(
|
||||
'-filter_complex',
|
||||
filter.join(' '),
|
||||
);
|
||||
|
||||
@@ -155,6 +155,8 @@ export class ClusterCore extends ScryptedDeviceBase implements Settings, Readme,
|
||||
}
|
||||
|
||||
async getReadmeMarkdown(): Promise<string> {
|
||||
return `Manage Scrypted's cluster mode. Run storage devices and compute services on separate servers.`;
|
||||
return `Manage Scrypted's cluster mode. Run storage devices and compute services on separate servers.
|
||||
|
||||
[Read Documentation](https://docs.scrypted.app/maintenance/cluster.html).`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { MediaCore } from './media-core';
|
||||
import { checkLegacyLxc, checkLxc } from './platform/lxc';
|
||||
import { ConsoleServiceNativeId, PluginSocketService, ReplServiceNativeId } from './plugin-socket-service';
|
||||
import { ScriptCore, ScriptCoreNativeId, newScript } from './script-core';
|
||||
import { TerminalService, TerminalServiceNativeId } from './terminal-service';
|
||||
import { TerminalService, TerminalServiceNativeId, newTerminalService } from './terminal-service';
|
||||
import { UsersCore, UsersNativeId } from './user';
|
||||
import { ClusterCore, ClusterCoreNativeId } from './cluster';
|
||||
|
||||
@@ -108,7 +108,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
(async () => {
|
||||
await deviceManager.onDeviceDiscovered(
|
||||
{
|
||||
name: 'Cluster',
|
||||
name: 'Cluster Manager',
|
||||
nativeId: ClusterCoreNativeId,
|
||||
interfaces: [ScryptedInterface.Settings, ScryptedInterface.Readme, ScryptedInterface.ScryptedSettings],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
@@ -121,7 +121,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
name: 'Media Core',
|
||||
nativeId: 'mediacore',
|
||||
interfaces: [ScryptedInterface.DeviceProvider, ScryptedInterface.BufferConverter, ScryptedInterface.HttpRequestHandler],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -131,7 +131,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
name: 'Scripts',
|
||||
nativeId: ScriptCoreNativeId,
|
||||
interfaces: [ScryptedInterface.ScryptedSystemDevice, ScryptedInterface.ScryptedDeviceCreator, ScryptedInterface.DeviceProvider, ScryptedInterface.DeviceCreator, ScryptedInterface.Readme],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -140,8 +140,8 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
{
|
||||
name: 'Terminal Service',
|
||||
nativeId: TerminalServiceNativeId,
|
||||
interfaces: [ScryptedInterface.StreamService, ScryptedInterface.TTY],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
interfaces: [ScryptedInterface.StreamService, ScryptedInterface.TTY, ScryptedInterface.ClusterForkInterface],
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -151,7 +151,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
name: 'REPL Service',
|
||||
nativeId: ReplServiceNativeId,
|
||||
interfaces: [ScryptedInterface.StreamService],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -161,7 +161,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
name: 'Console Service',
|
||||
nativeId: ConsoleServiceNativeId,
|
||||
interfaces: [ScryptedInterface.StreamService],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -172,7 +172,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
name: 'Automations',
|
||||
nativeId: AutomationCoreNativeId,
|
||||
interfaces: [ScryptedInterface.ScryptedSystemDevice, ScryptedInterface.ScryptedDeviceCreator, ScryptedInterface.DeviceProvider, ScryptedInterface.DeviceCreator, ScryptedInterface.Readme],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -185,7 +185,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
ScryptedInterface.MixinProvider,
|
||||
ScryptedInterface.Readme,
|
||||
],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
});
|
||||
|
||||
(async () => {
|
||||
@@ -206,7 +206,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
name: 'Scrypted Users',
|
||||
nativeId: UsersNativeId,
|
||||
interfaces: [ScryptedInterface.ScryptedSystemDevice, ScryptedInterface.ScryptedDeviceCreator, ScryptedInterface.DeviceProvider, ScryptedInterface.DeviceCreator, ScryptedInterface.Readme],
|
||||
type: ScryptedDeviceType.Builtin,
|
||||
type: ScryptedDeviceType.Internal,
|
||||
},
|
||||
);
|
||||
})();
|
||||
@@ -242,7 +242,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Dev
|
||||
if (nativeId === UsersNativeId)
|
||||
return this.users ||= new UsersCore();
|
||||
if (nativeId === TerminalServiceNativeId)
|
||||
return this.terminalService ||= new TerminalService();
|
||||
return this.terminalService ||= new TerminalService(TerminalServiceNativeId, false);
|
||||
if (nativeId === ReplServiceNativeId)
|
||||
return this.replService ||= new PluginSocketService(ReplServiceNativeId, 'repl');
|
||||
if (nativeId === ConsoleServiceNativeId)
|
||||
@@ -331,5 +331,6 @@ export async function fork() {
|
||||
return {
|
||||
tsCompile,
|
||||
newScript,
|
||||
newTerminalService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function checkLegacyLxc() {
|
||||
if (process.env.SCRYPTED_INSTALL_ENVIRONMENT !== SCRYPTED_INSTALL_ENVIRONMENT_LXC)
|
||||
return;
|
||||
|
||||
sdk.log.a('This system is currently running the legacy LXC installation method and must be migrated to the new LXC manually: https://docs.scrypted.app/installation.html#proxmox-ve-container-reset');
|
||||
sdk.log.a('This system is currently running the legacy LXC installation method and must be migrated to the new LXC manually: https://docs.scrypted.app/install/proxmox-ve.html#proxmox-ve-container-reset');
|
||||
}
|
||||
|
||||
const DOCKER_COMPOSE_SH_PATH = '/root/.scrypted/docker-compose.sh';
|
||||
|
||||
@@ -93,7 +93,7 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De
|
||||
let script = new Script(nativeId);
|
||||
let worker: ForkWorker;
|
||||
|
||||
const triggerDeviceDiscover = async (name: string, type: ScryptedDeviceType, interfaces: string[]) => {
|
||||
const triggerDeviceDiscover = async (name: string, type: ScryptedDeviceType | string, interfaces: string[]) => {
|
||||
const e = this.scripts.get(nativeId);
|
||||
if (e?.script == script)
|
||||
e.script = undefined;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ScriptCoreNativeId } from "./script-core";
|
||||
const { deviceManager } = sdk;
|
||||
|
||||
export class Script extends ScryptedDeviceBase implements Scriptable, Program, ScriptDeviceImpl {
|
||||
constructor(nativeId: string, public triggerDeviceDiscover?: (name: string, type: ScryptedDeviceType, interfaces: string[]) => Promise<string>) {
|
||||
constructor(nativeId: string, public triggerDeviceDiscover?: (name: string, type: ScryptedDeviceType | string, interfaces: string[]) => Promise<string>) {
|
||||
super(nativeId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { ScryptedDeviceBase, ScryptedInterface, ScryptedNativeId, StreamService, TTYSettings } from "@scrypted/sdk";
|
||||
import sdk, { ClusterForkInterface, ClusterForkInterfaceOptions, ScryptedDeviceBase, ScryptedInterface, ScryptedNativeId, StreamService, TTYSettings } from "@scrypted/sdk";
|
||||
import type { IPty, spawn as ptySpawn } from 'node-pty';
|
||||
import { createAsyncQueue } from '@scrypted/common/src/async-queue'
|
||||
import { ChildProcess, spawn as childSpawn } from "child_process";
|
||||
@@ -111,8 +111,11 @@ class NoninteractiveTerminal {
|
||||
}
|
||||
|
||||
|
||||
export class TerminalService extends ScryptedDeviceBase implements StreamService<Buffer | string, Buffer> {
|
||||
constructor(nativeId?: ScryptedNativeId) {
|
||||
export class TerminalService extends ScryptedDeviceBase implements StreamService<Buffer | string, Buffer>, ClusterForkInterface {
|
||||
private forks: { [clusterWorkerId: string]: TerminalService } = {};
|
||||
private forkClients: 0;
|
||||
|
||||
constructor(nativeId?: ScryptedNativeId, private isFork: boolean = false) {
|
||||
super(nativeId);
|
||||
}
|
||||
|
||||
@@ -134,6 +137,42 @@ export class TerminalService extends ScryptedDeviceBase implements StreamService
|
||||
return extraPaths;
|
||||
}
|
||||
|
||||
async forkInterface<StreamService>(forkInterface: ScryptedInterface, options?: ClusterForkInterfaceOptions): Promise<StreamService> {
|
||||
if (forkInterface !== ScryptedInterface.StreamService) {
|
||||
throw new Error('can only fork StreamService');
|
||||
}
|
||||
|
||||
if (!options?.clusterWorkerId) {
|
||||
throw new Error('clusterWorkerId required');
|
||||
}
|
||||
|
||||
if (this.isFork) {
|
||||
throw new Error('cannot fork a fork');
|
||||
}
|
||||
|
||||
const clusterWorkerId = options.clusterWorkerId;
|
||||
if (this.forks[clusterWorkerId]) {
|
||||
return this.forks[clusterWorkerId] as StreamService;
|
||||
}
|
||||
|
||||
const fork = sdk.fork<{
|
||||
newTerminalService: typeof newTerminalService,
|
||||
}>({ clusterWorkerId });
|
||||
try {
|
||||
const result = await fork.result;
|
||||
const terminalService = await result.newTerminalService();
|
||||
this.forks[clusterWorkerId] = terminalService;
|
||||
fork.worker.on('exit', () => {
|
||||
delete this.forks[clusterWorkerId];
|
||||
});
|
||||
return terminalService as StreamService;
|
||||
}
|
||||
catch (e) {
|
||||
fork.worker.terminate();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The input to this stream can send buffers for normal terminal data and strings
|
||||
* for control messages. Control messages are JSON-formatted.
|
||||
@@ -149,6 +188,19 @@ export class TerminalService extends ScryptedDeviceBase implements StreamService
|
||||
const queue = createAsyncQueue<Buffer>();
|
||||
const extraPaths = await this.getExtraPaths();
|
||||
|
||||
if (this.isFork) {
|
||||
this.forkClients++;
|
||||
}
|
||||
|
||||
queue.endPromise.then(() => {
|
||||
if (this.isFork) {
|
||||
this.forkClients--;
|
||||
if (this.forkClients === 0) {
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function registerChildListeners() {
|
||||
cp.onExit(() => queue.end());
|
||||
|
||||
@@ -226,10 +278,16 @@ export class TerminalService extends ScryptedDeviceBase implements StreamService
|
||||
}
|
||||
catch (e) {
|
||||
this.console.log(e);
|
||||
}
|
||||
finally {
|
||||
cp?.kill();
|
||||
}
|
||||
})();
|
||||
|
||||
return generator();
|
||||
}
|
||||
}
|
||||
|
||||
export async function newTerminalService(): Promise<TerminalService> {
|
||||
return new TerminalService(TerminalServiceNativeId, true);
|
||||
}
|
||||
4
plugins/coreml/package-lock.json
generated
4
plugins/coreml/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/coreml",
|
||||
"version": "0.1.76",
|
||||
"version": "0.1.77",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/coreml",
|
||||
"version": "0.1.76",
|
||||
"version": "0.1.77",
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
|
||||
@@ -48,5 +48,5 @@
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.1.76"
|
||||
"version": "0.1.77"
|
||||
}
|
||||
|
||||
124
plugins/doorbird/package-lock.json
generated
124
plugins/doorbird/package-lock.json
generated
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "@scrypted/doorbird",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/doorbird",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"dependencies": {
|
||||
"doorbird": "^2.1.2"
|
||||
"doorbird": "2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/node": "^22.10.10",
|
||||
"cross-env": "^7.0.3"
|
||||
}
|
||||
},
|
||||
@@ -24,36 +24,41 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.10.8",
|
||||
"@types/node": "^20.11.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.108",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-changelog": "bin/scrypted-changelog.js",
|
||||
@@ -65,11 +70,9 @@
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21"
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.26.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/common": {
|
||||
@@ -81,10 +84,14 @@
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.15.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz",
|
||||
"integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==",
|
||||
"dev": true
|
||||
"version": "22.10.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.10.tgz",
|
||||
"integrity": "sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
@@ -92,11 +99,12 @@
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
|
||||
"integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
|
||||
"version": "1.7.9",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.4",
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
@@ -145,10 +153,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -167,25 +176,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/doorbird": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/doorbird/-/doorbird-2.1.2.tgz",
|
||||
"integrity": "sha512-ivwwsS/nOslDnuLg3UB60Axo76w5LQuZ67mCPEeWFr5+HbGYRL7PCY3iLjWYaIakh5+IvZyFPHKR4yHAvAc1WQ==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/doorbird/-/doorbird-2.6.0.tgz",
|
||||
"integrity": "sha512-HZBI5uFhwEVF8JFULQlpzXXvjSHmtQMJUNWfogq6vHe3kv7mCSmg0g/TDbeV5fVvisi8w7GxKD0/PpZCrtcGOg==",
|
||||
"dependencies": {
|
||||
"axios": "^1.2.1",
|
||||
"axios": "^1.6.2",
|
||||
"chacha-js": "^2.1.1",
|
||||
"libsodium-wrappers-sumo": "^0.7.11"
|
||||
"libsodium-wrappers-sumo": "^0.7.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
@@ -225,16 +238,16 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/libsodium-sumo": {
|
||||
"version": "0.7.11",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.11.tgz",
|
||||
"integrity": "sha512-bY+7ph7xpk51Ez2GbE10lXAQ5sJma6NghcIDaSPbM/G9elfrjLa0COHl/7P6Wb/JizQzl5UQontOOP1z0VwbLA=="
|
||||
"version": "0.7.15",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.15.tgz",
|
||||
"integrity": "sha512-5tPmqPmq8T8Nikpm1Nqj0hBHvsLFCXvdhBFV7SGOitQPZAA6jso8XoL0r4L7vmfKXr486fiQInvErHtEvizFMw=="
|
||||
},
|
||||
"node_modules/libsodium-wrappers-sumo": {
|
||||
"version": "0.7.11",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.11.tgz",
|
||||
"integrity": "sha512-DGypHOmJbB1nZn89KIfGOAkDgfv5N6SBGC3Qvmy/On0P0WD1JQvNRS/e3UL3aFF+xC0m+MYz5M+MnRnK2HMrKQ==",
|
||||
"version": "0.7.15",
|
||||
"resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.15.tgz",
|
||||
"integrity": "sha512-aSWY8wKDZh5TC7rMvEdTHoyppVq/1dTSAeAR7H6pzd6QRT3vQWcT5pGwCotLcpPEOLXX6VvqihSPkpEhYAjANA==",
|
||||
"dependencies": {
|
||||
"libsodium-sumo": "^0.7.11"
|
||||
"libsodium-sumo": "^0.7.15"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
@@ -307,6 +320,13 @@
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/doorbird",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
"prescrypted-setup-project": "scrypted-package-json",
|
||||
@@ -33,12 +33,12 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"doorbird": "^2.1.2"
|
||||
"doorbird": "2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/node": "^22.10.10",
|
||||
"cross-env": "^7.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { listenZero } from '@scrypted/common/src/listen-cluster';
|
||||
import sdk, { BinarySensor, Camera, DeviceProvider, DeviceCreator, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, MediaObject, PictureOptions, ResponseMediaStreamOptions, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, VideoCamera, MotionSensor } from '@scrypted/sdk';
|
||||
import child_process, { ChildProcess } from 'child_process';
|
||||
import { ffmpegLogInitialOutput, safePrintFFmpegArguments } from "@scrypted/common/src/media-helpers";
|
||||
import net from 'net';
|
||||
import { randomBytes } from 'crypto';
|
||||
import { PassThrough, Readable } from "stream";
|
||||
import { readLength } from "@scrypted/common/src/read-stream";
|
||||
import { authHttpFetch } from "@scrypted/common/src/http-auth-fetch";
|
||||
import { ApiRingEvent, ApiMotionEvent, DoorbirdAPI } from "./doorbird-api";
|
||||
import { listenZero } from '@scrypted/common/src/listen-cluster';
|
||||
import { ffmpegLogInitialOutput, safePrintFFmpegArguments } from "@scrypted/common/src/media-helpers";
|
||||
import { readLength } from "@scrypted/common/src/read-stream";
|
||||
import sdk, { BinarySensor, Camera, DeviceCreator, DeviceCreatorSettings, DeviceInformation, DeviceProvider, FFmpegInput, Intercom, MediaObject, MotionSensor, PictureOptions, ResponseMediaStreamOptions, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, VideoCamera } from '@scrypted/sdk';
|
||||
import child_process, { ChildProcess } from 'child_process';
|
||||
import { randomBytes } from 'crypto';
|
||||
import net from 'net';
|
||||
import { PassThrough, Readable } from "stream";
|
||||
import { ApiMotionEvent, ApiRingEvent, DoorbirdAPI } from "./doorbird-api";
|
||||
|
||||
const { deviceManager, mediaManager } = sdk;
|
||||
|
||||
@@ -384,7 +384,7 @@ class DoorbirdCamera extends ScryptedDeviceBase implements Intercom, Camera, Vid
|
||||
this.console.log('Doorbird: timed out waiting for tcp client from ffmpeg');
|
||||
server.close();
|
||||
}, 30000);
|
||||
const port = await listenZero(server);
|
||||
const port = await listenZero(server, '127.0.0.1');
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"target": "esnext",
|
||||
"moduleResolution": "Node16",
|
||||
"esModuleInterop": true,
|
||||
|
||||
2
plugins/dummy-switch/.vscode/settings.json
vendored
2
plugins/dummy-switch/.vscode/settings.json
vendored
@@ -1,4 +1,4 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
"scrypted.debugHost": "scrypted-nvr",
|
||||
}
|
||||
130
plugins/dummy-switch/package-lock.json
generated
130
plugins/dummy-switch/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/dummy-switch",
|
||||
"version": "0.0.24",
|
||||
"version": "0.0.25",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/dummy-switch",
|
||||
"version": "0.0.24",
|
||||
"version": "0.0.25",
|
||||
"dependencies": {
|
||||
"@types/node": "^16.6.1",
|
||||
"axios": "^1.3.6"
|
||||
@@ -23,35 +23,41 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^3.0.2",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^4.4.3"
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.9.0"
|
||||
"@types/node": "^20.11.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.2.97",
|
||||
"version": "0.3.106",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-changelog": "bin/scrypted-changelog.js",
|
||||
@@ -63,11 +69,9 @@
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21"
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.26.11"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
@@ -92,11 +96,11 @@
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz",
|
||||
"integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==",
|
||||
"version": "1.7.9",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
@@ -121,9 +125,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -182,35 +186,39 @@
|
||||
"version": "file:../../common",
|
||||
"requires": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"@types/node": "^16.9.0",
|
||||
"http-auth-utils": "^3.0.2",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^4.4.3"
|
||||
"@types/node": "^20.11.0",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
},
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"@types/node": "^22.10.1",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typedoc": "^0.26.11",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
@@ -224,11 +232,11 @@
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz",
|
||||
"integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==",
|
||||
"version": "1.7.9",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
@@ -247,9 +255,9 @@
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
|
||||
@@ -40,5 +40,5 @@
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.0.24"
|
||||
"version": "0.0.25"
|
||||
}
|
||||
|
||||
@@ -2,11 +2,60 @@ import { BinarySensor, DeviceCreator, DeviceCreatorSettings, DeviceProvider, Loc
|
||||
import sdk from '@scrypted/sdk';
|
||||
import { ReplaceMotionSensor, ReplaceMotionSensorNativeId } from './replace-motion-sensor';
|
||||
import { ReplaceBinarySensor, ReplaceBinarySensorNativeId } from './replace-binary-sensor';
|
||||
import { StorageSettings } from '@scrypted/sdk/storage-settings';
|
||||
|
||||
const { log, deviceManager } = sdk;
|
||||
|
||||
class DummyDevice extends ScryptedDeviceBase implements OnOff, Lock, StartStop, OccupancySensor, MotionSensor, BinarySensor, Settings {
|
||||
timeout: NodeJS.Timeout;
|
||||
storageSettings = new StorageSettings(this, {
|
||||
reset: {
|
||||
title: 'Reset Sensor',
|
||||
description: 'Reset the motion sensor and binary sensor after the given seconds. Enter 0 to never reset.',
|
||||
defaultValue: 10,
|
||||
type: 'number',
|
||||
placeholder: '10',
|
||||
onPut: () => {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
},
|
||||
actionTypes: {
|
||||
title: 'Action Types',
|
||||
description: 'Select the action types to expose.',
|
||||
defaultValue: [
|
||||
ScryptedInterface.OnOff,
|
||||
ScryptedInterface.StartStop,
|
||||
ScryptedInterface.Lock,
|
||||
],
|
||||
multiple: true,
|
||||
choices: [
|
||||
ScryptedInterface.OnOff,
|
||||
ScryptedInterface.StartStop,
|
||||
ScryptedInterface.Lock,
|
||||
],
|
||||
onPut: () => {
|
||||
this.reportInterfaces();
|
||||
},
|
||||
},
|
||||
sensorTypes: {
|
||||
title: 'Sensor Types',
|
||||
description: 'Select the sensor types to expose.',
|
||||
defaultValue: [
|
||||
ScryptedInterface.MotionSensor,
|
||||
ScryptedInterface.BinarySensor,
|
||||
ScryptedInterface.OccupancySensor,
|
||||
],
|
||||
multiple: true,
|
||||
choices: [
|
||||
ScryptedInterface.MotionSensor,
|
||||
ScryptedInterface.BinarySensor,
|
||||
ScryptedInterface.OccupancySensor,
|
||||
],
|
||||
onPut: () => {
|
||||
this.reportInterfaces();
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
constructor(nativeId: string) {
|
||||
super(nativeId);
|
||||
@@ -19,6 +68,22 @@ class DummyDevice extends ScryptedDeviceBase implements OnOff, Lock, StartStop,
|
||||
this.occupied = false;
|
||||
}
|
||||
|
||||
async reportInterfaces() {
|
||||
const interfaces: ScryptedInterface[] = this.storageSettings.values.sensorTypes || [];
|
||||
if (!interfaces.length)
|
||||
interfaces.push(ScryptedInterface.MotionSensor, ScryptedInterface.BinarySensor, ScryptedInterface.OccupancySensor);
|
||||
const actionTyoes = this.storageSettings.values.actionTypes || [];
|
||||
if (!actionTyoes.length)
|
||||
actionTyoes.push(ScryptedInterface.OnOff, ScryptedInterface.StartStop, ScryptedInterface.Lock);
|
||||
|
||||
await sdk.deviceManager.onDeviceDiscovered({
|
||||
nativeId: this.nativeId,
|
||||
interfaces: [...interfaces, ...actionTyoes, ScryptedInterface.Settings],
|
||||
type: ScryptedDeviceType.Switch,
|
||||
name: this.providedName,
|
||||
});
|
||||
}
|
||||
|
||||
lock(): Promise<void> {
|
||||
return this.turnOff();
|
||||
}
|
||||
@@ -31,20 +96,12 @@ class DummyDevice extends ScryptedDeviceBase implements OnOff, Lock, StartStop,
|
||||
stop(): Promise<void> {
|
||||
return this.turnOff();
|
||||
}
|
||||
|
||||
async getSettings(): Promise<Setting[]> {
|
||||
return [
|
||||
{
|
||||
key: 'reset',
|
||||
title: 'Reset Sensor',
|
||||
description: 'Reset the motion sensor and binary sensor after the given seconds. Enter 0 to never reset.',
|
||||
value: this.storage.getItem('reset') || '10',
|
||||
placeholder: '10',
|
||||
}
|
||||
]
|
||||
return this.storageSettings.getSettings();
|
||||
}
|
||||
async putSetting(key: string, value: SettingValue): Promise<void> {
|
||||
this.storage.setItem(key, value.toString());
|
||||
clearTimeout(this.timeout);
|
||||
return this.storageSettings.putSetting(key, value);
|
||||
}
|
||||
|
||||
// note that turnOff locks the lock
|
||||
@@ -131,12 +188,6 @@ class DummyDeviceProvider extends ScryptedDeviceBase implements DeviceProvider,
|
||||
const nativeId = 'shell:' + Math.random().toString();
|
||||
const name = settings.name?.toString();
|
||||
|
||||
await this.onDiscovered(nativeId, name);
|
||||
|
||||
return nativeId;
|
||||
}
|
||||
|
||||
async onDiscovered(nativeId: string, name: string) {
|
||||
await deviceManager.onDeviceDiscovered({
|
||||
nativeId,
|
||||
name,
|
||||
@@ -151,6 +202,8 @@ class DummyDeviceProvider extends ScryptedDeviceBase implements DeviceProvider,
|
||||
],
|
||||
type: ScryptedDeviceType.Switch,
|
||||
});
|
||||
|
||||
return nativeId;
|
||||
}
|
||||
|
||||
async getDevice(nativeId: string) {
|
||||
@@ -163,11 +216,6 @@ class DummyDeviceProvider extends ScryptedDeviceBase implements DeviceProvider,
|
||||
if (!ret) {
|
||||
ret = new DummyDevice(nativeId);
|
||||
|
||||
// remove legacy scriptable interface
|
||||
if (ret.interfaces.includes(ScryptedInterface.Scriptable)) {
|
||||
setTimeout(() => this.onDiscovered(ret.nativeId, ret.providedName), 2000);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
this.devices.set(nativeId, ret);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"module": "Node16",
|
||||
"target": "ES2021",
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "Node16",
|
||||
|
||||
131
plugins/google-home/package-lock.json
generated
131
plugins/google-home/package-lock.json
generated
@@ -21,6 +21,7 @@
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/debug": "^4.1.5",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^22.13.11",
|
||||
"@types/url-parse": "^1.4.3"
|
||||
}
|
||||
},
|
||||
@@ -31,51 +32,55 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^3.0.2",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^4.4.3"
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.9.0"
|
||||
"@types/node": "^20.11.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.2.53",
|
||||
"version": "0.5.10",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-changelog": "bin/scrypted-changelog.js",
|
||||
"scrypted-debug": "bin/scrypted-debug.js",
|
||||
"scrypted-deploy": "bin/scrypted-deploy.js",
|
||||
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
|
||||
"scrypted-package-json": "bin/scrypted-package-json.js",
|
||||
"scrypted-readme": "bin/scrypted-readme.js",
|
||||
"scrypted-setup-project": "bin/scrypted-setup-project.js",
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21"
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.26.11"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
@@ -182,9 +187,13 @@
|
||||
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "14.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
|
||||
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ=="
|
||||
"version": "22.13.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz",
|
||||
"integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.6",
|
||||
@@ -712,6 +721,12 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.9",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.9.tgz",
|
||||
@@ -778,35 +793,39 @@
|
||||
"version": "file:../../common",
|
||||
"requires": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"@types/node": "^16.9.0",
|
||||
"http-auth-utils": "^3.0.2",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^4.4.3"
|
||||
"@types/node": "^20.11.0",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
},
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"@types/node": "^22.10.1",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typedoc": "^0.26.11",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
}
|
||||
},
|
||||
"@types/aws-lambda": {
|
||||
@@ -877,9 +896,12 @@
|
||||
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
|
||||
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ=="
|
||||
"version": "22.13.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz",
|
||||
"integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==",
|
||||
"requires": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.6",
|
||||
@@ -1259,6 +1281,11 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.5.9",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.9.tgz",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/debug": "^4.1.5",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^22.13.11",
|
||||
"@types/url-parse": "^1.4.3"
|
||||
},
|
||||
"version": "0.0.61"
|
||||
|
||||
@@ -7,7 +7,7 @@ const { systemManager } = sdk;
|
||||
|
||||
export interface DummyDevice {
|
||||
interfaces?: string[];
|
||||
type?: ScryptedDeviceType;
|
||||
type?: ScryptedDeviceType | string;
|
||||
}
|
||||
|
||||
interface SupportedType {
|
||||
|
||||
265
plugins/hikvision-doorbell/package-lock.json
generated
265
plugins/hikvision-doorbell/package-lock.json
generated
@@ -1,24 +1,25 @@
|
||||
{
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.200",
|
||||
"name": "@vityevato/hikvision-doorbell",
|
||||
"version": "1.0.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.200",
|
||||
"name": "@vityevato/hikvision-doorbell",
|
||||
"version": "1.0.1",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@scrypted/server": "file:../../server",
|
||||
"@types/xml2js": "^0.4.11",
|
||||
"http-auth-client": "^0.4.1",
|
||||
"ip": "^1.1.8",
|
||||
"lodash": "^4.17.21",
|
||||
"sip": "git+https://github.com/kirm/sip.js.git",
|
||||
"xml2js": "^0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@scrypted/server": "file:../../server",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/node": "^18.15.11"
|
||||
}
|
||||
@@ -26,39 +27,43 @@
|
||||
"../../common": {
|
||||
"name": "@scrypted/common",
|
||||
"version": "1.0.1",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.5",
|
||||
"dev": true,
|
||||
"version": "0.3.118",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-changelog": "bin/scrypted-changelog.js",
|
||||
@@ -70,67 +75,61 @@
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21"
|
||||
"@types/node": "^22.10.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.26.11"
|
||||
}
|
||||
},
|
||||
"../../server": {
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.94.0",
|
||||
"dev": true,
|
||||
"version": "0.138.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
"@scrypted/types": "^0.3.4",
|
||||
"adm-zip": "^0.5.10",
|
||||
"body-parser": "^1.20.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"engine.io": "^6.5.4",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"follow-redirects": "^1.15.5",
|
||||
"@scrypted/ffmpeg-static": "^6.1.0-build3",
|
||||
"@scrypted/node-pty": "^1.0.22",
|
||||
"@scrypted/types": "^0.3.108",
|
||||
"adm-zip": "^0.5.16",
|
||||
"body-parser": "^1.20.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"dotenv": "^16.4.5",
|
||||
"engine.io": "^6.6.2",
|
||||
"express": "^4.21.1",
|
||||
"follow-redirects": "^1.15.9",
|
||||
"http-auth": "^4.2.0",
|
||||
"ip": "^1.1.8",
|
||||
"level": "^8.0.0",
|
||||
"level": "^8.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"nan": "^2.18.0",
|
||||
"node-dijkstra": "^2.5.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-gyp": "^10.0.1",
|
||||
"router": "^1.3.8",
|
||||
"semver": "^7.5.4",
|
||||
"sharp": "^0.33.2",
|
||||
"node-gyp": "^10.2.0",
|
||||
"py": "npm:@bjia56/portable-python@^0.1.112",
|
||||
"semver": "^7.6.3",
|
||||
"sharp": "^0.33.5",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tar": "^6.2.0",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"tar": "^7.4.3",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.5.4",
|
||||
"whatwg-mimetype": "^4.0.0",
|
||||
"ws": "^8.16.0"
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-serve": "bin/scrypted-serve"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/adm-zip": "^0.5.5",
|
||||
"@types/cookie-parser": "^1.4.6",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/follow-redirects": "^1.14.4",
|
||||
"@types/http-auth": "^4.1.4",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/node": "^22.10.1",
|
||||
"@types/node-dijkstra": "^2.5.6",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"@types/semver": "^7.5.6",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/source-map-support": "^0.5.10",
|
||||
"@types/tar": "^6.1.10",
|
||||
"@types/whatwg-mimetype": "^3.0.2",
|
||||
"@types/ws": "^8.5.10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"node-pty-prebuilt-multiarch": "^0.10.1-pre.5"
|
||||
"@types/ws": "^8.5.13",
|
||||
"rimraf": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
@@ -193,6 +192,37 @@
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"node_modules/sip": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "git+ssh://git@github.com/kirm/sip.js.git#fd7e0c2389507b00811feb51bc5c0f6595bac53d",
|
||||
"dependencies": {
|
||||
"ws": "^7.4.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "7.5.10",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xml2js": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz",
|
||||
@@ -219,81 +249,83 @@
|
||||
"version": "file:../../common",
|
||||
"requires": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"@types/node": "^20.11.0",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
},
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"@types/node": "^22.10.1",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.7.8",
|
||||
"babel-loader": "^9.2.1",
|
||||
"babel-plugin-const-enum": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.23.21",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.27.4",
|
||||
"tmp": "^0.2.3",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typedoc": "^0.26.11",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-bundle-analyzer": "^4.10.2"
|
||||
}
|
||||
},
|
||||
"@scrypted/server": {
|
||||
"version": "file:../../server",
|
||||
"requires": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
"@scrypted/types": "^0.3.4",
|
||||
"@types/adm-zip": "^0.5.5",
|
||||
"@types/cookie-parser": "^1.4.6",
|
||||
"@types/express": "^4.17.21",
|
||||
"@scrypted/ffmpeg-static": "^6.1.0-build3",
|
||||
"@scrypted/node-pty": "^1.0.22",
|
||||
"@scrypted/types": "^0.3.108",
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/follow-redirects": "^1.14.4",
|
||||
"@types/http-auth": "^4.1.4",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/node": "^22.10.1",
|
||||
"@types/node-dijkstra": "^2.5.6",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"@types/semver": "^7.5.6",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/source-map-support": "^0.5.10",
|
||||
"@types/tar": "^6.1.10",
|
||||
"@types/whatwg-mimetype": "^3.0.2",
|
||||
"@types/ws": "^8.5.10",
|
||||
"adm-zip": "^0.5.10",
|
||||
"body-parser": "^1.20.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"engine.io": "^6.5.4",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"follow-redirects": "^1.15.5",
|
||||
"@types/ws": "^8.5.13",
|
||||
"adm-zip": "^0.5.16",
|
||||
"body-parser": "^1.20.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"dotenv": "^16.4.5",
|
||||
"engine.io": "^6.6.2",
|
||||
"express": "^4.21.1",
|
||||
"follow-redirects": "^1.15.9",
|
||||
"http-auth": "^4.2.0",
|
||||
"ip": "^1.1.8",
|
||||
"level": "^8.0.0",
|
||||
"level": "^8.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"nan": "^2.18.0",
|
||||
"node-dijkstra": "^2.5.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-gyp": "^10.0.1",
|
||||
"node-pty-prebuilt-multiarch": "^0.10.1-pre.5",
|
||||
"router": "^1.3.8",
|
||||
"semver": "^7.5.4",
|
||||
"sharp": "^0.33.2",
|
||||
"node-gyp": "^10.2.0",
|
||||
"py": "npm:@bjia56/portable-python@^0.1.112",
|
||||
"rimraf": "^6.0.1",
|
||||
"semver": "^7.6.3",
|
||||
"sharp": "^0.33.5",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tar": "^6.2.0",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"tar": "^7.4.3",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.5.4",
|
||||
"whatwg-mimetype": "^4.0.0",
|
||||
"ws": "^8.16.0"
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
},
|
||||
"@types/ip": {
|
||||
@@ -338,6 +370,19 @@
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"sip": {
|
||||
"version": "git+ssh://git@github.com/kirm/sip.js.git#fd7e0c2389507b00811feb51bc5c0f6595bac53d",
|
||||
"from": "sip@git+https://github.com/kirm/sip.js.git",
|
||||
"requires": {
|
||||
"ws": "^7.4.6"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.5.10",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"module": "Node16",
|
||||
"target": "ES2021",
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "Node16",
|
||||
|
||||
2
plugins/hikvision/.vscode/launch.json
vendored
2
plugins/hikvision/.vscode/launch.json
vendored
@@ -10,7 +10,7 @@
|
||||
"port": 10081,
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"**/plugin-remote-worker.*",
|
||||
"**/plugin-console.*",
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"preLaunchTask": "scrypted: deploy+debug",
|
||||
|
||||
2
plugins/hikvision/.vscode/settings.json
vendored
2
plugins/hikvision/.vscode/settings.json
vendored
@@ -1,4 +1,4 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
"scrypted.debugHost": "scrypted-nvr",
|
||||
}
|
||||
4
plugins/hikvision/package-lock.json
generated
4
plugins/hikvision/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.160",
|
||||
"version": "0.0.165",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.160",
|
||||
"version": "0.0.165",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.160",
|
||||
"version": "0.0.165",
|
||||
"description": "Hikvision Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
|
||||
57
plugins/hikvision/src/alarm-switch.ts
Normal file
57
plugins/hikvision/src/alarm-switch.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { OnOff, Readme, ScryptedDeviceBase } from "@scrypted/sdk";
|
||||
import type { HikvisionCamera } from "./main";
|
||||
|
||||
export class HikvisionAlarmSwitch extends ScryptedDeviceBase implements OnOff, Readme {
|
||||
on: boolean = false;
|
||||
|
||||
constructor(public camera: HikvisionCamera, nativeId: string) {
|
||||
super(nativeId);
|
||||
this.on = false;
|
||||
}
|
||||
|
||||
async turnOn() {
|
||||
this.on = true;
|
||||
await this.setAlarm(true);
|
||||
}
|
||||
|
||||
async turnOff() {
|
||||
this.on = false;
|
||||
await this.setAlarm(false);
|
||||
}
|
||||
|
||||
private async setAlarm(state: boolean): Promise<void> {
|
||||
const api = this.camera.getClient();
|
||||
await api.setAlarm(state);
|
||||
}
|
||||
|
||||
async getReadmeMarkdown(): Promise<string> {
|
||||
return `
|
||||
## **Alarm Switch**
|
||||
This switch triggers the camera's alarm input.
|
||||
|
||||
### **Enabling Alarm Linkages**
|
||||
To link the alarm to the camera's equipped features like strobe light, or audio alarm:
|
||||
|
||||
1. Log in to the camera’s web interface.
|
||||
2. Go to *Configuration > Event > Event and Detection (or Basic Event)*.
|
||||
3. Select Alarm Input.
|
||||
4. Edit under Operation(pencil icon) (or Linkage Method).
|
||||
4. Set Linkage Actions
|
||||
- Audible Warning (siren)
|
||||
- Alarm (strobe light)
|
||||
|
||||
When the alarm is switched on, the linkages will activate.
|
||||
|
||||
### **Strobe Light and Audio Alarm Settings**
|
||||
To configure the strobe light and audio alarm:
|
||||
|
||||
1. Log in to the camera’s web interface.
|
||||
2. Navigate to *Configuration > Event > Alarm Setting (or Basic Event)*.
|
||||
3. **For Strobe Light**:
|
||||
- Select 'Flashing Alarm Light Output'.
|
||||
|
||||
**For Audio Alarm**:
|
||||
- Select 'Audible Alarm Output'.
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -399,3 +399,140 @@ export interface AudioCompressionType {
|
||||
export interface GeneratedType35 {
|
||||
opt: string
|
||||
}
|
||||
|
||||
export interface PtzCapabilitiesRoot {
|
||||
PTZChanelCap: PTZChanelCap;
|
||||
}
|
||||
|
||||
export interface PTZChanelCap {
|
||||
AbsolutePanTiltPositionSpace: AbsolutePanTiltPositionSpaceClass;
|
||||
AbsoluteZoomPositionSpace: AbsoluteZoomPositionSpaceClass;
|
||||
ContinuousPanTiltSpace: AbsolutePanTiltPositionSpaceClass;
|
||||
ContinuousZoomSpace: AbsoluteZoomPositionSpaceClass;
|
||||
maxPresetNum: string;
|
||||
maxPatrolNum: string;
|
||||
maxPatternNum: string;
|
||||
maxLimitesNum: string;
|
||||
maxTimeTaskNum: string;
|
||||
controlProtocol: ControlProtocol;
|
||||
controlAddress: string;
|
||||
PTZRs485Para: PTZRs485Para;
|
||||
PresetNameCap: PresetNameCap;
|
||||
wiperStatusSupport: string;
|
||||
isSupportPosition3D: string;
|
||||
manualControlSpeed: ManualControlSpeed;
|
||||
isSpportPtzlimiteds: string;
|
||||
oneKeyParkAction: string;
|
||||
oneKeyMenu: string;
|
||||
ParkAction: ParkAction;
|
||||
TimeTaskList: TimeTaskList;
|
||||
TrackInitPosition: TrackInitPosition;
|
||||
LockPT: string;
|
||||
LFPositionCap: LFPositionCap;
|
||||
isSupportManualWiper: string;
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface AbsolutePanTiltPositionSpaceClass {
|
||||
XRange: Range;
|
||||
YRange: Range;
|
||||
}
|
||||
|
||||
export interface Range {
|
||||
Min: string;
|
||||
Max: string;
|
||||
}
|
||||
|
||||
export interface AbsoluteZoomPositionSpaceClass {
|
||||
ZRange: Range;
|
||||
}
|
||||
|
||||
export interface LFPositionCap {
|
||||
elevation: AbsoluteZoom;
|
||||
azimuth: AbsoluteZoom;
|
||||
absoluteZoom: AbsoluteZoom;
|
||||
}
|
||||
|
||||
export interface AbsoluteZoom {
|
||||
_min: string;
|
||||
_max: string;
|
||||
__text: string;
|
||||
}
|
||||
|
||||
export interface PTZRs485Para {
|
||||
baudRate: ControlProtocol;
|
||||
dataBits: ControlProtocol;
|
||||
parityType: ControlProtocol;
|
||||
stopBits: ControlProtocol;
|
||||
flowCtrl: ControlProtocol;
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface ControlProtocol {
|
||||
_opt: string;
|
||||
__text: string;
|
||||
}
|
||||
|
||||
export interface ParkAction {
|
||||
enabled: ControlProtocol;
|
||||
Parktime: AbsoluteZoom;
|
||||
Action: Action;
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface Action {
|
||||
ActionType: ControlProtocol;
|
||||
ActionNum: AbsoluteZoom;
|
||||
}
|
||||
|
||||
export interface PresetNameCap {
|
||||
presetNameSupport: string;
|
||||
maxPresetNameLen: MaxPresetNameLen;
|
||||
specialNo: ManualControlSpeed;
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface MaxPresetNameLen {
|
||||
_max: string;
|
||||
}
|
||||
|
||||
export interface ManualControlSpeed {
|
||||
_opt: string;
|
||||
}
|
||||
|
||||
export interface TimeTaskList {
|
||||
enabled: ControlProtocol;
|
||||
TimeTaskBlock: TimeTaskBlock[];
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface TimeTaskBlock {
|
||||
dayOfWeek: AbsoluteZoom;
|
||||
TimeTaskRange: TimeTaskRange[];
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface TimeTaskRange {
|
||||
TaskID: AbsoluteZoom;
|
||||
Task: Task;
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
TaskType: ControlProtocol;
|
||||
presetTaskNum: AbsoluteZoom;
|
||||
}
|
||||
|
||||
export interface TrackInitPosition {
|
||||
slaveCameraID: SlaveCameraID;
|
||||
}
|
||||
|
||||
export interface SlaveCameraID {
|
||||
_min: string;
|
||||
_max: string;
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
import { HttpFetchOptions } from '@scrypted/common/src/http-auth-fetch';
|
||||
import { MediaStreamConfiguration, MediaStreamOptions } from '@scrypted/sdk';
|
||||
import { MediaStreamConfiguration, MediaStreamOptions, PanTiltZoomCommand } from '@scrypted/sdk';
|
||||
import { Readable } from 'stream';
|
||||
import { Destroyable } from '../../rtsp/src/rtsp';
|
||||
import { PtzPresetsRoot, TextOverlayRoot, VideoOverlayRoot } from './hikvision-overlay';
|
||||
import { SupplementLightRoot } from './hikvision-xml-types';
|
||||
import { PtzCapabilitiesRoot } from './hikvision-api-capabilities';
|
||||
|
||||
export interface HikvisionCameraStreamSetup {
|
||||
videoCodecType: string;
|
||||
@@ -16,10 +19,33 @@ export interface HikvisionAPI {
|
||||
checkTwoWayAudio(): Promise<boolean>;
|
||||
checkDeviceModel(): Promise<string>;
|
||||
checkIsOldModel(): Promise<boolean>;
|
||||
checkStreamSetup(channel: string, isOld: boolean): Promise<HikvisionCameraStreamSetup>;
|
||||
jpegSnapshot(channel: string, timeout: number): Promise<Buffer>;
|
||||
listenEvents(): Promise<Destroyable>;
|
||||
putVcaResource(channel: string, resource: 'smart' | 'facesnap' | 'close'): Promise<boolean>;
|
||||
getCodecs(camNumber: string): Promise<MediaStreamOptions[]>;
|
||||
configureCodecs(camNumber: string, channelNumber: string, options: MediaStreamOptions): Promise<MediaStreamConfiguration>;
|
||||
|
||||
getOverlay(): Promise<{
|
||||
json: VideoOverlayRoot;
|
||||
xml: any;
|
||||
}>;
|
||||
getOverlayText(overlayId: string): Promise<{
|
||||
json: TextOverlayRoot;
|
||||
xml: any;
|
||||
}>;
|
||||
updateOverlayText(overlayId: string, entry: TextOverlayRoot): Promise<void>;
|
||||
|
||||
getSupplementLight(): Promise<{json: SupplementLightRoot; xml: any }>;
|
||||
setSupplementLight(params: { on?: boolean, brightness?: number, mode?: 'auto' | 'manual' }): Promise<void>;
|
||||
|
||||
getAlarmCapabilities(): Promise<{ json: any; xml: string }>;
|
||||
getAlarm(port: string): Promise<{ json: any; xml: string }>;
|
||||
setAlarm(isOn: boolean): Promise<{ json: any; xml: string }>;
|
||||
|
||||
getPtzCapabilities(): Promise<{ json: PtzCapabilitiesRoot; xml: string }>;
|
||||
ptzCommand(command: PanTiltZoomCommand): Promise<any>;
|
||||
getPresets(): Promise<{
|
||||
json: PtzPresetsRoot;
|
||||
xml: any;
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { AuthFetchCredentialState, HttpFetchOptions, authHttpFetch } from '@scrypted/common/src/http-auth-fetch';
|
||||
import { readLine } from '@scrypted/common/src/read-stream';
|
||||
import { parseHeaders, readBody, readMessage } from '@scrypted/common/src/rtsp-server';
|
||||
import { MediaStreamConfiguration, MediaStreamOptions } from "@scrypted/sdk";
|
||||
import { MediaStreamConfiguration, MediaStreamOptions, PanTiltZoomCommand } from "@scrypted/sdk";
|
||||
import contentType from 'content-type';
|
||||
import { IncomingMessage } from 'http';
|
||||
import { EventEmitter, Readable } from 'stream';
|
||||
import xml2js from 'xml2js';
|
||||
import { Destroyable } from '../../rtsp/src/rtsp';
|
||||
import { CapabiltiesResponse } from './hikvision-api-capabilities';
|
||||
import { CapabiltiesResponse, PtzCapabilitiesRoot } from './hikvision-api-capabilities';
|
||||
import { HikvisionAPI, HikvisionCameraStreamSetup } from "./hikvision-api-channels";
|
||||
import { ChannelResponse, ChannelsResponse } from './hikvision-xml-types';
|
||||
import { ChannelResponse, ChannelsResponse, SupplementLightRoot } from './hikvision-xml-types';
|
||||
import { getDeviceInfo } from './probe';
|
||||
import { PtzPresetsRoot, TextOverlayRoot, VideoOverlayRoot } from './hikvision-overlay';
|
||||
import { sleep } from '@scrypted/common/src/sleep';
|
||||
|
||||
export const detectionMap = {
|
||||
human: 'person',
|
||||
@@ -116,36 +118,15 @@ export class HikvisionCameraAPI implements HikvisionAPI {
|
||||
}
|
||||
|
||||
async checkIsOldModel() {
|
||||
// The old Hikvision DS-7608NI-E2 doesn't support channel capability checks, and the requests cause errors
|
||||
// The old Hikvision NVRs don't support channel capability checks, and the requests cause errors
|
||||
const oldModels = [
|
||||
/DS-76098NI-E2/,
|
||||
/ERI-K104-P4/
|
||||
];
|
||||
const model = await this.checkDeviceModel();
|
||||
if (!model)
|
||||
return;
|
||||
return !!model?.match(/DS-7608NI-E2/);
|
||||
}
|
||||
|
||||
async checkStreamSetup(channel: string, isOld: boolean): Promise<HikvisionCameraStreamSetup> {
|
||||
if (isOld) {
|
||||
this.console.error('NVR is old version. Defaulting camera capabilities to H.264/AAC');
|
||||
return {
|
||||
videoCodecType: "H.264",
|
||||
audioCodecType: "AAC",
|
||||
}
|
||||
}
|
||||
|
||||
const response = await this.request({
|
||||
url: `http://${this.ip}/ISAPI/Streaming/channels/${getChannel(channel)}/capabilities`,
|
||||
responseType: 'text',
|
||||
});
|
||||
|
||||
// this is bad:
|
||||
// <videoCodecType opt="H.264,H.265">H.265</videoCodecType>
|
||||
const vcodec = response.body.match(/>(.*?)<\/videoCodecType>/);
|
||||
const acodec = response.body.match(/>(.*?)<\/audioCompressionType>/);
|
||||
|
||||
return {
|
||||
videoCodecType: vcodec?.[1],
|
||||
audioCodecType: acodec?.[1],
|
||||
}
|
||||
return !!oldModels.find(oldModel => model?.match(oldModel));
|
||||
}
|
||||
|
||||
async jpegSnapshot(channel: string, timeout = 10000): Promise<Buffer> {
|
||||
@@ -478,4 +459,257 @@ export class HikvisionCameraAPI implements HikvisionAPI {
|
||||
return [...defaultMap.values()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getOverlay() {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}/ISAPI/System/Video/inputs/channels/1/overlays`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const json = await xml2js.parseStringPromise(response.body) as VideoOverlayRoot;
|
||||
|
||||
return { json, xml: response.body };
|
||||
}
|
||||
|
||||
async getOverlayText(overlayId: string) {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}//ISAPI/System/Video/inputs/channels/1/overlays/text/${overlayId}`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const json = await xml2js.parseStringPromise(response.body) as TextOverlayRoot;
|
||||
|
||||
return { json, xml: response.body };
|
||||
}
|
||||
|
||||
async updateOverlayText(overlayId: string, entry: TextOverlayRoot) {
|
||||
const builder = new xml2js.Builder();
|
||||
const xml = builder.buildObject(entry);
|
||||
|
||||
await this.request({
|
||||
method: 'PUT',
|
||||
url: `http://${this.ip}//ISAPI/System/Video/inputs/channels/1/overlays/text/${overlayId}`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
body: xml
|
||||
});
|
||||
}
|
||||
|
||||
async getSupplementLight(): Promise<{ json: SupplementLightRoot | any; xml: string }> {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}/ISAPI/Image/channels/1/supplementLight/capabilities`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const xml = response.body;
|
||||
const json = await xml2js.parseStringPromise(xml, {
|
||||
explicitArray: false,
|
||||
mergeAttrs: true,
|
||||
});
|
||||
return { json, xml };
|
||||
}
|
||||
|
||||
async setSupplementLight(params: { on?: boolean, brightness?: number, mode?: 'auto' | 'manual' }): Promise<void> {
|
||||
const { json } = await this.getSupplementLight();
|
||||
|
||||
if (json.ResponseStatus) {
|
||||
throw new Error("Supplemental light is not supported on this device.");
|
||||
}
|
||||
|
||||
const supp: any = json.SupplementLight;
|
||||
if (!supp) {
|
||||
throw new Error("Supplemental light configuration not available.");
|
||||
}
|
||||
|
||||
if (supp.supplementLightMode && supp.supplementLightMode.opt) {
|
||||
const availableModes = supp.supplementLightMode.opt.split(',').map(s => s.trim());
|
||||
const selectedMode = params.on
|
||||
? (availableModes.find(mode => mode.toLowerCase() !== 'close') || 'close')
|
||||
: 'close';
|
||||
supp.supplementLightMode = [selectedMode];
|
||||
}
|
||||
|
||||
if (params.mode) {
|
||||
supp.mixedLightBrightnessRegulatMode = [params.mode];
|
||||
} else if (params.on !== undefined) {
|
||||
supp.mixedLightBrightnessRegulatMode = [params.on ? "manual" : "auto"];
|
||||
}
|
||||
if (params.brightness !== undefined) {
|
||||
let brightness = Math.max(0, Math.min(100, params.brightness));
|
||||
supp.whiteLightBrightness = [brightness.toString()];
|
||||
}
|
||||
|
||||
const builder = new xml2js.Builder({
|
||||
headless: true,
|
||||
renderOpts: { pretty: false },
|
||||
});
|
||||
const newXml = builder.buildObject({ SupplementLight: supp });
|
||||
|
||||
await this.request({
|
||||
method: 'PUT',
|
||||
url: `http://${this.ip}/ISAPI/Image/channels/1/supplementLight`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
body: newXml,
|
||||
});
|
||||
}
|
||||
|
||||
async getAlarmCapabilities(): Promise<{ json: any; xml: string }> {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}/ISAPI/System/IO/inputs`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const xml = response.body;
|
||||
const json = await xml2js.parseStringPromise(xml, {
|
||||
explicitArray: false,
|
||||
mergeAttrs: true,
|
||||
});
|
||||
return { json, xml };
|
||||
}
|
||||
|
||||
async getAlarm(port: string): Promise<{ json: any; xml: string }> {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}/ISAPI/Event/triggers/IO-${port}`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const xml = response.body;
|
||||
const parsed = await xml2js.parseStringPromise(xml, { explicitArray: true });
|
||||
return { json: parsed.EventTrigger, xml };
|
||||
}
|
||||
|
||||
async setAlarm(isOn: boolean): Promise<{ json: any; xml: string }> {
|
||||
const data = `<IOPortData>
|
||||
<enabled>${isOn ? 'true' : 'false'}</enabled>
|
||||
<triggering>${isOn ? 'low' : 'high'}</triggering>
|
||||
</IOPortData>`;
|
||||
|
||||
const response = await this.request({
|
||||
method: 'PUT',
|
||||
url: `http://${this.ip}/ISAPI/System/IO/inputs/1`,
|
||||
responseType: 'text',
|
||||
headers: { 'Content-Type': 'application/xml' },
|
||||
body: data
|
||||
});
|
||||
|
||||
const xml = response.body;
|
||||
let json = {};
|
||||
|
||||
try {
|
||||
json = await xml2js.parseStringPromise(xml);
|
||||
} catch (error) {
|
||||
console.error("Failed to parse XML response for setAlarmInput:", error);
|
||||
}
|
||||
|
||||
return { json, xml };
|
||||
}
|
||||
|
||||
async getPtzCapabilities(): Promise<{ json: PtzCapabilitiesRoot; xml: string }> {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}/ISAPI/PTZCtrl/channels/1/capabilities`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const xml = response.body;
|
||||
const json = await xml2js.parseStringPromise(xml, {
|
||||
explicitArray: false,
|
||||
mergeAttrs: true,
|
||||
});
|
||||
return { json, xml };
|
||||
}
|
||||
|
||||
async setPtzPreset(presetId: string) {
|
||||
try {
|
||||
await this.request({
|
||||
method: 'PUT',
|
||||
url: `http://${this.ip}/ISAPI/PTZCtrl/channels/1/presets/${presetId}/goto`,
|
||||
responseType: 'text',
|
||||
headers: { 'Content-Type': 'application/xml' },
|
||||
});
|
||||
} catch (e) {
|
||||
this.console.error('Error during setPtzPreset', e);
|
||||
}
|
||||
}
|
||||
|
||||
async ptzCommand(command: PanTiltZoomCommand) {
|
||||
let startCommandData: string;
|
||||
let endCommandData: string;
|
||||
|
||||
const movement = 40;
|
||||
if (command.preset) {
|
||||
await this.setPtzPreset(command.preset);
|
||||
} else if (command.pan < 0 || command.pan > 0) {
|
||||
startCommandData = `<?xml version: "1.0" encoding="UTF-8"?><PTZData><pan>${command.pan > 0 ? movement : -movement}</pan><tilt>0</tilt></PTZData>`;
|
||||
endCommandData = `<?xml version: "1.0" encoding="UTF-8"?><PTZData><pan>0</pan><tilt>0</tilt></PTZData>`;
|
||||
} else if (command.tilt < 0 || command.tilt > 0) {
|
||||
startCommandData = `<?xml version: "1.0" encoding="UTF-8"?><PTZData><pan>0</pan><tilt>${command.tilt > 0 ? movement : -movement}</tilt></PTZData>`;
|
||||
endCommandData = `<?xml version: "1.0" encoding="UTF-8"?><PTZData><pan>0</pan><tilt>0</tilt></PTZData>`;
|
||||
} else if (command.zoom < 0 || command.zoom > 0) {
|
||||
startCommandData = `<?xml version: "1.0" encoding="UTF-8"?><PTZData><zoom>${command.zoom > 0 ? movement : -movement}</zoom></PTZData>`;
|
||||
endCommandData = `<?xml version: "1.0" encoding="UTF-8"?><PTZData><zoom>0</zoom></PTZData>`;
|
||||
}
|
||||
|
||||
if (!startCommandData || !endCommandData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.request({
|
||||
method: 'PUT',
|
||||
url: `http://${this.ip}/ISAPI/PTZCtrl/channels/1/continuous`,
|
||||
responseType: 'text',
|
||||
headers: { 'Content-Type': 'application/xml' },
|
||||
body: startCommandData
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
|
||||
await this.request({
|
||||
method: 'PUT',
|
||||
url: `http://${this.ip}/ISAPI/PTZCtrl/channels/1/continuous`,
|
||||
responseType: 'text',
|
||||
headers: { 'Content-Type': 'application/xml' },
|
||||
body: endCommandData
|
||||
});
|
||||
} catch (e) {
|
||||
this.console.error('Error during PTZ command', e);
|
||||
}
|
||||
}
|
||||
|
||||
async getPresets() {
|
||||
const response = await this.request({
|
||||
method: 'GET',
|
||||
url: `http://${this.ip}/ISAPI/PTZCtrl/channels/1/presets`,
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
const json = await xml2js.parseStringPromise(response.body) as PtzPresetsRoot;
|
||||
|
||||
return { json, xml: response.body };
|
||||
}
|
||||
}
|
||||
112
plugins/hikvision/src/hikvision-overlay.ts
Normal file
112
plugins/hikvision/src/hikvision-overlay.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
export interface VideoOverlayRoot {
|
||||
VideoOverlay: VideoOverlay;
|
||||
}
|
||||
|
||||
export interface VideoOverlay {
|
||||
$: VideoOverlayClass;
|
||||
normalizedScreenSize: NormalizedScreenSize[];
|
||||
attribute: Attribute[];
|
||||
fontSize: string[];
|
||||
TextOverlayList: TextOverlayListElement[];
|
||||
DateTimeOverlay: DateTimeOverlay[];
|
||||
channelNameOverlay: ChannelNameOverlay[];
|
||||
frontColorMode: string[];
|
||||
frontColor: string[];
|
||||
alignment: string[];
|
||||
boundary: string[];
|
||||
upDownboundary: string[];
|
||||
leftRightboundary: string[];
|
||||
}
|
||||
|
||||
export interface VideoOverlayClass {
|
||||
version: string;
|
||||
xmlns: string;
|
||||
}
|
||||
|
||||
export interface DateTimeOverlay {
|
||||
enabled: string[];
|
||||
positionX: string[];
|
||||
positionY: string[];
|
||||
dateStyle: string[];
|
||||
timeStyle: string[];
|
||||
displayWeek: string[];
|
||||
}
|
||||
|
||||
export interface TextOverlayListElement {
|
||||
$: TextOverlayList;
|
||||
TextOverlay: TextOverlay[];
|
||||
}
|
||||
|
||||
export interface TextOverlayList {
|
||||
size: string;
|
||||
}
|
||||
|
||||
export interface TextOverlay {
|
||||
id: string[];
|
||||
enabled: string[];
|
||||
positionX: string[];
|
||||
positionY: string[];
|
||||
displayText: string[];
|
||||
isPersistentText: string[];
|
||||
}
|
||||
|
||||
export interface Attribute {
|
||||
transparent: string[];
|
||||
flashing: string[];
|
||||
}
|
||||
|
||||
export interface ChannelNameOverlay {
|
||||
$: VideoOverlayClass;
|
||||
enabled: string[];
|
||||
positionX: string[];
|
||||
positionY: string[];
|
||||
}
|
||||
|
||||
export interface NormalizedScreenSize {
|
||||
normalizedScreenWidth: string[];
|
||||
normalizedScreenHeight: string[];
|
||||
}
|
||||
|
||||
|
||||
export interface TextOverlayRoot {
|
||||
TextOverlay: TextOverlay;
|
||||
}
|
||||
|
||||
export interface TextOverlay {
|
||||
$: Empty;
|
||||
id: string[];
|
||||
enabled: string[];
|
||||
positionX: string[];
|
||||
positionY: string[];
|
||||
displayText: string[];
|
||||
directAngle: string[];
|
||||
}
|
||||
|
||||
export interface Empty {
|
||||
version: string;
|
||||
xmlns: string;
|
||||
}
|
||||
|
||||
export interface PtzPresetsRoot {
|
||||
PTZPresetList: PTZPresetList;
|
||||
}
|
||||
|
||||
export interface PTZPresetList {
|
||||
PTZPreset: PTZPreset[];
|
||||
_xmlns: string;
|
||||
_version: string;
|
||||
}
|
||||
|
||||
export interface PTZPreset {
|
||||
enabled: string;
|
||||
id: string;
|
||||
presetName: string;
|
||||
AbsoluteHigh: AbsoluteHigh;
|
||||
}
|
||||
|
||||
export interface AbsoluteHigh {
|
||||
elevation: string;
|
||||
azimuth: string;
|
||||
absoluteZoom: string;
|
||||
}
|
||||
|
||||
@@ -172,4 +172,49 @@ export interface ChannelResponse {
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// }
|
||||
// }
|
||||
|
||||
export interface ValueWithRange {
|
||||
_: string;
|
||||
$: {
|
||||
min: string;
|
||||
max: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SupplementLightRoot {
|
||||
SupplementLight: SupplementLight;
|
||||
}
|
||||
|
||||
export interface SupplementLight {
|
||||
mode: string[];
|
||||
Schedule?: Schedule[];
|
||||
brightnessLimit: ValueWithRange[];
|
||||
supplementLightMode: string[];
|
||||
whiteLightBrightness?: ValueWithRange[];
|
||||
}
|
||||
|
||||
export interface Schedule {
|
||||
TimeRange: TimeRange[];
|
||||
}
|
||||
|
||||
export interface TimeRange {
|
||||
beginTime: string[];
|
||||
endTime: string[];
|
||||
}
|
||||
|
||||
export interface BrightnessLimit {
|
||||
_: string;
|
||||
$: {
|
||||
min: string;
|
||||
max: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface LightBrightness {
|
||||
_: string;
|
||||
$: {
|
||||
min: string;
|
||||
max: string;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { automaticallyConfigureSettings, checkPluginNeedsAutoConfigure } from "@scrypted/common/src/autoconfigure-codecs";
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, MediaObject, MediaStreamOptions, ObjectDetectionResult, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, Reboot, RequestPictureOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, VideoCameraConfiguration } from "@scrypted/sdk";
|
||||
import sdk, { Camera, Device, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, MediaObject, MediaStreamOptions, ObjectDetectionResult, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, PanTiltZoom, PanTiltZoomCommand, Reboot, RequestPictureOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, VideoCameraConfiguration, VideoTextOverlay, VideoTextOverlays } from "@scrypted/sdk";
|
||||
import crypto from 'crypto';
|
||||
import { PassThrough } from "stream";
|
||||
import xml2js from 'xml2js';
|
||||
@@ -10,6 +10,8 @@ import { startRtpForwarderProcess } from '../../webrtc/src/rtp-forwarders';
|
||||
import { HikvisionAPI } from "./hikvision-api-channels";
|
||||
import { autoconfigureSettings, hikvisionAutoConfigureSettings } from "./hikvision-autoconfigure";
|
||||
import { detectionMap, HikvisionCameraAPI, HikvisionCameraEvent } from "./hikvision-camera-api";
|
||||
import { HikvisionSupplementalLight } from "./supplemental-light";
|
||||
import { HikvisionAlarmSwitch } from "./alarm-switch";
|
||||
|
||||
const rtspChannelSetting: Setting = {
|
||||
subgroup: 'Advanced',
|
||||
@@ -27,11 +29,14 @@ function channelToCameraNumber(channel: string) {
|
||||
return channel.substring(0, channel.length - 2);
|
||||
}
|
||||
|
||||
export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom, Reboot, ObjectDetector, VideoCameraConfiguration {
|
||||
export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom, Reboot, ObjectDetector, VideoCameraConfiguration, VideoTextOverlays, PanTiltZoom {
|
||||
detectedChannels: Promise<Map<string, MediaStreamOptions>>;
|
||||
onvifIntercom = new OnvifIntercom(this);
|
||||
activeIntercom: Awaited<ReturnType<typeof startRtpForwarderProcess>>;
|
||||
hasSmartDetection: boolean;
|
||||
supplementLight: HikvisionSupplementalLight;
|
||||
alarm: HikvisionAlarmSwitch;
|
||||
ptzPresets: string[];
|
||||
|
||||
client: HikvisionAPI;
|
||||
|
||||
@@ -39,8 +44,43 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
super(nativeId, provider);
|
||||
|
||||
this.hasSmartDetection = this.storage.getItem('hasSmartDetection') === 'true';
|
||||
this.ptzPresets = JSON.parse(this.storage.getItem('storedPtzPresets') ?? '[]');
|
||||
|
||||
this.updateDevice();
|
||||
this.updateDeviceInfo();
|
||||
this.reportDevices();
|
||||
|
||||
if (this.interfaces.includes(ScryptedInterface.PanTiltZoom)) {
|
||||
const ptzCapabilities = JSON.parse(this.storage.getItem('ptzCapabilities') ?? '[]');
|
||||
this.fetchPtzPresets().catch(this.console.error);
|
||||
this.updatePtzCaps(ptzCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
async getVideoTextOverlays(): Promise<Record<string, VideoTextOverlay>> {
|
||||
const client = this.getClient();
|
||||
const overlays = await client.getOverlay();
|
||||
const ret: Record<string, VideoTextOverlay> = {};
|
||||
|
||||
for (const to of overlays.json.VideoOverlay.TextOverlayList?.[0]?.TextOverlay) {
|
||||
ret[to.id[0]] = {
|
||||
text: to.displayText[0],
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
async setVideoTextOverlay(id: string, value: VideoTextOverlay): Promise<void> {
|
||||
const client = this.getClient();
|
||||
const overlays = await client.getOverlay();
|
||||
// find the overlay by id
|
||||
const overlay = overlays.json.VideoOverlay.TextOverlayList?.[0]?.TextOverlay.find(o => o.id[0] === id);
|
||||
overlay.enabled[0] = value.text ? 'true' : 'false';
|
||||
if (typeof value.text === 'string')
|
||||
overlay.displayText = [value.text];
|
||||
client.updateOverlayText(id, {
|
||||
TextOverlay: overlay,
|
||||
});
|
||||
}
|
||||
|
||||
async reboot() {
|
||||
@@ -77,6 +117,11 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
async ptzCommand(command: PanTiltZoomCommand): Promise<void> {
|
||||
const client = this.getClient();
|
||||
await client.ptzCommand(command);
|
||||
}
|
||||
|
||||
async listenEvents() {
|
||||
let motionTimeout: NodeJS.Timeout;
|
||||
const api = (this.provider as HikvisionProvider).createSharedClient(this.getHttpAddress(), this.getUsername(), this.getPassword());
|
||||
@@ -161,14 +206,9 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
|
||||
const now = Date.now();
|
||||
let detections: ObjectDetectionResult[] = xml.EventNotificationAlert?.DetectionRegionList?.map(region => {
|
||||
const { DetectionRegionEntry } = region;
|
||||
const dre = DetectionRegionEntry[0];
|
||||
if (!DetectionRegionEntry)
|
||||
const name = region?.DetectionRegionEntry?.[0]?.detectionTarget?.name;
|
||||
if (!name)
|
||||
return;
|
||||
const { detectionTarget } = dre;
|
||||
// const { TargetRect } = dre;
|
||||
// const { X, Y, width, height } = TargetRect[0];
|
||||
const [name] = detectionTarget;
|
||||
return {
|
||||
score: 1,
|
||||
className: detectionMap[name] || name,
|
||||
@@ -385,6 +425,9 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
|| this.storage.getItem('twoWayAudio') === 'ONVIF'
|
||||
|| this.storage.getItem('twoWayAudio') === 'Hikvision';
|
||||
|
||||
const providedDevices = JSON.parse(this.storage.getItem('providedDevices') || '[]') as string[];
|
||||
const ptzCapabilities = JSON.parse(this.storage.getItem('ptzCapabilities') || '[]') as string[];
|
||||
|
||||
const interfaces = this.provider.getInterfaces();
|
||||
let type: ScryptedDeviceType = undefined;
|
||||
if (isDoorbell) {
|
||||
@@ -398,10 +441,64 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
if (this.hasSmartDetection)
|
||||
interfaces.push(ScryptedInterface.ObjectDetector);
|
||||
|
||||
if (!!providedDevices?.length) {
|
||||
interfaces.push(ScryptedInterface.DeviceProvider);
|
||||
}
|
||||
|
||||
if (!!ptzCapabilities?.length) {
|
||||
interfaces.push(ScryptedInterface.PanTiltZoom);
|
||||
}
|
||||
|
||||
this.provider.updateDevice(this.nativeId, this.name, interfaces, type);
|
||||
}
|
||||
|
||||
async putSetting(key: string, value: string) {
|
||||
async fetchPtzPresets() {
|
||||
try {
|
||||
const client = this.getClient();
|
||||
const cameraPresets: string[] = [];
|
||||
const presets = await client.getPresets();
|
||||
|
||||
const allPresets = presets.json?.PTZPresetList?.PTZPreset ?? [];
|
||||
for (const to of allPresets) {
|
||||
if (to.enabled?.[0] === 'true') {
|
||||
cameraPresets.push(`${to.id?.[0]}=${to.presetName?.[0]}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.storage.setItem('storedPtzPresets', JSON.stringify(cameraPresets));
|
||||
this.ptzPresets = cameraPresets;
|
||||
} catch (e) {
|
||||
this.console.error('Error in fetchPtzPresets', e);
|
||||
this.ptzPresets = [];
|
||||
}
|
||||
}
|
||||
|
||||
async updatePtzCaps(cameraPtzCapabilities: string[]) {
|
||||
this.ptzCapabilities = {
|
||||
...this.ptzCapabilities,
|
||||
pan: cameraPtzCapabilities?.includes('Pan'),
|
||||
tilt: cameraPtzCapabilities?.includes('Tilt'),
|
||||
zoom: cameraPtzCapabilities?.includes('Zoom'),
|
||||
}
|
||||
}
|
||||
|
||||
async updatePtzPresets(ptzPresets: string[]) {
|
||||
const presets: Record<string, string> = {};
|
||||
|
||||
ptzPresets.forEach(preset => {
|
||||
const parts = preset.split('=');
|
||||
if (parts.length === 2) {
|
||||
presets[parts[0]] = parts[1];
|
||||
}
|
||||
});
|
||||
|
||||
this.ptzCapabilities = {
|
||||
...this.ptzCapabilities,
|
||||
presets
|
||||
};
|
||||
}
|
||||
|
||||
async putSetting(key: string, value: string | string[]) {
|
||||
if (key === automaticallyConfigureSettings.key) {
|
||||
const client = this.getClient();
|
||||
autoconfigureSettings(client, this.getCameraNumber() || '1')
|
||||
@@ -413,14 +510,20 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
this.console.error('error autoconfiguring', e);
|
||||
});
|
||||
return;
|
||||
} else if (key === 'ptzPresets') {
|
||||
await this.updatePtzPresets(value as string[]);
|
||||
} else if (key === 'ptzCapabilities' && !!value?.length) {
|
||||
await this.fetchPtzPresets();
|
||||
this.updatePtzCaps(value as string[]);
|
||||
}
|
||||
|
||||
this.client = undefined;
|
||||
this.detectedChannels = undefined;
|
||||
super.putSetting(key, value);
|
||||
super.putSetting(key, typeof value === 'string' ? value : JSON.stringify(value));
|
||||
|
||||
this.updateDevice();
|
||||
this.updateDeviceInfo();
|
||||
this.reportDevices();
|
||||
}
|
||||
|
||||
async getOtherSettings(): Promise<Setting[]> {
|
||||
@@ -444,6 +547,9 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
if (!twoWayAudio)
|
||||
twoWayAudio = isDoorbell ? 'Hikvision' : 'None';
|
||||
|
||||
const providedDevices = JSON.parse(this.storage.getItem('providedDevices') || '[]') as string[];
|
||||
const ptzCapabilities = JSON.parse(this.storage.getItem('ptzCapabilities') || '[]') as string[];
|
||||
|
||||
ret.push(
|
||||
{
|
||||
subgroup: 'Advanced',
|
||||
@@ -461,8 +567,47 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
description: 'Hikvision cameras may support both Hikvision and ONVIF two way audio protocols. ONVIF generally performs better when supported.',
|
||||
choices,
|
||||
},
|
||||
{
|
||||
key: 'providedDevices',
|
||||
subgroup: 'Advanced',
|
||||
title: 'Provided devices',
|
||||
value: providedDevices,
|
||||
choices: [
|
||||
'Alarm',
|
||||
'SupplementLight',
|
||||
],
|
||||
multiple: true,
|
||||
},
|
||||
{
|
||||
key: 'ptzCapabilities',
|
||||
subgroup: 'Advanced',
|
||||
value: ptzCapabilities,
|
||||
title: 'PTZ Capabilities',
|
||||
choices: [
|
||||
'Pan',
|
||||
'Tilt',
|
||||
'Zoom',
|
||||
],
|
||||
multiple: true,
|
||||
},
|
||||
);
|
||||
|
||||
if (this.interfaces.includes(ScryptedInterface.PanTiltZoom)) {
|
||||
const ptzPresets = JSON.parse(this.storage.getItem('ptzPresets') || '[]');
|
||||
ret.push(
|
||||
{
|
||||
key: 'ptzPresets',
|
||||
subgroup: 'Advanced',
|
||||
value: ptzPresets,
|
||||
title: 'Presets',
|
||||
description: 'PTZ Presets in the format "id=name". Where id is the PTZ Preset identifier and name is a friendly name.',
|
||||
multiple: true,
|
||||
combobox: true,
|
||||
choices: this.ptzPresets,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const ac = {
|
||||
...automaticallyConfigureSettings,
|
||||
subgroup: 'Advanced',
|
||||
@@ -477,6 +622,70 @@ export class HikvisionCamera extends RtspSmartCamera implements Camera, Intercom
|
||||
return ret;
|
||||
}
|
||||
|
||||
reportDevices() {
|
||||
const providedDevices = JSON.parse(this.storage.getItem('providedDevices') || '[]') as string[];
|
||||
const devices: Device[] = [];
|
||||
|
||||
if (providedDevices?.includes('Alarm')) {
|
||||
const alarmNativeId = `${this.nativeId}-alarm`;
|
||||
const alarmDevice: Device = {
|
||||
providerNativeId: this.nativeId,
|
||||
name: `${this.name} Alarm`,
|
||||
nativeId: alarmNativeId,
|
||||
info: {
|
||||
...this.info,
|
||||
},
|
||||
interfaces: [
|
||||
ScryptedInterface.OnOff,
|
||||
ScryptedInterface.Readme,
|
||||
],
|
||||
type: ScryptedDeviceType.Switch,
|
||||
};
|
||||
devices.push(alarmDevice);
|
||||
}
|
||||
|
||||
if (providedDevices?.includes('SupplementLight')) {
|
||||
const supplementLightNativeId = `${this.nativeId}-supplementlight`;
|
||||
const supplementLightDevice: Device = {
|
||||
providerNativeId: this.nativeId,
|
||||
name: `${this.name} Supplemental Light`,
|
||||
nativeId: supplementLightNativeId,
|
||||
info: {
|
||||
...this.info,
|
||||
},
|
||||
interfaces: [
|
||||
ScryptedInterface.OnOff,
|
||||
ScryptedInterface.Brightness,
|
||||
ScryptedInterface.Settings,
|
||||
],
|
||||
type: ScryptedDeviceType.Light,
|
||||
};
|
||||
devices.push(supplementLightDevice);
|
||||
}
|
||||
|
||||
sdk.deviceManager.onDevicesChanged({
|
||||
providerNativeId: this.nativeId,
|
||||
devices,
|
||||
});
|
||||
}
|
||||
|
||||
async getDevice(nativeId: string): Promise<any> {
|
||||
if (nativeId.endsWith('-supplementlight')) {
|
||||
this.supplementLight ||= new HikvisionSupplementalLight(this, nativeId);
|
||||
return this.supplementLight;
|
||||
}
|
||||
if (nativeId.endsWith('-alarm')) {
|
||||
this.alarm ||= new HikvisionAlarmSwitch(this, nativeId);
|
||||
return this.alarm;
|
||||
}
|
||||
}
|
||||
|
||||
async releaseDevice(id: string, nativeId: string) {
|
||||
if (nativeId.endsWith('-supplementlight'))
|
||||
delete this.supplementLight;
|
||||
else if (nativeId.endsWith('-alarm'))
|
||||
delete this.alarm;
|
||||
}
|
||||
|
||||
async startIntercom(media: MediaObject): Promise<void> {
|
||||
if (this.storage.getItem('twoWayAudio') === 'ONVIF') {
|
||||
@@ -631,6 +840,7 @@ class HikvisionProvider extends RtspProvider {
|
||||
ScryptedInterface.Reboot,
|
||||
ScryptedInterface.Camera,
|
||||
ScryptedInterface.MotionSensor,
|
||||
ScryptedInterface.VideoTextOverlays,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
66
plugins/hikvision/src/supplemental-light.ts
Normal file
66
plugins/hikvision/src/supplemental-light.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { Brightness, OnOff, ScryptedDeviceBase, Setting, Settings, SettingValue } from "@scrypted/sdk";
|
||||
import { StorageSettings } from "@scrypted/sdk/storage-settings";
|
||||
import type { HikvisionCamera } from "./main";
|
||||
|
||||
export class HikvisionSupplementalLight extends ScryptedDeviceBase implements OnOff, Brightness, Settings {
|
||||
storageSettings = new StorageSettings(this, {
|
||||
mode: {
|
||||
title: 'Mode',
|
||||
description: 'Choose "auto" for automatic brightness control or "manual" for custom brightness.',
|
||||
defaultValue: 'auto',
|
||||
type: 'string',
|
||||
choices: ['auto', 'manual'],
|
||||
onPut: async () => {
|
||||
await this.updateSupplementalLight();
|
||||
},
|
||||
},
|
||||
brightness: {
|
||||
title: 'Manual Brightness',
|
||||
description: 'Set brightness (0–100) when in manual mode.',
|
||||
defaultValue: 100,
|
||||
type: 'number',
|
||||
placeholder: '0-100',
|
||||
immediate: true,
|
||||
onPut: async () => {
|
||||
await this.updateSupplementalLight();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
on: boolean = false;
|
||||
brightness: number = 100;
|
||||
|
||||
constructor(public camera: HikvisionCamera, nativeId: string) {
|
||||
super(nativeId);
|
||||
}
|
||||
|
||||
async turnOn(): Promise<void> {
|
||||
this.on = true;
|
||||
await this.updateSupplementalLight();
|
||||
}
|
||||
|
||||
async turnOff(): Promise<void> {
|
||||
this.on = false;
|
||||
await this.updateSupplementalLight();
|
||||
}
|
||||
|
||||
async setBrightness(brightness: number): Promise<void> {
|
||||
this.brightness = brightness;
|
||||
await this.updateSupplementalLight();
|
||||
}
|
||||
|
||||
private async updateSupplementalLight(): Promise<void> {
|
||||
const api = this.camera.getClient();
|
||||
const mode = this.storageSettings.values.mode;
|
||||
const brightness = this.storageSettings.values.brightness;
|
||||
await api.setSupplementLight({ on: this.on, brightness: brightness, mode });
|
||||
}
|
||||
|
||||
async getSettings(): Promise<Setting[]> {
|
||||
return this.storageSettings.getSettings();
|
||||
}
|
||||
|
||||
async putSetting(key: string, value: SettingValue): Promise<void> {
|
||||
await this.storageSettings.putSetting(key, value);
|
||||
}
|
||||
}
|
||||
2
plugins/homekit/.vscode/settings.json
vendored
2
plugins/homekit/.vscode/settings.json
vendored
@@ -1,4 +1,4 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1"
|
||||
"scrypted.debugHost": "scrypted-nvr"
|
||||
}
|
||||
4
plugins/homekit/package-lock.json
generated
4
plugins/homekit/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/homekit",
|
||||
"version": "1.2.61",
|
||||
"version": "1.2.65",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/homekit",
|
||||
"version": "1.2.61",
|
||||
"version": "1.2.65",
|
||||
"dependencies": {
|
||||
"@koush/werift-src": "file:../../external/werift",
|
||||
"check-disk-space": "^3.4.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/homekit",
|
||||
"version": "1.2.61",
|
||||
"version": "1.2.65",
|
||||
"description": "HomeKit Plugin for Scrypted",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
|
||||
@@ -8,7 +8,7 @@ const { systemManager, deviceManager, log } = sdk;
|
||||
|
||||
export const defaultObjectDetectionContactSensorTimeout = 60;
|
||||
|
||||
export function canCameraMixin(type: ScryptedDeviceType, interfaces: string[]) {
|
||||
export function canCameraMixin(type: ScryptedDeviceType | string, interfaces: string[]) {
|
||||
return (type === ScryptedDeviceType.Camera || type === ScryptedDeviceType.Doorbell)
|
||||
&& interfaces.includes(ScryptedInterface.VideoCamera);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { HomeKitPlugin } from "./main";
|
||||
|
||||
export interface DummyDevice {
|
||||
interfaces?: string[];
|
||||
type?: ScryptedDeviceType;
|
||||
type?: ScryptedDeviceType | string;
|
||||
}
|
||||
|
||||
export interface SnapshotThrottle {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user