From 1497da9cbb3373cabc9f248b236eb7dd93f30225 Mon Sep 17 00:00:00 2001 From: Nicolae-Rares Ailincai Date: Fri, 20 Oct 2023 19:28:26 +0300 Subject: [PATCH] Feat/v2 (#78) * feat/humidifier-dual-200s --- .github/workflows/build.yml | 2 +- .vscode/settings.json | 6 +- README.md | 39 +- config.schema.json | 2 +- package.json | 27 +- src/VeSyncHumAccessory.ts | 107 ++++ ...SyncAccessory.ts => VeSyncPurAccessory.ts} | 6 +- src/api/VeSync.ts | 63 +- src/api/VeSyncFan.ts | 5 +- src/api/VeSyncGeneric.ts | 9 + src/api/VeSyncHumidifier.ts | 193 ++++++ src/api/deviceTypes.ts | 20 + src/characteristics/Active.ts | 2 +- src/characteristics/AirQuality.ts | 2 +- src/characteristics/CurrentState.ts | 2 +- src/characteristics/FilterChangeIndication.ts | 2 +- src/characteristics/FilterLifeLevel.ts | 2 +- src/characteristics/LockPhysicalControls.ts | 2 +- src/characteristics/PM25Density.ts | 2 +- src/characteristics/RotationSpeed.ts | 2 +- src/characteristics/TargetState.ts | 2 +- src/experimentalCharacteristics/Display.ts | 2 +- src/humidifierCharacteristics/Active.ts | 38 ++ src/humidifierCharacteristics/AutoMode.ts | 27 + .../CurrentHumidifierDehumidifierState.ts | 18 + .../CurrentRelativeHumidity.ts | 18 + .../RelativeHumidityHumidifierThreshold.ts | 34 ++ .../RotationSpeed.ts | 44 ++ src/platform.ts | 48 +- src/types.ts | 1 + yarn.lock | 570 +++++++++--------- 31 files changed, 960 insertions(+), 337 deletions(-) create mode 100644 src/VeSyncHumAccessory.ts rename src/{VeSyncAccessory.ts => VeSyncPurAccessory.ts} (97%) create mode 100644 src/api/VeSyncGeneric.ts create mode 100644 src/api/VeSyncHumidifier.ts create mode 100644 src/humidifierCharacteristics/Active.ts create mode 100644 src/humidifierCharacteristics/AutoMode.ts create mode 100644 src/humidifierCharacteristics/CurrentHumidifierDehumidifierState.ts create mode 100644 src/humidifierCharacteristics/CurrentRelativeHumidity.ts create mode 100644 src/humidifierCharacteristics/RelativeHumidityHumidifierThreshold.ts create mode 100644 src/humidifierCharacteristics/RotationSpeed.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50f0b76..97f27bd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: # the Node.js versions to build on - node-version: [14.x, 16.x, 18.x, 19.x] + node-version: [16.x, 18.x, 19.x, 20.x] steps: - uses: actions/checkout@v3 diff --git a/.vscode/settings.json b/.vscode/settings.json index 7b0d4c5..69f1559 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "files.eol": "\n", - "cSpell.words": ["accountid", "appversion"], + "cSpell.words": [ + "accountid", + "appversion", + "Levoit" + ], "editor.defaultFormatter": "vscode.typescript-language-features", "editor.codeActionsOnSave": { "source.fixAll.eslint": true diff --git a/README.md b/README.md index 0fab508..c8b219a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ # Homebridge Levoit Air Purifier -This is a Homebridge plugin to control Levoit Air Purifiers with via the VeSync Platform. +This is a Homebridge plugin to control Levoit Air Purifiers/Humidifiers with via the VeSync Platform. | Supported Versions | Tested | | ------------------ | ------ | @@ -24,13 +24,9 @@ This is a Homebridge plugin to control Levoit Air Purifiers with via the VeSync **If you have a newer version that is not in this table, then open a issue and i will try to add support for it** -This plugin uses similar API calls as -[homebridge-levoitcore-client](https://github.com/tushardhadiwal/homebridge-levoitcore-client) but with differences on API implementation -and extra features. - Any device from VeSync that is not listed in the supported versions are automatically skipped when discovering devices. -### Features +### Features for Purifiers 1. Displaying the air quality (the same display as the one on the physical device) (Not for 200S) 2. Display the PM2.5 Density value in Home App shown in µg/m^3 (Not for 200S) @@ -47,16 +43,43 @@ Any device from VeSync that is not listed in the supported versions are automati - Auto - Manual +### Humidifiers (Experimental Feature) + +The version 2.x adds support for humidifiers as an experimental feature which by default is disabled, the devices and features are limited for this devices for now + +| Supported Versions | Tested | +| ------------------ | ------ | +| Dual 200S | ✅ | +| Other versions | ❌ | + +**If you have a newer version that is not in this table, then open a issue +and i will try to add support for it** + +#### Features + +1. Displaying the humidity level +2. Target Humidity +3. Speed option: + - 0 -> Off + - 1 -> LOW + - 2 -> HIGH +4. Mode change as Swing in home app + - Auto (Swing enabled) + - Manual (Swing disabled) + ### Experimental Features For the experimental features to be activated you need to add them in the config file of the platform, e.g. + ```json { "name": "Levoit Air Purifiers", - "experimentalFeatures": ["DeviceDisplay"] + "experimentalFeatures": ["DeviceDisplay", "Humidifiers"] } ``` +--- + 1. Show the display's switch as a light in the app (`DeviceDisplay`) The read data is cached for 5 seconds to not trigger the rate limiter for the API. @@ -64,6 +87,8 @@ Each request is delayed by 500ms to not trigger the rate limiter if a huge numbe The timers are not included because you can accomplish similar results by using Home App's Automatization or the Shortcuts app +2. Discovers supported humidifiers (`Humidifiers`) + ### Configuration - Via the Homebridge UI, enter the Homebridge VeSync Client plugin settings. diff --git a/config.schema.json b/config.schema.json index 266edc0..40d334d 100644 --- a/config.schema.json +++ b/config.schema.json @@ -30,7 +30,7 @@ "items": { "title": "Feature", "type": "string", - "enum": ["DeviceDisplay"] + "enum": ["DeviceDisplay", "Humidifiers"] } } } diff --git a/package.json b/package.json index 69c1534..58b8a4b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "displayName": "Levoit Air Purifier", "main": "dist/index.js", "license": "Apache-2.0", - "version": "1.3.1", + "version": "2.0.0", "private": false, "bugs": { "url": "https://github.com/RaresAil/homebridge-levoit-air-purifier/issues" @@ -26,27 +26,30 @@ "start": "npm run build && nodemon" }, "devDependencies": { - "@types/async-lock": "^1.4.0", - "@types/big.js": "^6.1.6", - "@types/node": "^20.2.5", - "@typescript-eslint/eslint-plugin": "^5.59.8", - "@typescript-eslint/parser": "^5.59.8", - "eslint": "^8.41.0", + "@types/async-lock": "^1.4.1", + "@types/big.js": "^6.2.1", + "@types/node": "^20.8.7", + "@typescript-eslint/eslint-plugin": "^6.8.0", + "@typescript-eslint/parser": "^6.8.0", + "eslint": "^8.51.0", "homebridge": "^1.6.1", - "nodemon": "^2.0.22", - "rimraf": "^5.0.1", + "nodemon": "^3.0.1", + "rimraf": "^5.0.5", "ts-node": "^10.9.1", - "typescript": "^5.0.4" + "typescript": "^5.2.2" }, "engines": { "homebridge": ">=1.3.5", - "node": ">=14.18.1" + "node": ">=16" }, "dependencies": { "async-lock": "^1.4.0", - "axios": "^1.4.0", + "axios": "^1.5.1", "big.js": "^6.2.1" }, + "resolutions": { + "semver": "^7.5.2" + }, "keywords": [ "homebridge-plugin", "air-purifier", diff --git a/src/VeSyncHumAccessory.ts b/src/VeSyncHumAccessory.ts new file mode 100644 index 0000000..39c6b3c --- /dev/null +++ b/src/VeSyncHumAccessory.ts @@ -0,0 +1,107 @@ +import { Characteristic, Service } from 'homebridge'; + +import Platform, { VeSyncContext, VeSyncPlatformAccessory } from './platform'; +import VeSyncHumidifier from './api/VeSyncHumidifier'; + +import RelativeHumidityHumidifierThreshold from './humidifierCharacteristics/RelativeHumidityHumidifierThreshold'; +import CurrentHumidifierDehumidifierState from './humidifierCharacteristics/CurrentHumidifierDehumidifierState'; +import CurrentRelativeHumidity from './humidifierCharacteristics/CurrentRelativeHumidity'; +import RotationSpeed from './humidifierCharacteristics/RotationSpeed'; +import AutoMode from './humidifierCharacteristics/AutoMode'; +import Active from './humidifierCharacteristics/Active'; + +export type AccessoryThisType = ThisType<{ + currentStateChar?: Characteristic; + humidifierService: Service; + modeChar?: Characteristic; + device: VeSyncHumidifier; + platform: Platform; +}>; + +export default class VeSyncHumAccessory { + private currentStateChar?: Characteristic; + private modeChar?: Characteristic; + + private humidifierService?: Service; + + public get UUID() { + return this.device.uuid.toString(); + } + + private get device() { + return (this.accessory.context as VeSyncContext).device as VeSyncHumidifier; + } + + constructor( + private readonly platform: Platform, + private readonly accessory: VeSyncPlatformAccessory, + ) { + try { + const { manufacturer, model, mac } = this.device; + + this.accessory + .getService(this.platform.Service.AccessoryInformation)! + .setCharacteristic( + this.platform.Characteristic.Manufacturer, + manufacturer + ) + .setCharacteristic(this.platform.Characteristic.Model, model) + .setCharacteristic(this.platform.Characteristic.SerialNumber, mac); + + this.humidifierService = + this.accessory.getService(this.platform.Service.HumidifierDehumidifier) || + this.accessory.addService(this.platform.Service.HumidifierDehumidifier); + + this.humidifierService + .getCharacteristic(this.platform.Characteristic.Active) + .onGet(Active.get.bind(this)) + .onSet(Active.set.bind(this)); + + this.currentStateChar = this.humidifierService + .getCharacteristic(this.platform.Characteristic.CurrentHumidifierDehumidifierState) + .onGet(CurrentHumidifierDehumidifierState.get.bind(this)); + + this.humidifierService + .getCharacteristic(this.platform.Characteristic.TargetHumidifierDehumidifierState) + .setProps({ + minValue: 1, + maxValue: 1, + validValueRanges: [1, 1], + validValues: [1] + }) + .onGet(() => { + return this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER; + }); + + this.humidifierService + .getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity) + .onGet(CurrentRelativeHumidity.get.bind(this)); + + if (this.device.deviceType.hasAutoMode) { + this.humidifierService + .getCharacteristic(this.platform.Characteristic.RelativeHumidityHumidifierThreshold) + .setProps({ + maxValue: 110, + minValue: 30, + }) + .onGet(RelativeHumidityHumidifierThreshold.get.bind(this)) + .onSet(RelativeHumidityHumidifierThreshold.set.bind(this)); + + this.modeChar = this.humidifierService.getCharacteristic(this.platform.Characteristic.SwingMode) + .onGet(AutoMode.get.bind(this)) + .onSet(AutoMode.set.bind(this)); + } + + this.humidifierService + .getCharacteristic(this.platform.Characteristic.RotationSpeed) + .setProps({ + minStep: this.device.deviceType.speedMinStep, + maxValue: 100 + }) + .onGet(RotationSpeed.get.bind(this)) + .onSet(RotationSpeed.set.bind(this)); + } catch (error: any) { + this.platform.log.error(`Error: ${error?.message}`); + } + } +} diff --git a/src/VeSyncAccessory.ts b/src/VeSyncPurAccessory.ts similarity index 97% rename from src/VeSyncAccessory.ts rename to src/VeSyncPurAccessory.ts index eecbc6b..39156f6 100644 --- a/src/VeSyncAccessory.ts +++ b/src/VeSyncPurAccessory.ts @@ -16,13 +16,13 @@ import DisplayLight from './experimentalCharacteristics/Display'; export type AccessoryThisType = ThisType<{ airPurifierCurrentCharacteristic?: Characteristic; - HomeAirQuality: VeSyncAccessory['HomeAirQuality']; + HomeAirQuality: VeSyncPurAccessory['HomeAirQuality']; airPurifierService: Service; platform: Platform; device: VeSyncFan; }>; -export default class VeSyncAccessory { +export default class VeSyncPurAccessory { private HomeAirQuality = this.platform.Characteristic.AirQuality; private airPurifierCurrentCharacteristic?: Characteristic; private airPurifierService?: Service; @@ -32,7 +32,7 @@ export default class VeSyncAccessory { } private get device() { - return (this.accessory.context as VeSyncContext).device; + return (this.accessory.context as VeSyncContext).device as VeSyncFan; } constructor( diff --git a/src/api/VeSync.ts b/src/api/VeSync.ts index 18bf055..76f9986 100644 --- a/src/api/VeSync.ts +++ b/src/api/VeSync.ts @@ -3,7 +3,9 @@ import { Logger } from 'homebridge'; import AsyncLock from 'async-lock'; import crypto from 'crypto'; -import deviceTypes from './deviceTypes'; +import deviceTypes, { humidifierDeviceTypes } from './deviceTypes'; +import VeSyncHumidifier from './VeSyncHumidifier'; +import { VeSyncGeneric } from './VeSyncGeneric'; import DebugMode from '../debugMode'; import VeSyncFan from './VeSyncFan'; @@ -17,6 +19,16 @@ export enum BypassMethod { SPEED = 'setLevel' } +export enum HumidifierBypassMethod { + HUMIDITY = 'setTargetHumidity', + STATUS = 'getHumidifierStatus', + MIST_LEVEL = 'setVirtualLevel', + MODE = 'setHumidityMode', + DISPLAY = 'setDisplay', + SWITCH = 'setSwitch', + LEVEL = 'setLevel', +} + const lock = new AsyncLock(); const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -66,7 +78,7 @@ export default class VeSync { }; } - private generateV2Body(fan: VeSyncFan, method: BypassMethod, data = {}) { + private generateV2Body(fan: VeSyncGeneric, method: BypassMethod | HumidifierBypassMethod, data = {}) { return { method: 'bypassV2', debugMode: false, @@ -84,8 +96,8 @@ export default class VeSync { } public async sendCommand( - fan: VeSyncFan, - method: BypassMethod, + fan: VeSyncGeneric, + method: BypassMethod | HumidifierBypassMethod, body = {} ): Promise { return lock.acquire('api-call', async () => { @@ -137,7 +149,7 @@ export default class VeSync { }); } - public async getDeviceInfo(fan: VeSyncFan): Promise { + public async getDeviceInfo(fan: VeSyncGeneric, humidifier = false): Promise { return lock.acquire('api-call', async () => { try { if (!this.api) { @@ -149,7 +161,7 @@ export default class VeSync { const response = await this.api.post( 'cloud/v2/deviceManaged/bypassV2', { - ...this.generateV2Body(fan, BypassMethod.STATUS), + ...this.generateV2Body(fan, humidifier ? HumidifierBypassMethod.STATUS : BypassMethod.STATUS), ...this.generateDetailBody(), ...this.generateBody(true) } @@ -269,8 +281,11 @@ export default class VeSync { }); } - public async getDevices(): Promise { - return lock.acquire('api-call', async () => { + public async getDevices() { + return lock.acquire<{ + purifiers: VeSyncFan[]; + humidifiers: VeSyncHumidifier[]; + }>('api-call', async () => { try { if (!this.api) { throw new Error('The user is not logged in!'); @@ -291,7 +306,10 @@ export default class VeSync { JSON.stringify(response) ); - return []; + return { + purifiers: [], + humidifiers: [] + }; } if (!Array.isArray(response.data?.result?.list)) { @@ -301,7 +319,10 @@ export default class VeSync { JSON.stringify(response.data) ); - return []; + return { + purifiers: [], + humidifiers: [] + }; } const { list } = response.data.result ?? { list: [] }; @@ -312,7 +333,8 @@ export default class VeSync { JSON.stringify(list) ); - const devices = list + + const purifiers = list .filter( ({ deviceType, type, extension }) => !!deviceTypes.find(({ isValid }) => isValid(deviceType)) && @@ -321,12 +343,27 @@ export default class VeSync { ) .map(VeSyncFan.fromResponse(this)); + const humidifiers = list + .filter( + ({ deviceType, type, extension }) => + !!humidifierDeviceTypes.find(({ isValid }) => isValid(deviceType)) && + type === 'wifi-air' && + !extension + ) + .map(VeSyncHumidifier.fromResponse(this)); + await delay(1500); - return devices; + return { + purifiers, + humidifiers + }; } catch (error: any) { this.log.error('Failed to get devices', `Error: ${error?.message}`); - return []; + return { + purifiers: [], + humidifiers: [] + }; } }); } diff --git a/src/api/VeSyncFan.ts b/src/api/VeSyncFan.ts index 88f1ce3..b9e5e55 100644 --- a/src/api/VeSyncFan.ts +++ b/src/api/VeSyncFan.ts @@ -2,6 +2,7 @@ import AsyncLock from 'async-lock'; import deviceTypes, { DeviceType } from './deviceTypes'; import VeSync, { BypassMethod } from './VeSync'; +import { VeSyncGeneric } from './VeSyncGeneric'; export enum AirQuality { VERY_GOOD = 1, @@ -16,7 +17,7 @@ export enum Mode { Auto = 'auto' } -export default class VeSyncFan { +export default class VeSyncFan implements VeSyncGeneric { private lock: AsyncLock = new AsyncLock(); public readonly deviceType: DeviceType; private lastCheck = 0; @@ -69,7 +70,7 @@ export default class VeSyncFan { return value < 0 ? 0 : value > 1000 ? 1000 : value; } - constructor ( + constructor( private readonly client: VeSync, public readonly name: string, private _mode: Mode, diff --git a/src/api/VeSyncGeneric.ts b/src/api/VeSyncGeneric.ts new file mode 100644 index 0000000..f927054 --- /dev/null +++ b/src/api/VeSyncGeneric.ts @@ -0,0 +1,9 @@ +export interface VeSyncGeneric { + readonly name: string; + readonly uuid: string; + readonly cid: string; + readonly region: string; + readonly model: string; + readonly mac: string; + readonly configModule: string; +} \ No newline at end of file diff --git a/src/api/VeSyncHumidifier.ts b/src/api/VeSyncHumidifier.ts new file mode 100644 index 0000000..6c8fc22 --- /dev/null +++ b/src/api/VeSyncHumidifier.ts @@ -0,0 +1,193 @@ +import AsyncLock from 'async-lock'; + +import { HumidifierDeviceType, humidifierDeviceTypes } from './deviceTypes'; +import VeSync, { HumidifierBypassMethod } from './VeSync'; +import { VeSyncGeneric } from './VeSyncGeneric'; + +export enum AirQuality { + VERY_GOOD = 1, + MODERATE = 3, + UNKNOWN = 0, + GOOD = 2, + POOR = 4 +} + +export enum Mode { + Manual = 'manual', + Auto = 'auto', +} + +export default class VeSyncHumidifier implements VeSyncGeneric { + public readonly deviceType: HumidifierDeviceType; + + private lock: AsyncLock = new AsyncLock(); + private lastCheck = 0; + + private _mode: Mode = Mode.Manual; + private _autoTargetHumidity = 0; + private _screenVisible = true; + private _idle = false; + private _humidity = 0; + private _speed = 1; + + public readonly manufacturer = 'Levoit'; + + public get screenVisible() { + return this._screenVisible; + } + + public get isOn() { + return this._isOn; + } + + public get speed() { + return this._speed; + } + + public get humidity() { + return this._humidity; + } + + public get targetHumidity() { + return this._autoTargetHumidity; + } + + public get mode() { + return this._mode; + } + + public get currentState() { + if (!this._isOn) { + return 0; + } + + if (this._idle) { + return 1; + } + + return 2; + } + + constructor( + private readonly client: VeSync, + public readonly name: string, + public readonly uuid: string, + private _isOn: boolean, + public readonly cid: string, + public readonly region: string, + public readonly model: string, + public readonly mac: string, + public readonly configModule: string, + ) { + this.deviceType = humidifierDeviceTypes.find(({ isValid }) => isValid(this.model))!; + } + + public async setPower(power: boolean): Promise { + const success = await this.client.sendCommand(this, HumidifierBypassMethod.SWITCH, { + enabled: power, + id: 0 + }); + + if (success) { + this._isOn = power; + } + + return success; + } + + public async setTarget(value: number): Promise { + const success = await this.client.sendCommand(this, HumidifierBypassMethod.HUMIDITY, { + 'target_humidity': value, + id: 0 + }); + + if (success) { + this._autoTargetHumidity = value; + } + + return success; + } + + public async setMode(mode: Mode): Promise { + const success = await this.client.sendCommand(this, HumidifierBypassMethod.MODE, { + mode: mode, + id: 0 + }); + + if (success) { + this._mode = mode; + } + + return success; + } + + public async setSpeed(value: number): Promise { + const success = await this.client.sendCommand(this, HumidifierBypassMethod.MIST_LEVEL, { + level: value, + type: 'mist', + id: 0 + }); + + if (success) { + this._speed = value; + this._mode = Mode.Manual; + } + + return success; + } + + + public async updateInfo(): Promise { + return this.lock.acquire('update-info', async () => { + try { + if (Date.now() - this.lastCheck < 5 * 1000) { + return; + } + + const data = await this.client.getDeviceInfo(this, true); + this.lastCheck = Date.now(); + + if (!data?.result?.result) { + return; + } + + const result = data.result.result; + + this._idle = (result.configuration?.automatic_stop && result.automatic_stop_reach_target); + this._autoTargetHumidity = result.configuration?.auto_target_humidity ?? 0; + this._speed = result.mist_virtual_level; + this._screenVisible = result.display; + this._humidity = result.humidity; + this._isOn = result.enabled; + this._mode = result.mode; + } catch (err: any) { + this.client.log.error(err?.message); + } + }); + } + + public static fromResponse = + (client: VeSync) => + ({ + deviceStatus, + deviceName, + uuid, + cid, + deviceRegion, + deviceType, + macID, + configModule, + }) => { + return new VeSyncHumidifier( + client, + deviceName, + uuid, + deviceStatus === 'on', + cid, + deviceRegion, + deviceType, + macID, + configModule + ); + }; +} diff --git a/src/api/deviceTypes.ts b/src/api/deviceTypes.ts index 2808a2b..e4a944f 100644 --- a/src/api/deviceTypes.ts +++ b/src/api/deviceTypes.ts @@ -11,6 +11,12 @@ export enum DeviceName { Core200S = '200S' } +export enum HumidifierDeviceName { + Dual200SLeg = 'Dual200S', + Dual200S = 'D301S', +} + + export interface DeviceType { isValid: (input: string) => boolean; hasAirQuality: boolean; @@ -20,6 +26,8 @@ export interface DeviceType { hasPM25: boolean; } +export type HumidifierDeviceType = Omit & { isHumidifier: true }; + const deviceTypes: DeviceType[] = [ { isValid: (input: string) => @@ -54,6 +62,18 @@ const deviceTypes: DeviceType[] = [ speedMinStep: 25, speedLevels: 4, hasPM25: false + }, +]; + +export const humidifierDeviceTypes: HumidifierDeviceType[] = [ + { + isValid: (input: string) => + input.includes(HumidifierDeviceName.Dual200S) || + input.includes(HumidifierDeviceName.Dual200SLeg), + hasAutoMode: true, + speedMinStep: 50, + speedLevels: 2, + isHumidifier: true } ]; diff --git a/src/characteristics/Active.ts b/src/characteristics/Active.ts index 1184ddc..33e220a 100644 --- a/src/characteristics/Active.ts +++ b/src/characteristics/Active.ts @@ -5,7 +5,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; import { delay } from '../util'; const characteristic: { diff --git a/src/characteristics/AirQuality.ts b/src/characteristics/AirQuality.ts index fdbf0fb..797557b 100644 --- a/src/characteristics/AirQuality.ts +++ b/src/characteristics/AirQuality.ts @@ -5,7 +5,7 @@ import { } from 'homebridge'; import { AirQuality } from '../api/VeSyncFan'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/characteristics/CurrentState.ts b/src/characteristics/CurrentState.ts index 3192de9..ed742f3 100644 --- a/src/characteristics/CurrentState.ts +++ b/src/characteristics/CurrentState.ts @@ -4,7 +4,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/characteristics/FilterChangeIndication.ts b/src/characteristics/FilterChangeIndication.ts index e2c6544..e707982 100644 --- a/src/characteristics/FilterChangeIndication.ts +++ b/src/characteristics/FilterChangeIndication.ts @@ -4,7 +4,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/characteristics/FilterLifeLevel.ts b/src/characteristics/FilterLifeLevel.ts index 066fea2..0d0388b 100644 --- a/src/characteristics/FilterLifeLevel.ts +++ b/src/characteristics/FilterLifeLevel.ts @@ -4,7 +4,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/characteristics/LockPhysicalControls.ts b/src/characteristics/LockPhysicalControls.ts index 22b0604..e542c1c 100644 --- a/src/characteristics/LockPhysicalControls.ts +++ b/src/characteristics/LockPhysicalControls.ts @@ -5,7 +5,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/characteristics/PM25Density.ts b/src/characteristics/PM25Density.ts index c4bcdd0..dabec48 100644 --- a/src/characteristics/PM25Density.ts +++ b/src/characteristics/PM25Density.ts @@ -4,7 +4,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/characteristics/RotationSpeed.ts b/src/characteristics/RotationSpeed.ts index 778b638..15ea004 100644 --- a/src/characteristics/RotationSpeed.ts +++ b/src/characteristics/RotationSpeed.ts @@ -7,7 +7,7 @@ import { } from 'homebridge'; import VeSyncFan, { Mode } from '../api/VeSyncFan'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const calculateSpeed = (device: VeSyncFan) => { let speed = (device.speed + 1) * device.deviceType.speedMinStep; diff --git a/src/characteristics/TargetState.ts b/src/characteristics/TargetState.ts index 1ca0d13..da077de 100644 --- a/src/characteristics/TargetState.ts +++ b/src/characteristics/TargetState.ts @@ -6,7 +6,7 @@ import { } from 'homebridge'; import { Mode } from '../api/VeSyncFan'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; const characteristic: { get: CharacteristicGetHandler; diff --git a/src/experimentalCharacteristics/Display.ts b/src/experimentalCharacteristics/Display.ts index c6052cd..afc5d07 100644 --- a/src/experimentalCharacteristics/Display.ts +++ b/src/experimentalCharacteristics/Display.ts @@ -5,7 +5,7 @@ import { Nullable } from 'homebridge'; -import { AccessoryThisType } from '../VeSyncAccessory'; +import { AccessoryThisType } from '../VeSyncPurAccessory'; import { delay } from '../util'; const characteristic: { diff --git a/src/humidifierCharacteristics/Active.ts b/src/humidifierCharacteristics/Active.ts new file mode 100644 index 0000000..6a51199 --- /dev/null +++ b/src/humidifierCharacteristics/Active.ts @@ -0,0 +1,38 @@ +import { + CharacteristicGetHandler, + CharacteristicSetHandler, + CharacteristicValue, + Nullable +} from 'homebridge'; + +import { AccessoryThisType } from '../VeSyncHumAccessory'; +import { delay } from '../util'; + +const characteristic: { + get: CharacteristicGetHandler; + set: CharacteristicSetHandler; +} & AccessoryThisType = { + get: async function (): Promise> { + await this.device.updateInfo(); + return this.device.isOn; + }, + set: async function (value: CharacteristicValue) { + let boolValue = value === 1; + + if (boolValue !== this.device.isOn) { + const success = await this.device.setPower(boolValue); + + if (!success) { + boolValue = !boolValue; + } + } else { + await delay(10); + } + + this.currentStateChar?.updateValue( + this.device.currentState, + ); + } +}; + +export default characteristic; diff --git a/src/humidifierCharacteristics/AutoMode.ts b/src/humidifierCharacteristics/AutoMode.ts new file mode 100644 index 0000000..91a408c --- /dev/null +++ b/src/humidifierCharacteristics/AutoMode.ts @@ -0,0 +1,27 @@ +import { + CharacteristicGetHandler, + CharacteristicSetHandler, + CharacteristicValue, + Nullable +} from 'homebridge'; + +import { AccessoryThisType } from '../VeSyncHumAccessory'; +import { Mode } from '../api/VeSyncHumidifier'; + +const characteristic: { + get: CharacteristicGetHandler; + set: CharacteristicSetHandler; +} & AccessoryThisType = { + get: async function (): Promise> { + await this.device.updateInfo(); + return this.device.mode === Mode.Auto ? 1 : 0; + }, + set: async function (value: CharacteristicValue) { + const mode = value === 1 ? Mode.Auto : Mode.Manual; + if (mode !== this.device.mode) { + await this.device.setMode(mode); + } + } +}; + +export default characteristic; diff --git a/src/humidifierCharacteristics/CurrentHumidifierDehumidifierState.ts b/src/humidifierCharacteristics/CurrentHumidifierDehumidifierState.ts new file mode 100644 index 0000000..0c1b53b --- /dev/null +++ b/src/humidifierCharacteristics/CurrentHumidifierDehumidifierState.ts @@ -0,0 +1,18 @@ +import { + CharacteristicGetHandler, + CharacteristicValue, + Nullable +} from 'homebridge'; + +import { AccessoryThisType } from '../VeSyncHumAccessory'; + +const characteristic: { + get: CharacteristicGetHandler; +} & AccessoryThisType = { + get: async function (): Promise> { + await this.device.updateInfo(); + return this.device.currentState; + } +}; + +export default characteristic; diff --git a/src/humidifierCharacteristics/CurrentRelativeHumidity.ts b/src/humidifierCharacteristics/CurrentRelativeHumidity.ts new file mode 100644 index 0000000..95168ea --- /dev/null +++ b/src/humidifierCharacteristics/CurrentRelativeHumidity.ts @@ -0,0 +1,18 @@ +import { + CharacteristicGetHandler, + CharacteristicValue, + Nullable +} from 'homebridge'; + +import { AccessoryThisType } from '../VeSyncHumAccessory'; + +const characteristic: { + get: CharacteristicGetHandler; +} & AccessoryThisType = { + get: async function (): Promise> { + await this.device.updateInfo(); + return this.device.humidity; + } +}; + +export default characteristic; diff --git a/src/humidifierCharacteristics/RelativeHumidityHumidifierThreshold.ts b/src/humidifierCharacteristics/RelativeHumidityHumidifierThreshold.ts new file mode 100644 index 0000000..d84e1fd --- /dev/null +++ b/src/humidifierCharacteristics/RelativeHumidityHumidifierThreshold.ts @@ -0,0 +1,34 @@ +import { + CharacteristicGetHandler, + CharacteristicSetHandler, + CharacteristicValue, + Nullable +} from 'homebridge'; + +import { AccessoryThisType } from '../VeSyncHumAccessory'; + +const characteristic: { + get: CharacteristicGetHandler; + set: CharacteristicSetHandler; +} & AccessoryThisType = { + get: async function (): Promise> { + await this.device.updateInfo(); + return this.device.targetHumidity; + }, + set: async function (value: CharacteristicValue) { + let newTarget = value as number; + if (newTarget < 30) { + newTarget = 30; + } + + if (newTarget > 80) { + newTarget = 80; + } + + if (newTarget !== this.device.targetHumidity) { + this.device.setTarget(newTarget); + } + } +}; + +export default characteristic; diff --git a/src/humidifierCharacteristics/RotationSpeed.ts b/src/humidifierCharacteristics/RotationSpeed.ts new file mode 100644 index 0000000..beb11b5 --- /dev/null +++ b/src/humidifierCharacteristics/RotationSpeed.ts @@ -0,0 +1,44 @@ +import Big from 'big.js'; +import { + CharacteristicGetHandler, + CharacteristicSetHandler, + CharacteristicValue, + Nullable +} from 'homebridge'; + +import VeSyncHumidifier from '../api/VeSyncHumidifier'; +import { AccessoryThisType } from '../VeSyncHumAccessory'; +import { delay } from '../util'; + +const calculateSpeed = (device: VeSyncHumidifier) => { + const speed = (device.speed) * device.deviceType.speedMinStep; + return device.isOn ? speed : 0; +}; + +const characteristic: { + get: CharacteristicGetHandler; + set: CharacteristicSetHandler; +} & AccessoryThisType = { + get: async function (): Promise> { + await this.device.updateInfo(); + return calculateSpeed(this.device); + }, + set: async function (value: CharacteristicValue) { + const realValue = new Big(parseInt(value.toString(), 10)).div( + this.device.deviceType.speedMinStep + ); + + if (realValue.eq(this.device.speed)) { + return; + } + + const success = await this.device.setSpeed(realValue.toNumber()); + + if (success && this.modeChar) { + await delay(10); + this.modeChar.updateValue(0); + } + } +}; + +export default characteristic; diff --git a/src/platform.ts b/src/platform.ts index 4e7629e..83017fd 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -9,7 +9,9 @@ import { } from 'homebridge'; import { PLATFORM_NAME, PLUGIN_NAME } from './settings'; -import VeSyncAccessory from './VeSyncAccessory'; +import VeSyncPurAccessory from './VeSyncPurAccessory'; +import VeSyncHumAccessory from './VeSyncHumAccessory'; +import VeSyncHumidifier from './api/VeSyncHumidifier'; import { ExperimentalFeatures } from './types'; import VeSyncFan from './api/VeSyncFan'; import DebugMode from './debugMode'; @@ -17,7 +19,7 @@ import VeSync from './api/VeSync'; export interface VeSyncContext { name: string; - device: VeSyncFan; + device: VeSyncFan | VeSyncHumidifier; } export enum VeSyncAdditionalType { @@ -47,14 +49,14 @@ export default class Platform implements DynamicPlatformPlugin { public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic; + public readonly registeredDevices: (VeSyncPurAccessory | VeSyncHumAccessory)[] = []; public readonly cachedAccessories: VeSyncPlatformAccessory[] = []; public readonly cachedAdditional: VeSyncPlatformAccessory[] = []; - public readonly registeredDevices: VeSyncAccessory[] = []; public readonly debugger: DebugMode; private readonly client?: VeSync; - constructor ( + constructor( public readonly log: Logger, public readonly config: Config, public readonly api: API @@ -125,8 +127,15 @@ export default class Platform implements DynamicPlatformPlugin { this.log.info('Discovering devices...'); - const devices = await this.client.getDevices(); - await Promise.all(devices.map(this.loadDevice.bind(this))); + const { purifiers, humidifiers } = await this.client.getDevices(); + + const experimentalFeatures = this.config?.experimentalFeatures || []; + + await Promise.all(purifiers.map(this.loadDevice.bind(this))); + + if (experimentalFeatures.includes(ExperimentalFeatures.Humidifiers)) { + await Promise.all(humidifiers.map(this.loadDevice.bind(this))); + } this.checkOldDevices(); } catch (error: any) { @@ -134,7 +143,7 @@ export default class Platform implements DynamicPlatformPlugin { } } - private async loadDevice(device: VeSyncFan) { + private async loadDevice(device: VeSyncFan | VeSyncHumidifier) { try { await device.updateInfo(); const { uuid, name } = device; @@ -143,7 +152,7 @@ export default class Platform implements DynamicPlatformPlugin { (accessory) => accessory.UUID === uuid ); - const additional = this.loadAdditional(device); + const additional = device instanceof VeSyncFan ? this.loadAdditional(device) : {} as Record; if (existingAccessory) { this.log.info( @@ -156,9 +165,15 @@ export default class Platform implements DynamicPlatformPlugin { device }; - this.registeredDevices.push( - new VeSyncAccessory(this, existingAccessory, additional) - ); + if (device instanceof VeSyncFan) { + this.registeredDevices.push( + new VeSyncPurAccessory(this, existingAccessory, additional) + ); + } else if (device instanceof VeSyncHumidifier) { + this.registeredDevices.push( + new VeSyncHumAccessory(this, existingAccessory) + ); + } return; } @@ -173,7 +188,16 @@ export default class Platform implements DynamicPlatformPlugin { device }; - this.registeredDevices.push(new VeSyncAccessory(this, accessory, additional)); + if (device instanceof VeSyncFan) { + this.registeredDevices.push( + new VeSyncPurAccessory(this, accessory, additional) + ); + } else if (device instanceof VeSyncHumidifier) { + this.registeredDevices.push( + new VeSyncHumAccessory(this, accessory) + ); + } + return this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [ accessory ]); diff --git a/src/types.ts b/src/types.ts index e52e417..ac054cf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,4 @@ export enum ExperimentalFeatures { DeviceDisplay = 'DeviceDisplay', + Humidifiers = 'Humidifiers' } diff --git a/yarn.lock b/yarn.lock index 5309b83..8be1697 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -9,26 +14,26 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@eslint-community/eslint-utils@^4.2.0": +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.4.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.0.tgz#f6f729b02feee2c749f57e334b7a1b5f40a81724" - integrity sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ== +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" + integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.2" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -36,10 +41,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.41.0": - version "8.41.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.41.0.tgz#080321c3b68253522f7646b55b577dd99d2950b3" - integrity sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA== +"@eslint/js@8.51.0": + version "8.51.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.51.0.tgz#6d419c240cfb2b66da37df230f7e7eef801c32fa" + integrity sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg== "@homebridge/ciao@^1.1.5": version "1.1.5" @@ -74,12 +79,12 @@ resolved "https://registry.yarnpkg.com/@homebridge/put/-/put-0.0.8.tgz#4b8b99f2c4d58bc762718863699df2c5bc0b4b8a" integrity sha512-mwxLHHqKebOmOSU0tsPEWQSBHGApPhuaqtNpCe7U+AMdsduweANiu64E9SXXUtdpyTjsOpgSMLhD1+kbLHD2gA== -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== +"@humanwhocodes/config-array@^0.11.11": + version "0.11.12" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.12.tgz#549afec9bfce5232ac6325db12765f407e70e3a0" + integrity sha512-NlGesA1usRNn6ctHCZ21M4/dKPgW9Nn1FypRdIKKgZOKzkVV4T1FlK5mBiLhHBCDmEbdQG0idrcXlbZfksJ+RA== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" + "@humanwhocodes/object-schema" "^2.0.0" debug "^4.1.1" minimatch "^3.0.5" @@ -88,10 +93,22 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.0.tgz#04ad39d82176c7da1591c81e78b993cffd8348d8" + integrity sha512-9S9QrXY2K0L4AGDcSgTi9vgiCcG8VcBv4Mp7/1hDPYoswIy6Z6KO5blYto82BT8M0MZNRWmCFLpCs3HlpYGGdw== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" @@ -162,114 +179,117 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== -"@types/async-lock@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.4.0.tgz#e7d555d037f93e911d54000acb626e783ff9023a" - integrity sha512-2+rYSaWrpdbQG3SA0LmMT6YxWLrI81AqpMlSkw3QtFc2HGDufkweQSn30Eiev7x9LL0oyFrBqk1PXOnB9IEgKg== - -"@types/big.js@^6.1.6": - version "6.1.6" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.1.6.tgz#3d417e758483d55345a03a087f7e0c87137ca444" - integrity sha512-0r9J+Zz9rYm2hOTwiMAVkm3XFQ4u5uTK37xrQMhc9bysn/sf/okzovWMYYIBMFTn/yrEZ11pusgLEaoarTlQbA== - -"@types/json-schema@^7.0.9": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== - -"@types/node@^20.2.5": - version "20.2.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" - integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== - -"@types/semver@^7.3.12": - version "7.3.12" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.12.tgz#920447fdd78d76b19de0438b7f60df3c4a80bf1c" - integrity sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A== - -"@typescript-eslint/eslint-plugin@^5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz#1e7a3e5318ece22251dfbc5c9c6feeb4793cc509" - integrity sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/type-utils" "5.59.8" - "@typescript-eslint/utils" "5.59.8" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" +"@types/async-lock@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.4.1.tgz#b27344e0f47de9273d21e040bc5207c061795f57" + integrity sha512-tpYc9kp2I8eI6qcDWtD2023jIlJYz6030qR1S5WhRbTK/JJcYdJ8fb2dRKPRgqioxcPZfTPmzl/PemHIPCrA9g== -"@typescript-eslint/parser@^5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.8.tgz#60cbb00671d86cf746044ab797900b1448188567" - integrity sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw== - dependencies: - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" +"@types/big.js@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.1.tgz#0e5eda9b8ffe33e2cc4540fad6e91a4c7255ca88" + integrity sha512-dKzZVT10m3ELZgYIShPJ+3Os/E1s3aDQS+wr1ne7VCLU/8hc/R+z/+gkm9WabxSkV9E8wJhTl5wC+0fD9nitsw== + +"@types/json-schema@^7.0.12": + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" + integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + +"@types/node@^20.8.7": + version "20.8.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.7.tgz#ad23827850843de973096edfc5abc9e922492a25" + integrity sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ== + dependencies: + undici-types "~5.25.1" + +"@types/semver@^7.5.0": + version "7.5.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" + integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== + +"@typescript-eslint/eslint-plugin@^6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz#06abe4265e7c82f20ade2dcc0e3403c32d4f148b" + integrity sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.8.0" + "@typescript-eslint/type-utils" "6.8.0" + "@typescript-eslint/utils" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.8.0.tgz#bb2a969d583db242f1ee64467542f8b05c2e28cb" + integrity sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg== + dependencies: + "@typescript-eslint/scope-manager" "6.8.0" + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/typescript-estree" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz#ff4ad4fec6433647b817c4a7d4b4165d18ea2fa8" - integrity sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig== +"@typescript-eslint/scope-manager@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz#5cac7977385cde068ab30686889dd59879811efd" + integrity sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g== dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" -"@typescript-eslint/type-utils@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz#aa6c029a9d7706d26bbd25eb4666398781df6ea2" - integrity sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA== +"@typescript-eslint/type-utils@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz#50365e44918ca0fd159844b5d6ea96789731e11f" + integrity sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g== dependencies: - "@typescript-eslint/typescript-estree" "5.59.8" - "@typescript-eslint/utils" "5.59.8" + "@typescript-eslint/typescript-estree" "6.8.0" + "@typescript-eslint/utils" "6.8.0" debug "^4.3.4" - tsutils "^3.21.0" + ts-api-utils "^1.0.1" -"@typescript-eslint/types@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.8.tgz#212e54414733618f5d0fd50b2da2717f630aebf8" - integrity sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w== +"@typescript-eslint/types@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.8.0.tgz#1ab5d4fe1d613e3f65f6684026ade6b94f7e3ded" + integrity sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ== -"@typescript-eslint/typescript-estree@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz#801a7b1766481629481b3b0878148bd7a1f345d7" - integrity sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg== +"@typescript-eslint/typescript-estree@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz#9565f15e0cd12f55cf5aa0dfb130a6cb0d436ba1" + integrity sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg== dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.8.tgz#34d129f35a2134c67fdaf024941e8f96050dca2b" - integrity sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz#aa6a7ef862add919401470c09e1609392ef3cc40" - integrity sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ== - dependencies: - "@typescript-eslint/types" "5.59.8" - eslint-visitor-keys "^3.3.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.8.0.tgz#d42939c2074c6b59844d0982ce26a51d136c4029" + integrity sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.8.0" + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/typescript-estree" "6.8.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz#cffebed56ae99c45eba901c378a6447b06be58b8" + integrity sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg== + dependencies: + "@typescript-eslint/types" "6.8.0" + eslint-visitor-keys "^3.4.1" abbrev@1: version "1.1.1" @@ -291,12 +311,12 @@ acorn@^8.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== -acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -311,6 +331,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -318,6 +343,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -361,10 +391,10 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axios@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" - integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== +axios@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f" + integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" @@ -459,15 +489,6 @@ chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" -cliui@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -601,11 +622,21 @@ duplexer@^0.1.1, duplexer@~0.1.1: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + es-abstract@^1.18.5: version "1.19.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" @@ -660,18 +691,10 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -686,27 +709,32 @@ eslint-visitor-keys@^3.4.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== -eslint@^8.41.0: - version "8.41.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.41.0.tgz#3062ca73363b4714b16dbc1e60f035e6134b6f1c" - integrity sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q== +eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.51.0: + version "8.51.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.51.0.tgz#4a82dae60d209ac89a5cff1604fea978ba4950f3" + integrity sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.41.0" - "@humanwhocodes/config-array" "^0.11.8" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "8.51.0" + "@humanwhocodes/config-array" "^0.11.11" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -716,7 +744,6 @@ eslint@^8.41.0: globals "^13.19.0" graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" @@ -726,17 +753,16 @@ eslint@^8.41.0: lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" @@ -754,11 +780,6 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" @@ -947,16 +968,16 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^10.2.5: - version "10.2.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.6.tgz#1e27edbb3bbac055cb97113e27a066c100a4e5e1" - integrity sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA== +glob@^10.3.7: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== dependencies: foreground-child "^3.1.0" - jackspeak "^2.0.3" + jackspeak "^2.3.5" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@^7.1.3: version "7.2.0" @@ -994,11 +1015,6 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -1082,7 +1098,12 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -1278,12 +1299,12 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -jackspeak@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.0.3.tgz#672eb397b97744a265b5862d7762b96e8dad6e61" - integrity sha512-0Jud3OMUdMbrlr3PyUMKESq51LXVAB+a239Ywdvd+Kgxj3MaBRml/nVRxf8tQFyfthMjuRkxkv7Vg58pmIMfuQ== +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== dependencies: - cliui "^7.0.4" + "@isaacs/cliui" "^8.0.2" optionalDependencies: "@pkgjs/parseargs" "^0.11.0" @@ -1340,10 +1361,10 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.0.tgz#19efafa9d08d1c08eb8efd78876075f0b8b1b07b" - integrity sha512-qFXQEwchrZcMVen2uIDceR8Tii6kCJak5rzDStfEM0qA3YLMswaxIEZO0DhIbJ3aqaJiDjt+3crlplOb0tDtKQ== +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== make-error@^1.1.1: version "1.3.6" @@ -1399,15 +1420,10 @@ minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== mkdirp@~0.5.1: version "0.5.5" @@ -1439,11 +1455,6 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -1457,18 +1468,18 @@ node-persist@^0.0.11: mkdirp "~0.5.1" q "~1.1.1" -nodemon@^2.0.22: - version "2.0.22" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" - integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== +nodemon@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" + integrity sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw== dependencies: chokidar "^3.5.2" debug "^3.2.7" ignore-by-default "^1.0.1" minimatch "^3.1.2" pstree.remy "^1.1.8" - semver "^5.7.1" - simple-update-notifier "^1.0.7" + semver "^7.5.3" + simple-update-notifier "^2.0.0" supports-color "^5.5.0" touch "^3.1.0" undefsafe "^2.0.5" @@ -1520,17 +1531,17 @@ once@^1.3.0: dependencies: wrappy "1" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" p-limit@^3.0.2: version "3.1.0" @@ -1568,13 +1579,13 @@ path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-scurry@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.7.0.tgz#99c741a2cfbce782294a39994d63748b5a24f6db" - integrity sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: - lru-cache "^9.0.0" - minipass "^5.0.0" + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-type@^4.0.0: version "4.0.0" @@ -1660,12 +1671,12 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== +rimraf@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" + integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A== dependencies: - glob "^10.2.5" + glob "^10.3.7" run-parallel@^1.1.9: version "1.2.0" @@ -1684,23 +1695,13 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -1727,12 +1728,12 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.1.tgz#96a61033896120ec9335d96851d902cc98f0ba2a" integrity sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw== -simple-update-notifier@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" - integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== +simple-update-notifier@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== dependencies: - semver "~7.0.0" + semver "^7.5.3" slash@^3.0.0: version "3.0.0" @@ -1767,7 +1768,8 @@ stream-combiner@^0.2.2: duplexer "~0.1.1" through "~2.3.4" -string-width@^4.1.0, string-width@^4.2.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: + name string-width-cjs version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1776,6 +1778,15 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string.prototype.trimend@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" @@ -1792,14 +1803,21 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -1847,6 +1865,11 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -1866,23 +1889,11 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - tslib@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" @@ -1900,10 +1911,10 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typescript@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== +typescript@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== unbox-primitive@^1.0.1: version "1.0.1" @@ -1920,6 +1931,11 @@ undefsafe@^2.0.5: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== +undici-types@~5.25.1: + version "5.25.3" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" + integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -1977,12 +1993,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -1991,6 +2002,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"