diff --git a/.homeycompose/capabilities/vividstorm_lock_down.json b/.homeycompose/capabilities/vividstorm_lock_down.json new file mode 100644 index 0000000..249563b --- /dev/null +++ b/.homeycompose/capabilities/vividstorm_lock_down.json @@ -0,0 +1,10 @@ +{ + "type": "button", + "title": { + "en": "Set Lower Limit" + }, + "getable": false, + "setable": true, + "uiComponent": "button", + "icon": "/assets/capabilities/lock.svg" +} \ No newline at end of file diff --git a/.homeycompose/capabilities/vividstorm_lock_up.json b/.homeycompose/capabilities/vividstorm_lock_up.json new file mode 100644 index 0000000..9802b10 --- /dev/null +++ b/.homeycompose/capabilities/vividstorm_lock_up.json @@ -0,0 +1,10 @@ +{ + "type": "button", + "title": { + "en": "Set Upper Limit" + }, + "getable": false, + "setable": true, + "uiComponent": "button", + "icon": "/assets/capabilities/lock.svg" +} \ No newline at end of file diff --git a/app.json b/app.json index fd92488..636bf7e 100644 --- a/app.json +++ b/app.json @@ -6181,7 +6181,9 @@ { "capabilities": [ "windowcoverings_state", - "windowcoverings_set" + "windowcoverings_set", + "vividstorm_lock_up", + "vividstorm_lock_down" ], "connectivity": [ "cloud" @@ -6586,6 +6588,26 @@ "setable": true, "uiComponent": "button", "icon": "assets/capabilities/alarm_siren.svg" + }, + "vividstorm_lock_up": { + "type": "button", + "title": { + "en": "Set Upper Limit" + }, + "getable": false, + "setable": true, + "uiComponent": "button", + "icon": "/assets/capabilities/lock.svg" + }, + "vividstorm_lock_down": { + "type": "button", + "title": { + "en": "Set Lower Limit" + }, + "getable": false, + "setable": true, + "uiComponent": "button", + "icon": "/assets/capabilities/lock.svg" } } } \ No newline at end of file diff --git a/assets/capabilities/lock.svg b/assets/capabilities/lock.svg new file mode 100644 index 0000000..8ce5820 --- /dev/null +++ b/assets/capabilities/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/drivers/window_coverings/TuyaWindowCoveringsConstants.ts b/drivers/window_coverings/TuyaWindowCoveringsConstants.ts index 22bd984..49e83a9 100644 --- a/drivers/window_coverings/TuyaWindowCoveringsConstants.ts +++ b/drivers/window_coverings/TuyaWindowCoveringsConstants.ts @@ -6,10 +6,21 @@ export const WINDOW_COVERINGS_CAPABILITY_MAPPING = { position: 'windowcoverings_set', percent_control: 'windowcoverings_set', percent_state: 'windowcoverings_set', + // Vividstorm / Curtain Settings + // Mapping 'border' so it passes allowlists. Logic handled in device.ts sends 'up'/'down' values for 'border' code. + border: 'vividstorm_lock_up', } as const; +export const VIVIDSTORM_PRODUCT_IDS = ['lfkr93x0ukp5gaia']; // Vividstorm Motorised Screens + export const WINDOW_COVERINGS_CAPABILITIES = { - read_write: ['control', 'position', 'mach_operate', 'percent_control'], + read_write: [ + 'control', + 'position', + 'mach_operate', + 'percent_control', + 'border', + ], setting: ['opposite', 'control_back'], } as const; diff --git a/drivers/window_coverings/device.ts b/drivers/window_coverings/device.ts index 212ada4..9161b9b 100644 --- a/drivers/window_coverings/device.ts +++ b/drivers/window_coverings/device.ts @@ -7,6 +7,7 @@ import { WINDOW_COVERINGS_SETTING_LABELS, HomeyWindowCoveringsSettings, TuyaWindowCoveringsSettings, + VIVIDSTORM_PRODUCT_IDS, } from './TuyaWindowCoveringsConstants'; module.exports = class TuyaOAuth2DeviceWindowCoverings extends TuyaOAuth2Device { @@ -43,6 +44,19 @@ module.exports = class TuyaOAuth2DeviceWindowCoverings extends TuyaOAuth2Device this.sendCommand({ code: code, value: Math.round(value * 100) }), ); } + // Vividstorm Lock Listeners + if (VIVIDSTORM_PRODUCT_IDS.includes(this.getData().productId)) { + if (this.hasCapability('vividstorm_lock_up')) { + this.registerCapabilityListener('vividstorm_lock_up', async () => { + return await this.sendCommand({ code: 'border', value: 'up' }); + }); + } + if (this.hasCapability('vividstorm_lock_down')) { + this.registerCapabilityListener('vividstorm_lock_down', async () => { + return await this.sendCommand({ code: 'border', value: 'down' }); + }); + } + } } async onTuyaStatus(status: TuyaStatus, changed: string[]): Promise { diff --git a/drivers/window_coverings/driver.ts b/drivers/window_coverings/driver.ts index f95e12c..1ad9104 100644 --- a/drivers/window_coverings/driver.ts +++ b/drivers/window_coverings/driver.ts @@ -6,11 +6,20 @@ import { TuyaDeviceResponse, TuyaDeviceSpecificationResponse, } from '../../types/TuyaApiTypes'; -import { WINDOW_COVERINGS_CAPABILITIES, WINDOW_COVERINGS_CAPABILITY_MAPPING } from './TuyaWindowCoveringsConstants'; +import { + WINDOW_COVERINGS_CAPABILITIES, + WINDOW_COVERINGS_CAPABILITY_MAPPING, + VIVIDSTORM_PRODUCT_IDS, +} from './TuyaWindowCoveringsConstants'; module.exports = class TuyaOAuth2DriverWindowCoverings extends TuyaOAuth2Driver { TUYA_DEVICE_CATEGORIES = [DEVICE_CATEGORIES.SMALL_HOME_APPLIANCES.CURTAIN] as const; + onTuyaPairListDeviceFilter(device: TuyaDeviceResponse): boolean { + if (VIVIDSTORM_PRODUCT_IDS.includes(device.product_id)) return true; + return super.onTuyaPairListDeviceFilter(device); + } + onTuyaPairListDeviceProperties( device: TuyaDeviceResponse, specifications?: TuyaDeviceSpecificationResponse, @@ -32,6 +41,16 @@ module.exports = class TuyaOAuth2DriverWindowCoverings extends TuyaOAuth2Driver } } + // Vividstorm Specific: Explicitly add lock capabilities if 'border' is present + if (VIVIDSTORM_PRODUCT_IDS.includes(device.product_id) && props.store.tuya_capabilities.includes('border')) { + const vividstormCapabilities = ['vividstorm_lock_up', 'vividstorm_lock_down']; + const uniqueCapabilities = new Set(props.capabilities); + for (const capability of vividstormCapabilities) { + uniqueCapabilities.add(capability); + } + props.capabilities = Array.from(uniqueCapabilities); + } + return props; } }; diff --git a/lib/TuyaHaClient.ts b/lib/TuyaHaClient.ts index dcddae3..6ce80fa 100644 --- a/lib/TuyaHaClient.ts +++ b/lib/TuyaHaClient.ts @@ -474,7 +474,8 @@ export default class TuyaHaClient extends OAuth2Client { } private refreshApiToken(): void { - if (Date.now() - this.lastTokenSave < (this.tokenExpireTime - 100) * 1000) { + const token = this.getToken(); + if (token && Date.now() - this.lastTokenSave < (this.tokenExpireTime - 100) * 1000) { // No need to refresh return; } diff --git a/lib/TuyaOAuth2Driver.ts b/lib/TuyaOAuth2Driver.ts index b3b271f..7048eb9 100644 --- a/lib/TuyaOAuth2Driver.ts +++ b/lib/TuyaOAuth2Driver.ts @@ -222,15 +222,22 @@ export default class TuyaOAuth2Driver extends OAuth2Driver { } async onPairListDevices({ oAuth2Client }: { oAuth2Client: TuyaHaClient }): Promise { - const devices = await oAuth2Client.getDevices(); + let devices: TuyaDeviceResponse[] = []; + try { + devices = await oAuth2Client.getDevices(); + } catch (err) { + this.error('Failed to get devices from cloud. Automatic discovery unavailable; proceed with manual pairing.', err instanceof Error ? err.message : err); + } + const filteredDevices = devices.filter(device => { return !oAuth2Client.isRegistered(device.product_id, device.id) && this.onTuyaPairListDeviceFilter(device); }); + const listDevices: OAuth2DeviceResult[] = []; this.log('Listing devices to pair:'); - for (const device of filteredDevices) { + const devicePromises = filteredDevices.map(async device => { this.log('Device:', JSON.stringify(TuyaOAuth2Util.redactFields(device))); const deviceSpecs = (await oAuth2Client @@ -249,14 +256,23 @@ export default class TuyaOAuth2Driver extends OAuth2Driver { const deviceProperties = this.onTuyaPairListDeviceProperties({ ...device }, deviceSpecs, dataPoints); - listDevices.push({ + return { ...deviceProperties, name: device.name, data: { deviceId: device.id, productId: device.product_id, }, - }); + }; + }); + + const results = await Promise.allSettled(devicePromises); + for (const result of results) { + if (result.status === 'fulfilled') { + listDevices.push(result.value); + } else { + this.error('Failed to prepare device for pairing', result.reason); + } } return listDevices; } diff --git a/package-lock.json b/package-lock.json index 11c49ac..c7afc8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,9 +43,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -53,13 +53,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -270,6 +270,7 @@ "resolved": "https://registry.npmjs.org/homey-apps-sdk-v3-types/-/homey-apps-sdk-v3-types-0.3.6.tgz", "integrity": "sha512-uUeIE+KUBH7tQkzscpVCdq1tlCf0mL/IyL1Vu5XCs2x2dkHSIkexjXDHjhqweYT5HWPfjZZNOxMGoo7NzFjrPA==", "dev": true, + "license": "ISC", "dependencies": { "@types/node": "^14.14.20" } @@ -299,9 +300,10 @@ }, "node_modules/@types/node-fetch": { "version": "2.6.13", - "resolved": "https://npm.drenso.dev/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "form-data": "^4.0.4" @@ -318,9 +320,9 @@ } }, "node_modules/@types/readable-stream": { - "version": "4.0.22", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.22.tgz", - "integrity": "sha512-/FFhJpfCLAPwAcN3mFycNUa77ddnr8jTgF5VmSNetaemWB2cIlfCA9t0YTM3JAT0wOcv8D4tjPo7pkDhK3EJIg==", + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.23.tgz", + "integrity": "sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -385,6 +387,7 @@ "integrity": "sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.30.7", "@typescript-eslint/types": "5.30.7", @@ -555,6 +558,7 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -688,9 +692,9 @@ "license": "MIT" }, "node_modules/bl": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.4.tgz", - "integrity": "sha512-ZV/9asSuknOExbM/zPPA8z00lc1ihPKWaStHkkQrxHNeYx+yY+TmF+v80dpv2G0mv3HVXBu7ryoAsxbFFhf4eg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.6.tgz", + "integrity": "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg==", "license": "MIT", "dependencies": { "@types/readable-stream": "^4.0.0", @@ -836,6 +840,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -932,6 +937,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -1112,8 +1118,10 @@ "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -1167,9 +1175,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "license": "MIT", "bin": { @@ -1412,9 +1420,9 @@ "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { @@ -1422,7 +1430,7 @@ "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -1462,16 +1470,26 @@ "license": "0BSD" }, "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, - "license": "MIT" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -1492,6 +1510,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -1555,9 +1574,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, @@ -1582,6 +1601,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" }, @@ -1806,16 +1826,18 @@ }, "node_modules/homey-oauth2app": { "version": "3.7.2", - "resolved": "https://npm.drenso.dev/homey-oauth2app/-/homey-oauth2app-3.7.2.tgz", + "resolved": "https://registry.npmjs.org/homey-oauth2app/-/homey-oauth2app-3.7.2.tgz", "integrity": "sha512-YznxcrHg2xqzPkggLkjCOiEKHETPCkCWFQHGuXDD/JltFebPA2QcNmoiWKacZqd7V6Fh7BLbJJGrVkuMXGstig==", + "license": "MIT", "dependencies": { "node-fetch": "^2.3.0" } }, "node_modules/homey-oauth2app/node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://npm.drenso.dev/node-fetch/-/node-fetch-2.7.0.tgz", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -1862,9 +1884,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2153,8 +2175,9 @@ }, "node_modules/mqtt": { "version": "5.14.1", - "resolved": "https://npm.drenso.dev/mqtt/-/mqtt-5.14.1.tgz", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.14.1.tgz", "integrity": "sha512-NxkPxE70Uq3Ph7goefQa7ggSsVzHrayCD0OyxlJgITN/EbzlZN+JEPmaAZdxP1LsIT5FamDyILoQTF72W7Nnbw==", + "license": "MIT", "dependencies": { "@types/readable-stream": "^4.0.21", "@types/ws": "^8.18.1", @@ -2228,6 +2251,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "license": "MIT", "dependencies": { "clone": "2.x" }, @@ -2239,6 +2263,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", "funding": [ { "type": "github", @@ -2249,14 +2274,16 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } }, "node_modules/node-fetch": { "version": "3.3.2", - "resolved": "https://npm.drenso.dev/node-fetch/-/node-fetch-3.3.2.tgz", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -2397,9 +2424,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, @@ -2589,9 +2616,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -2667,9 +2694,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -2857,9 +2884,9 @@ } }, "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2920,7 +2947,8 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" }, "node_modules/tslib": { "version": "1.14.1", @@ -2983,6 +3011,7 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3024,6 +3053,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -3031,12 +3061,14 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -3092,21 +3124,21 @@ "license": "0BSD" }, "node_modules/worker-timers": { - "version": "8.0.25", - "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.25.tgz", - "integrity": "sha512-X7Z5dmM6PlrEnaadtFQOyXHGD/IysPA3HZzaC2koqsU1VI+RvyGmjiiLiUBQixK8PH5R7ilkOzZupWskNRaXmA==", + "version": "8.0.26", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.26.tgz", + "integrity": "sha512-Yfr8t1SfvA5Qwr5JlvTHVd0aI1r1kQ+dtJQ5aHjNleK/GRIOrwtoEUnGhwumLR9qH6YghFZsqD9w8IzsP7RHwg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.4", "tslib": "^2.8.1", - "worker-timers-broker": "^8.0.11", + "worker-timers-broker": "^8.0.12", "worker-timers-worker": "^9.0.11" } }, "node_modules/worker-timers-broker": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.11.tgz", - "integrity": "sha512-uwhxKru8BI9m2tsogxr2fB6POZ8LB2xH+Pu3R0mvQnAZLPgLD6K3IX4LNKPTEgTJ/j5VsuQPB+gLI1NBNKkPlg==", + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.12.tgz", + "integrity": "sha512-Udml0yZv59tj/5Y2eCW2bYmrBgFSYmg0MXSzlDUdmsjcmf272hJaY8R3TWteetfL6tmL2+yJwRmcJgDtwCcOZg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.4",