@camera.ui/server 0.0.50-internal.0 → 0.0.50-internal.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interface/index.html +44 -44
- package/dist/interface/js/{@primevue.OhxoO3MD.0.0.50-internal.0.js → @primevue.BAIU_p3r.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{@tanstack.D1IL6eOv.0.0.50-internal.0.js → @tanstack.mdCorqzE.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{@vee-validate.BGPyWWTh.0.0.50-internal.0.js → @vee-validate.D0vsSsly.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{@vueuse.BsKtqdiG.0.0.50-internal.0.js → @vueuse.we5ZpWr2.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{Adminpanel.D93Kvbwp.0.0.50-internal.0.js → Adminpanel.9AEBJ3H1.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{Camera.DF2l3OMA.0.0.50-internal.0.js → Camera.CZcnEH0C.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{Cameras.YzvZccdv.0.0.50-internal.0.js → Cameras.DE0LkcGu.0.0.50-internal.2.js} +2 -2
- package/dist/interface/js/Cammesh.CVvmkelB.0.0.50-internal.2.js +1 -0
- package/dist/interface/js/{Camview.CB7_HnoQ.0.0.50-internal.0.js → Camview.CUr4pGoU.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{Config.BwflsWTm.0.0.50-internal.0.js → Config.CaJhu4fF.0.0.50-internal.2.js} +2 -2
- package/dist/interface/js/{Console.DZM8pN8Q.0.0.50-internal.0.js → Console.5VUmgryj.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{CuiConsole.BXXU7Gth.0.0.50-internal.0.js → CuiConsole.iYmUxAR5.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{CuiPluginCard.YFOrpbVD.0.0.50-internal.0.js → CuiPluginCard.DXPyE5mF.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{CuiTimeline.VV5KSJd5.0.0.50-internal.0.js → CuiTimeline.BqtlOFnV.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{FirstSteps.b-nvymgb.0.0.50-internal.0.js → FirstSteps.C_RI-SDQ.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{Plugin.BOMpVEwM.0.0.50-internal.0.js → Plugin.Ch_v02eN.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{Plugins.DdPwaUDA.0.0.50-internal.0.js → Plugins.BpXAYgSG.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/Recordings.CIKHJytH.0.0.50-internal.2.js +1 -0
- package/dist/interface/js/{Settings.D24ttaPu.0.0.50-internal.0.js → Settings.BcLoGNEy.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{SettingsAccount.ms3aqz4E.0.0.50-internal.0.js → SettingsAccount.DMROW8kx.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/SettingsAppearance.CUaHpihp.0.0.50-internal.2.js +1 -0
- package/dist/interface/js/{SettingsAppearance.vue_vue_type_script_setup_true_lang.CBQ6lL3T.0.0.50-internal.0.js → SettingsAppearance.vue_vue_type_script_setup_true_lang.BuKZ-Uco.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{SettingsBackup.BPEc4Rjg.0.0.50-internal.0.js → SettingsBackup.0QdwFSpv.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/SettingsRecordings.B-aj0U8_.0.0.50-internal.2.js +1 -0
- package/dist/interface/js/{SettingsRemote.BL5nXbUT.0.0.50-internal.0.js → SettingsRemote.Bi1YAJ76.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{SettingsSystem.D7T0AIpm.0.0.50-internal.0.js → SettingsSystem.CAx66Iir.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{SettingsUsers.1u0vCOVG.0.0.50-internal.0.js → SettingsUsers.CQcDtGy1.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{VersionsHandler.vue_vue_type_script_setup_true_lang.xDishkkS.0.0.50-internal.0.js → VersionsHandler.vue_vue_type_script_setup_true_lang.BhXMzIhV.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{ace-builds.D1nmvCwb.0.0.50-internal.0.js → ace-builds.C0sCXSu5.0.0.50-internal.2.js} +2 -2
- package/dist/interface/js/{ace.config.G96T2z54.0.0.50-internal.0.js → ace.config.DNqPWa0Q.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{backup.B_Gzxtp_.0.0.50-internal.0.js → backup.DAXgG3bP.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{chart.js.CP_nMnnf.0.0.50-internal.0.js → chart.js.Bq3YocRX.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{close-circle.DYLuVIOg.0.0.50-internal.0.js → close-circle.9rxyNw0z.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{dnd-core.T9OeW7mu.0.0.50-internal.0.js → dnd-core.BuEvHAsS.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{draggabilly.D3zGcBb3.0.0.50-internal.0.js → draggabilly.DUdE08x8.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{engine.io-client.kITRnq-g.0.0.50-internal.0.js → engine.io-client.DWU6YI8o.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{fast-deep-equal.Bpc9mIsj.0.0.50-internal.0.js → fast-deep-equal.BpPyC6E4.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{highlight.js.BlSXU-Wb.0.0.50-internal.0.js → highlight.js.BoR2Rhdd.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{linkify-it.C3N1lWsJ.0.0.50-internal.0.js → linkify-it.BXzPONHs.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{main.D0YR3Jat.0.0.50-internal.0.js → main.DwcBYfWc.0.0.50-internal.2.js} +3 -3
- package/dist/interface/js/{markdown-it.Dj0dt5s2.0.0.50-internal.0.js → markdown-it.BUDVOjPt.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{nprogress.BwQWDcGj.0.0.50-internal.0.js → nprogress.CsG-OBoI.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{pinia.DRh7plEC.0.0.50-internal.0.js → pinia.CqEQao5R.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{primevue.Cl58krXf.0.0.50-internal.0.js → primevue.D91sslRx.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{qrcode.C1sDj6P8.0.0.50-internal.0.js → qrcode.SdSTPzZO.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{react-dnd-touch-backend.BA4WhUJo.0.0.50-internal.0.js → react-dnd-touch-backend.BwroebQ4.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{refresh-rounded.D_SmhhUf.0.0.50-internal.0.js → refresh-rounded.DxM48YSv.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{rxjs.C-fTBwEO.0.0.50-internal.0.js → rxjs.Cmpbnzo4.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{socket.io-client.DKrRxgjP.0.0.50-internal.0.js → socket.io-client.DF2YgZo1.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{socket.io-parser.EXj3YDH2.0.0.50-internal.0.js → socket.io-parser.BUs2ineY.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{system.CY8rGd-Q.0.0.50-internal.0.js → system.DmkT2LKx.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{trash-fill.CMnCN3Oy.0.0.50-internal.0.js → trash-fill.dPzyZDVa.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{unidragger.D0w6Tqtt.0.0.50-internal.0.js → unidragger.y2ZlFveS.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vee-validate.BeiObIH8.0.0.50-internal.0.js → vee-validate.Y-alCADW.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vue-chartjs.DtdZdiYw.0.0.50-internal.0.js → vue-chartjs.sRVFTqDf.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vue-i18n.BW2bx_6z.0.0.50-internal.0.js → vue-i18n.D5WrXOZa.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vue-inline-svg.BJkQGmKz.0.0.50-internal.0.js → vue-inline-svg.R0uz_abA.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vue-router.B2mOXHaC.0.0.50-internal.0.js → vue-router.65mnGy-o.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vue-zoomable.BKDyCJE7.0.0.50-internal.0.js → vue-zoomable.B1Qop6Uu.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{vue3-dnd.DRK24CBp.0.0.50-internal.0.js → vue3-dnd.CwmyAcir.0.0.50-internal.2.js} +1 -1
- package/dist/interface/js/{zoom-out.DxvzgVEo.0.0.50-internal.0.js → zoom-out.CMPALvRh.0.0.50-internal.2.js} +1 -1
- package/dist/interface/sw.js +1 -1
- package/dist/server/package.json +1 -1
- package/dist/server/src/rpc/server.js +4 -1
- package/dist/server/src/rpc/server.js.map +1 -1
- package/package.json +1 -1
- package/.prettierignore +0 -12
- package/.prettierrc.json +0 -12
- package/artillery.yaml +0 -29
- package/bin/cameraui-server.ts +0 -11
- package/dist/interface/js/Cammesh.D-6dAROQ.0.0.50-internal.0.js +0 -1
- package/dist/interface/js/Recordings.DhxjIW7e.0.0.50-internal.0.js +0 -1
- package/dist/interface/js/SettingsAppearance.DsTjKXk1.0.0.50-internal.0.js +0 -1
- package/dist/interface/js/SettingsRecordings.DgW7M0jj.0.0.50-internal.0.js +0 -1
- package/eslint.config.js +0 -103
- package/localdeps.txt +0 -10
- package/mypy.ini +0 -30
- package/requirements.txt +0 -15
- package/ruff.toml +0 -90
- package/src/__init__.py +0 -0
- package/src/_camera_ui_tools/__init__.py +0 -0
- package/src/_camera_ui_tools/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/api/controllers/api.controller.ts +0 -19
- package/src/api/controllers/auth.controller.ts +0 -294
- package/src/api/controllers/backup.controller.ts +0 -72
- package/src/api/controllers/cameras.controller.ts +0 -1029
- package/src/api/controllers/config.controller.ts +0 -102
- package/src/api/controllers/files.controller.ts +0 -35
- package/src/api/controllers/frameWorkers.controller.ts +0 -109
- package/src/api/controllers/plugins.controller.ts +0 -1206
- package/src/api/controllers/system.controller.ts +0 -273
- package/src/api/controllers/users.controller.ts +0 -648
- package/src/api/database/checks.ts +0 -268
- package/src/api/database/constants.ts +0 -8
- package/src/api/database/index.ts +0 -262
- package/src/api/database/migration.ts +0 -62
- package/src/api/database/selfcheck.ts +0 -492
- package/src/api/database/types.ts +0 -104
- package/src/api/go2rtc/api/application.ts +0 -48
- package/src/api/go2rtc/api/config.ts +0 -61
- package/src/api/go2rtc/api/discover.ts +0 -197
- package/src/api/go2rtc/api/index.ts +0 -49
- package/src/api/go2rtc/api/snapshot.ts +0 -44
- package/src/api/go2rtc/api/streams.ts +0 -168
- package/src/api/go2rtc/index.ts +0 -43
- package/src/api/go2rtc/queue.ts +0 -50
- package/src/api/go2rtc/types.ts +0 -174
- package/src/api/index.ts +0 -286
- package/src/api/middlewares/authPermission.middleware.ts +0 -46
- package/src/api/middlewares/authValidation.middleware.ts +0 -160
- package/src/api/middlewares/pagination.middleware.ts +0 -67
- package/src/api/middlewares/socketAuth.middleware.ts +0 -136
- package/src/api/plugins/header.plugin.ts +0 -15
- package/src/api/plugins/logger.plugin.ts +0 -44
- package/src/api/plugins/proxy.plugin.ts +0 -255
- package/src/api/plugins/socket.plugin.ts +0 -28
- package/src/api/plugins/system.plugin.ts +0 -48
- package/src/api/plugins/useragent.plugin.ts +0 -19
- package/src/api/routes/api.routes.ts +0 -10
- package/src/api/routes/auth.routes.ts +0 -56
- package/src/api/routes/backup.routes.ts +0 -28
- package/src/api/routes/cameras.routes.ts +0 -281
- package/src/api/routes/config.routes.ts +0 -66
- package/src/api/routes/files.routes.ts +0 -15
- package/src/api/routes/frameWorkers.routes.ts +0 -39
- package/src/api/routes/index.ts +0 -37
- package/src/api/routes/plugins.routes.ts +0 -420
- package/src/api/routes/system.routes.ts +0 -101
- package/src/api/routes/users.routes.ts +0 -167
- package/src/api/schemas/backup.schema.ts +0 -112
- package/src/api/schemas/cameras.schema.ts +0 -479
- package/src/api/schemas/config.schema.ts +0 -38
- package/src/api/schemas/go2rtc.schema.ts +0 -189
- package/src/api/schemas/plugins.schema.ts +0 -126
- package/src/api/schemas/storage.schema.ts +0 -11
- package/src/api/schemas/system.schema.ts +0 -45
- package/src/api/schemas/users.schema.ts +0 -185
- package/src/api/services/auth.service.ts +0 -210
- package/src/api/services/backup.service.ts +0 -144
- package/src/api/services/cameras.service.ts +0 -671
- package/src/api/services/plugins.service.ts +0 -470
- package/src/api/services/system.service.ts +0 -85
- package/src/api/services/users.service.ts +0 -276
- package/src/api/types/index.ts +0 -675
- package/src/api/utils/cert.ts +0 -254
- package/src/api/utils/constants.ts +0 -17
- package/src/api/utils/fetch.ts +0 -21
- package/src/api/utils/moveFiles.ts +0 -45
- package/src/api/utils/parse.ts +0 -17
- package/src/api/websocket/index.ts +0 -110
- package/src/api/websocket/nsp/logs.ts +0 -240
- package/src/api/websocket/nsp/main.ts +0 -27
- package/src/api/websocket/nsp/metrics.ts +0 -301
- package/src/api/websocket/nsp/notifications.ts +0 -43
- package/src/api/websocket/nsp/plugins.ts +0 -37
- package/src/api/websocket/nsp/server.ts +0 -220
- package/src/api/websocket/nsp/status.ts +0 -77
- package/src/api/websocket/types.ts +0 -55
- package/src/api.ts +0 -163
- package/src/camera/classes.ts +0 -32
- package/src/camera/controller.ts +0 -579
- package/src/camera/device.ts +0 -422
- package/src/camera/frameWorker.ts +0 -403
- package/src/camera/index.ts +0 -679
- package/src/camera/interfaces.ts +0 -95
- package/src/camera/iou.ts +0 -153
- package/src/camera/polygon.ts +0 -226
- package/src/camera/python/__init__.py +0 -0
- package/src/camera/python/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/classes.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/delegate_controller.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/interfaces.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/iou.cpython-310.pyc +0 -0
- package/src/camera/python/__pycache__/iou.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/iou2.cpython-310.pyc +0 -0
- package/src/camera/python/__pycache__/polygon.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/typings.cpython-311.pyc +0 -0
- package/src/camera/python/__pycache__/video_frame.cpython-311.pyc +0 -0
- package/src/camera/python/classes.py +0 -41
- package/src/camera/python/interfaces.py +0 -130
- package/src/camera/python/iou.py +0 -158
- package/src/camera/python/polygon.py +0 -230
- package/src/camera/python/test/__pycache__/polygon.cpython-310.pyc +0 -0
- package/src/camera/python/test/iou_test.py +0 -799
- package/src/camera/python/test/polygon.py +0 -238
- package/src/camera/python/test/polygon_test.py +0 -256
- package/src/camera/python/test/polygon_test2.py +0 -484
- package/src/camera/python/typings.py +0 -50
- package/src/camera/python/video_frame.py +0 -143
- package/src/camera/session.ts +0 -192
- package/src/camera/streaming/fmp4-session.ts +0 -390
- package/src/camera/streaming/peer-connection.ts +0 -273
- package/src/camera/streaming/rtsp-session.ts +0 -331
- package/src/camera/streaming/webrtc-connection.ts +0 -260
- package/src/camera/streaming/werift-session.ts +0 -317
- package/src/camera/test/iou_test.ts +0 -761
- package/src/camera/test/polygon.test.ts +0 -611
- package/src/camera/test/polygon_test.ts +0 -210
- package/src/camera/types.ts +0 -48
- package/src/camera/utils.ts +0 -489
- package/src/camera/videoFrame.ts +0 -123
- package/src/cloud/index.ts +0 -61
- package/src/cloud/remote/cloudflare.ts +0 -18
- package/src/cloud/remote/upnp.ts +0 -18
- package/src/cloud/remote/utils.ts +0 -24
- package/src/cloud/types.ts +0 -16
- package/src/decoder/child.ts +0 -883
- package/src/decoder/imageUtils.ts +0 -275
- package/src/decoder/manager.ts +0 -251
- package/src/decoder/python/__init__.py +0 -0
- package/src/decoder/python/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/decoder/python/__pycache__/image_utils.cpython-311.pyc +0 -0
- package/src/decoder/python/__pycache__/typings.cpython-311.pyc +0 -0
- package/src/decoder/python/__pycache__/utils.cpython-311.pyc +0 -0
- package/src/decoder/python/child.py +0 -903
- package/src/decoder/python/image_utils.py +0 -196
- package/src/decoder/python/pool.py +0 -45
- package/src/decoder/python/test/group.py +0 -62
- package/src/decoder/python/test/motion.mp4 +0 -0
- package/src/decoder/python/test/motion2.mp4 +0 -0
- package/src/decoder/python/test/opencl.cl +0 -70
- package/src/decoder/python/test/opencl2.cl +0 -130
- package/src/decoder/python/test/test.py +0 -427
- package/src/decoder/python/test/test1.jpg +0 -0
- package/src/decoder/python/test/test1_resized.jpg +0 -0
- package/src/decoder/python/test/test2.jpg +0 -0
- package/src/decoder/python/test/test2.py +0 -451
- package/src/decoder/python/test/test2_resized.jpg +0 -0
- package/src/decoder/python/test/test3.jpg +0 -0
- package/src/decoder/python/test/utils.py +0 -50
- package/src/decoder/python/typings.py +0 -57
- package/src/decoder/python/utils.py +0 -70
- package/src/decoder/test/child.ts +0 -117
- package/src/decoder/test/ffmpeg.ts +0 -371
- package/src/decoder/test/test.ts +0 -182
- package/src/decoder/types.ts +0 -27
- package/src/decoder/utils.ts +0 -64
- package/src/decoder/wasm/asconfig.json +0 -28
- package/src/decoder/wasm/assembly/console.ts +0 -1
- package/src/decoder/wasm/assembly/index.ts +0 -890
- package/src/decoder/wasm/build/decoder.d.ts +0 -43
- package/src/decoder/wasm/build/decoder.js +0 -108
- package/src/decoder/wasm/build/decoder.wasm +0 -0
- package/src/decoder/wasm/tsconfig.json +0 -5
- package/src/decoder/worker.ts +0 -113
- package/src/go2rtc/index.ts +0 -324
- package/src/go2rtc/types.ts +0 -88
- package/src/main.ts +0 -267
- package/src/manager/coreManager.ts +0 -78
- package/src/manager/deviceManager.ts +0 -132
- package/src/manager/types.ts +0 -17
- package/src/plugins/index.ts +0 -443
- package/src/plugins/plugin.ts +0 -177
- package/src/plugins/runtime/base.ts +0 -282
- package/src/plugins/runtime/index.ts +0 -15
- package/src/plugins/runtime/node/child.ts +0 -193
- package/src/plugins/runtime/node/index.ts +0 -67
- package/src/plugins/runtime/node/plugin.ts +0 -122
- package/src/plugins/runtime/node/pluginApi.ts +0 -27
- package/src/plugins/runtime/node/proxy/cameraDevice.ts +0 -299
- package/src/plugins/runtime/node/proxy/coreManager.ts +0 -128
- package/src/plugins/runtime/node/proxy/deviceManager.ts +0 -187
- package/src/plugins/runtime/node/storage.ts +0 -312
- package/src/plugins/runtime/node/storageController.ts +0 -91
- package/src/plugins/runtime/python/__init__.py +0 -0
- package/src/plugins/runtime/python/__pycache__/__init__.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/camera_storage.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/config_service.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/constants.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/ipc.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/logger.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/message_queue.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/namespaces.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/plugin.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/plugin_api.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/plugin_logger.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/proxy_utils.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/schema.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/storage.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/storage_controller.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/__pycache__/typings.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/child.py +0 -248
- package/src/plugins/runtime/python/index.ts +0 -73
- package/src/plugins/runtime/python/namespaces.py +0 -101
- package/src/plugins/runtime/python/plugin.py +0 -155
- package/src/plugins/runtime/python/plugin_api.py +0 -29
- package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-310.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-38.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/constants.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/constants.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/core_manager.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-310.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-38.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-310.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-38.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-310.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-38.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-310.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-38.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-310.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-311.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-38.pyc +0 -0
- package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-39.pyc +0 -0
- package/src/plugins/runtime/python/proxy/camera_device.py +0 -1732
- package/src/plugins/runtime/python/proxy/core_manager.py +0 -126
- package/src/plugins/runtime/python/proxy/device_manager.py +0 -197
- package/src/plugins/runtime/python/schema.py +0 -99
- package/src/plugins/runtime/python/storage.py +0 -353
- package/src/plugins/runtime/python/storage_controller.py +0 -102
- package/src/plugins/runtime/python/typings.py +0 -195
- package/src/plugins/schema.ts +0 -472
- package/src/plugins/types.ts +0 -60
- package/src/plugins/worker.ts +0 -250
- package/src/rpc/index.ts +0 -149
- package/src/rpc/namespaces.ts +0 -79
- package/src/rpc/server.ts +0 -422
- package/src/rpc/types.ts +0 -119
- package/src/rpc/utils.ts +0 -16
- package/src/services/config/constants.ts +0 -47
- package/src/services/config/defaults.ts +0 -57
- package/src/services/config/index.ts +0 -744
- package/src/services/config/types.ts +0 -211
- package/src/services/logger/index.ts +0 -96
- package/src/types.ts +0 -47
- package/src/utils/path.ts +0 -16
- package/src/utils/pythonInstaller.ts +0 -597
- package/tsconfig.json +0 -37
- package/types/fastify.d.ts +0 -14
- package/updates.config.js +0 -3
- /package/dist/interface/assets/{@xterm.DYP7pi_n.0.0.50-internal.0.css → @xterm.DYP7pi_n.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{Adminpanel.BKek2EMH.0.0.50-internal.0.css → Adminpanel.BKek2EMH.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{Cameras.BDWZJqPN.0.0.50-internal.0.css → Cameras.BDWZJqPN.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{Camview.BFUFMoNX.0.0.50-internal.0.css → Camview.BFUFMoNX.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{CuiConsole.DCYyxdVg.0.0.50-internal.0.css → CuiConsole.DCYyxdVg.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{CuiPluginCard.yF8V0SZY.0.0.50-internal.0.css → CuiPluginCard.yF8V0SZY.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{CuiTimeline.BkIwlYtw.0.0.50-internal.0.css → CuiTimeline.BkIwlYtw.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{Plugin.DJElsAn5.0.0.50-internal.0.css → Plugin.DJElsAn5.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{Plugins.0h77qnmN.0.0.50-internal.0.css → Plugins.0h77qnmN.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{Settings.CkgfRkQr.0.0.50-internal.0.css → Settings.CkgfRkQr.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{SettingsAccount.DeFul3eQ.0.0.50-internal.0.css → SettingsAccount.DeFul3eQ.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{SettingsBackup.CX0rT0QJ.0.0.50-internal.0.css → SettingsBackup.CX0rT0QJ.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{highlight.Ch2EwETz.0.0.50-internal.0.css → highlight.Ch2EwETz.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{logo-256.BCQk9H1-.0.0.50-internal.0.png → logo-256.BCQk9H1-.0.0.50-internal.2.png} +0 -0
- /package/dist/interface/assets/{logo-512.DLKVOU2S.0.0.50-internal.0.png → logo-512.DLKVOU2S.0.0.50-internal.2.png} +0 -0
- /package/dist/interface/assets/{logo.DmEiRk0z.0.0.50-internal.0.png → logo.DmEiRk0z.0.0.50-internal.2.png} +0 -0
- /package/dist/interface/assets/{main.Cip9LkS3.0.0.50-internal.0.css → main.Cip9LkS3.0.0.50-internal.2.css} +0 -0
- /package/dist/interface/assets/{mode-json.Br7xisR1.0.0.50-internal.0.js → mode-json.Br7xisR1.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/assets/{mode-yaml.CIYL8U3d.0.0.50-internal.0.js → mode-yaml.CIYL8U3d.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/assets/{worker-base.jEXLGV2h.0.0.50-internal.0.js → worker-base.jEXLGV2h.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/assets/{worker-json.DgwNIOck.0.0.50-internal.0.js → worker-json.DgwNIOck.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/assets/{worker-yaml.B3uUYINB.0.0.50-internal.0.js → worker-yaml.B3uUYINB.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@babel.l0sNRNKZ.0.0.50-internal.0.js → @babel.l0sNRNKZ.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@intlify.BkGPX90O.0.0.50-internal.0.js → @intlify.BkGPX90O.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@kurkle.D8fDXNIl.0.0.50-internal.0.js → @kurkle.D8fDXNIl.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@primeuix.BFAY2Bk9.0.0.50-internal.0.js → @primeuix.BFAY2Bk9.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@react-dnd.CcwRs9xb.0.0.50-internal.0.js → @react-dnd.CcwRs9xb.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@socket.io.Dkula2eQ.0.0.50-internal.0.js → @socket.io.Dkula2eQ.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@vue.B5vqhCp2.0.0.50-internal.0.js → @vue.B5vqhCp2.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{@xterm.CAa7rpjv.0.0.50-internal.0.js → @xterm.C-5Lxnx_.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{axios.DHr9lByg.0.0.50-internal.0.js → axios.DHr9lByg.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{birpc.l0sNRNKZ.0.0.50-internal.0.js → birpc.l0sNRNKZ.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{compare-versions.DqEOhma6.0.0.50-internal.0.js → compare-versions.DqEOhma6.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{dijkstrajs.C00ieaqj.0.0.50-internal.0.js → dijkstrajs.C00ieaqj.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{engine.io-parser.BiEtp6m2.0.0.50-internal.0.js → engine.io-parser.BiEtp6m2.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{entities.C20TfXL6.0.0.50-internal.0.js → entities.C20TfXL6.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{ev-emitter.X5f1qa-c.0.0.50-internal.0.js → ev-emitter.X5f1qa-c.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{get-size.D1dS-IaP.0.0.50-internal.0.js → get-size.D1dS-IaP.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{hookable.l0sNRNKZ.0.0.50-internal.0.js → hookable.l0sNRNKZ.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{mdurl.k9Sl0PQj.0.0.50-internal.0.js → mdurl.k9Sl0PQj.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{perfect-debounce.l0sNRNKZ.0.0.50-internal.0.js → perfect-debounce.l0sNRNKZ.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{primelocale.Bga3dOQu.0.0.50-internal.0.js → primelocale.Bga3dOQu.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{punycode.js.Dj65hjkv.0.0.50-internal.0.js → punycode.js.Dj65hjkv.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{react-dnd-html5-backend.1HQjlkwI.0.0.50-internal.0.js → react-dnd-html5-backend.1HQjlkwI.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{redux.BFxtlG_c.0.0.50-internal.0.js → redux.BFxtlG_c.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{tslib.9k7AwCpt.0.0.50-internal.0.js → tslib.9k7AwCpt.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{uc.micro.kMc2yuuw.0.0.50-internal.0.js → uc.micro.kMc2yuuw.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{uuid.C6aID195.0.0.50-internal.0.js → uuid.C6aID195.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{vue.l0sNRNKZ.0.0.50-internal.0.js → vue.l0sNRNKZ.0.0.50-internal.2.js} +0 -0
- /package/dist/interface/js/{zod.SKKegNRO.0.0.50-internal.0.js → zod.SKKegNRO.0.0.50-internal.2.js} +0 -0
|
@@ -1,1206 +0,0 @@
|
|
|
1
|
-
import { orderBy } from '@camera.ui/common';
|
|
2
|
-
import TTLCache from '@isaacs/ttlcache';
|
|
3
|
-
import { pathExists } from 'fs-extra/esm';
|
|
4
|
-
import { createReadStream, truncate } from 'node:fs';
|
|
5
|
-
import { readFile } from 'node:fs/promises';
|
|
6
|
-
import { join } from 'node:path';
|
|
7
|
-
import { Readable } from 'node:stream';
|
|
8
|
-
import { gt, parse as parseVersion } from 'semver';
|
|
9
|
-
import sharp from 'sharp';
|
|
10
|
-
import { container } from 'tsyringe';
|
|
11
|
-
|
|
12
|
-
import { PluginManager } from '../../plugins/index.js';
|
|
13
|
-
import { CamerasService } from '../services/cameras.service.js';
|
|
14
|
-
import { PluginsService } from '../services/plugins.service.js';
|
|
15
|
-
import { fetchWithTimeout } from '../utils/fetch.js';
|
|
16
|
-
|
|
17
|
-
import type { JsonSchema } from '@camera.ui/types';
|
|
18
|
-
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
19
|
-
import type { Server } from 'socket.io';
|
|
20
|
-
import type { ProxyServer } from '../../rpc/index.js';
|
|
21
|
-
import type { ConfigService } from '../../services/config/index.js';
|
|
22
|
-
import type { LoggerService } from '../../services/logger/index.js';
|
|
23
|
-
import type {
|
|
24
|
-
AuthLoginRequest,
|
|
25
|
-
CameraUiPlugin,
|
|
26
|
-
INpmPluginState,
|
|
27
|
-
INpmRegistryModule,
|
|
28
|
-
INpmSearchResults,
|
|
29
|
-
IPackageJson,
|
|
30
|
-
PaginationRequest,
|
|
31
|
-
PluginExtension,
|
|
32
|
-
PluginExtensionConfig,
|
|
33
|
-
PluginsDetectAudioRequest,
|
|
34
|
-
PluginsDetectMotionRequest,
|
|
35
|
-
PluginsDetectObjectRequest,
|
|
36
|
-
PluginsInsertRequest,
|
|
37
|
-
PluginsParamsNameRequest,
|
|
38
|
-
PluginsParamsRemoveRequest,
|
|
39
|
-
PluginsProgress,
|
|
40
|
-
PluginsQueryRequest,
|
|
41
|
-
StoragePatchRequest,
|
|
42
|
-
StorageSetRequest,
|
|
43
|
-
StorageSubmitRequest,
|
|
44
|
-
} from '../types/index.js';
|
|
45
|
-
import type { SocketService } from '../websocket/index.js';
|
|
46
|
-
import type { ServerNamespace } from '../websocket/nsp/server.js';
|
|
47
|
-
|
|
48
|
-
const npmPluginCache = new TTLCache<string, INpmRegistryModule | IPackageJson>({ ttl: 300, max: 100 });
|
|
49
|
-
const searchResultBlacklist = new Set(['camera.ui', 'homebridge-camera-ui']);
|
|
50
|
-
const pluginLogoCache = new TTLCache<string, string>({ max: 100, ttl: 1000 * 60 * 60 * 24 });
|
|
51
|
-
|
|
52
|
-
export class PluginsController {
|
|
53
|
-
private app: FastifyInstance;
|
|
54
|
-
private logger: LoggerService;
|
|
55
|
-
private configService: ConfigService;
|
|
56
|
-
private io: Server;
|
|
57
|
-
private pluginManager: PluginManager;
|
|
58
|
-
private proxyServer: ProxyServer;
|
|
59
|
-
private service: PluginsService;
|
|
60
|
-
private camerasService: CamerasService;
|
|
61
|
-
private socketService: SocketService;
|
|
62
|
-
|
|
63
|
-
constructor(app: FastifyInstance) {
|
|
64
|
-
this.app = app;
|
|
65
|
-
this.io = app.io;
|
|
66
|
-
this.service = new PluginsService();
|
|
67
|
-
this.camerasService = new CamerasService();
|
|
68
|
-
|
|
69
|
-
this.logger = container.resolve<LoggerService>('logger');
|
|
70
|
-
this.configService = container.resolve<ConfigService>('configService');
|
|
71
|
-
this.pluginManager = container.resolve<PluginManager>('pluginManager');
|
|
72
|
-
this.proxyServer = container.resolve<ProxyServer>('proxy');
|
|
73
|
-
this.socketService = container.resolve<SocketService>('socketService');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public async enableByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
77
|
-
try {
|
|
78
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
79
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
80
|
-
|
|
81
|
-
if (!plugin) {
|
|
82
|
-
return reply.code(404).send({
|
|
83
|
-
statusCode: 404,
|
|
84
|
-
message: 'Plugin not exists',
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!plugin.disabled) {
|
|
89
|
-
return reply.code(400).send({
|
|
90
|
-
statusCode: 404,
|
|
91
|
-
message: 'Plugin already enabled',
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
plugin.disabled = false;
|
|
96
|
-
|
|
97
|
-
if (this.configService.config.plugins.disabledPlugins.includes(pluginName)) {
|
|
98
|
-
const index = this.configService.config.plugins.disabledPlugins.indexOf(pluginName);
|
|
99
|
-
this.configService.config.plugins.disabledPlugins.splice(index, 1);
|
|
100
|
-
this.configService.writeConfig();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
await this.pluginManager.startPluginChild(pluginName);
|
|
104
|
-
|
|
105
|
-
return reply.code(204).send();
|
|
106
|
-
} catch (error: any) {
|
|
107
|
-
return reply.code(500).send({
|
|
108
|
-
statusCode: 500,
|
|
109
|
-
message: error.message,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
public async disableByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
115
|
-
try {
|
|
116
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
117
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
118
|
-
|
|
119
|
-
if (!plugin) {
|
|
120
|
-
return reply.code(404).send({
|
|
121
|
-
statusCode: 404,
|
|
122
|
-
message: 'Plugin not exists',
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (plugin.disabled) {
|
|
127
|
-
return reply.code(400).send({
|
|
128
|
-
statusCode: 404,
|
|
129
|
-
message: 'Plugin already disabled',
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
plugin.disabled = true;
|
|
134
|
-
|
|
135
|
-
this.configService.config.plugins.disabledPlugins.push(pluginName);
|
|
136
|
-
this.configService.writeConfig();
|
|
137
|
-
|
|
138
|
-
await this.pluginManager.stopPluginChild(pluginName);
|
|
139
|
-
|
|
140
|
-
return reply.code(204).send();
|
|
141
|
-
} catch (error: any) {
|
|
142
|
-
return reply.code(500).send({
|
|
143
|
-
statusCode: 500,
|
|
144
|
-
message: error.message,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public getByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): FastifyReply {
|
|
150
|
-
try {
|
|
151
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
152
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
153
|
-
|
|
154
|
-
if (!plugin) {
|
|
155
|
-
return reply.code(404).send({
|
|
156
|
-
statusCode: 404,
|
|
157
|
-
message: 'Plugin not exists',
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return reply.code(200).send(plugin.info);
|
|
162
|
-
} catch (error: any) {
|
|
163
|
-
return reply.code(500).send({
|
|
164
|
-
statusCode: 500,
|
|
165
|
-
message: error.message,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
public async getPluginUpdateByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
171
|
-
try {
|
|
172
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
173
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
174
|
-
|
|
175
|
-
if (!plugin) {
|
|
176
|
-
return reply.code(404).send({
|
|
177
|
-
statusCode: 404,
|
|
178
|
-
message: 'Plugin not exists',
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const pluginUpdateState = await this.getPluginFromNpm(plugin.info);
|
|
183
|
-
|
|
184
|
-
return reply.code(200).send(pluginUpdateState);
|
|
185
|
-
} catch (error: any) {
|
|
186
|
-
return reply.code(500).send({
|
|
187
|
-
statusCode: 500,
|
|
188
|
-
message: error.message,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
public async getVersionsByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
194
|
-
try {
|
|
195
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
196
|
-
const availableVersions = await this.getAvailablePluginVersions(pluginName);
|
|
197
|
-
return reply.code(200).send(availableVersions);
|
|
198
|
-
} catch (error: any) {
|
|
199
|
-
return reply.code(500).send({
|
|
200
|
-
statusCode: 500,
|
|
201
|
-
message: error.message,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
public async getChangelogByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & PluginsQueryRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
207
|
-
try {
|
|
208
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
209
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
210
|
-
const pluginInfo = plugin?.info ?? (await this.searchNpmRegistrySingle(pluginName));
|
|
211
|
-
|
|
212
|
-
const version = req.query.pluginversion ?? 'latest';
|
|
213
|
-
|
|
214
|
-
// GITHUB API
|
|
215
|
-
try {
|
|
216
|
-
const repoMatch = pluginInfo?.links?.homepage?.match(/https:\/\/github.com\/([^/]+)\/([^/#]+)/);
|
|
217
|
-
const bugsMatch = pluginInfo?.links?.bugs?.match(/https:\/\/github.com\/([^/]+)\/([^/#]+)/);
|
|
218
|
-
const match: RegExpMatchArray | null | undefined = repoMatch ?? bugsMatch;
|
|
219
|
-
|
|
220
|
-
if (match) {
|
|
221
|
-
const response = await fetchWithTimeout(`https://api.github.com/repos/${match[1]}/${match[2]}/releases`, {
|
|
222
|
-
method: 'GET',
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
if (!response.ok) {
|
|
226
|
-
throw new Error(`Failed to fetch changelog from GitHub API - ${response.statusText}`);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const data = (await response.json()) as { body: string; tag_name: string }[];
|
|
230
|
-
const release = version === 'latest' ? data[0] : data.find((x) => x.tag_name === version);
|
|
231
|
-
|
|
232
|
-
if (release) {
|
|
233
|
-
reply.header('Content-Type', 'text/plain');
|
|
234
|
-
return reply.code(200).send(release.body);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
} catch {
|
|
238
|
-
//
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// UNPKG
|
|
242
|
-
try {
|
|
243
|
-
const response = await fetchWithTimeout(`https://unpkg.com/${pluginName}@${version}/CHANGELOG.md`, {
|
|
244
|
-
method: 'GET',
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
if (!response.ok) {
|
|
248
|
-
throw new Error(`Failed to fetch changelog from UNPKG - ${response.statusText}`);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const data = await response.text();
|
|
252
|
-
reply.header('Content-Type', 'text/plain');
|
|
253
|
-
return reply.code(200).send(data);
|
|
254
|
-
} catch {
|
|
255
|
-
//
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// LOCAL
|
|
259
|
-
if (plugin) {
|
|
260
|
-
try {
|
|
261
|
-
const changelog = join(plugin.installPath, 'CHANGELOG.md');
|
|
262
|
-
|
|
263
|
-
if (await pathExists(changelog)) {
|
|
264
|
-
const file = await readFile(`${plugin.installPath}/CHANGELOG.md`, 'utf8');
|
|
265
|
-
reply.header('Content-Type', 'text/plain');
|
|
266
|
-
return reply.code(200).send(file);
|
|
267
|
-
}
|
|
268
|
-
} catch {
|
|
269
|
-
//
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return reply.code(404).send({
|
|
274
|
-
statusCode: 404,
|
|
275
|
-
message: 'Changelog not found',
|
|
276
|
-
});
|
|
277
|
-
} catch (error: any) {
|
|
278
|
-
return reply.code(500).send({
|
|
279
|
-
statusCode: 500,
|
|
280
|
-
message: error.message,
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
public async getPluginLogoByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
286
|
-
try {
|
|
287
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
288
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
289
|
-
|
|
290
|
-
if (!plugin) {
|
|
291
|
-
return reply.code(200).send(Buffer.from('').toString('base64'));
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const logoPath = join(plugin.installPath, 'logo.png');
|
|
295
|
-
|
|
296
|
-
if (!(await pathExists(logoPath))) {
|
|
297
|
-
return reply.code(200).send(Buffer.from('').toString('base64'));
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
let base64Logo: string;
|
|
301
|
-
pluginLogoCache.purgeStale();
|
|
302
|
-
|
|
303
|
-
if (pluginLogoCache.has(pluginName)) {
|
|
304
|
-
base64Logo = pluginLogoCache.get(pluginName)!;
|
|
305
|
-
} else {
|
|
306
|
-
const logo = await sharp(logoPath).resize({ width: 100, height: 100, fit: 'cover', kernel: 'nearest' }).toBuffer();
|
|
307
|
-
base64Logo = Buffer.from(logo).toString('base64');
|
|
308
|
-
pluginLogoCache.set(pluginName, base64Logo);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
reply.header('Content-Type', 'image/png');
|
|
312
|
-
return reply.code(200).send(`data:image/png;base64,${base64Logo}`);
|
|
313
|
-
} catch (error: any) {
|
|
314
|
-
return reply.code(500).send({
|
|
315
|
-
statusCode: 500,
|
|
316
|
-
message: error.message,
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
public async getConfigByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
322
|
-
try {
|
|
323
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
324
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
325
|
-
|
|
326
|
-
if (!pluginWorker) {
|
|
327
|
-
return reply.code(404).send({
|
|
328
|
-
statusCode: 404,
|
|
329
|
-
message: 'Plugin not exists',
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const proxy = await pluginWorker.storageProxy();
|
|
334
|
-
const schemaConfig = await proxy.getConfig();
|
|
335
|
-
|
|
336
|
-
const cameraExtension: PluginExtensionConfig = {
|
|
337
|
-
pluginName: pluginWorker.plugin.pluginName,
|
|
338
|
-
displayName: pluginWorker.plugin.displayName,
|
|
339
|
-
type: pluginWorker.plugin.contract.extensions,
|
|
340
|
-
...schemaConfig,
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
return reply.code(200).send(cameraExtension);
|
|
344
|
-
} catch (error: any) {
|
|
345
|
-
return reply.code(500).send({
|
|
346
|
-
statusCode: 500,
|
|
347
|
-
message: error.message,
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
public async patchConfigByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & StoragePatchRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
353
|
-
try {
|
|
354
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
355
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
356
|
-
|
|
357
|
-
if (!pluginWorker) {
|
|
358
|
-
return reply.code(404).send({
|
|
359
|
-
statusCode: 404,
|
|
360
|
-
message: 'Plugin not exists',
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
const proxy = await pluginWorker.storageProxy();
|
|
365
|
-
await proxy.setConfig(req.body);
|
|
366
|
-
|
|
367
|
-
return reply.code(200).send(req.body);
|
|
368
|
-
} catch (error: any) {
|
|
369
|
-
return reply.code(500).send({
|
|
370
|
-
statusCode: 500,
|
|
371
|
-
message: error.message,
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
public async setConfigByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & StorageSetRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
377
|
-
try {
|
|
378
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
379
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
380
|
-
|
|
381
|
-
if (!pluginWorker) {
|
|
382
|
-
return reply.code(404).send({
|
|
383
|
-
statusCode: 404,
|
|
384
|
-
message: 'Plugin not exists',
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
const proxy = await pluginWorker.storageProxy();
|
|
389
|
-
await proxy.setValue<undefined>(req.body.key, undefined);
|
|
390
|
-
|
|
391
|
-
return reply.code(204).send();
|
|
392
|
-
} catch (error: any) {
|
|
393
|
-
return reply.code(500).send({
|
|
394
|
-
statusCode: 500,
|
|
395
|
-
message: error.message,
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
public async submitConfigByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & StorageSubmitRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
401
|
-
try {
|
|
402
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
403
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
404
|
-
|
|
405
|
-
if (!pluginWorker) {
|
|
406
|
-
return reply.code(404).send({
|
|
407
|
-
statusCode: 404,
|
|
408
|
-
message: 'Plugin not exists',
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
const proxy = await pluginWorker.storageProxy();
|
|
413
|
-
const response = await proxy.submitValue(req.body.key, req.body.payload);
|
|
414
|
-
|
|
415
|
-
return reply.code(200).send(response);
|
|
416
|
-
} catch (error: any) {
|
|
417
|
-
return reply.code(500).send({
|
|
418
|
-
statusCode: 500,
|
|
419
|
-
message: error.message,
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
public async getPluginInterface(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
425
|
-
try {
|
|
426
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
427
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
428
|
-
const pluginProxy = await pluginWorker?.pluginProxy();
|
|
429
|
-
|
|
430
|
-
if (!pluginProxy) {
|
|
431
|
-
return reply.code(404).send({
|
|
432
|
-
statusCode: 404,
|
|
433
|
-
message: 'Plugin not exists or not running',
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
let schemaJson: JsonSchema[] | undefined;
|
|
438
|
-
|
|
439
|
-
try {
|
|
440
|
-
schemaJson = await pluginProxy.interfaceSchema?.();
|
|
441
|
-
} catch {
|
|
442
|
-
//
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
return reply.code(200).send(schemaJson);
|
|
446
|
-
} catch (error: any) {
|
|
447
|
-
return reply.code(500).send({
|
|
448
|
-
statusCode: 500,
|
|
449
|
-
message: error.message,
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
public async detectObjects(
|
|
455
|
-
req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & PluginsDetectObjectRequest>,
|
|
456
|
-
reply: FastifyReply,
|
|
457
|
-
): Promise<FastifyReply | void> {
|
|
458
|
-
try {
|
|
459
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
460
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
461
|
-
const pluginProxy = await pluginWorker?.pluginProxy();
|
|
462
|
-
|
|
463
|
-
if (!pluginProxy) {
|
|
464
|
-
return reply.code(404).send({
|
|
465
|
-
statusCode: 404,
|
|
466
|
-
message: 'Plugin not exists or not running',
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (!req.isMultipart()) {
|
|
471
|
-
throw new Error('No multipart request!');
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
const file = req.body.upload;
|
|
475
|
-
if (!file) {
|
|
476
|
-
return reply.code(400).send({
|
|
477
|
-
statusCode: 400,
|
|
478
|
-
message: 'No file uploaded',
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
const fileBuffer = await file.toBuffer();
|
|
483
|
-
const response = await pluginProxy.detectObjects?.(fileBuffer, req.body.metadata, req.body.config);
|
|
484
|
-
|
|
485
|
-
return reply.code(201).send(response?.detections);
|
|
486
|
-
} catch (error: any) {
|
|
487
|
-
return reply.code(500).send({
|
|
488
|
-
statusCode: 500,
|
|
489
|
-
message: error.message,
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
public async detectAudio(
|
|
495
|
-
req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & PluginsDetectAudioRequest>,
|
|
496
|
-
reply: FastifyReply,
|
|
497
|
-
): Promise<FastifyReply | void> {
|
|
498
|
-
try {
|
|
499
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
500
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
501
|
-
const pluginProxy = await pluginWorker?.pluginProxy();
|
|
502
|
-
|
|
503
|
-
if (!pluginProxy) {
|
|
504
|
-
return reply.code(404).send({
|
|
505
|
-
statusCode: 404,
|
|
506
|
-
message: 'Plugin not exists or not running',
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
if (!req.isMultipart()) {
|
|
511
|
-
throw new Error('No multipart request!');
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
const file = req.body.upload;
|
|
515
|
-
if (!file) {
|
|
516
|
-
return reply.code(400).send({
|
|
517
|
-
statusCode: 400,
|
|
518
|
-
message: 'No file uploaded',
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
const fileBuffer = await file.toBuffer();
|
|
523
|
-
const response = await pluginProxy.detectAudio?.(fileBuffer, req.body.metadata, req.body.config);
|
|
524
|
-
|
|
525
|
-
return reply.code(201).send(response?.detected);
|
|
526
|
-
} catch (error: any) {
|
|
527
|
-
return reply.code(500).send({
|
|
528
|
-
statusCode: 500,
|
|
529
|
-
message: error.message,
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
public async detectMotion(
|
|
535
|
-
req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & PluginsDetectMotionRequest>,
|
|
536
|
-
reply: FastifyReply,
|
|
537
|
-
): Promise<FastifyReply | void> {
|
|
538
|
-
try {
|
|
539
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
540
|
-
const pluginWorker = this.service.getPluginProcessByName(pluginName);
|
|
541
|
-
const pluginProxy = await pluginWorker?.pluginProxy();
|
|
542
|
-
|
|
543
|
-
if (!pluginProxy) {
|
|
544
|
-
return reply.code(404).send({
|
|
545
|
-
statusCode: 404,
|
|
546
|
-
message: 'Plugin not exists or not running',
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
if (!req.isMultipart()) {
|
|
551
|
-
throw new Error('No multipart request!');
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
const file = req.body.upload;
|
|
555
|
-
if (!file) {
|
|
556
|
-
return reply.code(400).send({
|
|
557
|
-
statusCode: 400,
|
|
558
|
-
message: 'No file uploaded',
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
const fileBuffer = await file.toBuffer();
|
|
563
|
-
const response = await pluginProxy.detectMotion?.(fileBuffer, req.body.config);
|
|
564
|
-
|
|
565
|
-
reply.header('Content-Type', 'video/mp4');
|
|
566
|
-
reply.header('Content-Length', response?.videoData.toString().length ?? 0);
|
|
567
|
-
|
|
568
|
-
return reply.send(response?.videoData);
|
|
569
|
-
} catch (error: any) {
|
|
570
|
-
return reply.code(500).send({
|
|
571
|
-
statusCode: 500,
|
|
572
|
-
message: error.message,
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
public getContractByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): FastifyReply {
|
|
578
|
-
try {
|
|
579
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
580
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
581
|
-
|
|
582
|
-
if (!plugin) {
|
|
583
|
-
return reply.code(404).send({
|
|
584
|
-
statusCode: 404,
|
|
585
|
-
message: 'Plugin not exists',
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
const contract = plugin.contract;
|
|
590
|
-
const camerasList =
|
|
591
|
-
contract.extensions.length === 1 && contract.extensions[0] === 'cameraController' ? this.camerasService.listByPluginId(plugin.id) : this.camerasService.list();
|
|
592
|
-
|
|
593
|
-
const cameras =
|
|
594
|
-
camerasList?.map((camera) => {
|
|
595
|
-
return {
|
|
596
|
-
name: camera.name,
|
|
597
|
-
extensions: camera.extensions,
|
|
598
|
-
};
|
|
599
|
-
}) || [];
|
|
600
|
-
|
|
601
|
-
return reply.code(200).send({ contract, cameras });
|
|
602
|
-
} catch (error: any) {
|
|
603
|
-
return reply.code(500).send({
|
|
604
|
-
statusCode: 500,
|
|
605
|
-
message: error.message,
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
public async getReadmeByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & PluginsQueryRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
611
|
-
try {
|
|
612
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
613
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
614
|
-
|
|
615
|
-
if (!plugin) {
|
|
616
|
-
return reply.code(404).send({
|
|
617
|
-
statusCode: 404,
|
|
618
|
-
message: 'Plugin not exists',
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
try {
|
|
623
|
-
const readme = join(plugin.installPath, 'CHANGELOG.md');
|
|
624
|
-
|
|
625
|
-
if (await pathExists(readme)) {
|
|
626
|
-
const file = await readFile(`${plugin.installPath}/README.md`, 'utf8');
|
|
627
|
-
reply.header('Content-Type', 'text/plain');
|
|
628
|
-
return reply.code(200).send(file);
|
|
629
|
-
}
|
|
630
|
-
} catch {
|
|
631
|
-
//
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
const version = plugin.info.installedVersion ?? 'latest';
|
|
635
|
-
const response = await fetchWithTimeout(`https://unpkg.com/${plugin.pluginName}@${version}/README.md`, {
|
|
636
|
-
method: 'GET',
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
if (!response.ok) {
|
|
640
|
-
throw new Error(`Failed to fetch readme from UNPKG - ${response.statusText}`);
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
const data = await response.text();
|
|
644
|
-
|
|
645
|
-
return reply.code(200).send(data);
|
|
646
|
-
} catch (error: any) {
|
|
647
|
-
return reply.code(500).send({
|
|
648
|
-
statusCode: 500,
|
|
649
|
-
message: error.message,
|
|
650
|
-
});
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
public list(req: FastifyRequest<AuthLoginRequest & PaginationRequest>, reply: FastifyReply): FastifyReply | CameraUiPlugin[] {
|
|
655
|
-
try {
|
|
656
|
-
const installedPlugins = this.service.listPlugins();
|
|
657
|
-
const plugins = installedPlugins.map((plugin) => plugin.info);
|
|
658
|
-
|
|
659
|
-
return orderBy(plugins, ['displayName'], ['asc']);
|
|
660
|
-
// return orderBy(plugins, ['disabled', 'displayName'], ['asc', 'asc']);
|
|
661
|
-
} catch (error: any) {
|
|
662
|
-
return reply.code(500).send({
|
|
663
|
-
statusCode: 500,
|
|
664
|
-
message: error.message,
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
public listExtensions(req: FastifyRequest<AuthLoginRequest & PaginationRequest>, reply: FastifyReply): FastifyReply | PluginExtension[] {
|
|
670
|
-
try {
|
|
671
|
-
const installedPlugins = this.service.listPlugins();
|
|
672
|
-
const allExtensions: PluginExtension[] = installedPlugins.map((plugin) => ({
|
|
673
|
-
pluginName: plugin.pluginName,
|
|
674
|
-
displayName: plugin.displayName,
|
|
675
|
-
type: plugin.contract.extensions,
|
|
676
|
-
}));
|
|
677
|
-
|
|
678
|
-
return orderBy(allExtensions, ['displayName'], ['asc']);
|
|
679
|
-
} catch (error: any) {
|
|
680
|
-
return reply.code(500).send({
|
|
681
|
-
statusCode: 500,
|
|
682
|
-
message: error.message,
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
public async restartByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
688
|
-
try {
|
|
689
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
690
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
691
|
-
|
|
692
|
-
if (!plugin) {
|
|
693
|
-
return reply.code(404).send({
|
|
694
|
-
statusCode: 404,
|
|
695
|
-
message: 'Plugin not exists',
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
const pluginProcess = this.service.getPluginProcessByName(pluginName);
|
|
700
|
-
|
|
701
|
-
if (!pluginProcess) {
|
|
702
|
-
return reply.code(404).send({
|
|
703
|
-
statusCode: 404,
|
|
704
|
-
message: 'Plugin process not initialized',
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
await pluginProcess.restart();
|
|
709
|
-
|
|
710
|
-
return reply.code(204).send();
|
|
711
|
-
} catch (error: any) {
|
|
712
|
-
return reply.code(500).send({
|
|
713
|
-
statusCode: 500,
|
|
714
|
-
message: error.message,
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
public clearLog(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): FastifyReply | void {
|
|
720
|
-
try {
|
|
721
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
722
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
723
|
-
|
|
724
|
-
if (!plugin) {
|
|
725
|
-
return reply.code(404).send({
|
|
726
|
-
statusCode: 404,
|
|
727
|
-
message: 'Plugin not exists',
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
truncate(plugin.logPath, (error) => {
|
|
732
|
-
if (error) {
|
|
733
|
-
return reply.code(500).send({
|
|
734
|
-
statusCode: 500,
|
|
735
|
-
message: error.message,
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
this.app.io.of('/logs').emit('clear-plugin-log', pluginName);
|
|
740
|
-
|
|
741
|
-
return reply.code(204).send();
|
|
742
|
-
});
|
|
743
|
-
} catch (error: any) {
|
|
744
|
-
return reply.code(500).send({
|
|
745
|
-
statusCode: 500,
|
|
746
|
-
message: error.message,
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
public downloadLog(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): FastifyReply | void {
|
|
752
|
-
try {
|
|
753
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
754
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
755
|
-
|
|
756
|
-
if (!plugin) {
|
|
757
|
-
return reply.code(404).send({
|
|
758
|
-
statusCode: 404,
|
|
759
|
-
message: 'Plugin not exists',
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
const buffer = new Readable();
|
|
764
|
-
buffer._read = () => {};
|
|
765
|
-
|
|
766
|
-
const readStream = createReadStream(plugin.logPath);
|
|
767
|
-
|
|
768
|
-
readStream.on('data', (data) => {
|
|
769
|
-
buffer.push(data.toString('utf8').replace(/\x1b\[[0-9;]*m/g, ''));
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
readStream.on('end', () => {
|
|
773
|
-
buffer.push(null);
|
|
774
|
-
});
|
|
775
|
-
|
|
776
|
-
reply.header('Content-Type', 'application/octet-stream');
|
|
777
|
-
reply.header('Content-Disposition', `attachment; filename=camera.ui.${plugin.pluginName}.log.txt`);
|
|
778
|
-
|
|
779
|
-
return reply.code(200).send(buffer);
|
|
780
|
-
} catch (error: any) {
|
|
781
|
-
return reply.code(500).send({
|
|
782
|
-
statusCode: 500,
|
|
783
|
-
message: error.message,
|
|
784
|
-
});
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
public async search(req: FastifyRequest<AuthLoginRequest & PluginsQueryRequest & PaginationRequest>, reply: FastifyReply): Promise<FastifyReply | CameraUiPlugin[]> {
|
|
789
|
-
try {
|
|
790
|
-
const query = req.query.pluginname ?? '';
|
|
791
|
-
const q = (!query?.length ? '' : query + '+') + 'keywords:camera-ui-plugin+not:deprecated&size=30';
|
|
792
|
-
|
|
793
|
-
const response = await fetchWithTimeout(`https://registry.npmjs.org/-/v1/search?text=${q}`, {
|
|
794
|
-
method: 'GET',
|
|
795
|
-
});
|
|
796
|
-
|
|
797
|
-
if (!response.ok) {
|
|
798
|
-
throw new Error(`Failed to search the npm registry - ${response.statusText}`);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
const searchResults = (await response.json()) as INpmSearchResults;
|
|
802
|
-
|
|
803
|
-
const result: CameraUiPlugin[] = searchResults.objects
|
|
804
|
-
.filter((x) => x.package.name.startsWith('camera-ui-') || this.isScopedPlugin(x.package.name))
|
|
805
|
-
.filter((x) => !searchResultBlacklist.has(x.package.name))
|
|
806
|
-
.map((pkg) => {
|
|
807
|
-
let plugin: CameraUiPlugin = {
|
|
808
|
-
id: '0',
|
|
809
|
-
pluginName: pkg.package.name,
|
|
810
|
-
displayName: PluginManager.transformDisplaName(pkg.package.name),
|
|
811
|
-
private: false,
|
|
812
|
-
isPython: false,
|
|
813
|
-
isNode: true,
|
|
814
|
-
'camera.ui': {
|
|
815
|
-
extensions: [],
|
|
816
|
-
},
|
|
817
|
-
};
|
|
818
|
-
|
|
819
|
-
const installedPlugins = this.service.listPlugins();
|
|
820
|
-
const isInstalled = installedPlugins.find((installedPlugin) => installedPlugin.pluginName === plugin.pluginName);
|
|
821
|
-
|
|
822
|
-
if (isInstalled) {
|
|
823
|
-
plugin = isInstalled.info;
|
|
824
|
-
plugin.lastUpdated = pkg.package.date;
|
|
825
|
-
return plugin;
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
plugin.publicPackage = true;
|
|
829
|
-
plugin.installedVersion = undefined;
|
|
830
|
-
plugin.latestVersion = pkg.package.version;
|
|
831
|
-
plugin.lastUpdated = pkg.package.date;
|
|
832
|
-
plugin.description = pkg.package.description ? pkg.package.description.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '').trim() : pkg.package.name;
|
|
833
|
-
plugin.links = pkg.package.links;
|
|
834
|
-
plugin.author = pkg.package.publisher ? pkg.package.publisher.username : undefined;
|
|
835
|
-
|
|
836
|
-
return plugin;
|
|
837
|
-
});
|
|
838
|
-
|
|
839
|
-
if (!result.length && (query.startsWith('camera-ui-') || this.isScopedPlugin(query)) && !searchResultBlacklist.has(query.toLowerCase())) {
|
|
840
|
-
const singlePluginQuey = await this.searchNpmRegistrySingle(query.toLowerCase());
|
|
841
|
-
return singlePluginQuey ? [singlePluginQuey] : [];
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
return orderBy(result, ['displayName'], ['asc']);
|
|
845
|
-
} catch (error: any) {
|
|
846
|
-
return reply.code(500).send({
|
|
847
|
-
statusCode: 500,
|
|
848
|
-
message: error.message,
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
public async startByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
854
|
-
try {
|
|
855
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
856
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
857
|
-
|
|
858
|
-
if (!plugin) {
|
|
859
|
-
return reply.code(404).send({
|
|
860
|
-
statusCode: 404,
|
|
861
|
-
message: 'Plugin not exists',
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
const pluginProcess = this.service.getPluginProcessByName(pluginName);
|
|
866
|
-
|
|
867
|
-
if (!pluginProcess) {
|
|
868
|
-
return reply.code(404).send({
|
|
869
|
-
statusCode: 404,
|
|
870
|
-
message: 'Plugin process not initialized',
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
await pluginProcess.start();
|
|
875
|
-
|
|
876
|
-
return reply.code(204).send();
|
|
877
|
-
} catch (error: any) {
|
|
878
|
-
return reply.code(500).send({
|
|
879
|
-
statusCode: 500,
|
|
880
|
-
message: error.message,
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
public async stopByName(req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
886
|
-
try {
|
|
887
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
888
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
889
|
-
|
|
890
|
-
if (!plugin) {
|
|
891
|
-
return reply.code(404).send({
|
|
892
|
-
statusCode: 404,
|
|
893
|
-
message: 'Plugin not exists',
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
const pluginProcess = this.service.getPluginProcessByName(pluginName);
|
|
898
|
-
|
|
899
|
-
if (!pluginProcess) {
|
|
900
|
-
return reply.code(404).send({
|
|
901
|
-
statusCode: 404,
|
|
902
|
-
message: 'Plugin process not initialized',
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
await pluginProcess.teardown();
|
|
907
|
-
|
|
908
|
-
return reply.code(204).send();
|
|
909
|
-
} catch (error: any) {
|
|
910
|
-
return reply.code(500).send({
|
|
911
|
-
statusCode: 500,
|
|
912
|
-
message: error.message,
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
public async installOrUpdate(req: FastifyRequest<AuthLoginRequest & PluginsInsertRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
918
|
-
try {
|
|
919
|
-
let plugin = this.pluginManager.plugins.get(req.body.pluginname);
|
|
920
|
-
|
|
921
|
-
const command = plugin ? 'update' : 'install';
|
|
922
|
-
|
|
923
|
-
this.logger.log(`${plugin ? 'Updating' : 'Installing'} plugin: ${req.body.pluginname}@${req.body.pluginversion}`);
|
|
924
|
-
|
|
925
|
-
const installPath = await this.service.manage(req.body.pluginname, command, req.body.pluginversion, plugin?.id);
|
|
926
|
-
|
|
927
|
-
if (!plugin) {
|
|
928
|
-
plugin = await this.pluginManager.loadPlugin(installPath);
|
|
929
|
-
|
|
930
|
-
this.logger.log(`Plugin installed: ${plugin.pluginName}.${plugin.displayName} (${plugin.info.installedVersion})`);
|
|
931
|
-
|
|
932
|
-
this.pluginManager.initializeInstalledPlugin(plugin);
|
|
933
|
-
} else {
|
|
934
|
-
this.logger.log(`Plugin updated: ${plugin.pluginName}.${plugin.displayName} (${req.body.pluginversion})`);
|
|
935
|
-
|
|
936
|
-
// const pluginProcess = this.service.getPluginProcessByName(req.body.pluginname);
|
|
937
|
-
// pluginProcess?.restart();
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
npmPluginCache.delete(plugin.pluginName);
|
|
941
|
-
plugin.reparsePackageJson();
|
|
942
|
-
|
|
943
|
-
const serverNsp = this.socketService.namespaces.get('/server');
|
|
944
|
-
(serverNsp as ServerNamespace).checkPlugins();
|
|
945
|
-
|
|
946
|
-
return reply.code(201).send(plugin.info);
|
|
947
|
-
} catch (error: any) {
|
|
948
|
-
return reply.code(500).send({
|
|
949
|
-
statusCode: 500,
|
|
950
|
-
message: error.message,
|
|
951
|
-
});
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
public async installProgress(req: FastifyRequest<AuthLoginRequest & PaginationRequest>, reply: FastifyReply): Promise<FastifyReply | PluginsProgress[]> {
|
|
956
|
-
try {
|
|
957
|
-
const pluginsInProgress = this.service.installingPlugins();
|
|
958
|
-
return orderBy(pluginsInProgress, ['pluginName'], ['asc']);
|
|
959
|
-
} catch (error: any) {
|
|
960
|
-
return reply.code(500).send({
|
|
961
|
-
statusCode: 500,
|
|
962
|
-
message: error.message,
|
|
963
|
-
});
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
public async uninstallByName(
|
|
968
|
-
req: FastifyRequest<AuthLoginRequest & PluginsParamsNameRequest & PluginsParamsRemoveRequest>,
|
|
969
|
-
reply: FastifyReply,
|
|
970
|
-
): Promise<FastifyReply> {
|
|
971
|
-
try {
|
|
972
|
-
const pluginName = this.resolvePluginName(req.params);
|
|
973
|
-
const plugin = this.service.getPluginByName(pluginName);
|
|
974
|
-
|
|
975
|
-
if (!plugin) {
|
|
976
|
-
return reply.code(404).send({
|
|
977
|
-
statusCode: 404,
|
|
978
|
-
message: 'Plugin not exists',
|
|
979
|
-
});
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
this.logger.log(`Uninstalling plugin: ${plugin.pluginName}.${plugin.displayName} (${plugin.info.installedVersion})`);
|
|
983
|
-
|
|
984
|
-
await this.service.manage(plugin.pluginName, 'uninstall', undefined, plugin.id);
|
|
985
|
-
await this.pluginManager.removePlugin(plugin, req.query.removeStorage);
|
|
986
|
-
|
|
987
|
-
npmPluginCache.delete(plugin.pluginName);
|
|
988
|
-
npmPluginCache.delete(`lookup-${plugin.pluginName}`);
|
|
989
|
-
|
|
990
|
-
this.logger.log(`Plugin uninstalled: ${plugin.pluginName}.${plugin.displayName} (${plugin.info.installedVersion})`);
|
|
991
|
-
|
|
992
|
-
return reply.code(204).send();
|
|
993
|
-
} catch (error: any) {
|
|
994
|
-
return reply.code(500).send({
|
|
995
|
-
statusCode: 500,
|
|
996
|
-
message: error.message,
|
|
997
|
-
});
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
public async uninstallAll(req: FastifyRequest<AuthLoginRequest & PluginsParamsRemoveRequest>, reply: FastifyReply): Promise<FastifyReply> {
|
|
1002
|
-
try {
|
|
1003
|
-
this.logger.log('Uninstalling all plugins');
|
|
1004
|
-
|
|
1005
|
-
const plugins = this.service.listPlugins();
|
|
1006
|
-
const pluginNames = plugins.map((plugin) => plugin.pluginName);
|
|
1007
|
-
|
|
1008
|
-
await Promise.all(plugins.map((plugin) => this.service.manage(plugin.pluginName, 'uninstall', undefined, plugin.id)));
|
|
1009
|
-
|
|
1010
|
-
for (const plugin of plugins) {
|
|
1011
|
-
await this.pluginManager.removePlugin(plugin, req.query.removeStorage);
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
const pluginsToDelete = [...pluginNames, ...pluginNames.map((pluginName) => `lookup-${pluginName}`)];
|
|
1015
|
-
pluginsToDelete.forEach((p) => npmPluginCache.delete(p));
|
|
1016
|
-
|
|
1017
|
-
this.logger.log('All plugins uninstalled');
|
|
1018
|
-
|
|
1019
|
-
return reply.code(204).send();
|
|
1020
|
-
} catch (error: any) {
|
|
1021
|
-
return reply.code(500).send({
|
|
1022
|
-
statusCode: 500,
|
|
1023
|
-
message: error.message,
|
|
1024
|
-
});
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
private async getAvailablePluginVersions(pluginName: string): Promise<{ tags: Record<string, string>; versions: string[] }> {
|
|
1029
|
-
npmPluginCache.purgeStale();
|
|
1030
|
-
|
|
1031
|
-
const fromCache = npmPluginCache.get(`lookup-${pluginName}`);
|
|
1032
|
-
|
|
1033
|
-
let pkg = fromCache as INpmRegistryModule;
|
|
1034
|
-
|
|
1035
|
-
if (!pkg) {
|
|
1036
|
-
const response = await fetchWithTimeout(`https://registry.npmjs.org/${encodeURIComponent(pluginName).replace(/%40/g, '@')}`, {
|
|
1037
|
-
method: 'GET',
|
|
1038
|
-
headers: {
|
|
1039
|
-
accept: 'application/vnd.npm.install-v1+json', // only return minimal information
|
|
1040
|
-
},
|
|
1041
|
-
});
|
|
1042
|
-
|
|
1043
|
-
if (!response.ok) {
|
|
1044
|
-
throw new Error(`Failed to fetch versions from npm registry - ${response.statusText}`);
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
pkg = (await response.json()) as INpmRegistryModule;
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
if (!fromCache) {
|
|
1051
|
-
npmPluginCache.set(`lookup-${pluginName}`, pkg, { ttl: 60 * 1000 });
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
return {
|
|
1055
|
-
tags: pkg['dist-tags'],
|
|
1056
|
-
versions: Object.keys(pkg.versions).reverse(),
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
private async getPluginFromNpm(plugin: CameraUiPlugin): Promise<INpmPluginState> {
|
|
1061
|
-
const pluginState: INpmPluginState = {
|
|
1062
|
-
updateAvailable: false,
|
|
1063
|
-
betaUpdateAvailable: false,
|
|
1064
|
-
};
|
|
1065
|
-
|
|
1066
|
-
if (plugin.private) {
|
|
1067
|
-
return pluginState;
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
try {
|
|
1071
|
-
npmPluginCache.purgeStale();
|
|
1072
|
-
|
|
1073
|
-
// attempt to load from cache
|
|
1074
|
-
const fromCache = npmPluginCache.get(plugin.pluginName);
|
|
1075
|
-
|
|
1076
|
-
let pkg = fromCache as IPackageJson;
|
|
1077
|
-
if (!pkg) {
|
|
1078
|
-
const response = await fetchWithTimeout(`https://registry.npmjs.org/${encodeURIComponent(plugin.pluginName).replace(/%40/g, '@')}/latest`, {
|
|
1079
|
-
method: 'GET',
|
|
1080
|
-
});
|
|
1081
|
-
|
|
1082
|
-
if (!response.ok) {
|
|
1083
|
-
throw new Error(`Failed to check registry.npmjs.org for updates for plugin "${plugin.pluginName}" - ${response.statusText}`);
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
pkg = (await response.json()) as IPackageJson;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
pluginState.latestVersion = pkg.version;
|
|
1090
|
-
|
|
1091
|
-
try {
|
|
1092
|
-
pluginState.updateAvailable = gt(pkg.version, plugin.installedVersion!);
|
|
1093
|
-
} catch {
|
|
1094
|
-
pluginState.updateAvailable = false;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
// check for beta updates, if no latest version is available
|
|
1098
|
-
if (!pluginState.updateAvailable) {
|
|
1099
|
-
const pluginVersion = parseVersion(plugin.installedVersion);
|
|
1100
|
-
if (pluginVersion?.prerelease[0] === 'beta' && gt(plugin.installedVersion!, pluginState.latestVersion || '0.0.1')) {
|
|
1101
|
-
const versions = await this.getAvailablePluginVersions(plugin.pluginName);
|
|
1102
|
-
if (versions.tags.beta && gt(versions.tags.beta, plugin.installedVersion!)) {
|
|
1103
|
-
pluginState.betaUpdateAvailable = true;
|
|
1104
|
-
pluginState.latestVersion = versions.tags.beta;
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// store in cache if it was not there already
|
|
1110
|
-
if (!fromCache) {
|
|
1111
|
-
npmPluginCache.set(plugin.pluginName, pkg);
|
|
1112
|
-
}
|
|
1113
|
-
} catch (error: any) {
|
|
1114
|
-
this.logger.error(error);
|
|
1115
|
-
pluginState.latestVersion = undefined;
|
|
1116
|
-
pluginState.updateAvailable = false;
|
|
1117
|
-
pluginState.betaUpdateAvailable = false;
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
return pluginState;
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
private async searchNpmRegistrySingle(query: string, timeout?: number): Promise<CameraUiPlugin | undefined> {
|
|
1124
|
-
try {
|
|
1125
|
-
npmPluginCache.purgeStale();
|
|
1126
|
-
|
|
1127
|
-
const fromCache = npmPluginCache.get(`lookup-${query}`);
|
|
1128
|
-
|
|
1129
|
-
let pkg = fromCache as INpmRegistryModule;
|
|
1130
|
-
|
|
1131
|
-
if (!pkg) {
|
|
1132
|
-
const response = await fetchWithTimeout(
|
|
1133
|
-
`https://registry.npmjs.org/${encodeURIComponent(query).replace(/%40/g, '@')}`,
|
|
1134
|
-
{
|
|
1135
|
-
method: 'GET',
|
|
1136
|
-
},
|
|
1137
|
-
timeout,
|
|
1138
|
-
);
|
|
1139
|
-
|
|
1140
|
-
if (!response.ok) {
|
|
1141
|
-
throw new Error(`Failed to search the npm registry - ${response.statusText}`);
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
pkg = (await response.json()) as INpmRegistryModule;
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
if (!fromCache) {
|
|
1148
|
-
npmPluginCache.set(`lookup-${query}`, pkg, { ttl: 60 * 1000 });
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
if (!pkg.keywords?.includes('camera-ui-plugin')) {
|
|
1152
|
-
return;
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
let plugin: CameraUiPlugin;
|
|
1156
|
-
const installedPlugins = this.service.listPlugins();
|
|
1157
|
-
const isInstalled = installedPlugins.find((installedPlugin) => installedPlugin.pluginName === pkg.name);
|
|
1158
|
-
|
|
1159
|
-
if (isInstalled) {
|
|
1160
|
-
plugin = isInstalled.info;
|
|
1161
|
-
plugin.lastUpdated = pkg.time.modified;
|
|
1162
|
-
return plugin;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
plugin = {
|
|
1166
|
-
id: '0',
|
|
1167
|
-
pluginName: pkg.name,
|
|
1168
|
-
private: false,
|
|
1169
|
-
displayName: PluginManager.transformDisplaName(pkg.name),
|
|
1170
|
-
description: pkg.description ? pkg.description.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '').trim() : pkg.name,
|
|
1171
|
-
isPython: false,
|
|
1172
|
-
isNode: true,
|
|
1173
|
-
publicPackage: true,
|
|
1174
|
-
latestVersion: pkg['dist-tags'] ? pkg['dist-tags'].latest : undefined,
|
|
1175
|
-
lastUpdated: pkg.time.modified,
|
|
1176
|
-
links: {
|
|
1177
|
-
npm: `https://www.npmjs.com/package/${pkg.name}`,
|
|
1178
|
-
homepage: pkg.homepage,
|
|
1179
|
-
},
|
|
1180
|
-
author: pkg.maintainers[0]?.name,
|
|
1181
|
-
'camera.ui': {
|
|
1182
|
-
extensions: [],
|
|
1183
|
-
},
|
|
1184
|
-
};
|
|
1185
|
-
|
|
1186
|
-
return plugin;
|
|
1187
|
-
} catch (error: any) {
|
|
1188
|
-
if (error.response?.status !== 404) {
|
|
1189
|
-
this.logger.error('Failed to search the npm registry', error);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
private resolvePluginName(params: PluginsParamsNameRequest['Params']): string {
|
|
1195
|
-
if (params.scope) {
|
|
1196
|
-
const at = params.scope.startsWith('@') ? '' : '@';
|
|
1197
|
-
return `${at}${params.scope}/${params.pluginname}`;
|
|
1198
|
-
} else {
|
|
1199
|
-
return params.pluginname;
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
private isScopedPlugin(pluginName: string): boolean {
|
|
1204
|
-
return pluginName.startsWith('@') && pluginName.split('/').length > 0 && pluginName.split('/')[1]?.startsWith('camera-ui-');
|
|
1205
|
-
}
|
|
1206
|
-
}
|