From 96fbc85345df99ea0f07b2d9fb888861545f2707 Mon Sep 17 00:00:00 2001 From: AlCalzone Date: Mon, 4 Nov 2024 10:55:58 +0100 Subject: [PATCH] chore: transition modules to hybrid ESM/CJS, switch to vitest for testing (#7349) --- .github/workflows/test-and-release.yml | 77 +- .vscode/launch.json | 24 +- ...dings-interface-npm-1.2.2-e597dbc676.patch | 22 + .../ts-pegjs-npm-4.2.1-0f567a1059.patch | 13 + api-extractor-base.json | 2 +- ava.config.cjs | 9 - commitlint.config.js => commitlint.config.mjs | 2 +- docs/api/CCs/AlarmSensor.md | 2 +- docs/api/CCs/Association.md | 2 +- docs/api/CCs/AssociationGroupInfo.md | 2 +- docs/api/CCs/FirmwareUpdateMetaData.md | 6 +- docs/api/CCs/Indicator.md | 2 +- docs/api/CCs/ManufacturerProprietary.md | 4 +- docs/api/CCs/MultiChannel.md | 5 +- docs/api/CCs/Notification.md | 4 +- docs/api/CCs/Security.md | 4 +- docs/api/CCs/Security2.md | 6 +- docs/api/CCs/SoundSwitch.md | 2 +- docs/api/CCs/ThermostatMode.md | 2 +- docs/api/CCs/ThermostatSetback.md | 40 - docs/api/CCs/UserCode.md | 2 +- docs/api/controller.md | 52 +- docs/api/driver.md | 33 +- docs/api/node.md | 65 +- docs/api/valueid.md | 1 + docs/api/zniffer.md | 18 +- maintenance/build.ts | 12 +- maintenance/esbuild-register.js | 19 - maintenance/fmt-staged.js | 7 +- maintenance/parse-zwxml-manufacturers.ts | 2 +- maintenance/patch-typescript.js | 7 +- maintenance/{test.ts => test.mts} | 3 + maintenance/tsconfig.json | 3 +- maintenance/watch.ts | 10 +- package.json | 16 +- packages/cc/ava.config.cjs | 3 - packages/cc/maintenance/_tasks.ts | 10 +- packages/cc/maintenance/checkCCToLogEntry.ts | 7 +- .../cc/maintenance/generateCCAPIInterface.ts | 10 +- packages/cc/maintenance/generateCCExports.ts | 7 +- .../maintenance/generateCCValuesInterface.ts | 10 +- packages/cc/maintenance/lintCCConstructor.ts | 2 +- packages/cc/package.json | 37 +- packages/cc/src/cc/AlarmSensorCC.ts | 10 +- packages/cc/src/cc/AssociationCC.ts | 14 +- packages/cc/src/cc/AssociationGroupInfoCC.ts | 14 +- packages/cc/src/cc/BarrierOperatorCC.ts | 10 +- packages/cc/src/cc/BasicCC.ts | 10 +- packages/cc/src/cc/BatteryCC.ts | 12 +- packages/cc/src/cc/BinarySensorCC.ts | 10 +- packages/cc/src/cc/BinarySwitchCC.ts | 10 +- packages/cc/src/cc/CRC16CC.ts | 8 +- packages/cc/src/cc/CentralSceneCC.ts | 14 +- .../cc/src/cc/ClimateControlScheduleCC.ts | 14 +- packages/cc/src/cc/ClockCC.ts | 10 +- packages/cc/src/cc/ColorSwitchCC.ts | 14 +- packages/cc/src/cc/ConfigurationCC.ts | 16 +- packages/cc/src/cc/DeviceResetLocallyCC.ts | 8 +- packages/cc/src/cc/DoorLockCC.ts | 12 +- packages/cc/src/cc/DoorLockLoggingCC.ts | 12 +- packages/cc/src/cc/EnergyProductionCC.ts | 10 +- packages/cc/src/cc/EntryControlCC.ts | 12 +- .../cc/src/cc/FirmwareUpdateMetaDataCC.ts | 10 +- packages/cc/src/cc/HailCC.ts | 6 +- packages/cc/src/cc/HumidityControlModeCC.ts | 13 +- .../src/cc/HumidityControlOperatingStateCC.ts | 10 +- .../cc/src/cc/HumidityControlSetpointCC.ts | 10 +- packages/cc/src/cc/InclusionControllerCC.ts | 8 +- packages/cc/src/cc/IndicatorCC.ts | 14 +- packages/cc/src/cc/IrrigationCC.ts | 12 +- packages/cc/src/cc/LanguageCC.ts | 10 +- packages/cc/src/cc/LockCC.ts | 10 +- .../cc/src/cc/ManufacturerProprietaryCC.ts | 10 +- packages/cc/src/cc/ManufacturerSpecificCC.ts | 10 +- packages/cc/src/cc/MeterCC.ts | 10 +- .../cc/src/cc/MultiChannelAssociationCC.ts | 14 +- packages/cc/src/cc/MultiChannelCC.ts | 14 +- packages/cc/src/cc/MultiCommandCC.ts | 8 +- packages/cc/src/cc/MultilevelSensorCC.ts | 10 +- packages/cc/src/cc/MultilevelSwitchCC.ts | 10 +- packages/cc/src/cc/NoOperationCC.ts | 6 +- packages/cc/src/cc/NodeNamingCC.ts | 10 +- packages/cc/src/cc/NotificationCC.ts | 18 +- packages/cc/src/cc/PowerlevelCC.ts | 8 +- packages/cc/src/cc/ProtectionCC.ts | 12 +- packages/cc/src/cc/SceneActivationCC.ts | 10 +- .../cc/src/cc/SceneActuatorConfigurationCC.ts | 10 +- .../src/cc/SceneControllerConfigurationCC.ts | 12 +- packages/cc/src/cc/ScheduleEntryLockCC.ts | 14 +- packages/cc/src/cc/Security2CC.ts | 28 +- packages/cc/src/cc/SecurityCC.ts | 16 +- packages/cc/src/cc/SoundSwitchCC.ts | 12 +- packages/cc/src/cc/SupervisionCC.ts | 10 +- packages/cc/src/cc/ThermostatFanModeCC.ts | 10 +- packages/cc/src/cc/ThermostatFanStateCC.ts | 13 +- packages/cc/src/cc/ThermostatModeCC.ts | 10 +- .../cc/src/cc/ThermostatOperatingStateCC.ts | 10 +- packages/cc/src/cc/ThermostatSetbackCC.ts | 10 +- packages/cc/src/cc/ThermostatSetpointCC.ts | 10 +- packages/cc/src/cc/TimeCC.ts | 12 +- packages/cc/src/cc/TimeParametersCC.ts | 10 +- packages/cc/src/cc/TransportServiceCC.ts | 6 +- packages/cc/src/cc/UserCodeCC.ts | 12 +- packages/cc/src/cc/VersionCC.ts | 10 +- packages/cc/src/cc/WakeUpCC.ts | 12 +- packages/cc/src/cc/WindowCoveringCC.ts | 10 +- packages/cc/src/cc/ZWaveLongRangeCC.ts | 4 +- packages/cc/src/cc/ZWavePlusCC.ts | 10 +- packages/cc/src/cc/ZWaveProtocolCC.ts | 6 +- packages/cc/src/cc/index.ts | 262 +- .../cc/manufacturerProprietary/Decorators.ts | 6 +- .../cc/manufacturerProprietary/FibaroCC.ts | 12 +- packages/cc/src/index.ts | 24 +- packages/cc/src/index_safe.ts | 4 +- packages/cc/src/lib/API.ts | 133 +- packages/cc/src/lib/CommandClass.ts | 10 +- packages/cc/src/lib/CommandClassDecorators.ts | 6 +- .../cc/src/lib/EncapsulatingCommandClass.ts | 4 +- .../cc/src/lib/NotificationEventPayload.ts | 2 +- packages/cc/src/lib/Values.test.ts | 48 +- packages/cc/src/lib/Values.ts | 110 +- packages/cc/src/lib/serializers.test.ts | 27 +- packages/cc/src/lib/serializers.ts | 4 +- packages/cc/src/lib/utils.ts | 12 +- packages/cc/tsconfig.build.json | 2 +- packages/cc/tsconfig.json | 2 +- packages/config/ava.config.cjs | 3 - packages/config/maintenance/codegen.ts | 9 +- packages/config/maintenance/importConfig.ts | 4 +- .../config/maintenance/lintConfigFiles.ts | 34 +- packages/config/package.json | 31 +- packages/config/src/ConfigManager.test.ts | 176 +- packages/config/src/ConfigManager.ts | 10 +- packages/config/src/JsonTemplate.test.ts | 225 +- packages/config/src/JsonTemplate.ts | 2 +- packages/config/src/Logger.ts | 2 +- packages/config/src/Logic.test.ts | 6 +- packages/config/src/Logic.ts | 7 +- packages/config/src/Manufacturers.test.ts | 122 +- packages/config/src/Manufacturers.ts | 6 +- packages/config/src/_version.ts | 2 +- .../config/src/devices/AssociationConfig.ts | 6 +- packages/config/src/devices/CompatConfig.ts | 8 +- .../devices/ConditionalDeviceConfig.test.ts | 116 +- .../config/src/devices/ConditionalItem.ts | 8 +- .../src/devices/ConditionalPrimitive.ts | 8 +- .../src/devices/DeviceConfig.hash.test.ts | 183 +- packages/config/src/devices/DeviceConfig.ts | 26 +- packages/config/src/devices/DeviceMetadata.ts | 10 +- packages/config/src/devices/EndpointConfig.ts | 14 +- .../config/src/devices/ParamInformation.ts | 10 +- .../config/src/devices/lookupDevice.test.ts | 91 +- packages/config/src/index.ts | 24 +- packages/config/src/index_safe.ts | 4 +- packages/config/src/utils.ts | 9 +- packages/config/tsconfig.build.json | 2 +- packages/core/ava.config.cjs | 3 - packages/core/package.json | 32 +- .../capabilities/ControllerCapabilities.ts | 6 +- .../core/src/capabilities/NodeInfo.test.ts | 24 +- packages/core/src/capabilities/NodeInfo.ts | 8 +- .../core/src/capabilities/ZWaveChipTypes.ts | 2 +- packages/core/src/consts/Transmission.test.ts | 8 +- packages/core/src/consts/Transmission.ts | 10 +- packages/core/src/consts/index.ts | 8 +- packages/core/src/error/ZWaveError.test.ts | 11 +- packages/core/src/error/ZWaveError.ts | 2 +- packages/core/src/index.ts | 98 +- packages/core/src/index_safe.ts | 74 +- packages/core/src/index_test.ts | 4 +- packages/core/src/log/Colorizer.ts | 2 +- packages/core/src/log/Controller.test.ts | 368 +- packages/core/src/log/Controller.ts | 12 +- packages/core/src/log/shared.ts | 4 +- packages/core/src/log/shared_safe.ts | 4 +- .../core/src/registries/Indicators.test.ts | 8 +- packages/core/src/registries/Indicators.ts | 2 +- packages/core/src/registries/Meters.test.ts | 12 +- packages/core/src/registries/Scales.test.ts | 12 +- packages/core/src/registries/Scales.ts | 2 +- packages/core/src/registries/Sensors.test.ts | 12 +- packages/core/src/registries/Sensors.ts | 2 +- packages/core/src/security/DSK.ts | 6 +- packages/core/src/security/Manager.test.ts | 162 +- packages/core/src/security/Manager.ts | 4 +- packages/core/src/security/Manager2.test.ts | 77 +- packages/core/src/security/Manager2.ts | 15 +- packages/core/src/security/QR.test.ts | 19 +- packages/core/src/security/QR.ts | 10 +- packages/core/src/security/SecurityClass.ts | 2 +- packages/core/src/security/crypto.test.ts | 24 +- packages/core/src/security/crypto.ts | 2 +- packages/core/src/security/ctr_drbg.test.ts | 11 +- packages/core/src/security/ctr_drbg.ts | 4 +- packages/core/src/test/SpyTransport.ts | 30 +- packages/core/src/test/assertZWaveError.ts | 16 +- packages/core/src/traits/CommandClasses.ts | 4 +- packages/core/src/traits/Endpoints.ts | 2 +- packages/core/src/traits/Nodes.ts | 8 +- packages/core/src/traits/SecurityManagers.ts | 4 +- packages/core/src/util/compareVersions.ts | 2 +- packages/core/src/util/crc.test.ts | 16 +- packages/core/src/util/date.test.ts | 12 +- packages/core/src/util/firmware.ts | 12 +- packages/core/src/util/graph.test.ts | 10 +- packages/core/src/util/misc.test.ts | 52 +- packages/core/src/util/misc.ts | 2 +- packages/core/src/values/Cache.test.ts | 34 +- packages/core/src/values/Cache.ts | 10 +- packages/core/src/values/Duration.test.ts | 112 +- packages/core/src/values/Duration.ts | 4 +- packages/core/src/values/Metadata.test.ts | 8 +- packages/core/src/values/Metadata.ts | 4 +- packages/core/src/values/Primitive.test.ts | 96 +- packages/core/src/values/Primitive.ts | 6 +- packages/core/src/values/Timeout.ts | 2 +- packages/core/src/values/ValueDB.test.ts | 221 +- packages/core/src/values/ValueDB.ts | 12 +- packages/core/src/values/_Types.ts | 4 +- packages/core/tsconfig.build.json | 2 +- packages/eslint-plugin/package.json | 4 +- .../src/rules/no-forbidden-imports.ts | 18 +- packages/eslint-plugin/src/utils.ts | 4 +- packages/flash/bin/flash.js | 2 - packages/flash/bin/flash.mjs | 2 + packages/flash/package.json | 7 +- packages/flash/src/cli.ts | 5 +- packages/host/package.json | 17 +- packages/host/src/ZWaveHost.ts | 2 +- packages/host/src/index.ts | 8 +- packages/host/src/index_safe.ts | 6 +- packages/host/src/mocks.ts | 2 +- packages/host/tsconfig.build.json | 2 +- packages/maintenance/package.json | 11 +- packages/maintenance/src/codefind.ts | 13 +- packages/maintenance/src/convert-json.ts | 8 +- packages/maintenance/src/dprint.ts | 2 +- packages/maintenance/src/esmImports.ts | 52 + packages/maintenance/src/generateTypedDocs.ts | 49 +- .../src/generateTypedDocsWorker.js | 3 - packages/maintenance/src/implementedCCs.ts | 6 +- packages/maintenance/src/index.ts | 6 +- packages/maintenance/src/refactorTests.01.ts | 271 + packages/maintenance/src/refactorTests.02.ts | 113 + packages/maintenance/src/refactorTests.03.ts | 246 + .../maintenance/src/remove-unnecessary.ts | 8 +- packages/maintenance/src/reportProblem.ts | 4 +- packages/maintenance/src/resolveDirtyTests.ts | 5 +- packages/maintenance/src/tsAPITools.ts | 5 +- packages/maintenance/tsconfig.build.json | 2 +- packages/nvmedit/ava.config.cjs | 3 - packages/nvmedit/package.json | 28 +- .../src/__snapshots__/convert.test.ts.snap | 8801 ++++++++++++++++ packages/nvmedit/src/cli.ts | 12 +- packages/nvmedit/src/convert.test.ts | 32 +- packages/nvmedit/src/convert.test.ts.md | 8833 ----------------- packages/nvmedit/src/convert.test.ts.snap | Bin 42175 -> 0 bytes packages/nvmedit/src/convert.ts | 40 +- packages/nvmedit/src/index.ts | 34 +- packages/nvmedit/src/index_safe.ts | 18 +- packages/nvmedit/src/lib/NVM3.ts | 18 +- packages/nvmedit/src/lib/NVM500.ts | 18 +- .../nvmedit/src/lib/common/definitions.ts | 6 +- .../nvmedit/src/lib/common/sucUpdateEntry.ts | 5 +- packages/nvmedit/src/lib/common/utils.ts | 2 +- .../nvmedit/src/lib/io/BufferedNVMReader.ts | 2 +- packages/nvmedit/src/lib/io/NVMFileIO.ts | 2 +- packages/nvmedit/src/lib/io/NVMMemoryIO.ts | 2 +- packages/nvmedit/src/lib/nvm3/adapter.ts | 12 +- .../src/lib/nvm3/files/ApplicationCCsFile.ts | 4 +- .../src/lib/nvm3/files/ApplicationDataFile.ts | 2 +- .../src/lib/nvm3/files/ApplicationNameFile.ts | 4 +- .../lib/nvm3/files/ApplicationRFConfigFile.ts | 4 +- .../src/lib/nvm3/files/ApplicationTypeFile.ts | 4 +- .../src/lib/nvm3/files/ControllerInfoFile.ts | 4 +- .../nvmedit/src/lib/nvm3/files/NVMFile.ts | 8 +- .../src/lib/nvm3/files/NodeInfoFiles.ts | 4 +- .../lib/nvm3/files/ProtocolNodeMaskFiles.ts | 4 +- .../src/lib/nvm3/files/RouteCacheFiles.ts | 6 +- .../lib/nvm3/files/SUCUpdateEntriesFile.ts | 8 +- .../src/lib/nvm3/files/VersionFiles.ts | 4 +- packages/nvmedit/src/lib/nvm3/files/index.ts | 24 +- packages/nvmedit/src/lib/nvm3/object.ts | 4 +- packages/nvmedit/src/lib/nvm3/page.ts | 6 +- packages/nvmedit/src/lib/nvm3/utils.test.ts | 6 +- packages/nvmedit/src/lib/nvm3/utils.ts | 8 +- .../nvmedit/src/lib/nvm500/EntryParsers.ts | 4 +- packages/nvmedit/src/lib/nvm500/adapter.ts | 18 +- .../src/lib/nvm500/impls/Bridge_6_6x.ts | 6 +- .../src/lib/nvm500/impls/Bridge_6_7x.ts | 6 +- .../src/lib/nvm500/impls/Bridge_6_8x.ts | 6 +- .../src/lib/nvm500/impls/Static_6_6x.ts | 6 +- .../src/lib/nvm500/impls/Static_6_7x.ts | 6 +- .../src/lib/nvm500/impls/Static_6_8x.ts | 6 +- .../nvmedit/src/lib/nvm500/impls/index.ts | 12 +- packages/nvmedit/src/lib/nvm500/shared.ts | 8 +- packages/nvmedit/src/nvm500/NVMParser.ts | 8 +- packages/nvmedit/tsconfig.build.json | 2 +- packages/serial/ava.config.cjs | 3 - packages/serial/package.json | 38 +- packages/serial/src/index.ts | 36 +- packages/serial/src/index_mock.ts | 6 +- packages/serial/src/index_safe.ts | 8 +- packages/serial/src/index_serialapi.ts | 110 +- packages/serial/src/log/Logger.ts | 4 +- packages/serial/src/message/Constants.ts | 2 +- packages/serial/src/message/Message.test.ts | 41 +- packages/serial/src/message/Message.ts | 4 +- .../serial/src/message/SuccessIndicator.ts | 2 +- .../serial/src/message/ZnifferMessages.ts | 2 +- packages/serial/src/mock/MockSerialPort.ts | 8 +- packages/serial/src/mock/SerialPortMock.ts | 2 +- .../serial/src/parsers/BootloaderParsers.ts | 4 +- .../serial/src/parsers/SerialAPIParser.ts | 4 +- packages/serial/src/parsers/ZnifferParser.ts | 6 +- .../application/ApplicationCommandRequest.ts | 2 +- .../BridgeApplicationCommandRequest.test.ts | 6 +- .../BridgeApplicationCommandRequest.ts | 81 +- .../capability/SerialAPISetupMessages.test.ts | 22 +- .../misc/GetBackgroundRSSIMessages.ts | 2 +- .../GetNodeProtocolInfoMessages.ts | 2 +- .../network-mgmt/RequestNodeInfoMessages.ts | 2 +- .../transport/SendDataBridgeMessages.ts | 101 +- .../serialapi/transport/SendDataMessages.ts | 10 +- .../src/serialapi/transport/SendDataShared.ts | 16 +- packages/serial/src/serialapi/utils.ts | 9 +- .../src/serialport/ZWaveSerialPort.test.ts | 69 +- .../serial/src/serialport/ZWaveSerialPort.ts | 4 +- .../src/serialport/ZWaveSerialPortBase.ts | 10 +- .../ZWaveSerialPortImplementation.ts | 2 +- packages/serial/src/serialport/ZWaveSocket.ts | 4 +- .../serial/src/zniffer/ZnifferSerialPort.ts | 4 +- .../src/zniffer/ZnifferSerialPortBase.ts | 6 +- packages/serial/src/zniffer/ZnifferSocket.ts | 4 +- packages/serial/tsconfig.build.json | 2 +- packages/shared/ava.config.cjs | 3 - packages/shared/package.json | 28 +- packages/shared/src/AsyncQueue.test.ts | 22 +- packages/shared/src/AsyncQueue.ts | 2 +- packages/shared/src/Bytes.test.ts | 58 +- packages/shared/src/Bytes.ts | 2 +- packages/shared/src/EventEmitter.test.ts | 22 +- packages/shared/src/EventEmitter.ts | 2 +- packages/shared/src/ObjectKeyMap.test.ts | 66 +- packages/shared/src/ObjectKeyMap.ts | 2 +- packages/shared/src/TimedExpectation.test.ts | 12 +- packages/shared/src/TimedExpectation.ts | 2 +- packages/shared/src/fs.ts | 2 +- packages/shared/src/index.ts | 32 +- packages/shared/src/index_safe.ts | 24 +- packages/shared/src/inheritance.ts | 2 +- packages/shared/src/strings.test.ts | 24 +- packages/shared/src/strings.ts | 6 +- packages/shared/src/utils.test.ts | 120 +- packages/shared/src/utils.throttle.test.ts | 46 +- packages/shared/src/utils.ts | 4 +- packages/shared/src/wrappingCounter.test.ts | 24 +- packages/shared/tsconfig.build.json | 2 +- packages/testing/package.json | 16 +- packages/testing/src/MockController.ts | 8 +- .../testing/src/MockControllerCapabilities.ts | 2 + packages/testing/src/MockNode.ts | 10 +- packages/testing/src/MockNodeCapabilities.ts | 2 +- packages/testing/src/index.ts | 20 +- packages/testing/tsconfig.build.json | 2 +- packages/transformers/ava.config.cjs | 7 - packages/transformers/package.json | 11 +- packages/transformers/src/index.test.ts | 8 +- packages/transformers/vitest.config.mjs | 9 + packages/zwave-js/ava.config.cjs | 3 - packages/zwave-js/maintenance/codegen.ts | 3 + packages/zwave-js/package.json | 62 +- packages/zwave-js/src/Controller.ts | 14 +- packages/zwave-js/src/Controller_safe.ts | 10 +- packages/zwave-js/src/Driver.ts | 6 +- packages/zwave-js/src/Node.ts | 18 +- packages/zwave-js/src/Node_safe.ts | 8 +- packages/zwave-js/src/Testing.ts | 6 +- packages/zwave-js/src/Utils.ts | 8 +- packages/zwave-js/src/Utils_safe.ts | 4 +- packages/zwave-js/src/Values.ts | 2 +- packages/zwave-js/src/Zniffer.ts | 12 +- packages/zwave-js/src/Zniffer_safe.ts | 4 +- packages/zwave-js/src/index.ts | 14 +- packages/zwave-js/src/index_safe.ts | 12 +- packages/zwave-js/src/lib/_version.ts | 2 +- .../Controller.getAssociationGroups.test.ts | 54 +- .../Controller.manageAssociations.test.ts | 9 +- .../Controller.nodes.getOrThrow.test.ts | 74 +- .../zwave-js/src/lib/controller/Controller.ts | 44 +- .../lib/controller/ControllerStatistics.ts | 2 +- .../zwave-js/src/lib/controller/Features.ts | 2 +- .../lib/controller/FirmwareUpdateService.ts | 10 +- .../zwave-js/src/lib/controller/Inclusion.ts | 2 +- .../lib/controller/MockControllerBehaviors.ts | 210 +- packages/zwave-js/src/lib/controller/NVMIO.ts | 2 +- .../lib/controller/ZWaveSDKVersions.test.ts | 18 +- .../src/lib/controller/ZWaveSDKVersions.ts | 2 +- .../utils.assertProvisioningEntry.test.ts | 30 +- packages/zwave-js/src/lib/controller/utils.ts | 6 +- packages/zwave-js/src/lib/driver/Driver.ts | 62 +- ...r.unit.test.ts => Driver.unit.test.ts.txt} | 83 +- .../zwave-js/src/lib/driver/DriverMock.ts | 6 +- .../src/lib/driver/MessageGenerators.ts | 8 +- .../zwave-js/src/lib/driver/NetworkCache.ts | 8 +- packages/zwave-js/src/lib/driver/Queue.ts | 6 +- .../driver/SerialAPICommandMachine.test.ts | 77 +- .../src/lib/driver/SerialAPICommandMachine.ts | 2 +- .../src/lib/driver/StateMachineShared.ts | 4 +- .../src/lib/driver/Statistics.test.ts | 6 +- packages/zwave-js/src/lib/driver/Task.test.ts | 161 +- packages/zwave-js/src/lib/driver/Task.ts | 11 +- .../src/lib/driver/ThrottlePresets.ts | 2 +- .../src/lib/driver/Transaction.test.ts | 118 +- .../zwave-js/src/lib/driver/Transaction.ts | 8 +- .../zwave-js/src/lib/driver/UpdateConfig.ts | 5 +- .../zwave-js/src/lib/driver/ZWaveOptions.ts | 2 +- .../zwave-js/src/lib/driver/mDNSDiscovery.ts | 2 +- packages/zwave-js/src/lib/log/Driver.test.ts | 254 +- packages/zwave-js/src/lib/log/Driver.ts | 8 +- packages/zwave-js/src/lib/log/Zniffer.ts | 6 +- .../zwave-js/src/lib/node/Endpoint.test.ts | 206 +- packages/zwave-js/src/lib/node/Endpoint.ts | 10 +- packages/zwave-js/src/lib/node/HealthCheck.ts | 4 +- .../src/lib/node/MockNodeBehaviors.ts | 38 +- packages/zwave-js/src/lib/node/Node.ts | 40 +- .../src/lib/node/NodeReadyMachine.test.ts | 20 +- .../zwave-js/src/lib/node/NodeStatistics.ts | 2 +- .../src/lib/node/NodeStatusMachine.test.ts | 20 +- .../src/lib/node/NodeStatusMachine.ts | 4 +- .../src/lib/node/VirtualEndpoint.test.ts | 341 +- .../zwave-js/src/lib/node/VirtualEndpoint.ts | 8 +- packages/zwave-js/src/lib/node/VirtualNode.ts | 8 +- packages/zwave-js/src/lib/node/_Types.ts | 6 +- .../zwave-js/src/lib/node/mixins/00_Base.ts | 2 +- .../src/lib/node/mixins/01_NetworkRole.ts | 4 +- .../src/lib/node/mixins/05_Security.ts | 8 +- .../zwave-js/src/lib/node/mixins/10_Events.ts | 10 +- .../zwave-js/src/lib/node/mixins/20_Status.ts | 16 +- .../zwave-js/src/lib/node/mixins/30_Wakeup.ts | 2 +- .../zwave-js/src/lib/node/mixins/40_Values.ts | 10 +- .../src/lib/node/mixins/50_Endpoints.ts | 10 +- .../src/lib/node/mixins/60_ScheduledPoll.ts | 6 +- .../src/lib/node/mixins/70_FirmwareUpdate.ts | 18 +- .../zwave-js/src/lib/node/mixins/index.ts | 2 +- .../node/mockCCBehaviors/ScheduleEntryLock.ts | 2 +- .../src/lib/telemetry/deviceConfig.ts | 4 +- .../zwave-js/src/lib/telemetry/statistics.ts | 4 +- packages/zwave-js/src/lib/test/assertCC.ts | 14 +- .../cc-specific/configurationSetThrow.test.ts | 6 +- .../discardUnsupportedReports.test.ts | 12 +- .../mapNotificationDoorLock.test.ts | 8 +- .../meterReportPropertyKeyName.test.ts | 6 +- .../cc-specific/notificationEnums.test.ts | 64 +- .../notificationIdleManually.test.ts | 35 +- .../notificationIdleRelated.test.ts | 10 +- ...notificationMultipleEventsMetadata.test.ts | 4 +- .../sceneActivationValueID.test.ts | 4 +- ...dSwitchInterviewValueChangeOptions.test.ts | 4 +- .../cc-specific/undefinedTargetValue.test.ts | 6 +- .../cc-specific/unknownNotifications.test.ts | 19 +- packages/zwave-js/src/lib/test/cc/API.test.ts | 89 +- .../src/lib/test/cc/AssociationCC.test.ts | 26 +- .../test/cc/AssociationGroupInfoCC.test.ts | 50 +- .../zwave-js/src/lib/test/cc/BasicCC.test.ts | 50 +- .../src/lib/test/cc/BatteryCC.test.ts | 38 +- .../src/lib/test/cc/BinarySensorCC.test.ts | 24 +- .../src/lib/test/cc/BinarySwitchCC.test.ts | 28 +- .../zwave-js/src/lib/test/cc/CRC16CC.test.ts | 24 +- .../src/lib/test/cc/CentralSceneCC.test.ts | 48 +- .../src/lib/test/cc/ColorSwitchCC.test.ts | 42 +- .../cc/CommandClass.nonImplemented.test.ts | 4 +- .../cc/CommandClass.persistValues.test.ts | 106 +- .../src/lib/test/cc/CommandClass.test.ts | 37 +- .../src/lib/test/cc/DoorLockCC.test.ts | 141 +- .../src/lib/test/cc/DoorLockLoggingCC.test.ts | 25 +- .../src/lib/test/cc/EntryControlCC.test.ts | 46 +- .../src/lib/test/cc/FibaroCC.FGR222.test.ts | 4 +- .../zwave-js/src/lib/test/cc/FibaroCC.test.ts | 18 +- .../lib/test/cc/HumidityControlModeCC.test.ts | 22 +- .../HumidityControlOperatingStateCC.test.ts | 8 +- .../test/cc/HumidityControlSetpointCC.test.ts | 52 +- .../src/lib/test/cc/IndicatorCC.test.ts | 30 +- .../src/lib/test/cc/LanguageCC.test.ts | 22 +- .../test/cc/ManufacturerSpecificCC.test.ts | 12 +- .../zwave-js/src/lib/test/cc/MeterCC.test.ts | 115 +- .../test/cc/MultiChannelAssociationCC.test.ts | 50 +- .../src/lib/test/cc/MultiChannelCC.test.ts | 30 +- .../src/lib/test/cc/MultiCommandCC.test.ts | 4 +- .../lib/test/cc/MultilevelSwitchCC.test.ts | 34 +- .../src/lib/test/cc/NoOperationCC.test.ts | 8 +- .../src/lib/test/cc/PowerlevelCC.test.ts | 24 +- .../src/lib/test/cc/SceneActivationCC.test.ts | 14 +- .../cc/SceneActuatorConfigurationCC.test.ts | 18 +- .../cc/SceneControllerConfigurationCC.test.ts | 18 +- .../src/lib/test/cc/SupervisionCC.test.ts | 8 +- .../lib/test/cc/ThermostatFanModeCC.test.ts | 14 +- .../lib/test/cc/ThermostatFanStateCC.test.ts | 10 +- .../zwave-js/src/lib/test/cc/TimeCC.test.ts | 24 +- .../zwave-js/src/lib/test/cc/WakeUpCC.test.ts | 8 +- .../src/lib/test/cc/ZWavePlusCC.test.ts | 4 +- .../compat/basicCCReportForThermostat.test.ts | 12 +- .../basicCCSupportWhenForbidden.test.ts | 42 +- ...rySensorReportAnyUseFirstSupported.test.ts | 8 +- .../compat/corruptACKAfterSoftReset.test.ts | 4 +- .../invalidCallbackFunctionTypes.test.ts | 8 +- .../compat/notificationAlarmMapping.test.ts | 14 +- .../test/compat/reInterviewWakeUpNIF.test.ts | 5 +- .../test/compat/treatBasicSetAsEvent.test.ts | 66 +- .../test/compliance/decodeLowerS2Keys.test.ts | 6 +- .../discardInsecureCommands.test.ts | 8 +- .../encapsulationAnswerAsAsked.test.ts | 26 +- .../handleMultiCommandPayload.test.ts | 4 +- .../secureNodeSecureEndpoint.test.ts | 3 +- .../compliance/zwavePlusInfoResponse.test.ts | 8 +- .../src/lib/test/driver/SerialLogger.test.ts | 156 +- .../test/driver/assemblePartialCCs.test.ts | 168 +- .../test/driver/bootloaderDetection.test.ts | 6 +- .../driver/computeNetCCPayloadSize.test.ts | 78 +- .../test/driver/configImportFallback.test.ts | 6 +- .../lib/test/driver/controllerJammed.test.ts | 54 +- .../createCCValuesUsingKnownVersion.test.ts | 10 +- .../lib/test/driver/getNextCallbackId.test.ts | 54 +- .../driver/handleNonImplementedCCs.test.ts | 4 +- .../lib/test/driver/handleUnsolicited.test.ts | 311 +- .../test/driver/hasPendingMessages.test.ts | 83 +- .../test/driver/highestSecurityClass.test.ts | 34 +- ...noreCCVersion0ForKnownSupportedCCs.test.ts | 8 +- .../lib/test/driver/invalidPayloadLog.test.ts | 169 +- .../multiChannelUnknownVersions.test.ts | 4 +- .../multiStageResponseNoTimeout.test.ts | 10 +- .../multicastOptimisticValueUpdate.test.ts | 51 +- .../driver/nodeAsleepBlockNonceReport.test.ts | 6 +- .../driver/nodeAsleepMessageOrder.test.ts | 19 +- .../test/driver/nodeAsleepNoReject.test.ts | 34 +- .../driver/nodeAsleepPingResolves.test.ts | 8 +- .../lib/test/driver/nodeDeadReject.test.ts | 38 +- .../driver/nodeUpdateBeforeCallback.test.ts | 6 +- .../test/driver/notificationPushNoAGI.test.ts | 4 +- .../queryVersionOfEndpointOnlyCCs.test.ts | 12 +- .../driver/reInterviewAssumeAwake.test.ts | 6 +- ...iveApplicationCommandHandlerBridge.test.ts | 204 +- .../lib/test/driver/receiveMessages.test.ts | 72 +- .../test/driver/s0AndS2Encapsulation.test.ts | 6 +- .../lib/test/driver/s0Encapsulation.test.ts | 6 +- .../driver/s0EncapsulationTwoNodes.test.ts | 8 +- .../src/lib/test/driver/s2Collisions.test.ts | 16 +- .../driver/secureAndSupervisionEncap.test.ts | 8 +- .../test/driver/sendCommandProgress.test.ts | 10 +- .../driver/sendDataAbortAfterTimeout.test.ts | 34 +- .../lib/test/driver/sendDataFailThrow.test.ts | 217 +- .../sendDataMissingCallbackAbort.test.ts | 83 +- .../driver/sendDataMissingResponse.test.ts | 44 +- .../setValueFailedSupervisionGet.test.ts | 6 +- .../test/driver/setValueNoSupervision.test.ts | 6 +- .../setValueSucceedAfterFailure.test.ts | 8 +- ...setValueSuccessfulSupervisionNoGet.test.ts | 6 +- .../driver/setValueSupervision255Get.test.ts | 6 +- ...ValueSupervisionSuccessMoreUpdates.test.ts | 6 +- .../driver/setValueSupervisionWorking.test.ts | 20 +- .../successfulPingChangeNodeStatus.test.ts | 217 +- .../driver/supervisionRepeatedReport.test.ts | 6 +- .../driver/targetValueVersionUnknown.test.ts | 6 +- .../src/lib/test/driver/unknownValues.test.ts | 36 +- .../lib/test/driver/unresponsiveStick.test.ts | 16 +- .../src/lib/test/integrationTestSuite.ts | 25 +- .../src/lib/test/integrationTestSuiteMulti.ts | 25 +- .../lib/test/integrationTestSuiteShared.ts | 41 +- packages/zwave-js/src/lib/test/mocks.ts | 4 +- .../src/lib/test/node/Node.ccVersions.test.ts | 82 +- .../lib/test/node/Node.constructor.test.ts | 106 +- .../test/node/Node.createCCInstance.test.ts | 86 +- .../lib/test/node/Node.getEndpoint.test.ts | 126 +- .../lib/test/node/Node.getSetValue.test.ts | 127 +- .../lib/test/node/Node.handleCommand.test.ts | 21 +- .../lib/test/node/Node.interviewOrder.test.ts | 52 +- .../node/Node.sendNoMoreInformation.test.ts | 30 +- .../src/lib/test/node/Node.status.test.ts | 113 +- .../lib/test/node/Node.updateNodeInfo.test.ts | 136 +- .../lib/test/node/Node.valueEvents.test.ts | 97 +- .../lib/test/node/Node.waitForWakeup.test.ts | 113 +- .../legacyRefreshActuatorSensorCCs.test.ts | 6 +- packages/zwave-js/src/lib/test/utils.ts | 74 - packages/zwave-js/src/lib/zniffer/MPDU.ts | 4 +- packages/zwave-js/src/lib/zniffer/Zniffer.ts | 8 +- packages/zwave-js/src/mockServer.ts | 6 +- packages/zwave-js/tsconfig.build.json | 4 +- server_config.js | 2 +- test/{run.ts => run.cts} | 21 +- test/run_duplex.ts | 30 +- test/run_zniffer.ts | 2 +- test/tsconfig.json | 2 +- tsconfig.all.json | 2 +- tsconfig.docs.json | 8 +- turbo.json | 12 +- vitest.config.mjs | 17 + yarn.lock | 1960 ++-- 597 files changed, 18274 insertions(+), 16542 deletions(-) create mode 100644 .yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch create mode 100644 .yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch delete mode 100644 ava.config.cjs rename commitlint.config.js => commitlint.config.mjs (93%) delete mode 100644 maintenance/esbuild-register.js rename maintenance/{test.ts => test.mts} (94%) delete mode 100644 packages/cc/ava.config.cjs delete mode 100644 packages/config/ava.config.cjs delete mode 100644 packages/core/ava.config.cjs delete mode 100644 packages/flash/bin/flash.js create mode 100644 packages/flash/bin/flash.mjs create mode 100644 packages/maintenance/src/esmImports.ts delete mode 100644 packages/maintenance/src/generateTypedDocsWorker.js create mode 100644 packages/maintenance/src/refactorTests.01.ts create mode 100644 packages/maintenance/src/refactorTests.02.ts create mode 100644 packages/maintenance/src/refactorTests.03.ts delete mode 100644 packages/nvmedit/ava.config.cjs create mode 100644 packages/nvmedit/src/__snapshots__/convert.test.ts.snap delete mode 100644 packages/nvmedit/src/convert.test.ts.md delete mode 100644 packages/nvmedit/src/convert.test.ts.snap delete mode 100644 packages/serial/ava.config.cjs delete mode 100644 packages/shared/ava.config.cjs delete mode 100644 packages/transformers/ava.config.cjs create mode 100644 packages/transformers/vitest.config.mjs delete mode 100644 packages/zwave-js/ava.config.cjs rename packages/zwave-js/src/lib/driver/{Driver.unit.test.ts => Driver.unit.test.ts.txt} (85%) delete mode 100644 packages/zwave-js/src/lib/test/utils.ts rename test/{run.ts => run.cts} (74%) create mode 100644 vitest.config.mjs diff --git a/.github/workflows/test-and-release.yml b/.github/workflows/test-and-release.yml index 6993852434e9..fbb6615b409c 100644 --- a/.github/workflows/test-and-release.yml +++ b/.github/workflows/test-and-release.yml @@ -93,7 +93,27 @@ jobs: npm init -y npm i .tarballs/zwave-js.tgz - echo "Testing entry points..." + echo "Testing ESM entry points..." + # Now all entrypoints should work + node -e '(async () => { await import("zwave-js") })()' + node -e '(async () => { await import("@zwave-js/cc") })()' + node -e '(async () => { await import("@zwave-js/config") })()' + node -e '(async () => { await import("@zwave-js/core") })()' + node -e '(async () => { await import("@zwave-js/host") })()' + node -e '(async () => { await import("@zwave-js/nvmedit") })()' + node -e '(async () => { await import("@zwave-js/serial") })()' + node -e '(async () => { await import("@zwave-js/shared") })()' + node -e '(async () => { await import("@zwave-js/testing") })()' + node -e '(async () => { await import("zwave-js/safe") })()' + node -e '(async () => { await import("@zwave-js/cc/safe") })()' + node -e '(async () => { await import("@zwave-js/config/safe") })()' + node -e '(async () => { await import("@zwave-js/core/safe") })()' + node -e '(async () => { await import("@zwave-js/host/safe") })()' + node -e '(async () => { await import("@zwave-js/nvmedit/safe") })()' + node -e '(async () => { await import("@zwave-js/serial/safe") })()' + node -e '(async () => { await import("@zwave-js/shared/safe") })()' + + echo "Testing CJS entry points..." # Now all entrypoints should work node -e 'require("zwave-js")' node -e 'require("@zwave-js/cc")' @@ -194,11 +214,13 @@ jobs: # =================== # Runs unit tests on all supported node versions and OSes unit-tests: + name: "Unit tests: ${{ matrix.os }}, Node.js ${{ matrix.node-version }} (part ${{ matrix.shard }})" runs-on: ${{ matrix.os }} strategy: matrix: node-version: [18, 20] os: [ubuntu-latest] + shard: [1/4, 2/4, 3/4, 4/4] steps: - name: Checkout code @@ -214,18 +236,47 @@ jobs: - name: Perform code generation run: yarn turbo run codegen - # For pull requests, only run tests for changed files - - name: Run component tests (changes) - if: github.event_name == 'pull_request' - run: | - git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1 - yarn run test:dirty --resolve --base origin/${{ github.event.pull_request.base.ref }} + # # For pull requests, only run tests for changed files + # - name: Run component tests (changes) + # if: github.event_name == 'pull_request' + # run: | + # git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1 + # yarn run test:dirty --resolve --base origin/${{ github.event.pull_request.base.ref }} # For all other events, especially on master and releases, run the full test suite # Run the full test suite on master, release branches and tags - name: Run component tests (full) - if: github.event_name != 'pull_request' - run: yarn run test:ts $TURBO_FLAGS + # if: github.event_name != 'pull_request' + run: yarn run test:ts --shard ${{ matrix.shard }} + + # =================== + # Test if the transformers are working + test-transformers: + runs-on: ${{ matrix.os }} + strategy: + matrix: + node-version: [18, 20] + os: [ubuntu-latest] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Prepare testing environment + uses: ./.github/actions/prepare-env + with: + node-version: ${{ matrix.node-version }} + githubToken: ${{ secrets.GITHUB_TOKEN }} + + # Transformer tests need their dependencies to be compiled + - name: Compile test dependencies + run: | + yarn workspace @zwave-js/shared run build + yarn workspace @zwave-js/core run build + + # For pull requests, only run tests for changed files + - name: Test transformers + run: yarn workspace @zwave-js/transformers run test:ts # # =================== # # This job checks if a PR changes the public API surface @@ -353,7 +404,13 @@ jobs: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') - needs: [build, lint, lint-zwave, unit-tests, test-packages] + needs: + - build + - lint + - lint-zwave + - unit-tests + - test-transformers + - test-packages runs-on: ubuntu-latest strategy: diff --git a/.vscode/launch.json b/.vscode/launch.json index 66ae7a57dc2e..3485a4c8ac3f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -29,10 +29,8 @@ "name": "Debug locally", "runtimeExecutable": "yarn", "runtimeArgs": [ - "node", + "tsx", "--async-stack-traces", - "-r", - "./maintenance/esbuild-register.js", "--conditions=@@dev", "${workspaceFolder}/test/run.ts" ], @@ -52,10 +50,8 @@ "name": "Debug primary and secondary", "runtimeExecutable": "yarn", "runtimeArgs": [ - "node", + "tsx", "--async-stack-traces", - "-r", - "./maintenance/esbuild-register.js", "--conditions=@@dev", "${workspaceFolder}/test/run_duplex.ts" ], @@ -75,11 +71,9 @@ "name": "Generate typed docs", "runtimeExecutable": "yarn", "runtimeArgs": [ - "node", + "tsx", "--async-stack-traces", "--inspect-brk=9229", - "-r", - "./maintenance/esbuild-register.js", "${workspaceFolder}/packages/maintenance/src/generateTypedDocs.ts" ], "console": "integratedTerminal", @@ -94,11 +88,9 @@ "name": "Decode message", "runtimeExecutable": "yarn", "runtimeArgs": [ - "node", + "tsx", "--async-stack-traces", "--inspect-brk=9229", - "-r", - "./maintenance/esbuild-register.js", "--conditions=@@dev", "${workspaceFolder}/test/decodeMessage.ts" ], @@ -114,11 +106,9 @@ "cwd": "${workspaceFolder}", "runtimeExecutable": "yarn", "runtimeArgs": [ - "node", + "tsx", "--async-stack-traces", "--inspect=9229", - "-r", - "./maintenance/esbuild-register.js", "--conditions=@@dev", "${workspaceFolder}/packages/config/maintenance/importConfig.ts", "-dm -s zwa" @@ -131,10 +121,8 @@ "name": "Run Zniffer", "runtimeExecutable": "yarn", "runtimeArgs": [ - "node", + "tsx", "--async-stack-traces", - "-r", - "./maintenance/esbuild-register.js", "--conditions=@@dev", "${workspaceFolder}/test/run_zniffer.ts" ], diff --git a/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch b/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch new file mode 100644 index 000000000000..68569eb474f5 --- /dev/null +++ b/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch @@ -0,0 +1,22 @@ +diff --git a/dist/index-esm.mjs b/dist/index-esm.mjs +deleted file mode 100644 +index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000 +--- a/dist/index-esm.mjs ++++ /dev/null +@@ -1 +0,0 @@ +- +diff --git a/package.json b/package.json +index 1f46c413862b1b4df9bc152a21f1c7405923074e..f0db3ef8b2643b5a37922dc5362c83e36abd4f87 100644 +--- a/package.json ++++ b/package.json +@@ -4,10 +4,6 @@ + "description": "SerialPort Bindings Typescript Types", + "types": "dist/index.d.ts", + "main": "./dist/index.js", +- "exports": { +- "require": "./dist/index.js", +- "default": "./dist/index-esm.mjs" +- }, + "publishConfig": { + "access": "public" + }, diff --git a/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch b/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch new file mode 100644 index 000000000000..43ce6bb28fbb --- /dev/null +++ b/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch @@ -0,0 +1,13 @@ +diff --git a/dist/tspegjs.mjs b/dist/tspegjs.mjs +index 80c07aa0716f74f7c23c2e51d2b0fb8613941071..ac02b7d22be46a708821755efe4d5d2b9442259d 100644 +--- a/dist/tspegjs.mjs ++++ b/dist/tspegjs.mjs +@@ -20,7 +20,7 @@ var __privateMethod = (obj, member, method) => { + var _renameGrammarRules, renameGrammarRules_fn, _initNameMap, initNameMap_fn, _initSourceHeader, initSourceHeader_fn; + import { ts, Project, ScriptTarget } from "ts-morph"; + import * as peggy from "peggy"; +-import * as prettierPluginTypescript from "prettier/parser-typescript"; ++import prettierPluginTypescript from "prettier/parser-typescript"; + import prettier from "prettier/standalone"; + function wrapNodeInAsConstDeclaration(node) { + node.transform( diff --git a/api-extractor-base.json b/api-extractor-base.json index 063640268a93..acf03b68261a 100644 --- a/api-extractor-base.json +++ b/api-extractor-base.json @@ -45,7 +45,7 @@ * * SUPPORTED TOKENS: , , */ - "mainEntryPointFilePath": "/build/index.d.ts", + "mainEntryPointFilePath": "/build/esm/index.d.ts", /** * A list of NPM package names whose exports should be treated as part of this package. diff --git a/ava.config.cjs b/ava.config.cjs deleted file mode 100644 index af9cdd9cae43..000000000000 --- a/ava.config.cjs +++ /dev/null @@ -1,9 +0,0 @@ -const path = require("path"); -module.exports = { - extensions: ["ts"], - files: ["test/**", "**/*.test.ts", "!build/**"], - require: [path.join(__dirname, "./maintenance/esbuild-register.js")], - nodeArguments: [ - "--conditions=@@dev", - ], -}; diff --git a/commitlint.config.js b/commitlint.config.mjs similarity index 93% rename from commitlint.config.js rename to commitlint.config.mjs index 542f98883440..76511dd0471e 100644 --- a/commitlint.config.js +++ b/commitlint.config.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { extends: ["@commitlint/config-conventional"], rules: { "body-max-length": [0, "always", Infinity], diff --git a/docs/api/CCs/AlarmSensor.md b/docs/api/CCs/AlarmSensor.md index 1fcee69157dd..1f58b44365c9 100644 --- a/docs/api/CCs/AlarmSensor.md +++ b/docs/api/CCs/AlarmSensor.md @@ -19,7 +19,7 @@ Retrieves the current value from this sensor. ### `getSupportedSensorTypes` ```ts -async getSupportedSensorTypes(): Promise; +async getSupportedSensorTypes(): Promise; ``` ## Alarm Sensor CC values diff --git a/docs/api/CCs/Association.md b/docs/api/CCs/Association.md index ae040f34382b..b521db51e676 100644 --- a/docs/api/CCs/Association.md +++ b/docs/api/CCs/Association.md @@ -31,7 +31,7 @@ Returns information about an association group. ```ts async sendReport( - options: AssociationCCReportSpecificOptions, + options: AssociationCCReportOptions, ): Promise; ``` diff --git a/docs/api/CCs/AssociationGroupInfo.md b/docs/api/CCs/AssociationGroupInfo.md index 3d14097bdb1f..a72af46d380d 100644 --- a/docs/api/CCs/AssociationGroupInfo.md +++ b/docs/api/CCs/AssociationGroupInfo.md @@ -26,7 +26,7 @@ async getGroupInfo(groupId: number, refreshCache: boolean = false): Promise<{ mo ```ts async reportGroupInfo( - options: AssociationGroupInfoCCInfoReportSpecificOptions, + options: AssociationGroupInfoCCInfoReportOptions, ): Promise; ``` diff --git a/docs/api/CCs/FirmwareUpdateMetaData.md b/docs/api/CCs/FirmwareUpdateMetaData.md index a4da0402cdd0..168734068984 100644 --- a/docs/api/CCs/FirmwareUpdateMetaData.md +++ b/docs/api/CCs/FirmwareUpdateMetaData.md @@ -25,11 +25,11 @@ async reportMetaData( ```ts async requestUpdate( options: FirmwareUpdateMetaDataCCRequestGetOptions, -): Promise; +): Promise; ``` Requests the device to start the firmware update process. -WARNING: This method may wait up to 60 seconds for a reply. +This does not wait for the reply - that is up to the caller of this method. ### `sendFirmwareFragment` @@ -37,7 +37,7 @@ WARNING: This method may wait up to 60 seconds for a reply. async sendFirmwareFragment( fragmentNumber: number, isLastFragment: boolean, - data: Buffer, + data: Uint8Array, ): Promise; ``` diff --git a/docs/api/CCs/Indicator.md b/docs/api/CCs/Indicator.md index a601c9933d55..08fa51f4ad67 100644 --- a/docs/api/CCs/Indicator.md +++ b/docs/api/CCs/Indicator.md @@ -24,7 +24,7 @@ async set( ```ts async sendReport( - options: IndicatorCCReportSpecificOptions, + options: IndicatorCCReportOptions, ): Promise; ``` diff --git a/docs/api/CCs/ManufacturerProprietary.md b/docs/api/CCs/ManufacturerProprietary.md index db1f28f10968..beb403f1b6e1 100644 --- a/docs/api/CCs/ManufacturerProprietary.md +++ b/docs/api/CCs/ManufacturerProprietary.md @@ -9,12 +9,12 @@ ```ts async sendData( manufacturerId: number, - data?: Buffer, + data?: Uint8Array, ): Promise; ``` ### `sendAndReceiveData` ```ts -async sendAndReceiveData(manufacturerId: number, data?: Buffer): Promise<{ manufacturerId: number | undefined; data: Buffer; } | undefined>; +async sendAndReceiveData(manufacturerId: number, data?: Uint8Array): Promise<{ manufacturerId: number | undefined; data: Bytes; } | undefined>; ``` diff --git a/docs/api/CCs/MultiChannel.md b/docs/api/CCs/MultiChannel.md index 51b3f2cd7bc1..5642ed94c0ee 100644 --- a/docs/api/CCs/MultiChannel.md +++ b/docs/api/CCs/MultiChannel.md @@ -39,10 +39,7 @@ async getAggregatedMembers( ```ts async sendEncapsulated( - options: Omit< - MultiChannelCCCommandEncapsulationOptions, - keyof CCCommandOptions - >, + options: MultiChannelCCCommandEncapsulationOptions, ): Promise; ``` diff --git a/docs/api/CCs/Notification.md b/docs/api/CCs/Notification.md index 97c938e05301..8b42bd7a730a 100644 --- a/docs/api/CCs/Notification.md +++ b/docs/api/CCs/Notification.md @@ -8,7 +8,7 @@ ```ts async getInternal( - options: NotificationCCGetSpecificOptions, + options: NotificationCCGetOptions, ): Promise; ``` @@ -25,7 +25,7 @@ async sendReport( ### `get` ```ts -async get(options: NotificationCCGetSpecificOptions): Promise | undefined>; +async get(options: NotificationCCGetOptions): Promise | undefined>; ``` ### `set` diff --git a/docs/api/CCs/Security.md b/docs/api/CCs/Security.md index 706e400f0b1e..aa9feacc59fe 100644 --- a/docs/api/CCs/Security.md +++ b/docs/api/CCs/Security.md @@ -16,7 +16,7 @@ async sendEncapsulated( ### `getNonce` ```ts -async getNonce(): Promise; +async getNonce(): Promise; ``` Requests a new nonce for Security CC encapsulation which is not directly linked to a specific command. @@ -51,7 +51,7 @@ async inheritSecurityScheme(): Promise; ### `setNetworkKey` ```ts -async setNetworkKey(networkKey: Buffer): Promise; +async setNetworkKey(networkKey: Uint8Array): Promise; ``` ### `verifyNetworkKey` diff --git a/docs/api/CCs/Security2.md b/docs/api/CCs/Security2.md index 5f14b5094989..c1364e44b241 100644 --- a/docs/api/CCs/Security2.md +++ b/docs/api/CCs/Security2.md @@ -26,7 +26,7 @@ Notifies the target node that the MPAN state is out of sync. ```ts async sendMPAN( groupId: number, - innerMPANState: Buffer, + innerMPANState: Uint8Array, ): Promise; ``` @@ -115,7 +115,7 @@ Notifies the other node that the ongoing key exchange was aborted. ```ts async sendPublicKey( - publicKey: Buffer, + publicKey: Uint8Array, includingNode: boolean = true, ): Promise; ``` @@ -133,7 +133,7 @@ async requestNetworkKey( ```ts async sendNetworkKey( securityClass: SecurityClass, - networkKey: Buffer, + networkKey: Uint8Array, ): Promise; ``` diff --git a/docs/api/CCs/SoundSwitch.md b/docs/api/CCs/SoundSwitch.md index ee40e71bf2d3..f2239e1b9ab6 100644 --- a/docs/api/CCs/SoundSwitch.md +++ b/docs/api/CCs/SoundSwitch.md @@ -71,7 +71,7 @@ async getPlaying(): Promise; ``` diff --git a/docs/api/CCs/ThermostatSetback.md b/docs/api/CCs/ThermostatSetback.md index eddf9b12ec99..355f2dc5e36d 100644 --- a/docs/api/CCs/ThermostatSetback.md +++ b/docs/api/CCs/ThermostatSetback.md @@ -18,43 +18,3 @@ async set( setbackState: SetbackState, ): Promise; ``` - -## Thermostat Setback CC values - -### `setbackState` - -```ts -{ - commandClass: CommandClasses["Thermostat Setback"], - endpoint: number, - property: "setbackState", -} -``` - -- **label:** Setback state -- **min. CC version:** 1 -- **readable:** true -- **writeable:** true -- **stateful:** true -- **secret:** false -- **value type:** `"number"` -- **min. value:** -12.8 -- **max. value:** 12 - -### `setbackType` - -```ts -{ - commandClass: CommandClasses["Thermostat Setback"], - endpoint: number, - property: "setbackType", -} -``` - -- **label:** Setback type -- **min. CC version:** 1 -- **readable:** true -- **writeable:** true -- **stateful:** true -- **secret:** false -- **value type:** `"any"` diff --git a/docs/api/CCs/UserCode.md b/docs/api/CCs/UserCode.md index 01e5700c1abb..da70133b4b26 100644 --- a/docs/api/CCs/UserCode.md +++ b/docs/api/CCs/UserCode.md @@ -35,7 +35,7 @@ async set( UserIDStatus, UserIDStatus.Available | UserIDStatus.StatusNotAvailable >, - userCode: string | Buffer, + userCode: string | Uint8Array, ): Promise; ``` diff --git a/docs/api/controller.md b/docs/api/controller.md index b8d11ad84da6..08317a027402 100644 --- a/docs/api/controller.md +++ b/docs/api/controller.md @@ -402,10 +402,10 @@ interface RouteStatistics { ```ts enum ProtocolDataRate { - ZWave_9k6 = 1, - ZWave_40k = 2, - ZWave_100k = 3, - LongRange_100k = 4, + ZWave_9k6 = 0x01, + ZWave_40k = 0x02, + ZWave_100k = 0x03, + LongRange_100k = 0x04, } ``` @@ -770,19 +770,19 @@ This tells you whether an association is allowed, and if not, why: ```ts enum AssociationCheckResult { - OK = 1, + OK = 0x01, /** The association is forbidden, because the destination is a ZWLR node. ZWLR does not support direct communication between end devices. */ - Forbidden_DestinationIsLongRange = 2, + Forbidden_DestinationIsLongRange, /** The association is forbidden, because the source is a ZWLR node. ZWLR does not support direct communication between end devices. */ - Forbidden_SourceIsLongRange = 3, + Forbidden_SourceIsLongRange, /** The association is forbidden, because a node cannot be associated with itself. */ - Forbidden_SelfAssociation = 4, + Forbidden_SelfAssociation, /** The association is forbidden, because the source node's CC versions require the source and destination node to have the same (highest) security class. */ - Forbidden_SecurityClassMismatch = 5, + Forbidden_SecurityClassMismatch, /** The association is forbidden, because the source node's CC versions require the source node to have the key for the destination node's highest security class. */ - Forbidden_DestinationSecurityClassNotGranted = 6, + Forbidden_DestinationSecurityClassNotGranted, /** The association is forbidden, because none of the CCs the source node sends are supported by the destination. */ - Forbidden_NoSupportedCCs = 7, + Forbidden_NoSupportedCCs, } ``` @@ -1383,18 +1383,18 @@ Returns the type of the Z-Wave library that is supported by the controller hardw ```ts enum ZWaveLibraryTypes { - "Unknown" = 0, - "Static Controller" = 1, - "Controller" = 2, - "Enhanced Slave" = 3, - "Slave" = 4, - "Installer" = 5, - "Routing Slave" = 6, - "Bridge Controller" = 7, - "Device under Test" = 8, - "N/A" = 9, - "AV Remote" = 10, - "AV Device" = 11, + "Unknown", + "Static Controller", + "Controller", + "Enhanced Slave", + "Slave", + "Installer", + "Routing Slave", + "Bridge Controller", + "Device under Test", + "N/A", + "AV Remote", + "AV Device", } ``` @@ -1460,11 +1460,11 @@ This property tracks the status of the controller. Valid values are: ```ts enum ControllerStatus { /** The controller is ready to accept commands and transmit */ - Ready = 0, + Ready, /** The controller is unresponsive */ - Unresponsive = 1, + Unresponsive, /** The controller is unable to transmit */ - Jammed = 2, + Jammed, } ``` diff --git a/docs/api/driver.md b/docs/api/driver.md index 7ed099992604..953bab82b6f3 100644 --- a/docs/api/driver.md +++ b/docs/api/driver.md @@ -411,10 +411,12 @@ interface FileSystem { ensureDir(path: string): Promise; writeFile( file: string, - data: string | Buffer, - options?: { - encoding: BufferEncoding; - } | BufferEncoding, + data: string | Uint8Array, + options?: + | { + encoding: BufferEncoding; + } + | BufferEncoding, ): Promise; readFile(file: string, encoding: BufferEncoding): Promise; pathExists(path: string): Promise; @@ -488,6 +490,7 @@ interface SendMessageOptions { * For multi-stage messages, the callback may be called multiple times. */ onTXReport?: (report: TXReport) => void; + /** Will be called when the transaction for this message progresses. */ onProgress?: TransactionProgressListener; } @@ -581,8 +584,6 @@ TX status reports are supported by the more modern controllers and contain detai interface TXReport { /** Transmission time in ticks (multiples of 10ms) */ txTicks: number; - /** Number of repeaters used in the route to the destination, 0 for direct range */ - numRepeaters: number; /** RSSI value of the acknowledgement frame */ ackRSSI?: RSSI; /** RSSI values of the incoming acknowledgement frame, measured by repeater 0...3 */ @@ -642,10 +643,10 @@ enum RssiError { ```ts enum ProtocolDataRate { - ZWave_9k6 = 1, - ZWave_40k = 2, - ZWave_100k = 3, - LongRange_100k = 4, + ZWave_9k6 = 0x01, + ZWave_40k = 0x02, + ZWave_100k = 0x03, + LongRange_100k = 0x04, } ``` @@ -830,18 +831,18 @@ interface ZWaveOptions extends ZWaveHostOptions { * Specify the security keys to use for encryption (Z-Wave Classic). Each one must be a Buffer of exactly 16 bytes. */ securityKeys?: { - S2_AccessControl?: Buffer; - S2_Authenticated?: Buffer; - S2_Unauthenticated?: Buffer; - S0_Legacy?: Buffer; + S2_AccessControl?: Uint8Array; + S2_Authenticated?: Uint8Array; + S2_Unauthenticated?: Uint8Array; + S0_Legacy?: Uint8Array; }; /** * Specify the security keys to use for encryption (Z-Wave Long Range). Each one must be a Buffer of exactly 16 bytes. */ securityKeysLongRange?: { - S2_AccessControl?: Buffer; - S2_Authenticated?: Buffer; + S2_AccessControl?: Uint8Array; + S2_Authenticated?: Uint8Array; }; /** diff --git a/docs/api/node.md b/docs/api/node.md index 3eef5a7533c6..9dfd1a5ec3d4 100644 --- a/docs/api/node.md +++ b/docs/api/node.md @@ -318,23 +318,25 @@ Retrieves the firmware update capabilities of a node to decide which options (e. ```ts -type FirmwareUpdateCapabilities = { - /** Indicates whether the node's firmware can be upgraded */ - readonly firmwareUpgradable: false; -} | { - /** Indicates whether the node's firmware can be upgraded */ - readonly firmwareUpgradable: true; - /** An array of firmware targets that can be upgraded */ - readonly firmwareTargets: readonly number[]; - /** Indicates whether the node continues to function normally during an upgrade */ - readonly continuesToFunction: MaybeNotKnown; - /** Indicates whether the node supports delayed activation of the new firmware */ - readonly supportsActivation: MaybeNotKnown; - /** Indicates whether the node supports resuming aborted firmware transfers */ - readonly supportsResuming: MaybeNotKnown; - /** Indicates whether the node supports non-secure firmware transfers */ - readonly supportsNonSecureTransfer: MaybeNotKnown; -}; +type FirmwareUpdateCapabilities = + | { + /** Indicates whether the node's firmware can be upgraded */ + readonly firmwareUpgradable: false; + } + | { + /** Indicates whether the node's firmware can be upgraded */ + readonly firmwareUpgradable: true; + /** An array of firmware targets that can be upgraded */ + readonly firmwareTargets: readonly number[]; + /** Indicates whether the node continues to function normally during an upgrade */ + readonly continuesToFunction: MaybeNotKnown; + /** Indicates whether the node supports delayed activation of the new firmware */ + readonly supportsActivation: MaybeNotKnown; + /** Indicates whether the node supports resuming aborted firmware transfers */ + readonly supportsResuming: MaybeNotKnown; + /** Indicates whether the node supports non-secure firmware transfers */ + readonly supportsNonSecureTransfer: MaybeNotKnown; + }; ``` ### `updateFirmware` @@ -356,7 +358,7 @@ This method an array of firmware updates, each of which contains the following p ```ts interface Firmware { - data: Buffer; + data: Uint8Array; firmwareTarget?: number; } ``` @@ -856,25 +858,28 @@ This property tracks the current status of the node interview. It contains a val ```ts enum InterviewStage { /** The interview process hasn't started for this node */ - None = 0, + None, /** The node's protocol information has been queried from the controller */ - ProtocolInfo = 1, + ProtocolInfo, /** The node has been queried for supported and controlled command classes */ - NodeInfo = 2, + NodeInfo, + /** * Information for all command classes has been queried. * This includes static information that is requested once as well as dynamic * information that is requested on every restart. */ - CommandClasses = 3, + CommandClasses, + /** * Device information for the node has been loaded from a config file. * If defined, some of the reported information will be overwritten based on the * config file contents. */ - OverwriteConfig = 4, + OverwriteConfig, + /** The interview process has finished */ - Complete = 5, + Complete, } ``` @@ -949,8 +954,8 @@ If the `Z-Wave+` Command Class is supported, this returns the `Z-Wave+` node typ ```ts enum ZWavePlusNodeType { - Node = 0, // ZWave+ Node - IPGateway = 2, + Node = 0x00, // ZWave+ Node + IPGateway = 0x02, // ZWave+ for IP Gateway } ``` @@ -1401,7 +1406,7 @@ interface ZWaveNotificationCallbackArgs_EntryControlCC { dataType: EntryControlDataTypes; /** A human-readable label for the data type */ dataTypeLabel: string; - eventData?: Buffer | string; + eventData?: Uint8Array | string; } ``` @@ -1502,9 +1507,9 @@ with ```ts enum PowerlevelTestStatus { - Failed = 0, - Success = 1, - "In Progress" = 2, + Failed = 0x00, + Success = 0x01, + "In Progress" = 0x02, } ``` diff --git a/docs/api/valueid.md b/docs/api/valueid.md index 87ec9be81b9c..2d1dd4fa7af9 100644 --- a/docs/api/valueid.md +++ b/docs/api/valueid.md @@ -181,6 +181,7 @@ type BinarySensorValueMetadata = ValueMetadata & { type IndicatorMetadata = ValueMetadata & { ccSpecific: { indicatorId: number; + // only present on V2+ indicators: propertyId?: number; }; }; diff --git a/docs/api/zniffer.md b/docs/api/zniffer.md index 2d1bf662985d..a3e9c7b73e5d 100644 --- a/docs/api/zniffer.md +++ b/docs/api/zniffer.md @@ -189,7 +189,7 @@ type CorruptedFrame = { protocolDataRate: ZnifferProtocolDataRate; - payload: Buffer; + payload: Uint8Array; }; ``` @@ -235,7 +235,7 @@ type ZWaveFrame = type: ZWaveFrameType.Singlecast; destinationNodeId: number; ackRequested: boolean; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; } // Only present in routed frames: & AllOrNone< @@ -274,13 +274,13 @@ type ZWaveFrame = type: ZWaveFrameType.Broadcast; destinationNodeId: typeof NODE_ID_BROADCAST; ackRequested: boolean; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; } | { // Multicast frame, not routed type: ZWaveFrameType.Multicast; destinationNodeIds: number[]; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; } | { // Ack frame, not routed @@ -291,7 +291,7 @@ type ZWaveFrame = // Different kind of explorer frames & ({ type: ZWaveFrameType.ExplorerNormal; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; } | { type: ZWaveFrameType.ExplorerSearchResult; searchingNodeId: number; @@ -301,7 +301,7 @@ type ZWaveFrame = } | { type: ZWaveFrameType.ExplorerInclusionRequest; networkHomeId: number; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; }) // Common fields for all explorer frames & { @@ -344,7 +344,7 @@ type LongRangeFrame = // Singlecast frame type: LongRangeFrameType.Singlecast; ackRequested: boolean; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; } | { // Broadcast frame. This is technically a singlecast frame, @@ -352,13 +352,13 @@ type LongRangeFrame = type: LongRangeFrameType.Broadcast; destinationNodeId: typeof NODE_ID_BROADCAST_LR; ackRequested: boolean; - payload: Buffer | CommandClass; + payload: Uint8Array | CommandClass; } | { // Acknowledgement frame type: LongRangeFrameType.Ack; incomingRSSI: RSSI; - payload: Buffer; + payload: Uint8Array; } ); ``` diff --git a/maintenance/build.ts b/maintenance/build.ts index 444b5fcb42d5..d8101d32a406 100644 --- a/maintenance/build.ts +++ b/maintenance/build.ts @@ -5,8 +5,9 @@ const buildArgs = process.argv .slice(3) .filter((a) => a !== "-w" && a !== "--watch"); -// TODO: Parse package.json dependency graph to figure out if codegen and/or +// FIXME: Parse package.json dependency graph to figure out if codegen and/or // partial builds are necessary, instead of hardcoding it here. +// FIXME: dependency graph is needed to create CJS builds for affected packages // Only cc, config and projects that depend on them need codegen and partial builds const needsNoCodegen = [ @@ -130,6 +131,15 @@ async function main() { execOptions, ); } + + // Perform ESM to CJS transformation + console.log(); + console.log(`Transpiling to CommonJS...`); + await execa( + "yarn", + ["workspaces", "foreach", "--all", "--parallel", "run", "postbuild"], + execOptions, + ); } main() diff --git a/maintenance/esbuild-register.js b/maintenance/esbuild-register.js deleted file mode 100644 index bb709de2f1e9..000000000000 --- a/maintenance/esbuild-register.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; - -const { register } = require("esbuild-register/dist/node"); - -register({ - hookMatcher(f) { - return f.endsWith(".ts"); - }, - // Prevent esbuild from adding a "2" to the names of CC classes for some reason. - keepNames: true, - // Target the correct node version in transpilation - target: `node${process.versions.node}`, - // Stick to legacy decorators for now - tsconfigRaw: { - compilerOptions: { - experimentalDecorators: true, - }, - }, -}); diff --git a/maintenance/fmt-staged.js b/maintenance/fmt-staged.js index 7a455c8c3602..c4f1af174b3e 100644 --- a/maintenance/fmt-staged.js +++ b/maintenance/fmt-staged.js @@ -1,9 +1,12 @@ -const path = require("path"); +import { spawnSync } from "node:child_process"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Dprint parallelizes formatting and is generally fast enough to run on the whole repo // despite lint-staged telling us which files have changed. const repoRoot = path.join(__dirname, ".."); -require("child_process").spawnSync("yarn", ["fmt"], { +spawnSync("yarn", ["fmt"], { cwd: repoRoot, }); diff --git a/maintenance/parse-zwxml-manufacturers.ts b/maintenance/parse-zwxml-manufacturers.ts index 2b73ec51692e..8550dbe18bd2 100644 --- a/maintenance/parse-zwxml-manufacturers.ts +++ b/maintenance/parse-zwxml-manufacturers.ts @@ -1,5 +1,5 @@ import { formatId } from "@zwave-js/shared"; -import { isArray } from "alcalzone-shared/typeguards"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; import fs from "node:fs/promises"; import xml2js from "xml2js"; diff --git a/maintenance/patch-typescript.js b/maintenance/patch-typescript.js index 8ea265317ee1..fb85c797a7d2 100644 --- a/maintenance/patch-typescript.js +++ b/maintenance/patch-typescript.js @@ -1,6 +1,9 @@ // @ts-check -const path = require("path"); -const fs = require("fs"); +import fs from "node:fs"; +import { createRequire } from "node:module"; +import path from "node:path"; + +const require = createRequire(import.meta.url); const tsDirectory = path.dirname(require.resolve("typescript")); const tsLibPath = path.join(tsDirectory, "typescript.js"); diff --git a/maintenance/test.ts b/maintenance/test.mts similarity index 94% rename from maintenance/test.ts rename to maintenance/test.mts index d93ba76b392b..5889e3e28ab7 100644 --- a/maintenance/test.ts +++ b/maintenance/test.mts @@ -4,6 +4,9 @@ import execa from "execa"; import path from "node:path"; import { readJSON } from "../packages/shared/src/fs"; +import { fileURLToPath } from "node:url"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const repoRoot = path.join(__dirname, ".."); const filenames = process.argv diff --git a/maintenance/tsconfig.json b/maintenance/tsconfig.json index 15e1c98a9204..90c99d3c147a 100644 --- a/maintenance/tsconfig.json +++ b/maintenance/tsconfig.json @@ -3,10 +3,9 @@ "compileOnSave": true, "compilerOptions": { "module": "commonjs", - "moduleResolution": "node", // "noImplicitAny": true, "rootDir": "../", "newLine": "lf" }, - "include": ["*.ts", "../packages/*/src/**/*.ts"] + "include": ["*.ts", "*.mts", "../packages/*/src/**/*.ts"] } diff --git a/maintenance/watch.ts b/maintenance/watch.ts index 6366fc5aa9ca..5ba029df9cd7 100644 --- a/maintenance/watch.ts +++ b/maintenance/watch.ts @@ -1,4 +1,4 @@ -import { bold, gray, green, red } from "ansi-colors"; +import c from "ansi-colors"; import chokidar from "chokidar"; import cp from "node:child_process"; import crypto from "node:crypto"; @@ -101,7 +101,7 @@ async function exec(): Promise { if (child) child.kill("SIGTERM"); console.log(); - console.log(`👀 ${bold(task)}: starting...`); + console.log(`👀 ${c.bold(task)}: starting...`); console.log(); child = cp.spawn("yarn", [task, ...taskArgs], { @@ -111,15 +111,15 @@ async function exec(): Promise { }); child.on("exit", (code) => { if (code === 0) { - console.log(green(`👀 ${bold(task)}: completed successfully!`)); + console.log(c.green(`👀 ${c.bold(task)}: completed successfully!`)); prevHash = totalHash; } else { - console.log(red(`👀 ${bold(task)}: failed with code ${code}`)); + console.log(c.red(`👀 ${c.bold(task)}: failed with code ${code}`)); } child = undefined; console.log( - gray(` Waiting for file changes... Press Ctrl+C to exit.`), + c.gray(` Waiting for file changes... Press Ctrl+C to exit.`), ); }); } diff --git a/package.json b/package.json index 9278b1d6448a..50ecb47d7c98 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "14.0.0-beta.2", "private": true, "description": "Z-Wave driver written entirely in JavaScript/TypeScript", + "type": "module", "keywords": [], "author": { "name": "AlCalzone", @@ -31,6 +32,7 @@ "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", + "@alcalzone/esm2cjs": "^1.2.3", "@alcalzone/jsonl-db": "^3.1.1", "@alcalzone/monopack": "^1.3.0", "@alcalzone/release-script": "~3.8.0", @@ -67,8 +69,6 @@ "cz-conventional-changelog": "^3.3.0", "del-cli": "^6.0.0", "dprint": "^0.47.2", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", "eslint": "^9.12.0", "eslint-plugin-unicorn": "^56.0.0", "eslint-plugin-unused-imports": "patch:eslint-plugin-unused-imports@npm%3A4.1.4#~/.yarn/patches/eslint-plugin-unused-imports-npm-4.1.4-a7d7c7cdf3.patch", @@ -82,26 +82,30 @@ "semver": "^7.6.3", "source-map-support": "^0.5.21", "ts-patch": "3.2.1", + "tsx": "^4.19.2", "turbo": "2.2.3", "typescript": "5.6.2", "typescript-eslint": "^8.12.2", + "vitest": "^2.1.4", "xml2js": "^0.6.2", "zwave-js": "workspace:*" }, "resolutions": { "minimist": "^1.2.6", - "colors": "1.4.0" + "colors": "1.4.0", + "@serialport/bindings-interface@npm:^1.2.1": "patch:@serialport/bindings-interface@npm%3A1.2.2#~/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch", + "@serialport/bindings-interface@npm:1.2.2": "patch:@serialport/bindings-interface@npm%3A1.2.2#~/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch" }, "scripts": { - "ts": "node -r source-map-support/register -r ./maintenance/esbuild-register.js --conditions=@@dev", + "ts": "tsx --conditions=@@dev", "w": "yarn ts maintenance/watch.ts", "foreach": "yarn workspaces foreach --all -pvi --exclude @zwave-js/repo", "clean": "yarn turbo run clean", "build": "yarn turbo run build:turbo --", "build:turbo": "yarn ts maintenance/build.ts", "watch": "yarn w build", - "test:ts": "FORCE_COLOR=1 yarn turbo run test:ts ${TURBO_FLAGS:-'--concurrency=1'} --", - "test": "yarn ts maintenance/test.ts", + "test:ts": "vitest run", + "test": "yarn ts maintenance/test.mts", "test:dirty:resolve": "yarn ts packages/maintenance/src/resolveDirtyTests.ts", "test:dirty": "yarn ts packages/maintenance/src/resolveDirtyTests.ts --run", "test:watch": "yarn w test:dirty", diff --git a/packages/cc/ava.config.cjs b/packages/cc/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/cc/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/cc/maintenance/_tasks.ts b/packages/cc/maintenance/_tasks.ts index 01c886fdf5fc..e2a4a4a996ae 100644 --- a/packages/cc/maintenance/_tasks.ts +++ b/packages/cc/maintenance/_tasks.ts @@ -1,7 +1,7 @@ -import { red } from "ansi-colors"; -import { generateCCAPIInterface } from "./generateCCAPIInterface"; -import { generateCCExports } from "./generateCCExports"; -import { generateCCValuesInterface } from "./generateCCValuesInterface"; +import c from "ansi-colors"; +import { generateCCAPIInterface } from "./generateCCAPIInterface.js"; +import { generateCCExports } from "./generateCCExports.js"; +import { generateCCValuesInterface } from "./generateCCValuesInterface.js"; // import { lintCCConstructors } from "./lintCCConstructor"; const argv = process.argv.slice(2); @@ -18,7 +18,7 @@ const codegen = () => await codegen(); } })().catch((e) => { - console.error(red(e.stack)); + console.error(c.red(e.stack)); console.error(" "); process.exit(1); }); diff --git a/packages/cc/maintenance/checkCCToLogEntry.ts b/packages/cc/maintenance/checkCCToLogEntry.ts index d77c8e59edd5..5995e5144726 100644 --- a/packages/cc/maintenance/checkCCToLogEntry.ts +++ b/packages/cc/maintenance/checkCCToLogEntry.ts @@ -3,7 +3,8 @@ */ import { loadTSConfig, projectRoot } from "@zwave-js/maintenance"; -import * as path from "path"; +import esMain from "es-main"; +import * as path from "node:path"; import ts from "typescript"; export function checkCCToLogEntry(): void { @@ -22,7 +23,7 @@ export function checkCCToLogEntry(): void { for (const sourceFile of program.getSourceFiles()) { const relativePath = path .relative(projectRoot, sourceFile.fileName) - .replace(/\\/g, "/"); + .replaceAll("\\", "/"); // Only look at files in this package if (relativePath.startsWith("..")) continue; @@ -100,7 +101,7 @@ export function checkCCToLogEntry(): void { } } -if (require.main === module) { +if (esMain(import.meta)) { checkCCToLogEntry(); process.exit(0); } diff --git a/packages/cc/maintenance/generateCCAPIInterface.ts b/packages/cc/maintenance/generateCCAPIInterface.ts index 4338ba39374c..5cd6d60f76a2 100644 --- a/packages/cc/maintenance/generateCCAPIInterface.ts +++ b/packages/cc/maintenance/generateCCAPIInterface.ts @@ -5,8 +5,12 @@ */ import { formatWithDprint } from "@zwave-js/maintenance"; +import esMain from "es-main"; import fs from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const apiRegex = /^@API\(CommandClasses(?:\.|\[)(.+?)(?:\])?\)/m; const classNameRegex = /class ([^\s]+) extends (\w+)?CCAPI/; @@ -40,7 +44,7 @@ export async function generateCCAPIInterface(): Promise { const classMatch = classNameRegex.exec(fileContent); if (apiMatch && classMatch) { CCsWithAPI.push({ - file: ccFile.replace(/\.ts$/, ""), + file: ccFile.replace(/\.ts$/, ".js"), name: apiMatch[1], className: classMatch[1], }); @@ -110,4 +114,4 @@ export async function generateCCAPIInterface(): Promise { } } -if (require.main === module) void generateCCAPIInterface(); +if (esMain(import.meta)) void generateCCAPIInterface(); diff --git a/packages/cc/maintenance/generateCCExports.ts b/packages/cc/maintenance/generateCCExports.ts index 59116722173e..215473de42b3 100644 --- a/packages/cc/maintenance/generateCCExports.ts +++ b/packages/cc/maintenance/generateCCExports.ts @@ -9,8 +9,9 @@ import { projectRoot, } from "@zwave-js/maintenance"; import { compareStrings } from "@zwave-js/shared"; +import esMain from "es-main"; import fs from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; import ts from "typescript"; // Define where the CC index file is located @@ -180,7 +181,7 @@ export async function generateCCExports(): Promise { // normalize to slashes .replaceAll("\\", "/") // TS imports may not end with ".ts" - .replace(/\.ts$/, "") + .replace(/\.ts$/, ".js") // By passing the index file as "from", we get an erraneous "../" at the path start .replace(/^\.\.\//, "./"); const typeExports = fileExports.filter((e) => e.typeOnly); @@ -212,4 +213,4 @@ export async function generateCCExports(): Promise { } } -if (require.main === module) void generateCCExports(); +if (esMain(import.meta)) void generateCCExports(); diff --git a/packages/cc/maintenance/generateCCValuesInterface.ts b/packages/cc/maintenance/generateCCValuesInterface.ts index 6384e752d595..fe4b725fe6f5 100644 --- a/packages/cc/maintenance/generateCCValuesInterface.ts +++ b/packages/cc/maintenance/generateCCValuesInterface.ts @@ -5,8 +5,12 @@ */ import { formatWithDprint } from "@zwave-js/maintenance"; +import esMain from "es-main"; import fs from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const apiRegex = /^@API\(CommandClasses(?:\.|\[)(.+?)(?:\])?\)/m; const valuesDefinitionRegex = /export const ([^\s]+CCValues) =/; @@ -37,7 +41,7 @@ export async function generateCCValuesInterface(): Promise { const classMatch = valuesDefinitionRegex.exec(fileContent); if (apiMatch && classMatch) { CCsWithValues.push({ - file: ccFile.replace(/\.ts$/, ""), + file: ccFile.replace(/\.ts$/, ".js"), name: apiMatch[1], className: classMatch[1], }); @@ -77,4 +81,4 @@ export async function generateCCValuesInterface(): Promise { } } -if (require.main === module) void generateCCValuesInterface(); +if (esMain(import.meta)) void generateCCValuesInterface(); diff --git a/packages/cc/maintenance/lintCCConstructor.ts b/packages/cc/maintenance/lintCCConstructor.ts index 96df68da738f..06283ff851c0 100644 --- a/packages/cc/maintenance/lintCCConstructor.ts +++ b/packages/cc/maintenance/lintCCConstructor.ts @@ -242,7 +242,7 @@ // } // } -// if (require.main === module) +// if (esMain(import.meta)) // lintCCConstructors() // .then(() => process.exit(0)) // .catch(() => process.exit(1)); diff --git a/packages/cc/package.json b/packages/cc/package.json index ac125f378be8..6cff37a10d8a 100644 --- a/packages/cc/package.json +++ b/packages/cc/package.json @@ -6,32 +6,33 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./cc": { "@@dev": "./src/cc/index.ts", - "types": "./build/cc/index.d.ts", - "default": "./build/cc/index.js" + "import": "./build/esm/cc/index.js", + "require": "./build/cjs/cc/index.js" }, "./package.json": "./package.json", "./*": { "@@dev": "./src/cc/*.ts", - "types": "./build/cc/*.d.ts", - "default": "./build/cc/*.js" + "import": "./build/esm/cc/*.js", + "require": "./build/cjs/cc/*.js" } }, "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -55,14 +56,15 @@ "scripts": { "task": "yarn ts maintenance/_tasks.ts", "codegen": "yarn task codegen", - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", - "ts": "node -r esbuild-register --conditions=@@dev", + "ts": "tsx --conditions=@@dev", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "dependencies": { "@zwave-js/core": "workspace:*", @@ -73,12 +75,15 @@ "reflect-metadata": "^0.2.2" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "@zwave-js/maintenance": "workspace:*", "@zwave-js/transformers": "workspace:*", - "ava": "^6.1.3", "del-cli": "^6.0.0", - "typescript": "5.6.2" + "es-main": "^1.3.0", + "tsx": "^4.19.2", + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/cc/src/cc/AlarmSensorCC.ts b/packages/cc/src/cc/AlarmSensorCC.ts index 253e2c173bfd..4228ff54f087 100644 --- a/packages/cc/src/cc/AlarmSensorCC.ts +++ b/packages/cc/src/cc/AlarmSensorCC.ts @@ -20,14 +20,14 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, isEnumMember, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -36,9 +36,9 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { AlarmSensorCommand, AlarmSensorType } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { AlarmSensorCommand, AlarmSensorType } from "../lib/_Types.js"; export const AlarmSensorCCValues = Object.freeze({ ...V.defineDynamicCCValues(CommandClasses["Alarm Sensor"], { diff --git a/packages/cc/src/cc/AssociationCC.ts b/packages/cc/src/cc/AssociationCC.ts index 40e4fc177af8..2414039f1ced 100644 --- a/packages/cc/src/cc/AssociationCC.ts +++ b/packages/cc/src/cc/AssociationCC.ts @@ -22,14 +22,14 @@ import type { } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { distinct } from "alcalzone-shared/arrays"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -39,10 +39,10 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { type AssociationAddress, AssociationCommand } from "../lib/_Types"; -import * as ccUtils from "../lib/utils"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { type AssociationAddress, AssociationCommand } from "../lib/_Types.js"; +import * as ccUtils from "../lib/utils.js"; export const AssociationCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Association, { diff --git a/packages/cc/src/cc/AssociationGroupInfoCC.ts b/packages/cc/src/cc/AssociationGroupInfoCC.ts index 57228b9aed8c..887d00b4db20 100644 --- a/packages/cc/src/cc/AssociationGroupInfoCC.ts +++ b/packages/cc/src/cc/AssociationGroupInfoCC.ts @@ -20,14 +20,14 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { cpp2js, getEnumMemberName, num2hex } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -36,14 +36,14 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { AssociationGroupInfoCommand, AssociationGroupInfoProfile, -} from "../lib/_Types"; -import { AssociationCC } from "./AssociationCC"; -import { MultiChannelAssociationCC } from "./MultiChannelAssociationCC"; +} from "../lib/_Types.js"; +import { AssociationCC } from "./AssociationCC.js"; +import { MultiChannelAssociationCC } from "./MultiChannelAssociationCC.js"; export const AssociationGroupInfoCCValues = Object.freeze({ // Defines values that do not depend on anything else diff --git a/packages/cc/src/cc/BarrierOperatorCC.ts b/packages/cc/src/cc/BarrierOperatorCC.ts index 3978323afecf..f77aea5cf056 100644 --- a/packages/cc/src/cc/BarrierOperatorCC.ts +++ b/packages/cc/src/cc/BarrierOperatorCC.ts @@ -40,14 +40,14 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -57,14 +57,14 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { BarrierOperatorCommand, BarrierState, SubsystemState, SubsystemType, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const BarrierOperatorCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Barrier Operator"], { diff --git a/packages/cc/src/cc/BasicCC.ts b/packages/cc/src/cc/BasicCC.ts index d94bdff5615d..9ac6907512ad 100644 --- a/packages/cc/src/cc/BasicCC.ts +++ b/packages/cc/src/cc/BasicCC.ts @@ -40,7 +40,7 @@ import { type SetValueImplementationHooksFactory, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -48,7 +48,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -58,9 +58,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { BasicCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { BasicCommand } from "../lib/_Types.js"; export const BasicCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Basic, { diff --git a/packages/cc/src/cc/BatteryCC.ts b/packages/cc/src/cc/BatteryCC.ts index 28065bb2f5fa..cae36cdb8b5d 100644 --- a/packages/cc/src/cc/BatteryCC.ts +++ b/packages/cc/src/cc/BatteryCC.ts @@ -34,14 +34,14 @@ import { PhysicalCCAPI, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -50,14 +50,14 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { BatteryChargingStatus, BatteryCommand, BatteryReplacementStatus, -} from "../lib/_Types"; -import { NotificationCCValues } from "./NotificationCC"; +} from "../lib/_Types.js"; +import { NotificationCCValues } from "./NotificationCC.js"; export const BatteryCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Battery, { diff --git a/packages/cc/src/cc/BinarySensorCC.ts b/packages/cc/src/cc/BinarySensorCC.ts index 3cd1f382089e..0b50c8aafd85 100644 --- a/packages/cc/src/cc/BinarySensorCC.ts +++ b/packages/cc/src/cc/BinarySensorCC.ts @@ -25,14 +25,14 @@ import { PhysicalCCAPI, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -41,9 +41,9 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { BinarySensorCommand, BinarySensorType } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { BinarySensorCommand, BinarySensorType } from "../lib/_Types.js"; export const BinarySensorCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Binary Sensor"], { diff --git a/packages/cc/src/cc/BinarySwitchCC.ts b/packages/cc/src/cc/BinarySwitchCC.ts index 5af379e7e221..e0d4a179d058 100644 --- a/packages/cc/src/cc/BinarySwitchCC.ts +++ b/packages/cc/src/cc/BinarySwitchCC.ts @@ -32,14 +32,14 @@ import { type SetValueImplementationHooksFactory, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -49,9 +49,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { BinarySwitchCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { BinarySwitchCommand } from "../lib/_Types.js"; export const BinarySwitchCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Binary Switch"], { diff --git a/packages/cc/src/cc/CRC16CC.ts b/packages/cc/src/cc/CRC16CC.ts index 1d5017a081ec..a8a935280119 100644 --- a/packages/cc/src/cc/CRC16CC.ts +++ b/packages/cc/src/cc/CRC16CC.ts @@ -12,18 +12,18 @@ import type { CCParsingContext, GetValueDB, } from "@zwave-js/host/safe"; -import { CCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { CCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { Bytes } from "@zwave-js/shared/safe"; -import { CRC16Command } from "../lib/_Types"; +import { CRC16Command } from "../lib/_Types.js"; const headerBuffer = Bytes.from([ CommandClasses["CRC-16 Encapsulation"], diff --git a/packages/cc/src/cc/CentralSceneCC.ts b/packages/cc/src/cc/CentralSceneCC.ts index 8ad235ff2574..0bb971860374 100644 --- a/packages/cc/src/cc/CentralSceneCC.ts +++ b/packages/cc/src/cc/CentralSceneCC.ts @@ -23,7 +23,7 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import { CCAPI, POLL_VALUE, @@ -32,13 +32,13 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -48,10 +48,10 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { CentralSceneCommand, CentralSceneKeys } from "../lib/_Types"; -import * as ccUtils from "../lib/utils"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { CentralSceneCommand, CentralSceneKeys } from "../lib/_Types.js"; +import * as ccUtils from "../lib/utils.js"; export const CentralSceneCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Central Scene"], { diff --git a/packages/cc/src/cc/ClimateControlScheduleCC.ts b/packages/cc/src/cc/ClimateControlScheduleCC.ts index 0015e8ca18e1..e2d05cd5ebe8 100644 --- a/packages/cc/src/cc/ClimateControlScheduleCC.ts +++ b/packages/cc/src/cc/ClimateControlScheduleCC.ts @@ -18,9 +18,9 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { padStart } from "alcalzone-shared/strings"; -import { CCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import { CCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, @@ -30,21 +30,21 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { ClimateControlScheduleCommand, ScheduleOverrideType, type SetbackState, type Switchpoint, Weekday, -} from "../lib/_Types"; +} from "../lib/_Types.js"; import { decodeSetbackState, decodeSwitchpoint, encodeSetbackState, encodeSwitchpoint, -} from "../lib/serializers"; +} from "../lib/serializers.js"; export const ClimateControlScheduleCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Climate Control Schedule"], { diff --git a/packages/cc/src/cc/ClockCC.ts b/packages/cc/src/cc/ClockCC.ts index fa4aa9d8b967..ff5abfd72511 100644 --- a/packages/cc/src/cc/ClockCC.ts +++ b/packages/cc/src/cc/ClockCC.ts @@ -19,14 +19,14 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { padStart } from "alcalzone-shared/strings"; -import { CCAPI } from "../lib/API"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import { CCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -34,8 +34,8 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { ClockCommand, Weekday } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { ClockCommand, Weekday } from "../lib/_Types.js"; // @noSetValueAPI - This CC has no simple value to set diff --git a/packages/cc/src/cc/ColorSwitchCC.ts b/packages/cc/src/cc/ColorSwitchCC.ts index 5fbe88d0f576..0d20f4c810f1 100644 --- a/packages/cc/src/cc/ColorSwitchCC.ts +++ b/packages/cc/src/cc/ColorSwitchCC.ts @@ -30,8 +30,8 @@ import { pick, } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { clamp } from "alcalzone-shared/math"; -import { isObject } from "alcalzone-shared/typeguards"; +import { clamp } from "alcalzone-shared/math/index.js"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import { CCAPI, POLL_VALUE, @@ -42,7 +42,7 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -50,7 +50,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -60,8 +60,8 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { ColorComponent, ColorComponentMap, @@ -69,7 +69,7 @@ import { ColorSwitchCommand, type ColorTable, LevelChangeDirection, -} from "../lib/_Types"; +} from "../lib/_Types.js"; const hexColorRegex = /^#?(?[0-9a-f]{2})(?[0-9a-f]{2})(?[0-9a-f]{2})$/i; diff --git a/packages/cc/src/cc/ConfigurationCC.ts b/packages/cc/src/cc/ConfigurationCC.ts index 01fabfca0ec7..4e26e76d0a1a 100644 --- a/packages/cc/src/cc/ConfigurationCC.ts +++ b/packages/cc/src/cc/ConfigurationCC.ts @@ -41,9 +41,9 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { distinct } from "alcalzone-shared/arrays"; -import { composeObject } from "alcalzone-shared/objects"; -import { padStart } from "alcalzone-shared/strings"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { composeObject } from "alcalzone-shared/objects/index.js"; +import { padStart } from "alcalzone-shared/strings/index.js"; import { CCAPI, type CCAPIEndpoint, @@ -54,7 +54,7 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -62,7 +62,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -71,9 +71,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { type ConfigValue, ConfigurationCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { type ConfigValue, ConfigurationCommand } from "../lib/_Types.js"; function configValueToString(value: ConfigValue): string { if (typeof value === "number") return value.toString(); diff --git a/packages/cc/src/cc/DeviceResetLocallyCC.ts b/packages/cc/src/cc/DeviceResetLocallyCC.ts index 88f330e12af7..4ebfb2718bfd 100644 --- a/packages/cc/src/cc/DeviceResetLocallyCC.ts +++ b/packages/cc/src/cc/DeviceResetLocallyCC.ts @@ -5,15 +5,15 @@ import { validatePayload, } from "@zwave-js/core/safe"; import { type CCParsingContext } from "@zwave-js/host"; -import { CCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { CCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, commandClass, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { DeviceResetLocallyCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { DeviceResetLocallyCommand } from "../lib/_Types.js"; // @noInterview: There is no interview procedure diff --git a/packages/cc/src/cc/DoorLockCC.ts b/packages/cc/src/cc/DoorLockCC.ts index 64dabab944a9..d122c68de592 100644 --- a/packages/cc/src/cc/DoorLockCC.ts +++ b/packages/cc/src/cc/DoorLockCC.ts @@ -24,7 +24,7 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { isArray } from "alcalzone-shared/typeguards"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; import { CCAPI, POLL_VALUE, @@ -34,14 +34,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -51,14 +51,14 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { type DoorHandleStatus, DoorLockCommand, DoorLockMode, DoorLockOperationType, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const DoorLockCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Door Lock"], { diff --git a/packages/cc/src/cc/DoorLockLoggingCC.ts b/packages/cc/src/cc/DoorLockLoggingCC.ts index 12849003b794..750cb50f9f99 100644 --- a/packages/cc/src/cc/DoorLockLoggingCC.ts +++ b/packages/cc/src/cc/DoorLockLoggingCC.ts @@ -17,13 +17,13 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { isPrintableASCII, num2hex } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -32,15 +32,15 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { DoorLockLoggingCommand, DoorLockLoggingEventType, type DoorLockLoggingRecord, DoorLockLoggingRecordStatus, -} from "../lib/_Types"; -import { userCodeToLogString } from "./UserCodeCC"; +} from "../lib/_Types.js"; +import { userCodeToLogString } from "./UserCodeCC.js"; interface DateSegments { year: number; diff --git a/packages/cc/src/cc/EnergyProductionCC.ts b/packages/cc/src/cc/EnergyProductionCC.ts index 5952c44baaff..bc7c054007de 100644 --- a/packages/cc/src/cc/EnergyProductionCC.ts +++ b/packages/cc/src/cc/EnergyProductionCC.ts @@ -21,14 +21,14 @@ import { POLL_VALUE, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -36,14 +36,14 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { EnergyProductionCommand, EnergyProductionParameter, type EnergyProductionScale, getEnergyProductionScale, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const EnergyProductionCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Energy Production"], { diff --git a/packages/cc/src/cc/EntryControlCC.ts b/packages/cc/src/cc/EntryControlCC.ts index f3ae57f3bd91..6118de5e69b5 100644 --- a/packages/cc/src/cc/EntryControlCC.ts +++ b/packages/cc/src/cc/EntryControlCC.ts @@ -30,14 +30,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -47,14 +47,14 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { EntryControlCommand, EntryControlDataTypes, EntryControlEventTypes, -} from "../lib/_Types"; -import * as ccUtils from "../lib/utils"; +} from "../lib/_Types.js"; +import * as ccUtils from "../lib/utils.js"; export const EntryControlCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Entry Control"], { diff --git a/packages/cc/src/cc/FirmwareUpdateMetaDataCC.ts b/packages/cc/src/cc/FirmwareUpdateMetaDataCC.ts index 9f6afef71bfe..c0864fbccc06 100644 --- a/packages/cc/src/cc/FirmwareUpdateMetaDataCC.ts +++ b/packages/cc/src/cc/FirmwareUpdateMetaDataCC.ts @@ -23,13 +23,13 @@ import { pick, } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -38,8 +38,8 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { FirmwareDownloadStatus, FirmwareUpdateActivationStatus, @@ -47,7 +47,7 @@ import { FirmwareUpdateMetaDataCommand, FirmwareUpdateRequestStatus, FirmwareUpdateStatus, -} from "../lib/_Types"; +} from "../lib/_Types.js"; // @noSetValueAPI There are no values to set here diff --git a/packages/cc/src/cc/HailCC.ts b/packages/cc/src/cc/HailCC.ts index a12c21173ca3..e44af5c3e80f 100644 --- a/packages/cc/src/cc/HailCC.ts +++ b/packages/cc/src/cc/HailCC.ts @@ -1,11 +1,11 @@ import { CommandClasses } from "@zwave-js/core/safe"; -import { CommandClass } from "../lib/CommandClass"; +import { CommandClass } from "../lib/CommandClass.js"; import { CCCommand, commandClass, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { HailCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { HailCommand } from "../lib/_Types.js"; // Decorators are applied in the reverse source order, so for @CCCommand to work, // it must come before @commandClass diff --git a/packages/cc/src/cc/HumidityControlModeCC.ts b/packages/cc/src/cc/HumidityControlModeCC.ts index 87695b37d73c..2e57ddee5310 100644 --- a/packages/cc/src/cc/HumidityControlModeCC.ts +++ b/packages/cc/src/cc/HumidityControlModeCC.ts @@ -29,14 +29,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -46,9 +46,12 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { HumidityControlMode, HumidityControlModeCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { + HumidityControlMode, + HumidityControlModeCommand, +} from "../lib/_Types.js"; export const HumidityControlModeCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Humidity Control Mode"], { diff --git a/packages/cc/src/cc/HumidityControlOperatingStateCC.ts b/packages/cc/src/cc/HumidityControlOperatingStateCC.ts index 868a14d6ebef..0de2c16eb538 100644 --- a/packages/cc/src/cc/HumidityControlOperatingStateCC.ts +++ b/packages/cc/src/cc/HumidityControlOperatingStateCC.ts @@ -15,13 +15,13 @@ import { POLL_VALUE, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -30,12 +30,12 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { HumidityControlOperatingState, HumidityControlOperatingStateCommand, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const HumidityControlOperatingStateCCValues = Object.freeze({ ...V.defineStaticCCValues( diff --git a/packages/cc/src/cc/HumidityControlSetpointCC.ts b/packages/cc/src/cc/HumidityControlSetpointCC.ts index 81b5fde9cfc1..8c64c4f31178 100644 --- a/packages/cc/src/cc/HumidityControlSetpointCC.ts +++ b/packages/cc/src/cc/HumidityControlSetpointCC.ts @@ -34,14 +34,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -51,14 +51,14 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { type HumidityControlSetpointCapabilities, HumidityControlSetpointCommand, HumidityControlSetpointType, type HumidityControlSetpointValue, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const HumidityControlSetpointCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Humidity Control Setpoint"], { diff --git a/packages/cc/src/cc/InclusionControllerCC.ts b/packages/cc/src/cc/InclusionControllerCC.ts index d8f456521375..3a67a74e921a 100644 --- a/packages/cc/src/cc/InclusionControllerCC.ts +++ b/packages/cc/src/cc/InclusionControllerCC.ts @@ -11,19 +11,19 @@ import type { GetValueDB, } from "@zwave-js/host"; import { Bytes, getEnumMemberName } from "@zwave-js/shared"; -import { CCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { CCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, commandClass, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { InclusionControllerCommand, InclusionControllerStatus, InclusionControllerStep, -} from "../lib/_Types"; +} from "../lib/_Types.js"; // This CC should not be used directly from user code /* eslint-disable @zwave-js/ccapi-validate-args */ diff --git a/packages/cc/src/cc/IndicatorCC.ts b/packages/cc/src/cc/IndicatorCC.ts index 39c51ec4c6bd..5ba661b58a3a 100644 --- a/packages/cc/src/cc/IndicatorCC.ts +++ b/packages/cc/src/cc/IndicatorCC.ts @@ -24,8 +24,8 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { num2hex } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { clamp, roundTo } from "alcalzone-shared/math"; -import { isArray } from "alcalzone-shared/typeguards"; +import { clamp, roundTo } from "alcalzone-shared/math/index.js"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; import { CCAPI, POLL_VALUE, @@ -34,14 +34,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -50,9 +50,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { IndicatorCommand, type IndicatorTimeout } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { IndicatorCommand, type IndicatorTimeout } from "../lib/_Types.js"; function isManufacturerDefinedIndicator(indicatorId: number): boolean { return indicatorId >= 0x80 && indicatorId <= 0x9f; diff --git a/packages/cc/src/cc/IrrigationCC.ts b/packages/cc/src/cc/IrrigationCC.ts index 2e6a76c7811e..95cfe5d2f358 100644 --- a/packages/cc/src/cc/IrrigationCC.ts +++ b/packages/cc/src/cc/IrrigationCC.ts @@ -24,7 +24,7 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import { CCAPI, POLL_VALUE, @@ -35,14 +35,14 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -52,15 +52,15 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { IrrigationCommand, IrrigationSensorPolarity, type ValveId, type ValveTableEntry, ValveType, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const IrrigationCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Irrigation, { diff --git a/packages/cc/src/cc/LanguageCC.ts b/packages/cc/src/cc/LanguageCC.ts index ddada460ee11..d721abb27131 100644 --- a/packages/cc/src/cc/LanguageCC.ts +++ b/packages/cc/src/cc/LanguageCC.ts @@ -21,13 +21,13 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI } from "../lib/API"; +import { CCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -37,9 +37,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { LanguageCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { LanguageCommand } from "../lib/_Types.js"; export const LanguageCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Language, { diff --git a/packages/cc/src/cc/LockCC.ts b/packages/cc/src/cc/LockCC.ts index cb1029e3c08d..ffbcaa64dc7f 100644 --- a/packages/cc/src/cc/LockCC.ts +++ b/packages/cc/src/cc/LockCC.ts @@ -27,13 +27,13 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -43,9 +43,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { LockCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { LockCommand } from "../lib/_Types.js"; export const LockCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Lock, { diff --git a/packages/cc/src/cc/ManufacturerProprietaryCC.ts b/packages/cc/src/cc/ManufacturerProprietaryCC.ts index 7a3c9546b2a5..6fea308cd93c 100644 --- a/packages/cc/src/cc/ManufacturerProprietaryCC.ts +++ b/packages/cc/src/cc/ManufacturerProprietaryCC.ts @@ -8,25 +8,25 @@ import { import type { CCEncodingContext, CCParsingContext } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, type CCAPIEndpoint, type CCAPIHost } from "../lib/API"; +import { CCAPI, type CCAPIEndpoint, type CCAPIHost } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { ManufacturerSpecificCCValues } from "./ManufacturerSpecificCC"; +} from "../lib/CommandClassDecorators.js"; +import { ManufacturerSpecificCCValues } from "./ManufacturerSpecificCC.js"; import { getManufacturerId, getManufacturerProprietaryAPI, getManufacturerProprietaryCCConstructor, -} from "./manufacturerProprietary/Decorators"; +} from "./manufacturerProprietary/Decorators.js"; export type ManufacturerProprietaryCCConstructor< T extends typeof ManufacturerProprietaryCC = diff --git a/packages/cc/src/cc/ManufacturerSpecificCC.ts b/packages/cc/src/cc/ManufacturerSpecificCC.ts index 70e06383ec24..705d94df22d8 100644 --- a/packages/cc/src/cc/ManufacturerSpecificCC.ts +++ b/packages/cc/src/cc/ManufacturerSpecificCC.ts @@ -16,12 +16,12 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, num2hex, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -30,9 +30,9 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { DeviceIdType, ManufacturerSpecificCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { DeviceIdType, ManufacturerSpecificCommand } from "../lib/_Types.js"; export const ManufacturerSpecificCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Manufacturer Specific"], { diff --git a/packages/cc/src/cc/MeterCC.ts b/packages/cc/src/cc/MeterCC.ts index 8e7014456bd4..9dfc7cf98dc7 100644 --- a/packages/cc/src/cc/MeterCC.ts +++ b/packages/cc/src/cc/MeterCC.ts @@ -59,7 +59,7 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -67,7 +67,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -78,9 +78,9 @@ import { getCommandClass, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { MeterCommand, type MeterReading, RateType } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { MeterCommand, type MeterReading, RateType } from "../lib/_Types.js"; export const MeterCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Meter, { diff --git a/packages/cc/src/cc/MultiChannelAssociationCC.ts b/packages/cc/src/cc/MultiChannelAssociationCC.ts index c099fd2c7b65..3530213d9dc2 100644 --- a/packages/cc/src/cc/MultiChannelAssociationCC.ts +++ b/packages/cc/src/cc/MultiChannelAssociationCC.ts @@ -24,13 +24,13 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -40,15 +40,15 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { type AssociationAddress, type EndpointAddress, MultiChannelAssociationCommand, -} from "../lib/_Types"; -import * as ccUtils from "../lib/utils"; -import { AssociationCCValues } from "./AssociationCC"; +} from "../lib/_Types.js"; +import * as ccUtils from "../lib/utils.js"; +import { AssociationCCValues } from "./AssociationCC.js"; export const MultiChannelAssociationCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Multi Channel Association"], { diff --git a/packages/cc/src/cc/MultiChannelCC.ts b/packages/cc/src/cc/MultiChannelCC.ts index 49f190052d2c..7fa26113f3ea 100644 --- a/packages/cc/src/cc/MultiChannelCC.ts +++ b/packages/cc/src/cc/MultiChannelCC.ts @@ -26,15 +26,15 @@ import type { } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { distinct } from "alcalzone-shared/arrays"; -import { CCAPI } from "../lib/API"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { CCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -43,13 +43,13 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { isEncapsulatingCommandClass, isMultiEncapsulatingCommandClass, -} from "../lib/EncapsulatingCommandClass"; -import { V } from "../lib/Values"; -import { MultiChannelCommand } from "../lib/_Types"; +} from "../lib/EncapsulatingCommandClass.js"; +import { V } from "../lib/Values.js"; +import { MultiChannelCommand } from "../lib/_Types.js"; // TODO: Handle removal reports of dynamic endpoints diff --git a/packages/cc/src/cc/MultiCommandCC.ts b/packages/cc/src/cc/MultiCommandCC.ts index ca20183dbb69..cb15c4efd855 100644 --- a/packages/cc/src/cc/MultiCommandCC.ts +++ b/packages/cc/src/cc/MultiCommandCC.ts @@ -13,15 +13,15 @@ import type { } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { CCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, commandClass, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { MultiCommandCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { MultiCommandCommand } from "../lib/_Types.js"; // TODO: Handle this command when received diff --git a/packages/cc/src/cc/MultilevelSensorCC.ts b/packages/cc/src/cc/MultilevelSensorCC.ts index 97b4bf404055..e82072a695b9 100644 --- a/packages/cc/src/cc/MultilevelSensorCC.ts +++ b/packages/cc/src/cc/MultilevelSensorCC.ts @@ -49,7 +49,7 @@ import { PhysicalCCAPI, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, type CCResponsePredicate, @@ -58,7 +58,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -68,12 +68,12 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { MultilevelSensorCommand, type MultilevelSensorValue, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const MultilevelSensorCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Multilevel Sensor"], { diff --git a/packages/cc/src/cc/MultilevelSwitchCC.ts b/packages/cc/src/cc/MultilevelSwitchCC.ts index 27ad81126dbb..efcbeccdac13 100644 --- a/packages/cc/src/cc/MultilevelSwitchCC.ts +++ b/packages/cc/src/cc/MultilevelSwitchCC.ts @@ -32,7 +32,7 @@ import { type SetValueImplementationHooksFactory, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -40,7 +40,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -50,13 +50,13 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { LevelChangeDirection, MultilevelSwitchCommand, SwitchType, -} from "../lib/_Types"; +} from "../lib/_Types.js"; /** * Translates a switch type into two actions that may be performed. Unknown types default to Down/Up diff --git a/packages/cc/src/cc/NoOperationCC.ts b/packages/cc/src/cc/NoOperationCC.ts index 993252cb840a..d5d76f79b6eb 100644 --- a/packages/cc/src/cc/NoOperationCC.ts +++ b/packages/cc/src/cc/NoOperationCC.ts @@ -1,11 +1,11 @@ import { CommandClasses, MessagePriority } from "@zwave-js/core/safe"; -import { PhysicalCCAPI } from "../lib/API"; -import { CommandClass } from "../lib/CommandClass"; +import { PhysicalCCAPI } from "../lib/API.js"; +import { CommandClass } from "../lib/CommandClass.js"; import { API, commandClass, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; // @noSetValueAPI This CC has no set-type commands // @noInterview There's nothing to interview here diff --git a/packages/cc/src/cc/NodeNamingCC.ts b/packages/cc/src/cc/NodeNamingCC.ts index f6b67269a26e..786fea6deae9 100644 --- a/packages/cc/src/cc/NodeNamingCC.ts +++ b/packages/cc/src/cc/NodeNamingCC.ts @@ -30,13 +30,13 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -46,9 +46,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { NodeNamingAndLocationCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { NodeNamingAndLocationCommand } from "../lib/_Types.js"; export const NodeNamingAndLocationCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Node Naming and Location"], { diff --git a/packages/cc/src/cc/NotificationCC.ts b/packages/cc/src/cc/NotificationCC.ts index 5143a9f9134f..b0058fae4481 100644 --- a/packages/cc/src/cc/NotificationCC.ts +++ b/packages/cc/src/cc/NotificationCC.ts @@ -48,14 +48,14 @@ import type { import { Bytes, isUint8Array } from "@zwave-js/shared/safe"; import { buffer2hex, num2hex, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { isArray } from "alcalzone-shared/typeguards"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; import { CCAPI, POLL_VALUE, PhysicalCCAPI, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { CCRaw, CommandClass, @@ -64,7 +64,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -74,12 +74,12 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { isNotificationEventPayload } from "../lib/NotificationEventPayload"; -import { V } from "../lib/Values"; -import { NotificationCommand, UserCodeCommand } from "../lib/_Types"; -import * as ccUtils from "../lib/utils"; -import { AssociationGroupInfoCC } from "./AssociationGroupInfoCC"; +} from "../lib/CommandClassDecorators.js"; +import { isNotificationEventPayload } from "../lib/NotificationEventPayload.js"; +import { V } from "../lib/Values.js"; +import { NotificationCommand, UserCodeCommand } from "../lib/_Types.js"; +import * as ccUtils from "../lib/utils.js"; +import { AssociationGroupInfoCC } from "./AssociationGroupInfoCC.js"; export const NotificationCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Notification, { diff --git a/packages/cc/src/cc/PowerlevelCC.ts b/packages/cc/src/cc/PowerlevelCC.ts index 6d8dc7756eea..11242d9fd97d 100644 --- a/packages/cc/src/cc/PowerlevelCC.ts +++ b/packages/cc/src/cc/PowerlevelCC.ts @@ -18,8 +18,8 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { PhysicalCCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { PhysicalCCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, @@ -27,12 +27,12 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { Powerlevel, PowerlevelCommand, PowerlevelTestStatus, -} from "../lib/_Types"; +} from "../lib/_Types.js"; @API(CommandClasses.Powerlevel) export class PowerlevelCCAPI extends PhysicalCCAPI { diff --git a/packages/cc/src/cc/ProtectionCC.ts b/packages/cc/src/cc/ProtectionCC.ts index 30b9905c0ff1..e16671eca8cf 100644 --- a/packages/cc/src/cc/ProtectionCC.ts +++ b/packages/cc/src/cc/ProtectionCC.ts @@ -23,7 +23,7 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import { CCAPI, POLL_VALUE, @@ -32,7 +32,7 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -40,7 +40,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -50,13 +50,13 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { LocalProtectionState, ProtectionCommand, RFProtectionState, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const ProtectionCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Protection, { diff --git a/packages/cc/src/cc/SceneActivationCC.ts b/packages/cc/src/cc/SceneActivationCC.ts index 5500fb3dc225..293e2f8f6698 100644 --- a/packages/cc/src/cc/SceneActivationCC.ts +++ b/packages/cc/src/cc/SceneActivationCC.ts @@ -24,8 +24,8 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +} from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, @@ -34,9 +34,9 @@ import { commandClass, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { SceneActivationCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { SceneActivationCommand } from "../lib/_Types.js"; export const SceneActivationCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Scene Activation"], { diff --git a/packages/cc/src/cc/SceneActuatorConfigurationCC.ts b/packages/cc/src/cc/SceneActuatorConfigurationCC.ts index eb941c974003..bb06990b02c9 100644 --- a/packages/cc/src/cc/SceneActuatorConfigurationCC.ts +++ b/packages/cc/src/cc/SceneActuatorConfigurationCC.ts @@ -30,13 +30,13 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -45,9 +45,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { SceneActuatorConfigurationCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { SceneActuatorConfigurationCommand } from "../lib/_Types.js"; export const SceneActuatorConfigurationCCValues = Object.freeze({ ...V.defineDynamicCCValues(CommandClasses["Scene Actuator Configuration"], { diff --git a/packages/cc/src/cc/SceneControllerConfigurationCC.ts b/packages/cc/src/cc/SceneControllerConfigurationCC.ts index f2a35633e53b..30639005207e 100644 --- a/packages/cc/src/cc/SceneControllerConfigurationCC.ts +++ b/packages/cc/src/cc/SceneControllerConfigurationCC.ts @@ -32,14 +32,14 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -48,10 +48,10 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { SceneControllerConfigurationCommand } from "../lib/_Types"; -import { AssociationCC } from "./AssociationCC"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { SceneControllerConfigurationCommand } from "../lib/_Types.js"; +import { AssociationCC } from "./AssociationCC.js"; export const SceneControllerConfigurationCCValues = Object.freeze({ ...V.defineDynamicCCValues( diff --git a/packages/cc/src/cc/ScheduleEntryLockCC.ts b/packages/cc/src/cc/ScheduleEntryLockCC.ts index d88bd4b8b61e..83144af72add 100644 --- a/packages/cc/src/cc/ScheduleEntryLockCC.ts +++ b/packages/cc/src/cc/ScheduleEntryLockCC.ts @@ -28,13 +28,13 @@ import { pick, } from "@zwave-js/shared"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI } from "../lib/API"; +import { CCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -44,8 +44,8 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { ScheduleEntryLockCommand, type ScheduleEntryLockDailyRepeatingSchedule, @@ -56,9 +56,9 @@ import { ScheduleEntryLockWeekday, type ScheduleEntryLockYearDaySchedule, type Timezone, -} from "../lib/_Types"; -import { encodeTimezone, parseTimezone } from "../lib/serializers"; -import { UserCodeCC } from "./UserCodeCC"; +} from "../lib/_Types.js"; +import { encodeTimezone, parseTimezone } from "../lib/serializers.js"; +import { UserCodeCC } from "./UserCodeCC.js"; export const ScheduleEntryLockCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Schedule Entry Lock"], { diff --git a/packages/cc/src/cc/Security2CC.ts b/packages/cc/src/cc/Security2CC.ts index 9db2b1edeb0f..c20ce644b3ca 100644 --- a/packages/cc/src/cc/Security2CC.ts +++ b/packages/cc/src/cc/Security2CC.ts @@ -44,22 +44,22 @@ import type { } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { buffer2hex, getEnumMemberName, pick } from "@zwave-js/shared/safe"; -import { wait } from "alcalzone-shared/async"; -import { isArray } from "alcalzone-shared/typeguards"; -import { CCAPI } from "../lib/API"; +import { wait } from "alcalzone-shared/async/index.js"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; +import { CCAPI } from "../lib/API.js"; import { type CCRaw, type CCResponseRole, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { MGRPExtension, MOSExtension, @@ -68,13 +68,17 @@ import { Security2Extension, ValidateS2ExtensionResult, validateS2Extension, -} from "../lib/Security2/Extension"; -import { ECDHProfiles, KEXFailType, KEXSchemes } from "../lib/Security2/shared"; -import { Security2Command } from "../lib/_Types"; -import { CRC16CC } from "./CRC16CC"; -import { MultiChannelCC } from "./MultiChannelCC"; -import { SecurityCC } from "./SecurityCC"; -import { TransportServiceCC } from "./TransportServiceCC"; +} from "../lib/Security2/Extension.js"; +import { + ECDHProfiles, + KEXFailType, + KEXSchemes, +} from "../lib/Security2/shared.js"; +import { Security2Command } from "../lib/_Types.js"; +import { CRC16CC } from "./CRC16CC.js"; +import { MultiChannelCC } from "./MultiChannelCC.js"; +import { SecurityCC } from "./SecurityCC.js"; +import { TransportServiceCC } from "./TransportServiceCC.js"; function securityClassToBitMask(key: SecurityClass): Bytes { return encodeBitMask( diff --git a/packages/cc/src/cc/SecurityCC.ts b/packages/cc/src/cc/SecurityCC.ts index 1da38047f43f..0497aeb766f0 100644 --- a/packages/cc/src/cc/SecurityCC.ts +++ b/packages/cc/src/cc/SecurityCC.ts @@ -29,25 +29,25 @@ import type { } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { buffer2hex, num2hex, pick } from "@zwave-js/shared/safe"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import { randomBytes } from "node:crypto"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { SecurityCommand } from "../lib/_Types"; -import { CRC16CC } from "./CRC16CC"; -import { Security2CC } from "./Security2CC"; -import { TransportServiceCC } from "./TransportServiceCC"; +} from "../lib/CommandClassDecorators.js"; +import { SecurityCommand } from "../lib/_Types.js"; +import { CRC16CC } from "./CRC16CC.js"; +import { Security2CC } from "./Security2CC.js"; +import { TransportServiceCC } from "./TransportServiceCC.js"; // @noSetValueAPI This is an encapsulation CC diff --git a/packages/cc/src/cc/SoundSwitchCC.ts b/packages/cc/src/cc/SoundSwitchCC.ts index 840f00e7dab5..1c503ecac43b 100644 --- a/packages/cc/src/cc/SoundSwitchCC.ts +++ b/packages/cc/src/cc/SoundSwitchCC.ts @@ -20,7 +20,7 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { clamp } from "alcalzone-shared/math"; +import { clamp } from "alcalzone-shared/math/index.js"; import { CCAPI, POLL_VALUE, @@ -29,13 +29,13 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, type CCResponsePredicate, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -45,9 +45,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { SoundSwitchCommand, type ToneId } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { SoundSwitchCommand, type ToneId } from "../lib/_Types.js"; export const SoundSwitchCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Sound Switch"], { diff --git a/packages/cc/src/cc/SupervisionCC.ts b/packages/cc/src/cc/SupervisionCC.ts index 25321e381fc1..1de7326d4457 100644 --- a/packages/cc/src/cc/SupervisionCC.ts +++ b/packages/cc/src/cc/SupervisionCC.ts @@ -28,8 +28,8 @@ import type { } from "@zwave-js/host/safe"; import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName } from "@zwave-js/shared/safe"; -import { PhysicalCCAPI } from "../lib/API"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { PhysicalCCAPI } from "../lib/API.js"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { API, CCCommand, @@ -37,9 +37,9 @@ import { expectedCCResponse, implementedVersion, shouldUseSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { SupervisionCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { SupervisionCommand } from "../lib/_Types.js"; export const SupervisionCCValues = Object.freeze({ ...V.defineDynamicCCValues(CommandClasses.Supervision, { diff --git a/packages/cc/src/cc/ThermostatFanModeCC.ts b/packages/cc/src/cc/ThermostatFanModeCC.ts index 2dfaf45dfca6..514297a4b204 100644 --- a/packages/cc/src/cc/ThermostatFanModeCC.ts +++ b/packages/cc/src/cc/ThermostatFanModeCC.ts @@ -30,14 +30,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -47,9 +47,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { ThermostatFanMode, ThermostatFanModeCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { ThermostatFanMode, ThermostatFanModeCommand } from "../lib/_Types.js"; export const ThermostatFanModeCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Thermostat Fan Mode"], { diff --git a/packages/cc/src/cc/ThermostatFanStateCC.ts b/packages/cc/src/cc/ThermostatFanStateCC.ts index 52eccf068a2d..ea8325577786 100644 --- a/packages/cc/src/cc/ThermostatFanStateCC.ts +++ b/packages/cc/src/cc/ThermostatFanStateCC.ts @@ -16,13 +16,13 @@ import { POLL_VALUE, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -31,9 +31,12 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { ThermostatFanState, ThermostatFanStateCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { + ThermostatFanState, + ThermostatFanStateCommand, +} from "../lib/_Types.js"; export const ThermostatFanStateCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Thermostat Fan State"], { diff --git a/packages/cc/src/cc/ThermostatModeCC.ts b/packages/cc/src/cc/ThermostatModeCC.ts index e8e09adb793a..efef3642a9b6 100644 --- a/packages/cc/src/cc/ThermostatModeCC.ts +++ b/packages/cc/src/cc/ThermostatModeCC.ts @@ -31,14 +31,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -48,9 +48,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { ThermostatMode, ThermostatModeCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { ThermostatMode, ThermostatModeCommand } from "../lib/_Types.js"; export const ThermostatModeCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Thermostat Mode"], { diff --git a/packages/cc/src/cc/ThermostatOperatingStateCC.ts b/packages/cc/src/cc/ThermostatOperatingStateCC.ts index 3987e436fedf..93a0c5f0c8ea 100644 --- a/packages/cc/src/cc/ThermostatOperatingStateCC.ts +++ b/packages/cc/src/cc/ThermostatOperatingStateCC.ts @@ -15,13 +15,13 @@ import { PhysicalCCAPI, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -30,12 +30,12 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { ThermostatOperatingState, ThermostatOperatingStateCommand, -} from "../lib/_Types"; +} from "../lib/_Types.js"; export const ThermostatOperatingStateCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Thermostat Operating State"], { diff --git a/packages/cc/src/cc/ThermostatSetbackCC.ts b/packages/cc/src/cc/ThermostatSetbackCC.ts index 01a77c607459..1f4c926bdb04 100644 --- a/packages/cc/src/cc/ThermostatSetbackCC.ts +++ b/packages/cc/src/cc/ThermostatSetbackCC.ts @@ -20,13 +20,13 @@ import { POLL_VALUE, type PollValueImplementation, throwUnsupportedProperty, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -34,13 +34,13 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { type SetbackState, SetbackType, ThermostatSetbackCommand, -} from "../lib/_Types"; -import { decodeSetbackState, encodeSetbackState } from "../lib/serializers"; +} from "../lib/_Types.js"; +import { decodeSetbackState, encodeSetbackState } from "../lib/serializers.js"; // @noSetValueAPI // The setback state consist of two values that must be set together diff --git a/packages/cc/src/cc/ThermostatSetpointCC.ts b/packages/cc/src/cc/ThermostatSetpointCC.ts index 2297a9f7363b..d1cebcbf73f9 100644 --- a/packages/cc/src/cc/ThermostatSetpointCC.ts +++ b/packages/cc/src/cc/ThermostatSetpointCC.ts @@ -35,14 +35,14 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -52,12 +52,12 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { ThermostatSetpointCommand, ThermostatSetpointType, -} from "../lib/_Types"; +} from "../lib/_Types.js"; // This array is used to map the advertised supported types (interpretation A) // to the actual enum values diff --git a/packages/cc/src/cc/TimeCC.ts b/packages/cc/src/cc/TimeCC.ts index a6f0899f522a..dc21bd2617d8 100644 --- a/packages/cc/src/cc/TimeCC.ts +++ b/packages/cc/src/cc/TimeCC.ts @@ -20,13 +20,13 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { padStart } from "alcalzone-shared/strings"; -import { CCAPI } from "../lib/API"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import { CCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -34,9 +34,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { TimeCommand } from "../lib/_Types"; -import { encodeTimezone, parseTimezone } from "../lib/serializers"; +} from "../lib/CommandClassDecorators.js"; +import { TimeCommand } from "../lib/_Types.js"; +import { encodeTimezone, parseTimezone } from "../lib/serializers.js"; // @noSetValueAPI // Only the timezone information can be set and that accepts a non-primitive value diff --git a/packages/cc/src/cc/TimeParametersCC.ts b/packages/cc/src/cc/TimeParametersCC.ts index b458086f2bea..3b49f245f209 100644 --- a/packages/cc/src/cc/TimeParametersCC.ts +++ b/packages/cc/src/cc/TimeParametersCC.ts @@ -30,13 +30,13 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -46,9 +46,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { TimeParametersCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { TimeParametersCommand } from "../lib/_Types.js"; export const TimeParametersCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Time Parameters"], { diff --git a/packages/cc/src/cc/TransportServiceCC.ts b/packages/cc/src/cc/TransportServiceCC.ts index a5df23ce0fd0..e7098f84ce63 100644 --- a/packages/cc/src/cc/TransportServiceCC.ts +++ b/packages/cc/src/cc/TransportServiceCC.ts @@ -19,14 +19,14 @@ import { type CCRaw, type CCResponseRole, CommandClass, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { CCCommand, commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { TransportServiceCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { TransportServiceCommand } from "../lib/_Types.js"; export const MAX_SEGMENT_SIZE = 39; diff --git a/packages/cc/src/cc/UserCodeCC.ts b/packages/cc/src/cc/UserCodeCC.ts index 9ed1717f1dad..0b8b5ffe5173 100644 --- a/packages/cc/src/cc/UserCodeCC.ts +++ b/packages/cc/src/cc/UserCodeCC.ts @@ -42,7 +42,7 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, @@ -50,7 +50,7 @@ import { type PersistValuesContext, type RefreshValuesContext, getEffectiveCCVersion, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -60,10 +60,10 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import type { NotificationEventPayload } from "../lib/NotificationEventPayload"; -import { V } from "../lib/Values"; -import { KeypadMode, UserCodeCommand, UserIDStatus } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import type { NotificationEventPayload } from "../lib/NotificationEventPayload.js"; +import { V } from "../lib/Values.js"; +import { KeypadMode, UserCodeCommand, UserIDStatus } from "../lib/_Types.js"; export const UserCodeCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["User Code"], { diff --git a/packages/cc/src/cc/VersionCC.ts b/packages/cc/src/cc/VersionCC.ts index 15241644b307..4a108216c304 100644 --- a/packages/cc/src/cc/VersionCC.ts +++ b/packages/cc/src/cc/VersionCC.ts @@ -24,12 +24,12 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, num2hex, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -39,9 +39,9 @@ import { expectedCCResponse, getImplementedVersion, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { VersionCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { VersionCommand } from "../lib/_Types.js"; export const VersionCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses.Version, { diff --git a/packages/cc/src/cc/WakeUpCC.ts b/packages/cc/src/cc/WakeUpCC.ts index 58f73ac5898a..e3c6fed9544d 100644 --- a/packages/cc/src/cc/WakeUpCC.ts +++ b/packages/cc/src/cc/WakeUpCC.ts @@ -18,7 +18,7 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { clamp } from "alcalzone-shared/math"; +import { clamp } from "alcalzone-shared/math/index.js"; import { CCAPI, POLL_VALUE, @@ -27,13 +27,13 @@ import { type SetValueImplementation, throwUnsupportedProperty, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, type PersistValuesContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -43,9 +43,9 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; -import { WakeUpCommand } from "../lib/_Types"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; +import { WakeUpCommand } from "../lib/_Types.js"; export const WakeUpCCValues = Object.freeze({ ...V.defineStaticCCValues(CommandClasses["Wake Up"], { diff --git a/packages/cc/src/cc/WindowCoveringCC.ts b/packages/cc/src/cc/WindowCoveringCC.ts index b471311e58bb..4a6e63ae1088 100644 --- a/packages/cc/src/cc/WindowCoveringCC.ts +++ b/packages/cc/src/cc/WindowCoveringCC.ts @@ -32,12 +32,12 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../lib/API"; +} from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -47,13 +47,13 @@ import { expectedCCResponse, implementedVersion, useSupervision, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { type LevelChangeDirection, WindowCoveringCommand, WindowCoveringParameter, -} from "../lib/_Types"; +} from "../lib/_Types.js"; function parameterToMetadataStates( parameter: WindowCoveringParameter, diff --git a/packages/cc/src/cc/ZWaveLongRangeCC.ts b/packages/cc/src/cc/ZWaveLongRangeCC.ts index 2c09895a2801..460dab6389ae 100644 --- a/packages/cc/src/cc/ZWaveLongRangeCC.ts +++ b/packages/cc/src/cc/ZWaveLongRangeCC.ts @@ -1,9 +1,9 @@ import { CommandClasses } from "@zwave-js/core"; -import { CommandClass } from "../lib/CommandClass"; +import { CommandClass } from "../lib/CommandClass.js"; import { commandClass, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; @commandClass(CommandClasses["Z-Wave Long Range"]) @implementedVersion(1) diff --git a/packages/cc/src/cc/ZWavePlusCC.ts b/packages/cc/src/cc/ZWavePlusCC.ts index 4db72a190cbf..205d8032e67a 100644 --- a/packages/cc/src/cc/ZWavePlusCC.ts +++ b/packages/cc/src/cc/ZWavePlusCC.ts @@ -14,12 +14,12 @@ import type { import { Bytes } from "@zwave-js/shared/safe"; import { getEnumMemberName, num2hex, pick } from "@zwave-js/shared/safe"; import { validateArgs } from "@zwave-js/transformers"; -import { CCAPI, PhysicalCCAPI } from "../lib/API"; +import { CCAPI, PhysicalCCAPI } from "../lib/API.js"; import { type CCRaw, CommandClass, type InterviewContext, -} from "../lib/CommandClass"; +} from "../lib/CommandClass.js"; import { API, CCCommand, @@ -28,13 +28,13 @@ import { commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; -import { V } from "../lib/Values"; +} from "../lib/CommandClassDecorators.js"; +import { V } from "../lib/Values.js"; import { ZWavePlusCommand, ZWavePlusNodeType, ZWavePlusRoleType, -} from "../lib/_Types"; +} from "../lib/_Types.js"; // SDS13782 The advertised Z-Wave Plus Version, Role Type and Node Type information values // MUST be identical for the Root Device and all Multi Channel End Points diff --git a/packages/cc/src/cc/ZWaveProtocolCC.ts b/packages/cc/src/cc/ZWaveProtocolCC.ts index 26c32ca1212d..d2b0a7b0d45f 100644 --- a/packages/cc/src/cc/ZWaveProtocolCC.ts +++ b/packages/cc/src/cc/ZWaveProtocolCC.ts @@ -23,19 +23,19 @@ import { } from "@zwave-js/core"; import type { CCEncodingContext, CCParsingContext } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import { type CCRaw, CommandClass } from "../lib/CommandClass"; +import { type CCRaw, CommandClass } from "../lib/CommandClass.js"; import { CCCommand, commandClass, expectedCCResponse, implementedVersion, -} from "../lib/CommandClassDecorators"; +} from "../lib/CommandClassDecorators.js"; import { type NetworkTransferStatus, WakeUpTime, ZWaveProtocolCommand, parseWakeUpTime, -} from "../lib/_Types"; +} from "../lib/_Types.js"; enum DataRateBitmask { "9k6" = 0b001, diff --git a/packages/cc/src/cc/index.ts b/packages/cc/src/cc/index.ts index 459dff05b456..481160696285 100644 --- a/packages/cc/src/cc/index.ts +++ b/packages/cc/src/cc/index.ts @@ -5,7 +5,7 @@ export type { AlarmSensorCCGetOptions, AlarmSensorCCReportOptions, AlarmSensorCCSupportedReportOptions, -} from "./AlarmSensorCC"; +} from "./AlarmSensorCC.js"; export { AlarmSensorCC, AlarmSensorCCGet, @@ -13,7 +13,7 @@ export { AlarmSensorCCSupportedGet, AlarmSensorCCSupportedReport, AlarmSensorCCValues, -} from "./AlarmSensorCC"; +} from "./AlarmSensorCC.js"; export type { AssociationCCGetOptions, AssociationCCRemoveOptions, @@ -21,7 +21,7 @@ export type { AssociationCCSetOptions, AssociationCCSpecificGroupReportOptions, AssociationCCSupportedGroupingsReportOptions, -} from "./AssociationCC"; +} from "./AssociationCC.js"; export { AssociationCC, AssociationCCGet, @@ -33,7 +33,7 @@ export { AssociationCCSupportedGroupingsGet, AssociationCCSupportedGroupingsReport, AssociationCCValues, -} from "./AssociationCC"; +} from "./AssociationCC.js"; export type { AssociationGroupInfoCCCommandListGetOptions, AssociationGroupInfoCCCommandListReportOptions, @@ -41,7 +41,7 @@ export type { AssociationGroupInfoCCInfoReportOptions, AssociationGroupInfoCCNameGetOptions, AssociationGroupInfoCCNameReportOptions, -} from "./AssociationGroupInfoCC"; +} from "./AssociationGroupInfoCC.js"; export { AssociationGroupInfoCC, AssociationGroupInfoCCCommandListGet, @@ -51,7 +51,7 @@ export { AssociationGroupInfoCCNameGet, AssociationGroupInfoCCNameReport, AssociationGroupInfoCCValues, -} from "./AssociationGroupInfoCC"; +} from "./AssociationGroupInfoCC.js"; export type { BarrierOperatorCCEventSignalingGetOptions, BarrierOperatorCCEventSignalingReportOptions, @@ -59,7 +59,7 @@ export type { BarrierOperatorCCReportOptions, BarrierOperatorCCSetOptions, BarrierOperatorCCSignalingCapabilitiesReportOptions, -} from "./BarrierOperatorCC"; +} from "./BarrierOperatorCC.js"; export { BarrierOperatorCC, BarrierOperatorCCEventSignalingGet, @@ -71,19 +71,19 @@ export { BarrierOperatorCCSignalingCapabilitiesGet, BarrierOperatorCCSignalingCapabilitiesReport, BarrierOperatorCCValues, -} from "./BarrierOperatorCC"; -export type { BasicCCReportOptions, BasicCCSetOptions } from "./BasicCC"; +} from "./BarrierOperatorCC.js"; +export type { BasicCCReportOptions, BasicCCSetOptions } from "./BasicCC.js"; export { BasicCC, BasicCCGet, BasicCCReport, BasicCCSet, BasicCCValues, -} from "./BasicCC"; +} from "./BasicCC.js"; export type { BatteryCCHealthReportOptions, BatteryCCReportOptions, -} from "./BatteryCC"; +} from "./BatteryCC.js"; export { BatteryCC, BatteryCCGet, @@ -91,12 +91,12 @@ export { BatteryCCHealthReport, BatteryCCReport, BatteryCCValues, -} from "./BatteryCC"; +} from "./BatteryCC.js"; export type { BinarySensorCCGetOptions, BinarySensorCCReportOptions, BinarySensorCCSupportedReportOptions, -} from "./BinarySensorCC"; +} from "./BinarySensorCC.js"; export { BinarySensorCC, BinarySensorCCGet, @@ -104,26 +104,26 @@ export { BinarySensorCCSupportedGet, BinarySensorCCSupportedReport, BinarySensorCCValues, -} from "./BinarySensorCC"; +} from "./BinarySensorCC.js"; export type { BinarySwitchCCReportOptions, BinarySwitchCCSetOptions, -} from "./BinarySwitchCC"; +} from "./BinarySwitchCC.js"; export { BinarySwitchCC, BinarySwitchCCGet, BinarySwitchCCReport, BinarySwitchCCSet, BinarySwitchCCValues, -} from "./BinarySwitchCC"; -export type { CRC16CCCommandEncapsulationOptions } from "./CRC16CC"; -export { CRC16CC, CRC16CCCommandEncapsulation } from "./CRC16CC"; +} from "./BinarySwitchCC.js"; +export type { CRC16CCCommandEncapsulationOptions } from "./CRC16CC.js"; +export { CRC16CC, CRC16CCCommandEncapsulation } from "./CRC16CC.js"; export type { CentralSceneCCConfigurationReportOptions, CentralSceneCCConfigurationSetOptions, CentralSceneCCNotificationOptions, CentralSceneCCSupportedReportOptions, -} from "./CentralSceneCC"; +} from "./CentralSceneCC.js"; export { CentralSceneCC, CentralSceneCCConfigurationGet, @@ -133,7 +133,7 @@ export { CentralSceneCCSupportedGet, CentralSceneCCSupportedReport, CentralSceneCCValues, -} from "./CentralSceneCC"; +} from "./CentralSceneCC.js"; export type { ClimateControlScheduleCCChangedReportOptions, ClimateControlScheduleCCGetOptions, @@ -141,7 +141,7 @@ export type { ClimateControlScheduleCCOverrideSetOptions, ClimateControlScheduleCCReportOptions, ClimateControlScheduleCCSetOptions, -} from "./ClimateControlScheduleCC"; +} from "./ClimateControlScheduleCC.js"; export { ClimateControlScheduleCC, ClimateControlScheduleCCChangedGet, @@ -153,9 +153,9 @@ export { ClimateControlScheduleCCReport, ClimateControlScheduleCCSet, ClimateControlScheduleCCValues, -} from "./ClimateControlScheduleCC"; -export type { ClockCCReportOptions, ClockCCSetOptions } from "./ClockCC"; -export { ClockCC, ClockCCGet, ClockCCReport, ClockCCSet } from "./ClockCC"; +} from "./ClimateControlScheduleCC.js"; +export type { ClockCCReportOptions, ClockCCSetOptions } from "./ClockCC.js"; +export { ClockCC, ClockCCGet, ClockCCReport, ClockCCSet } from "./ClockCC.js"; export type { ColorSwitchCCGetOptions, ColorSwitchCCReportOptions, @@ -163,7 +163,7 @@ export type { ColorSwitchCCStartLevelChangeOptions, ColorSwitchCCStopLevelChangeOptions, ColorSwitchCCSupportedReportOptions, -} from "./ColorSwitchCC"; +} from "./ColorSwitchCC.js"; export { ColorSwitchCC, ColorSwitchCCGet, @@ -174,7 +174,7 @@ export { ColorSwitchCCSupportedGet, ColorSwitchCCSupportedReport, ColorSwitchCCValues, -} from "./ColorSwitchCC"; +} from "./ColorSwitchCC.js"; export type { ConfigurationCCAPISetOptions, ConfigurationCCBulkGetOptions, @@ -186,7 +186,7 @@ export type { ConfigurationCCPropertiesReportOptions, ConfigurationCCReportOptions, ConfigurationCCSetOptions, -} from "./ConfigurationCC"; +} from "./ConfigurationCC.js"; export { ConfigurationCC, ConfigurationCCBulkGet, @@ -203,18 +203,18 @@ export { ConfigurationCCReport, ConfigurationCCSet, ConfigurationCCValues, -} from "./ConfigurationCC"; +} from "./ConfigurationCC.js"; export { DeviceResetLocallyCC, DeviceResetLocallyCCNotification, -} from "./DeviceResetLocallyCC"; +} from "./DeviceResetLocallyCC.js"; export type { DoorLockCCCapabilitiesReportOptions, DoorLockCCConfigurationReportOptions, DoorLockCCConfigurationSetOptions, DoorLockCCOperationReportOptions, DoorLockCCOperationSetOptions, -} from "./DoorLockCC"; +} from "./DoorLockCC.js"; export { DoorLockCC, DoorLockCCCapabilitiesGet, @@ -226,12 +226,12 @@ export { DoorLockCCOperationReport, DoorLockCCOperationSet, DoorLockCCValues, -} from "./DoorLockCC"; +} from "./DoorLockCC.js"; export type { DoorLockLoggingCCRecordGetOptions, DoorLockLoggingCCRecordReportOptions, DoorLockLoggingCCRecordsSupportedReportOptions, -} from "./DoorLockLoggingCC"; +} from "./DoorLockLoggingCC.js"; export { DoorLockLoggingCC, DoorLockLoggingCCRecordGet, @@ -239,24 +239,24 @@ export { DoorLockLoggingCCRecordsSupportedGet, DoorLockLoggingCCRecordsSupportedReport, DoorLockLoggingCCValues, -} from "./DoorLockLoggingCC"; +} from "./DoorLockLoggingCC.js"; export type { EnergyProductionCCGetOptions, EnergyProductionCCReportOptions, -} from "./EnergyProductionCC"; +} from "./EnergyProductionCC.js"; export { EnergyProductionCC, EnergyProductionCCGet, EnergyProductionCCReport, EnergyProductionCCValues, -} from "./EnergyProductionCC"; +} from "./EnergyProductionCC.js"; export type { EntryControlCCConfigurationReportOptions, EntryControlCCConfigurationSetOptions, EntryControlCCEventSupportedReportOptions, EntryControlCCKeySupportedReportOptions, EntryControlCCNotificationOptions, -} from "./EntryControlCC"; +} from "./EntryControlCC.js"; export { EntryControlCC, EntryControlCCConfigurationGet, @@ -268,7 +268,7 @@ export { EntryControlCCKeySupportedReport, EntryControlCCNotification, EntryControlCCValues, -} from "./EntryControlCC"; +} from "./EntryControlCC.js"; export type { FirmwareUpdateMetaDataCCActivationReportOptions, FirmwareUpdateMetaDataCCActivationSetOptions, @@ -280,7 +280,7 @@ export type { FirmwareUpdateMetaDataCCRequestGetOptions, FirmwareUpdateMetaDataCCRequestReportOptions, FirmwareUpdateMetaDataCCStatusReportOptions, -} from "./FirmwareUpdateMetaDataCC"; +} from "./FirmwareUpdateMetaDataCC.js"; export { FirmwareUpdateMetaDataCC, FirmwareUpdateMetaDataCCActivationReport, @@ -295,13 +295,13 @@ export { FirmwareUpdateMetaDataCCRequestReport, FirmwareUpdateMetaDataCCStatusReport, FirmwareUpdateMetaDataCCValues, -} from "./FirmwareUpdateMetaDataCC"; -export { HailCC } from "./HailCC"; +} from "./FirmwareUpdateMetaDataCC.js"; +export { HailCC } from "./HailCC.js"; export type { HumidityControlModeCCReportOptions, HumidityControlModeCCSetOptions, HumidityControlModeCCSupportedReportOptions, -} from "./HumidityControlModeCC"; +} from "./HumidityControlModeCC.js"; export { HumidityControlModeCC, HumidityControlModeCCGet, @@ -310,14 +310,14 @@ export { HumidityControlModeCCSupportedGet, HumidityControlModeCCSupportedReport, HumidityControlModeCCValues, -} from "./HumidityControlModeCC"; -export type { HumidityControlOperatingStateCCReportOptions } from "./HumidityControlOperatingStateCC"; +} from "./HumidityControlModeCC.js"; +export type { HumidityControlOperatingStateCCReportOptions } from "./HumidityControlOperatingStateCC.js"; export { HumidityControlOperatingStateCC, HumidityControlOperatingStateCCGet, HumidityControlOperatingStateCCReport, HumidityControlOperatingStateCCValues, -} from "./HumidityControlOperatingStateCC"; +} from "./HumidityControlOperatingStateCC.js"; export type { HumidityControlSetpointCCCapabilitiesGetOptions, HumidityControlSetpointCCCapabilitiesReportOptions, @@ -327,7 +327,7 @@ export type { HumidityControlSetpointCCScaleSupportedReportOptions, HumidityControlSetpointCCSetOptions, HumidityControlSetpointCCSupportedReportOptions, -} from "./HumidityControlSetpointCC"; +} from "./HumidityControlSetpointCC.js"; export { HumidityControlSetpointCC, HumidityControlSetpointCCCapabilitiesGet, @@ -340,16 +340,16 @@ export { HumidityControlSetpointCCSupportedGet, HumidityControlSetpointCCSupportedReport, HumidityControlSetpointCCValues, -} from "./HumidityControlSetpointCC"; +} from "./HumidityControlSetpointCC.js"; export type { InclusionControllerCCCompleteOptions, InclusionControllerCCInitiateOptions, -} from "./InclusionControllerCC"; +} from "./InclusionControllerCC.js"; export { InclusionControllerCC, InclusionControllerCCComplete, InclusionControllerCCInitiate, -} from "./InclusionControllerCC"; +} from "./InclusionControllerCC.js"; export type { IndicatorCCDescriptionGetOptions, IndicatorCCDescriptionReportOptions, @@ -359,7 +359,7 @@ export type { IndicatorCCSupportedGetOptions, IndicatorCCSupportedReportOptions, IndicatorObject, -} from "./IndicatorCC"; +} from "./IndicatorCC.js"; export { IndicatorCC, IndicatorCCDescriptionGet, @@ -370,7 +370,7 @@ export { IndicatorCCSupportedGet, IndicatorCCSupportedReport, IndicatorCCValues, -} from "./IndicatorCC"; +} from "./IndicatorCC.js"; export type { IrrigationCCSystemConfigReportOptions, IrrigationCCSystemConfigSetOptions, @@ -387,7 +387,7 @@ export type { IrrigationCCValveTableReportOptions, IrrigationCCValveTableRunOptions, IrrigationCCValveTableSetOptions, -} from "./IrrigationCC"; +} from "./IrrigationCC.js"; export { IrrigationCC, IrrigationCCSystemConfigGet, @@ -409,33 +409,33 @@ export { IrrigationCCValveTableReport, IrrigationCCValveTableRun, IrrigationCCValveTableSet, -} from "./IrrigationCC"; +} from "./IrrigationCC.js"; export type { LanguageCCReportOptions, LanguageCCSetOptions, -} from "./LanguageCC"; +} from "./LanguageCC.js"; export { LanguageCC, LanguageCCGet, LanguageCCReport, LanguageCCSet, LanguageCCValues, -} from "./LanguageCC"; -export type { LockCCReportOptions, LockCCSetOptions } from "./LockCC"; +} from "./LanguageCC.js"; +export type { LockCCReportOptions, LockCCSetOptions } from "./LockCC.js"; export { LockCC, LockCCGet, LockCCReport, LockCCSet, LockCCValues, -} from "./LockCC"; -export type { ManufacturerProprietaryCCOptions } from "./ManufacturerProprietaryCC"; -export { ManufacturerProprietaryCC } from "./ManufacturerProprietaryCC"; +} from "./LockCC.js"; +export type { ManufacturerProprietaryCCOptions } from "./ManufacturerProprietaryCC.js"; +export { ManufacturerProprietaryCC } from "./ManufacturerProprietaryCC.js"; export type { ManufacturerSpecificCCDeviceSpecificGetOptions, ManufacturerSpecificCCDeviceSpecificReportOptions, ManufacturerSpecificCCReportOptions, -} from "./ManufacturerSpecificCC"; +} from "./ManufacturerSpecificCC.js"; export { ManufacturerSpecificCC, ManufacturerSpecificCCDeviceSpecificGet, @@ -443,13 +443,13 @@ export { ManufacturerSpecificCCGet, ManufacturerSpecificCCReport, ManufacturerSpecificCCValues, -} from "./ManufacturerSpecificCC"; +} from "./ManufacturerSpecificCC.js"; export type { MeterCCGetOptions, MeterCCReportOptions, MeterCCResetOptions, MeterCCSupportedReportOptions, -} from "./MeterCC"; +} from "./MeterCC.js"; export { MeterCC, MeterCCGet, @@ -458,14 +458,14 @@ export { MeterCCSupportedGet, MeterCCSupportedReport, MeterCCValues, -} from "./MeterCC"; +} from "./MeterCC.js"; export type { MultiChannelAssociationCCGetOptions, MultiChannelAssociationCCRemoveOptions, MultiChannelAssociationCCReportOptions, MultiChannelAssociationCCSetOptions, MultiChannelAssociationCCSupportedGroupingsReportOptions, -} from "./MultiChannelAssociationCC"; +} from "./MultiChannelAssociationCC.js"; export { MultiChannelAssociationCC, MultiChannelAssociationCCGet, @@ -475,7 +475,7 @@ export { MultiChannelAssociationCCSupportedGroupingsGet, MultiChannelAssociationCCSupportedGroupingsReport, MultiChannelAssociationCCValues, -} from "./MultiChannelAssociationCC"; +} from "./MultiChannelAssociationCC.js"; export type { MultiChannelCCAggregatedMembersGetOptions, MultiChannelCCAggregatedMembersReportOptions, @@ -488,7 +488,7 @@ export type { MultiChannelCCV1CommandEncapsulationOptions, MultiChannelCCV1GetOptions, MultiChannelCCV1ReportOptions, -} from "./MultiChannelCC"; +} from "./MultiChannelCC.js"; export { MultiChannelCC, MultiChannelCCAggregatedMembersGet, @@ -504,19 +504,19 @@ export { MultiChannelCCV1Get, MultiChannelCCV1Report, MultiChannelCCValues, -} from "./MultiChannelCC"; -export type { MultiCommandCCCommandEncapsulationOptions } from "./MultiCommandCC"; +} from "./MultiChannelCC.js"; +export type { MultiCommandCCCommandEncapsulationOptions } from "./MultiCommandCC.js"; export { MultiCommandCC, MultiCommandCCCommandEncapsulation, -} from "./MultiCommandCC"; +} from "./MultiCommandCC.js"; export type { MultilevelSensorCCGetOptions, MultilevelSensorCCGetSupportedScaleOptions, MultilevelSensorCCReportOptions, MultilevelSensorCCSupportedScaleReportOptions, MultilevelSensorCCSupportedSensorReportOptions, -} from "./MultilevelSensorCC"; +} from "./MultilevelSensorCC.js"; export { MultilevelSensorCC, MultilevelSensorCCGet, @@ -526,13 +526,13 @@ export { MultilevelSensorCCSupportedScaleReport, MultilevelSensorCCSupportedSensorReport, MultilevelSensorCCValues, -} from "./MultilevelSensorCC"; +} from "./MultilevelSensorCC.js"; export type { MultilevelSwitchCCReportOptions, MultilevelSwitchCCSetOptions, MultilevelSwitchCCStartLevelChangeOptions, MultilevelSwitchCCSupportedReportOptions, -} from "./MultilevelSwitchCC"; +} from "./MultilevelSwitchCC.js"; export { MultilevelSwitchCC, MultilevelSwitchCCGet, @@ -543,14 +543,14 @@ export { MultilevelSwitchCCSupportedGet, MultilevelSwitchCCSupportedReport, MultilevelSwitchCCValues, -} from "./MultilevelSwitchCC"; -export { NoOperationCC } from "./NoOperationCC"; +} from "./MultilevelSwitchCC.js"; +export { NoOperationCC } from "./NoOperationCC.js"; export type { NodeNamingAndLocationCCLocationReportOptions, NodeNamingAndLocationCCLocationSetOptions, NodeNamingAndLocationCCNameReportOptions, NodeNamingAndLocationCCNameSetOptions, -} from "./NodeNamingCC"; +} from "./NodeNamingCC.js"; export { NodeNamingAndLocationCC, NodeNamingAndLocationCCLocationGet, @@ -560,7 +560,7 @@ export { NodeNamingAndLocationCCNameReport, NodeNamingAndLocationCCNameSet, NodeNamingAndLocationCCValues, -} from "./NodeNamingCC"; +} from "./NodeNamingCC.js"; export type { NotificationCCEventSupportedGetOptions, NotificationCCEventSupportedReportOptions, @@ -568,7 +568,7 @@ export type { NotificationCCReportOptions, NotificationCCSetOptions, NotificationCCSupportedReportOptions, -} from "./NotificationCC"; +} from "./NotificationCC.js"; export { NotificationCC, NotificationCCEventSupportedGet, @@ -579,13 +579,13 @@ export { NotificationCCSupportedGet, NotificationCCSupportedReport, NotificationCCValues, -} from "./NotificationCC"; +} from "./NotificationCC.js"; export type { PowerlevelCCReportOptions, PowerlevelCCSetOptions, PowerlevelCCTestNodeReportOptions, PowerlevelCCTestNodeSetOptions, -} from "./PowerlevelCC"; +} from "./PowerlevelCC.js"; export { PowerlevelCC, PowerlevelCCGet, @@ -594,7 +594,7 @@ export { PowerlevelCCTestNodeGet, PowerlevelCCTestNodeReport, PowerlevelCCTestNodeSet, -} from "./PowerlevelCC"; +} from "./PowerlevelCC.js"; export type { ProtectionCCExclusiveControlReportOptions, ProtectionCCExclusiveControlSetOptions, @@ -603,7 +603,7 @@ export type { ProtectionCCSupportedReportOptions, ProtectionCCTimeoutReportOptions, ProtectionCCTimeoutSetOptions, -} from "./ProtectionCC"; +} from "./ProtectionCC.js"; export { ProtectionCC, ProtectionCCExclusiveControlGet, @@ -618,37 +618,37 @@ export { ProtectionCCTimeoutReport, ProtectionCCTimeoutSet, ProtectionCCValues, -} from "./ProtectionCC"; -export type { SceneActivationCCSetOptions } from "./SceneActivationCC"; +} from "./ProtectionCC.js"; +export type { SceneActivationCCSetOptions } from "./SceneActivationCC.js"; export { SceneActivationCC, SceneActivationCCSet, SceneActivationCCValues, -} from "./SceneActivationCC"; +} from "./SceneActivationCC.js"; export type { SceneActuatorConfigurationCCGetOptions, SceneActuatorConfigurationCCReportOptions, SceneActuatorConfigurationCCSetOptions, -} from "./SceneActuatorConfigurationCC"; +} from "./SceneActuatorConfigurationCC.js"; export { SceneActuatorConfigurationCC, SceneActuatorConfigurationCCGet, SceneActuatorConfigurationCCReport, SceneActuatorConfigurationCCSet, SceneActuatorConfigurationCCValues, -} from "./SceneActuatorConfigurationCC"; +} from "./SceneActuatorConfigurationCC.js"; export type { SceneControllerConfigurationCCGetOptions, SceneControllerConfigurationCCReportOptions, SceneControllerConfigurationCCSetOptions, -} from "./SceneControllerConfigurationCC"; +} from "./SceneControllerConfigurationCC.js"; export { SceneControllerConfigurationCC, SceneControllerConfigurationCCGet, SceneControllerConfigurationCCReport, SceneControllerConfigurationCCSet, SceneControllerConfigurationCCValues, -} from "./SceneControllerConfigurationCC"; +} from "./SceneControllerConfigurationCC.js"; export type { ScheduleEntryLockCCDailyRepeatingScheduleGetOptions, ScheduleEntryLockCCDailyRepeatingScheduleReportOptions, @@ -664,7 +664,7 @@ export type { ScheduleEntryLockCCYearDayScheduleGetOptions, ScheduleEntryLockCCYearDayScheduleReportOptions, ScheduleEntryLockCCYearDayScheduleSetOptions, -} from "./ScheduleEntryLockCC"; +} from "./ScheduleEntryLockCC.js"; export { ScheduleEntryLockCC, ScheduleEntryLockCCDailyRepeatingScheduleGet, @@ -684,7 +684,7 @@ export { ScheduleEntryLockCCYearDayScheduleGet, ScheduleEntryLockCCYearDayScheduleReport, ScheduleEntryLockCCYearDayScheduleSet, -} from "./ScheduleEntryLockCC"; +} from "./ScheduleEntryLockCC.js"; export type { DecryptionResult, MulticastContext, @@ -699,7 +699,7 @@ export type { Security2CCNonceReportOptions, Security2CCPublicKeyReportOptions, Security2CCTransferEndOptions, -} from "./Security2CC"; +} from "./Security2CC.js"; export { Security2CC, Security2CCCommandsSupportedGet, @@ -716,12 +716,12 @@ export { Security2CCNonceReport, Security2CCPublicKeyReport, Security2CCTransferEnd, -} from "./Security2CC"; +} from "./Security2CC.js"; export type { SecurityCCCommandEncapsulationOptions, SecurityCCCommandsSupportedReportOptions, SecurityCCNetworkKeySetOptions, -} from "./SecurityCC"; +} from "./SecurityCC.js"; export { SecurityCC, SecurityCCCommandEncapsulation, @@ -735,7 +735,7 @@ export { SecurityCCSchemeGet, SecurityCCSchemeInherit, SecurityCCSchemeReport, -} from "./SecurityCC"; +} from "./SecurityCC.js"; export type { SoundSwitchCCConfigurationReportOptions, SoundSwitchCCConfigurationSetOptions, @@ -744,7 +744,7 @@ export type { SoundSwitchCCTonePlayReportOptions, SoundSwitchCCTonePlaySetOptions, SoundSwitchCCTonesNumberReportOptions, -} from "./SoundSwitchCC"; +} from "./SoundSwitchCC.js"; export { SoundSwitchCC, SoundSwitchCCConfigurationGet, @@ -758,22 +758,22 @@ export { SoundSwitchCCTonesNumberGet, SoundSwitchCCTonesNumberReport, SoundSwitchCCValues, -} from "./SoundSwitchCC"; +} from "./SoundSwitchCC.js"; export type { SupervisionCCGetOptions, SupervisionCCReportOptions, -} from "./SupervisionCC"; +} from "./SupervisionCC.js"; export { SupervisionCC, SupervisionCCGet, SupervisionCCReport, SupervisionCCValues, -} from "./SupervisionCC"; +} from "./SupervisionCC.js"; export type { ThermostatFanModeCCReportOptions, ThermostatFanModeCCSetOptions, ThermostatFanModeCCSupportedReportOptions, -} from "./ThermostatFanModeCC"; +} from "./ThermostatFanModeCC.js"; export { ThermostatFanModeCC, ThermostatFanModeCCGet, @@ -782,19 +782,19 @@ export { ThermostatFanModeCCSupportedGet, ThermostatFanModeCCSupportedReport, ThermostatFanModeCCValues, -} from "./ThermostatFanModeCC"; -export type { ThermostatFanStateCCReportOptions } from "./ThermostatFanStateCC"; +} from "./ThermostatFanModeCC.js"; +export type { ThermostatFanStateCCReportOptions } from "./ThermostatFanStateCC.js"; export { ThermostatFanStateCC, ThermostatFanStateCCGet, ThermostatFanStateCCReport, ThermostatFanStateCCValues, -} from "./ThermostatFanStateCC"; +} from "./ThermostatFanStateCC.js"; export type { ThermostatModeCCReportOptions, ThermostatModeCCSetOptions, ThermostatModeCCSupportedReportOptions, -} from "./ThermostatModeCC"; +} from "./ThermostatModeCC.js"; export { ThermostatModeCC, ThermostatModeCCGet, @@ -803,24 +803,24 @@ export { ThermostatModeCCSupportedGet, ThermostatModeCCSupportedReport, ThermostatModeCCValues, -} from "./ThermostatModeCC"; -export type { ThermostatOperatingStateCCReportOptions } from "./ThermostatOperatingStateCC"; +} from "./ThermostatModeCC.js"; +export type { ThermostatOperatingStateCCReportOptions } from "./ThermostatOperatingStateCC.js"; export { ThermostatOperatingStateCC, ThermostatOperatingStateCCGet, ThermostatOperatingStateCCReport, ThermostatOperatingStateCCValues, -} from "./ThermostatOperatingStateCC"; +} from "./ThermostatOperatingStateCC.js"; export type { ThermostatSetbackCCReportOptions, ThermostatSetbackCCSetOptions, -} from "./ThermostatSetbackCC"; +} from "./ThermostatSetbackCC.js"; export { ThermostatSetbackCC, ThermostatSetbackCCGet, ThermostatSetbackCCReport, ThermostatSetbackCCSet, -} from "./ThermostatSetbackCC"; +} from "./ThermostatSetbackCC.js"; export type { ThermostatSetpointCCCapabilitiesGetOptions, ThermostatSetpointCCCapabilitiesReportOptions, @@ -828,7 +828,7 @@ export type { ThermostatSetpointCCReportOptions, ThermostatSetpointCCSetOptions, ThermostatSetpointCCSupportedReportOptions, -} from "./ThermostatSetpointCC"; +} from "./ThermostatSetpointCC.js"; export { ThermostatSetpointCC, ThermostatSetpointCCCapabilitiesGet, @@ -839,13 +839,13 @@ export { ThermostatSetpointCCSupportedGet, ThermostatSetpointCCSupportedReport, ThermostatSetpointCCValues, -} from "./ThermostatSetpointCC"; +} from "./ThermostatSetpointCC.js"; export type { TimeCCDateReportOptions, TimeCCTimeOffsetReportOptions, TimeCCTimeOffsetSetOptions, TimeCCTimeReportOptions, -} from "./TimeCC"; +} from "./TimeCC.js"; export { TimeCC, TimeCCDateGet, @@ -855,25 +855,25 @@ export { TimeCCTimeOffsetReport, TimeCCTimeOffsetSet, TimeCCTimeReport, -} from "./TimeCC"; +} from "./TimeCC.js"; export type { TimeParametersCCReportOptions, TimeParametersCCSetOptions, -} from "./TimeParametersCC"; +} from "./TimeParametersCC.js"; export { TimeParametersCC, TimeParametersCCGet, TimeParametersCCReport, TimeParametersCCSet, TimeParametersCCValues, -} from "./TimeParametersCC"; +} from "./TimeParametersCC.js"; export type { TransportServiceCCFirstSegmentOptions, TransportServiceCCSegmentCompleteOptions, TransportServiceCCSegmentRequestOptions, TransportServiceCCSegmentWaitOptions, TransportServiceCCSubsequentSegmentOptions, -} from "./TransportServiceCC"; +} from "./TransportServiceCC.js"; export { TransportServiceCC, TransportServiceCCFirstSegment, @@ -883,7 +883,7 @@ export { TransportServiceCCSubsequentSegment, TransportServiceTimeouts, isTransportServiceEncapsulation, -} from "./TransportServiceCC"; +} from "./TransportServiceCC.js"; export type { UserCodeCCAdminCodeReportOptions, UserCodeCCAdminCodeSetOptions, @@ -898,7 +898,7 @@ export type { UserCodeCCSetOptions, UserCodeCCUserCodeChecksumReportOptions, UserCodeCCUsersNumberReportOptions, -} from "./UserCodeCC"; +} from "./UserCodeCC.js"; export { UserCodeCC, UserCodeCCAdminCodeGet, @@ -920,14 +920,14 @@ export { UserCodeCCUsersNumberGet, UserCodeCCUsersNumberReport, UserCodeCCValues, -} from "./UserCodeCC"; +} from "./UserCodeCC.js"; export type { VersionCCCapabilitiesReportOptions, VersionCCCommandClassGetOptions, VersionCCCommandClassReportOptions, VersionCCReportOptions, VersionCCZWaveSoftwareReportOptions, -} from "./VersionCC"; +} from "./VersionCC.js"; export { VersionCC, VersionCCCapabilitiesGet, @@ -939,12 +939,12 @@ export { VersionCCValues, VersionCCZWaveSoftwareGet, VersionCCZWaveSoftwareReport, -} from "./VersionCC"; +} from "./VersionCC.js"; export type { WakeUpCCIntervalCapabilitiesReportOptions, WakeUpCCIntervalReportOptions, WakeUpCCIntervalSetOptions, -} from "./WakeUpCC"; +} from "./WakeUpCC.js"; export { WakeUpCC, WakeUpCCIntervalCapabilitiesGet, @@ -955,7 +955,7 @@ export { WakeUpCCNoMoreInformation, WakeUpCCValues, WakeUpCCWakeUpNotification, -} from "./WakeUpCC"; +} from "./WakeUpCC.js"; export type { WindowCoveringCCGetOptions, WindowCoveringCCReportOptions, @@ -963,7 +963,7 @@ export type { WindowCoveringCCStartLevelChangeOptions, WindowCoveringCCStopLevelChangeOptions, WindowCoveringCCSupportedReportOptions, -} from "./WindowCoveringCC"; +} from "./WindowCoveringCC.js"; export { WindowCoveringCC, WindowCoveringCCGet, @@ -974,15 +974,15 @@ export { WindowCoveringCCSupportedGet, WindowCoveringCCSupportedReport, WindowCoveringCCValues, -} from "./WindowCoveringCC"; -export { ZWaveLongRangeCC } from "./ZWaveLongRangeCC"; -export type { ZWavePlusCCReportOptions } from "./ZWavePlusCC"; +} from "./WindowCoveringCC.js"; +export { ZWaveLongRangeCC } from "./ZWaveLongRangeCC.js"; +export type { ZWavePlusCCReportOptions } from "./ZWavePlusCC.js"; export { ZWavePlusCC, ZWavePlusCCGet, ZWavePlusCCReport, ZWavePlusCCValues, -} from "./ZWavePlusCC"; +} from "./ZWavePlusCC.js"; export type { ZWaveProtocolCCAcceptLostOptions, ZWaveProtocolCCAssignIDsOptions, @@ -1011,7 +1011,7 @@ export type { ZWaveProtocolCCTransferNodeInformationOptions, ZWaveProtocolCCTransferPresentationOptions, ZWaveProtocolCCTransferRangeInformationOptions, -} from "./ZWaveProtocolCC"; +} from "./ZWaveProtocolCC.js"; export { ZWaveProtocolCC, ZWaveProtocolCCAcceptLost, @@ -1049,7 +1049,7 @@ export { ZWaveProtocolCCTransferNodeInformation, ZWaveProtocolCCTransferPresentation, ZWaveProtocolCCTransferRangeInformation, -} from "./ZWaveProtocolCC"; +} from "./ZWaveProtocolCC.js"; export { fibaroCC, fibaroCCCommand, @@ -1063,15 +1063,15 @@ export { getManufacturerProprietaryCCConstructor, manufacturerId, manufacturerProprietaryAPI, -} from "./manufacturerProprietary/Decorators"; +} from "./manufacturerProprietary/Decorators.js"; export type { FibaroVenetianBlindCCReportOptions, FibaroVenetianBlindCCSetOptions, -} from "./manufacturerProprietary/FibaroCC"; +} from "./manufacturerProprietary/FibaroCC.js"; export { FibaroCC, FibaroVenetianBlindCC, FibaroVenetianBlindCCGet, FibaroVenetianBlindCCReport, FibaroVenetianBlindCCSet, -} from "./manufacturerProprietary/FibaroCC"; +} from "./manufacturerProprietary/FibaroCC.js"; diff --git a/packages/cc/src/cc/manufacturerProprietary/Decorators.ts b/packages/cc/src/cc/manufacturerProprietary/Decorators.ts index 1d7329517cbc..7ef80eef59ad 100644 --- a/packages/cc/src/cc/manufacturerProprietary/Decorators.ts +++ b/packages/cc/src/cc/manufacturerProprietary/Decorators.ts @@ -4,13 +4,13 @@ import { createReflectionDecoratorPair, createSimpleReflectionDecorator, } from "@zwave-js/core"; -import type { APIConstructor, CCAPI } from "../../lib/API"; +import type { APIConstructor, CCAPI } from "../../lib/API.js"; import type { ManufacturerProprietaryCC, ManufacturerProprietaryCCAPI, ManufacturerProprietaryCCConstructor, -} from "../ManufacturerProprietaryCC"; -import type { FibaroCC } from "./FibaroCC"; +} from "../ManufacturerProprietaryCC.js"; +import type { FibaroCC } from "./FibaroCC.js"; // === Define the manufacturer ID for a given Manufacturer Proprietary CC subclass diff --git a/packages/cc/src/cc/manufacturerProprietary/FibaroCC.ts b/packages/cc/src/cc/manufacturerProprietary/FibaroCC.ts index 9b90f9fc4268..544ceb300193 100644 --- a/packages/cc/src/cc/manufacturerProprietary/FibaroCC.ts +++ b/packages/cc/src/cc/manufacturerProprietary/FibaroCC.ts @@ -19,7 +19,7 @@ import type { } from "@zwave-js/host/safe"; import { Bytes, pick } from "@zwave-js/shared"; import { validateArgs } from "@zwave-js/transformers"; -import { isArray } from "alcalzone-shared/typeguards"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; import { POLL_VALUE, type PollValueImplementation, @@ -29,19 +29,19 @@ import { throwUnsupportedProperty, throwUnsupportedPropertyKey, throwWrongValueType, -} from "../../lib/API"; +} from "../../lib/API.js"; import { type CCRaw, type CommandClassOptions, type InterviewContext, type PersistValuesContext, type RefreshValuesContext, -} from "../../lib/CommandClass"; -import { expectedCCResponse } from "../../lib/CommandClassDecorators"; +} from "../../lib/CommandClass.js"; +import { expectedCCResponse } from "../../lib/CommandClassDecorators.js"; import { ManufacturerProprietaryCC, ManufacturerProprietaryCCAPI, -} from "../ManufacturerProprietaryCC"; +} from "../ManufacturerProprietaryCC.js"; import { fibaroCC, fibaroCCCommand, @@ -51,7 +51,7 @@ import { getFibaroCCId, manufacturerId, manufacturerProprietaryAPI, -} from "./Decorators"; +} from "./Decorators.js"; export const MANUFACTURERID_FIBARO = 0x10f; diff --git a/packages/cc/src/index.ts b/packages/cc/src/index.ts index c87f1b0b4cc5..643da4bf4f46 100644 --- a/packages/cc/src/index.ts +++ b/packages/cc/src/index.ts @@ -1,11 +1,11 @@ import "reflect-metadata"; -import * as utils from "./lib/utils"; +import * as utils from "./lib/utils.js"; -export * from "./cc/index"; -export * from "./lib/API"; -export * from "./lib/CommandClass"; -export * from "./lib/CommandClassDecorators"; -export * from "./lib/EncapsulatingCommandClass"; +export * from "./cc/index.js"; +export * from "./lib/API.js"; +export * from "./lib/CommandClass.js"; +export * from "./lib/CommandClassDecorators.js"; +export * from "./lib/EncapsulatingCommandClass.js"; export { MGRPExtension, MOSExtension, @@ -15,14 +15,14 @@ export { extensionType, getExtensionType, getS2ExtensionConstructor, -} from "./lib/Security2/Extension"; -export * from "./lib/Security2/shared"; -export * from "./lib/SetValueResult"; -export { defaultCCValueOptions } from "./lib/Values"; +} from "./lib/Security2/Extension.js"; +export * from "./lib/Security2/shared.js"; +export * from "./lib/SetValueResult.js"; +export { defaultCCValueOptions } from "./lib/Values.js"; export type { CCValueOptions, CCValuePredicate, PartialCCValuePredicate, -} from "./lib/Values"; -export * from "./lib/_Types"; +} from "./lib/Values.js"; +export * from "./lib/_Types.js"; export { utils }; diff --git a/packages/cc/src/index_safe.ts b/packages/cc/src/index_safe.ts index 6f93e56311b2..99eb5834d53d 100644 --- a/packages/cc/src/index_safe.ts +++ b/packages/cc/src/index_safe.ts @@ -1,4 +1,4 @@ /* @forbiddenImports external */ -export * from "./lib/SetValueResult"; -export * from "./lib/_Types"; +export * from "./lib/SetValueResult.js"; +export * from "./lib/_Types.js"; diff --git a/packages/cc/src/lib/API.ts b/packages/cc/src/lib/API.ts index 29bde3de01aa..e746573dc605 100644 --- a/packages/cc/src/lib/API.ts +++ b/packages/cc/src/lib/API.ts @@ -47,14 +47,14 @@ import { getErrorMessage, num2hex, } from "@zwave-js/shared"; -import { isArray } from "alcalzone-shared/typeguards"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; import { getAPI, getCCValues, getCommandClass, getImplementedVersion, -} from "./CommandClassDecorators"; -import { type CCValue, type StaticCCValue } from "./Values"; +} from "./CommandClassDecorators.js"; +import { type CCValue, type StaticCCValue } from "./Values.js"; export type ValueIDProperties = Pick; @@ -955,89 +955,92 @@ export interface CCAPIs { [Symbol.iterator](): Iterator; // AUTO GENERATION BELOW - "Alarm Sensor": import("../cc/AlarmSensorCC").AlarmSensorCCAPI; - Association: import("../cc/AssociationCC").AssociationCCAPI; + "Alarm Sensor": import("../cc/AlarmSensorCC.js").AlarmSensorCCAPI; + Association: import("../cc/AssociationCC.js").AssociationCCAPI; "Association Group Information": - import("../cc/AssociationGroupInfoCC").AssociationGroupInfoCCAPI; - "Barrier Operator": import("../cc/BarrierOperatorCC").BarrierOperatorCCAPI; - Basic: import("../cc/BasicCC").BasicCCAPI; - Battery: import("../cc/BatteryCC").BatteryCCAPI; - "Binary Sensor": import("../cc/BinarySensorCC").BinarySensorCCAPI; - "Binary Switch": import("../cc/BinarySwitchCC").BinarySwitchCCAPI; - "CRC-16 Encapsulation": import("../cc/CRC16CC").CRC16CCAPI; - "Central Scene": import("../cc/CentralSceneCC").CentralSceneCCAPI; + import("../cc/AssociationGroupInfoCC.js").AssociationGroupInfoCCAPI; + "Barrier Operator": + import("../cc/BarrierOperatorCC.js").BarrierOperatorCCAPI; + Basic: import("../cc/BasicCC.js").BasicCCAPI; + Battery: import("../cc/BatteryCC.js").BatteryCCAPI; + "Binary Sensor": import("../cc/BinarySensorCC.js").BinarySensorCCAPI; + "Binary Switch": import("../cc/BinarySwitchCC.js").BinarySwitchCCAPI; + "CRC-16 Encapsulation": import("../cc/CRC16CC.js").CRC16CCAPI; + "Central Scene": import("../cc/CentralSceneCC.js").CentralSceneCCAPI; "Climate Control Schedule": - import("../cc/ClimateControlScheduleCC").ClimateControlScheduleCCAPI; - Clock: import("../cc/ClockCC").ClockCCAPI; - "Color Switch": import("../cc/ColorSwitchCC").ColorSwitchCCAPI; - Configuration: import("../cc/ConfigurationCC").ConfigurationCCAPI; + import("../cc/ClimateControlScheduleCC.js").ClimateControlScheduleCCAPI; + Clock: import("../cc/ClockCC.js").ClockCCAPI; + "Color Switch": import("../cc/ColorSwitchCC.js").ColorSwitchCCAPI; + Configuration: import("../cc/ConfigurationCC.js").ConfigurationCCAPI; "Device Reset Locally": - import("../cc/DeviceResetLocallyCC").DeviceResetLocallyCCAPI; - "Door Lock": import("../cc/DoorLockCC").DoorLockCCAPI; - "Door Lock Logging": import("../cc/DoorLockLoggingCC").DoorLockLoggingCCAPI; + import("../cc/DeviceResetLocallyCC.js").DeviceResetLocallyCCAPI; + "Door Lock": import("../cc/DoorLockCC.js").DoorLockCCAPI; + "Door Lock Logging": + import("../cc/DoorLockLoggingCC.js").DoorLockLoggingCCAPI; "Energy Production": - import("../cc/EnergyProductionCC").EnergyProductionCCAPI; - "Entry Control": import("../cc/EntryControlCC").EntryControlCCAPI; + import("../cc/EnergyProductionCC.js").EnergyProductionCCAPI; + "Entry Control": import("../cc/EntryControlCC.js").EntryControlCCAPI; "Firmware Update Meta Data": - import("../cc/FirmwareUpdateMetaDataCC").FirmwareUpdateMetaDataCCAPI; + import("../cc/FirmwareUpdateMetaDataCC.js").FirmwareUpdateMetaDataCCAPI; "Humidity Control Mode": - import("../cc/HumidityControlModeCC").HumidityControlModeCCAPI; + import("../cc/HumidityControlModeCC.js").HumidityControlModeCCAPI; "Humidity Control Operating State": - import("../cc/HumidityControlOperatingStateCC").HumidityControlOperatingStateCCAPI; + import("../cc/HumidityControlOperatingStateCC.js").HumidityControlOperatingStateCCAPI; "Humidity Control Setpoint": - import("../cc/HumidityControlSetpointCC").HumidityControlSetpointCCAPI; + import("../cc/HumidityControlSetpointCC.js").HumidityControlSetpointCCAPI; "Inclusion Controller": - import("../cc/InclusionControllerCC").InclusionControllerCCAPI; - Indicator: import("../cc/IndicatorCC").IndicatorCCAPI; - Irrigation: import("../cc/IrrigationCC").IrrigationCCAPI; - Language: import("../cc/LanguageCC").LanguageCCAPI; - Lock: import("../cc/LockCC").LockCCAPI; + import("../cc/InclusionControllerCC.js").InclusionControllerCCAPI; + Indicator: import("../cc/IndicatorCC.js").IndicatorCCAPI; + Irrigation: import("../cc/IrrigationCC.js").IrrigationCCAPI; + Language: import("../cc/LanguageCC.js").LanguageCCAPI; + Lock: import("../cc/LockCC.js").LockCCAPI; "Manufacturer Proprietary": - import("../cc/ManufacturerProprietaryCC").ManufacturerProprietaryCCAPI; + import("../cc/ManufacturerProprietaryCC.js").ManufacturerProprietaryCCAPI; "Manufacturer Specific": - import("../cc/ManufacturerSpecificCC").ManufacturerSpecificCCAPI; - Meter: import("../cc/MeterCC").MeterCCAPI; + import("../cc/ManufacturerSpecificCC.js").ManufacturerSpecificCCAPI; + Meter: import("../cc/MeterCC.js").MeterCCAPI; "Multi Channel Association": - import("../cc/MultiChannelAssociationCC").MultiChannelAssociationCCAPI; - "Multi Channel": import("../cc/MultiChannelCC").MultiChannelCCAPI; - "Multi Command": import("../cc/MultiCommandCC").MultiCommandCCAPI; + import("../cc/MultiChannelAssociationCC.js").MultiChannelAssociationCCAPI; + "Multi Channel": import("../cc/MultiChannelCC.js").MultiChannelCCAPI; + "Multi Command": import("../cc/MultiCommandCC.js").MultiCommandCCAPI; "Multilevel Sensor": - import("../cc/MultilevelSensorCC").MultilevelSensorCCAPI; + import("../cc/MultilevelSensorCC.js").MultilevelSensorCCAPI; "Multilevel Switch": - import("../cc/MultilevelSwitchCC").MultilevelSwitchCCAPI; - "No Operation": import("../cc/NoOperationCC").NoOperationCCAPI; + import("../cc/MultilevelSwitchCC.js").MultilevelSwitchCCAPI; + "No Operation": import("../cc/NoOperationCC.js").NoOperationCCAPI; "Node Naming and Location": - import("../cc/NodeNamingCC").NodeNamingAndLocationCCAPI; - Notification: import("../cc/NotificationCC").NotificationCCAPI; - Powerlevel: import("../cc/PowerlevelCC").PowerlevelCCAPI; - Protection: import("../cc/ProtectionCC").ProtectionCCAPI; - "Scene Activation": import("../cc/SceneActivationCC").SceneActivationCCAPI; + import("../cc/NodeNamingCC.js").NodeNamingAndLocationCCAPI; + Notification: import("../cc/NotificationCC.js").NotificationCCAPI; + Powerlevel: import("../cc/PowerlevelCC.js").PowerlevelCCAPI; + Protection: import("../cc/ProtectionCC.js").ProtectionCCAPI; + "Scene Activation": + import("../cc/SceneActivationCC.js").SceneActivationCCAPI; "Scene Actuator Configuration": - import("../cc/SceneActuatorConfigurationCC").SceneActuatorConfigurationCCAPI; + import("../cc/SceneActuatorConfigurationCC.js").SceneActuatorConfigurationCCAPI; "Scene Controller Configuration": - import("../cc/SceneControllerConfigurationCC").SceneControllerConfigurationCCAPI; + import("../cc/SceneControllerConfigurationCC.js").SceneControllerConfigurationCCAPI; "Schedule Entry Lock": - import("../cc/ScheduleEntryLockCC").ScheduleEntryLockCCAPI; - "Security 2": import("../cc/Security2CC").Security2CCAPI; - Security: import("../cc/SecurityCC").SecurityCCAPI; - "Sound Switch": import("../cc/SoundSwitchCC").SoundSwitchCCAPI; - Supervision: import("../cc/SupervisionCC").SupervisionCCAPI; + import("../cc/ScheduleEntryLockCC.js").ScheduleEntryLockCCAPI; + "Security 2": import("../cc/Security2CC.js").Security2CCAPI; + Security: import("../cc/SecurityCC.js").SecurityCCAPI; + "Sound Switch": import("../cc/SoundSwitchCC.js").SoundSwitchCCAPI; + Supervision: import("../cc/SupervisionCC.js").SupervisionCCAPI; "Thermostat Fan Mode": - import("../cc/ThermostatFanModeCC").ThermostatFanModeCCAPI; + import("../cc/ThermostatFanModeCC.js").ThermostatFanModeCCAPI; "Thermostat Fan State": - import("../cc/ThermostatFanStateCC").ThermostatFanStateCCAPI; - "Thermostat Mode": import("../cc/ThermostatModeCC").ThermostatModeCCAPI; + import("../cc/ThermostatFanStateCC.js").ThermostatFanStateCCAPI; + "Thermostat Mode": import("../cc/ThermostatModeCC.js").ThermostatModeCCAPI; "Thermostat Operating State": - import("../cc/ThermostatOperatingStateCC").ThermostatOperatingStateCCAPI; + import("../cc/ThermostatOperatingStateCC.js").ThermostatOperatingStateCCAPI; "Thermostat Setback": - import("../cc/ThermostatSetbackCC").ThermostatSetbackCCAPI; + import("../cc/ThermostatSetbackCC.js").ThermostatSetbackCCAPI; "Thermostat Setpoint": - import("../cc/ThermostatSetpointCC").ThermostatSetpointCCAPI; - Time: import("../cc/TimeCC").TimeCCAPI; - "Time Parameters": import("../cc/TimeParametersCC").TimeParametersCCAPI; - "User Code": import("../cc/UserCodeCC").UserCodeCCAPI; - Version: import("../cc/VersionCC").VersionCCAPI; - "Wake Up": import("../cc/WakeUpCC").WakeUpCCAPI; - "Window Covering": import("../cc/WindowCoveringCC").WindowCoveringCCAPI; - "Z-Wave Plus Info": import("../cc/ZWavePlusCC").ZWavePlusCCAPI; + import("../cc/ThermostatSetpointCC.js").ThermostatSetpointCCAPI; + Time: import("../cc/TimeCC.js").TimeCCAPI; + "Time Parameters": import("../cc/TimeParametersCC.js").TimeParametersCCAPI; + "User Code": import("../cc/UserCodeCC.js").UserCodeCCAPI; + Version: import("../cc/VersionCC.js").VersionCCAPI; + "Wake Up": import("../cc/WakeUpCC.js").WakeUpCCAPI; + "Window Covering": import("../cc/WindowCoveringCC.js").WindowCoveringCCAPI; + "Z-Wave Plus Info": import("../cc/ZWavePlusCC.js").ZWavePlusCCAPI; } diff --git a/packages/cc/src/lib/CommandClass.ts b/packages/cc/src/lib/CommandClass.ts index 5be7e2358499..561e6af5c441 100644 --- a/packages/cc/src/lib/CommandClass.ts +++ b/packages/cc/src/lib/CommandClass.ts @@ -54,8 +54,8 @@ import { num2hex, staticExtends, } from "@zwave-js/shared"; -import { isArray } from "alcalzone-shared/typeguards"; -import type { CCAPIHost, CCAPINode, ValueIDProperties } from "./API"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; +import type { CCAPIHost, CCAPINode, ValueIDProperties } from "./API.js"; import { getCCCommand, getCCCommandConstructor, @@ -66,18 +66,18 @@ import { getCommandClass, getExpectedCCResponse, getImplementedVersion, -} from "./CommandClassDecorators"; +} from "./CommandClassDecorators.js"; import { type EncapsulatingCommandClass, isEncapsulatingCommandClass, isMultiEncapsulatingCommandClass, -} from "./EncapsulatingCommandClass"; +} from "./EncapsulatingCommandClass.js"; import { type CCValue, type DynamicCCValue, type StaticCCValue, defaultCCValueOptions, -} from "./Values"; +} from "./Values.js"; export interface CommandClassOptions extends CCAddress { ccId?: number; // Used to overwrite the declared CC ID diff --git a/packages/cc/src/lib/CommandClassDecorators.ts b/packages/cc/src/lib/CommandClassDecorators.ts index 19c97f21d300..39bd0d340940 100644 --- a/packages/cc/src/lib/CommandClassDecorators.ts +++ b/packages/cc/src/lib/CommandClassDecorators.ts @@ -10,18 +10,18 @@ import type { TypedClassDecorator, TypedPropertyDecorator, } from "@zwave-js/shared"; -import type { APIConstructor, CCAPI } from "./API"; +import type { APIConstructor, CCAPI } from "./API.js"; import type { CCConstructor, CCResponsePredicate, CommandClass, DynamicCCResponse, -} from "./CommandClass"; +} from "./CommandClass.js"; import type { DynamicCCValue, StaticCCValue, StaticCCValueFactory, -} from "./Values"; +} from "./Values.js"; const CCAndCommandDecorator = createReflectionDecoratorPair< CommandClass, diff --git a/packages/cc/src/lib/EncapsulatingCommandClass.ts b/packages/cc/src/lib/EncapsulatingCommandClass.ts index 5f9103e47682..605ad22bbb82 100644 --- a/packages/cc/src/lib/EncapsulatingCommandClass.ts +++ b/packages/cc/src/lib/EncapsulatingCommandClass.ts @@ -1,5 +1,5 @@ -import { isArray } from "alcalzone-shared/typeguards"; -import { CommandClass } from "./CommandClass"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; +import { CommandClass } from "./CommandClass.js"; export type EncapsulatedCommandClass = CommandClass & { encapsulatingCC: EncapsulatingCommandClass; diff --git a/packages/cc/src/lib/NotificationEventPayload.ts b/packages/cc/src/lib/NotificationEventPayload.ts index b4e05223cfc2..4c1d558ed5cd 100644 --- a/packages/cc/src/lib/NotificationEventPayload.ts +++ b/packages/cc/src/lib/NotificationEventPayload.ts @@ -1,5 +1,5 @@ import type { Duration } from "@zwave-js/core"; -import type { CommandClass } from "./CommandClass"; +import type { CommandClass } from "./CommandClass.js"; export interface NotificationEventPayload { toNotificationEventParameters(): diff --git a/packages/cc/src/lib/Values.test.ts b/packages/cc/src/lib/Values.test.ts index 5e8fd90b75a2..b90cc46c31e2 100644 --- a/packages/cc/src/lib/Values.test.ts +++ b/packages/cc/src/lib/Values.test.ts @@ -1,8 +1,8 @@ import { CommandClasses, ValueMetadata } from "@zwave-js/core"; import { getEnumMemberName } from "@zwave-js/shared"; -import test from "ava"; -import { V } from "./Values"; -import { AlarmSensorType } from "./_Types"; +import { test } from "vitest"; +import { V } from "./Values.js"; +import { AlarmSensorType } from "./_Types.js"; test("defineDynamicCCValues, dynamic property and meta", (t) => { const dfn = V.defineDynamicCCValues(CommandClasses.Basic, { @@ -35,66 +35,66 @@ test("defineDynamicCCValues, dynamic property and meta", (t) => { }); const actual1a = dfn.prop1("bar"); - t.deepEqual(actual1a.id, { + t.expect(actual1a.id).toStrictEqual({ commandClass: CommandClasses.Basic, property: "bar", propertyKey: "bar", }); - t.like(actual1a.meta, { + t.expect(actual1a.meta).toMatchObject({ readable: false, }); const actual1b = dfn.prop1("readable"); - t.deepEqual(actual1b.id, { + t.expect(actual1b.id).toStrictEqual({ commandClass: CommandClasses.Basic, property: "readable", propertyKey: "readable", }); - t.like(actual1b.meta, { + t.expect(actual1b.meta).toMatchObject({ readable: true, }); - t.like(dfn.prop1.options, { + t.expect(dfn.prop1.options).toMatchObject({ internal: true, secret: false, }); const actual2a = dfn.prop2("bar"); - t.deepEqual(actual2a.id, { + t.expect(actual2a.id).toStrictEqual({ commandClass: CommandClasses.Basic, property: "bar2", propertyKey: "bar2", }); - t.like(actual2a.meta, { + t.expect(actual2a.meta).toMatchObject({ writeable: true, }); const actual2b = dfn.prop2("not-writeable"); - t.deepEqual(actual2b.id, { + t.expect(actual2b.id).toStrictEqual({ commandClass: CommandClasses.Basic, property: "not-writeable2", propertyKey: "not-writeable2", }); - t.like(actual2b.meta, { + t.expect(actual2b.meta).toMatchObject({ writeable: false, }); - t.like(dfn.prop2.options, { + t.expect(dfn.prop2.options).toMatchObject({ internal: false, secret: true, }); - t.true( + t.expect( dfn.prop1.is({ commandClass: CommandClasses.Basic, property: "the same", propertyKey: "the same", }), - ); + ).toBe(true); - t.false( + t.expect( dfn.prop1.is({ commandClass: CommandClasses.Basic, property: "the same", propertyKey: "not the same", }), - ); + ).toBe(false); }); // This is a copy of the Basic CC value definitions, for resiliency @@ -109,7 +109,7 @@ const BasicCCValues = Object.freeze({ test("Basic CC, current value, no endpoint", (t) => { const actual = BasicCCValues.currentValue.id; - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ commandClass: CommandClasses.Basic, property: "currentValue", }); @@ -117,7 +117,7 @@ test("Basic CC, current value, no endpoint", (t) => { test("Basic CC, current value, endpoint 2", (t) => { const actual = BasicCCValues.currentValue.endpoint(2); - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ commandClass: CommandClasses.Basic, endpoint: 2, property: "currentValue", @@ -126,7 +126,7 @@ test("Basic CC, current value, endpoint 2", (t) => { test("Basic CC, compat event, endpoint 2", (t) => { const actual = BasicCCValues.compatEvent.endpoint(2); - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ commandClass: CommandClasses.Basic, endpoint: 2, property: "event", @@ -166,7 +166,7 @@ const AlarmSensorCCValues = Object.freeze({ test("(fake) Alarm Sensor CC, state (type 1), no endpoint", (t) => { const actual = AlarmSensorCCValues.state(1).id; - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ commandClass: CommandClasses["Alarm Sensor"], property: "state", propertyKey: 1, @@ -175,7 +175,7 @@ test("(fake) Alarm Sensor CC, state (type 1), no endpoint", (t) => { test("(fake) Alarm Sensor CC, state (type 1), endpoint 5", (t) => { const actual = AlarmSensorCCValues.state(1).endpoint(5); - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ commandClass: CommandClasses["Alarm Sensor"], endpoint: 5, property: "state", @@ -185,7 +185,7 @@ test("(fake) Alarm Sensor CC, state (type 1), endpoint 5", (t) => { test("(fake) Alarm Sensor CC, type (4), endpoint 5", (t) => { const actual = AlarmSensorCCValues.type(4).endpoint(5); - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ commandClass: CommandClasses["Alarm Sensor"], endpoint: 5, property: 4, @@ -194,7 +194,7 @@ test("(fake) Alarm Sensor CC, type (4), endpoint 5", (t) => { test("(fake) Alarm Sensor CC, dynamic metadata", (t) => { const actual = AlarmSensorCCValues.state(1).meta; - t.deepEqual(actual, { + t.expect(actual).toStrictEqual({ type: "boolean", readable: true, writeable: false, diff --git a/packages/cc/src/lib/Values.ts b/packages/cc/src/lib/Values.ts index ae4f074093b9..af6da87eeb60 100644 --- a/packages/cc/src/lib/Values.ts +++ b/packages/cc/src/lib/Values.ts @@ -10,8 +10,8 @@ import { type ReturnTypeOrStatic, evalOrStatic, } from "@zwave-js/shared/safe"; -import type { Overwrite } from "alcalzone-shared/types"; -import type { ValueIDProperties } from "./API"; +import type { Overwrite } from "alcalzone-shared/types/index.js"; +import type { ValueIDProperties } from "./API.js"; // HINT: To fully view types for definitions created by this, open // node_modules/typescript/lib/tsserver.js and change the definition of @@ -578,79 +578,85 @@ export type StaticCCValueFactory = (self: T) => StaticCCValue; // Do not edit it by hand or your changes will be lost export interface CCValues { // AUTO GENERATION BELOW - "Alarm Sensor": typeof import("../cc/AlarmSensorCC").AlarmSensorCCValues; - Association: typeof import("../cc/AssociationCC").AssociationCCValues; + "Alarm Sensor": typeof import("../cc/AlarmSensorCC.js").AlarmSensorCCValues; + Association: typeof import("../cc/AssociationCC.js").AssociationCCValues; "Association Group Information": - typeof import("../cc/AssociationGroupInfoCC").AssociationGroupInfoCCValues; + typeof import("../cc/AssociationGroupInfoCC.js").AssociationGroupInfoCCValues; "Barrier Operator": - typeof import("../cc/BarrierOperatorCC").BarrierOperatorCCValues; - Basic: typeof import("../cc/BasicCC").BasicCCValues; - Battery: typeof import("../cc/BatteryCC").BatteryCCValues; - "Binary Sensor": typeof import("../cc/BinarySensorCC").BinarySensorCCValues; - "Binary Switch": typeof import("../cc/BinarySwitchCC").BinarySwitchCCValues; - "Central Scene": typeof import("../cc/CentralSceneCC").CentralSceneCCValues; + typeof import("../cc/BarrierOperatorCC.js").BarrierOperatorCCValues; + Basic: typeof import("../cc/BasicCC.js").BasicCCValues; + Battery: typeof import("../cc/BatteryCC.js").BatteryCCValues; + "Binary Sensor": + typeof import("../cc/BinarySensorCC.js").BinarySensorCCValues; + "Binary Switch": + typeof import("../cc/BinarySwitchCC.js").BinarySwitchCCValues; + "Central Scene": + typeof import("../cc/CentralSceneCC.js").CentralSceneCCValues; "Climate Control Schedule": - typeof import("../cc/ClimateControlScheduleCC").ClimateControlScheduleCCValues; - "Color Switch": typeof import("../cc/ColorSwitchCC").ColorSwitchCCValues; - Configuration: typeof import("../cc/ConfigurationCC").ConfigurationCCValues; - "Door Lock": typeof import("../cc/DoorLockCC").DoorLockCCValues; + typeof import("../cc/ClimateControlScheduleCC.js").ClimateControlScheduleCCValues; + "Color Switch": typeof import("../cc/ColorSwitchCC.js").ColorSwitchCCValues; + Configuration: + typeof import("../cc/ConfigurationCC.js").ConfigurationCCValues; + "Door Lock": typeof import("../cc/DoorLockCC.js").DoorLockCCValues; "Door Lock Logging": - typeof import("../cc/DoorLockLoggingCC").DoorLockLoggingCCValues; + typeof import("../cc/DoorLockLoggingCC.js").DoorLockLoggingCCValues; "Energy Production": - typeof import("../cc/EnergyProductionCC").EnergyProductionCCValues; - "Entry Control": typeof import("../cc/EntryControlCC").EntryControlCCValues; + typeof import("../cc/EnergyProductionCC.js").EnergyProductionCCValues; + "Entry Control": + typeof import("../cc/EntryControlCC.js").EntryControlCCValues; "Firmware Update Meta Data": - typeof import("../cc/FirmwareUpdateMetaDataCC").FirmwareUpdateMetaDataCCValues; + typeof import("../cc/FirmwareUpdateMetaDataCC.js").FirmwareUpdateMetaDataCCValues; "Humidity Control Mode": - typeof import("../cc/HumidityControlModeCC").HumidityControlModeCCValues; + typeof import("../cc/HumidityControlModeCC.js").HumidityControlModeCCValues; "Humidity Control Operating State": - typeof import("../cc/HumidityControlOperatingStateCC").HumidityControlOperatingStateCCValues; + typeof import("../cc/HumidityControlOperatingStateCC.js").HumidityControlOperatingStateCCValues; "Humidity Control Setpoint": - typeof import("../cc/HumidityControlSetpointCC").HumidityControlSetpointCCValues; - Indicator: typeof import("../cc/IndicatorCC").IndicatorCCValues; - Irrigation: typeof import("../cc/IrrigationCC").IrrigationCCValues; - Language: typeof import("../cc/LanguageCC").LanguageCCValues; - Lock: typeof import("../cc/LockCC").LockCCValues; + typeof import("../cc/HumidityControlSetpointCC.js").HumidityControlSetpointCCValues; + Indicator: typeof import("../cc/IndicatorCC.js").IndicatorCCValues; + Irrigation: typeof import("../cc/IrrigationCC.js").IrrigationCCValues; + Language: typeof import("../cc/LanguageCC.js").LanguageCCValues; + Lock: typeof import("../cc/LockCC.js").LockCCValues; "Manufacturer Specific": - typeof import("../cc/ManufacturerSpecificCC").ManufacturerSpecificCCValues; - Meter: typeof import("../cc/MeterCC").MeterCCValues; + typeof import("../cc/ManufacturerSpecificCC.js").ManufacturerSpecificCCValues; + Meter: typeof import("../cc/MeterCC.js").MeterCCValues; "Multi Channel Association": - typeof import("../cc/MultiChannelAssociationCC").MultiChannelAssociationCCValues; - "Multi Channel": typeof import("../cc/MultiChannelCC").MultiChannelCCValues; + typeof import("../cc/MultiChannelAssociationCC.js").MultiChannelAssociationCCValues; + "Multi Channel": + typeof import("../cc/MultiChannelCC.js").MultiChannelCCValues; "Multilevel Sensor": - typeof import("../cc/MultilevelSensorCC").MultilevelSensorCCValues; + typeof import("../cc/MultilevelSensorCC.js").MultilevelSensorCCValues; "Multilevel Switch": - typeof import("../cc/MultilevelSwitchCC").MultilevelSwitchCCValues; + typeof import("../cc/MultilevelSwitchCC.js").MultilevelSwitchCCValues; "Node Naming and Location": - typeof import("../cc/NodeNamingCC").NodeNamingAndLocationCCValues; - Notification: typeof import("../cc/NotificationCC").NotificationCCValues; - Protection: typeof import("../cc/ProtectionCC").ProtectionCCValues; + typeof import("../cc/NodeNamingCC.js").NodeNamingAndLocationCCValues; + Notification: typeof import("../cc/NotificationCC.js").NotificationCCValues; + Protection: typeof import("../cc/ProtectionCC.js").ProtectionCCValues; "Scene Activation": - typeof import("../cc/SceneActivationCC").SceneActivationCCValues; + typeof import("../cc/SceneActivationCC.js").SceneActivationCCValues; "Scene Actuator Configuration": - typeof import("../cc/SceneActuatorConfigurationCC").SceneActuatorConfigurationCCValues; + typeof import("../cc/SceneActuatorConfigurationCC.js").SceneActuatorConfigurationCCValues; "Scene Controller Configuration": - typeof import("../cc/SceneControllerConfigurationCC").SceneControllerConfigurationCCValues; + typeof import("../cc/SceneControllerConfigurationCC.js").SceneControllerConfigurationCCValues; "Schedule Entry Lock": - typeof import("../cc/ScheduleEntryLockCC").ScheduleEntryLockCCValues; - "Sound Switch": typeof import("../cc/SoundSwitchCC").SoundSwitchCCValues; - Supervision: typeof import("../cc/SupervisionCC").SupervisionCCValues; + typeof import("../cc/ScheduleEntryLockCC.js").ScheduleEntryLockCCValues; + "Sound Switch": typeof import("../cc/SoundSwitchCC.js").SoundSwitchCCValues; + Supervision: typeof import("../cc/SupervisionCC.js").SupervisionCCValues; "Thermostat Fan Mode": - typeof import("../cc/ThermostatFanModeCC").ThermostatFanModeCCValues; + typeof import("../cc/ThermostatFanModeCC.js").ThermostatFanModeCCValues; "Thermostat Fan State": - typeof import("../cc/ThermostatFanStateCC").ThermostatFanStateCCValues; + typeof import("../cc/ThermostatFanStateCC.js").ThermostatFanStateCCValues; "Thermostat Mode": - typeof import("../cc/ThermostatModeCC").ThermostatModeCCValues; + typeof import("../cc/ThermostatModeCC.js").ThermostatModeCCValues; "Thermostat Operating State": - typeof import("../cc/ThermostatOperatingStateCC").ThermostatOperatingStateCCValues; + typeof import("../cc/ThermostatOperatingStateCC.js").ThermostatOperatingStateCCValues; "Thermostat Setpoint": - typeof import("../cc/ThermostatSetpointCC").ThermostatSetpointCCValues; + typeof import("../cc/ThermostatSetpointCC.js").ThermostatSetpointCCValues; "Time Parameters": - typeof import("../cc/TimeParametersCC").TimeParametersCCValues; - "User Code": typeof import("../cc/UserCodeCC").UserCodeCCValues; - Version: typeof import("../cc/VersionCC").VersionCCValues; - "Wake Up": typeof import("../cc/WakeUpCC").WakeUpCCValues; + typeof import("../cc/TimeParametersCC.js").TimeParametersCCValues; + "User Code": typeof import("../cc/UserCodeCC.js").UserCodeCCValues; + Version: typeof import("../cc/VersionCC.js").VersionCCValues; + "Wake Up": typeof import("../cc/WakeUpCC.js").WakeUpCCValues; "Window Covering": - typeof import("../cc/WindowCoveringCC").WindowCoveringCCValues; - "Z-Wave Plus Info": typeof import("../cc/ZWavePlusCC").ZWavePlusCCValues; + typeof import("../cc/WindowCoveringCC.js").WindowCoveringCCValues; + "Z-Wave Plus Info": typeof import("../cc/ZWavePlusCC.js").ZWavePlusCCValues; } diff --git a/packages/cc/src/lib/serializers.test.ts b/packages/cc/src/lib/serializers.test.ts index d4e0c715112b..beb6fcfe6b68 100644 --- a/packages/cc/src/lib/serializers.test.ts +++ b/packages/cc/src/lib/serializers.test.ts @@ -1,12 +1,12 @@ import { ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; -import test from "ava"; +import { test } from "vitest"; import { decodeSetbackState, decodeSwitchpoint, encodeSetbackState, encodeSwitchpoint, setbackSpecialStateValues, -} from "./serializers"; +} from "./serializers.js"; test("encodeSetbackState() should return the defined values for the special states", (t) => { for ( @@ -14,16 +14,15 @@ test("encodeSetbackState() should return the defined values for the special stat setbackSpecialStateValues, ) as (keyof typeof setbackSpecialStateValues)[] ) { - t.is( + t.expect( encodeSetbackState(state as any), - setbackSpecialStateValues[state], - ); + ).toBe(setbackSpecialStateValues[state]); } }); test("encodeSetbackState() should return the value times 10 otherwise", (t) => { for (const val of [0.1, 12, -12.7, 0, 5.5]) { - t.is(encodeSetbackState(val), val * 10); + t.expect(encodeSetbackState(val)).toBe(val * 10); } }); @@ -33,17 +32,19 @@ test("decodeSetbackState() should return the defined values for the special stat setbackSpecialStateValues, ) as (keyof typeof setbackSpecialStateValues)[] ) { - t.is(decodeSetbackState(setbackSpecialStateValues[state]), state); + t.expect(decodeSetbackState(setbackSpecialStateValues[state])).toBe( + state, + ); } }); test("decodeSetbackState() should return undefined if an unknown special state is passed", (t) => { - t.is(decodeSetbackState(0x7e), undefined); + t.expect(decodeSetbackState(0x7e)).toBeUndefined(); }); test("decodeSetbackState() should return the value divided by 10 otherwise", (t) => { for (const val of [1, 120, -127, 0, 55]) { - t.is(decodeSetbackState(val), val / 10); + t.expect(decodeSetbackState(val)).toBe(val / 10); } }); @@ -53,7 +54,7 @@ test("encodeSwitchpoint() should correctly encode the hour part", (t) => { state: 0, }; for (let hour = 0; hour < 24; hour++) { - t.is(encodeSwitchpoint({ ...base, hour })[0], hour); + t.expect(encodeSwitchpoint({ ...base, hour })[0]).toBe(hour); } }); @@ -63,13 +64,13 @@ test("encodeSwitchpoint() should correctly encode the minute part", (t) => { state: 0, }; for (let minute = 0; minute < 60; minute++) { - t.is(encodeSwitchpoint({ ...base, minute })[1], minute); + t.expect(encodeSwitchpoint({ ...base, minute })[1]).toBe(minute); } }); test("encodeSwitchpoint() should throw when the switchpoint state is undefined", (t) => { assertZWaveError( - t, + t.expect, () => encodeSwitchpoint({ hour: 1, minute: 5, state: undefined }), { errorCode: ZWaveErrorCodes.CC_Invalid, @@ -78,7 +79,7 @@ test("encodeSwitchpoint() should throw when the switchpoint state is undefined", }); test("decodeSwitchpoint() should work correctly", (t) => { - t.deepEqual(decodeSwitchpoint(Uint8Array.from([15, 37, 0])), { + t.expect(decodeSwitchpoint(Uint8Array.from([15, 37, 0]))).toStrictEqual({ hour: 15, minute: 37, state: 0, diff --git a/packages/cc/src/lib/serializers.ts b/packages/cc/src/lib/serializers.ts index f7ac9f79e369..a95a2649c3e5 100644 --- a/packages/cc/src/lib/serializers.ts +++ b/packages/cc/src/lib/serializers.ts @@ -1,12 +1,12 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import { clamp } from "alcalzone-shared/math"; +import { clamp } from "alcalzone-shared/math/index.js"; import type { SetbackSpecialState, SetbackState, Switchpoint, Timezone, -} from "./_Types"; +} from "./_Types.js"; export const setbackSpecialStateValues: Record = { "Frost Protection": 0x79, diff --git a/packages/cc/src/lib/utils.ts b/packages/cc/src/lib/utils.ts index 6a5d7d617db4..593529b68b0a 100644 --- a/packages/cc/src/lib/utils.ts +++ b/packages/cc/src/lib/utils.ts @@ -30,18 +30,18 @@ import { type ReadonlyObjectKeyMap, getEnumMemberName, } from "@zwave-js/shared/safe"; -import { distinct } from "alcalzone-shared/arrays"; -import { AssociationCC, AssociationCCValues } from "../cc/AssociationCC"; -import { AssociationGroupInfoCC } from "../cc/AssociationGroupInfoCC"; -import { MultiChannelAssociationCC } from "../cc/MultiChannelAssociationCC"; -import { CCAPI, type CCAPIHost, type CCAPINode } from "./API"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { AssociationCC, AssociationCCValues } from "../cc/AssociationCC.js"; +import { AssociationGroupInfoCC } from "../cc/AssociationGroupInfoCC.js"; +import { MultiChannelAssociationCC } from "../cc/MultiChannelAssociationCC.js"; +import { CCAPI, type CCAPIHost, type CCAPINode } from "./API.js"; import { type AssociationAddress, AssociationCheckResult, type AssociationGroup, AssociationGroupInfoProfile, type EndpointAddress, -} from "./_Types"; +} from "./_Types.js"; export function getAssociations( ctx: GetValueDB, diff --git a/packages/cc/tsconfig.build.json b/packages/cc/tsconfig.build.json index 1105b5ff1f35..4d9c5d18f8a7 100644 --- a/packages/cc/tsconfig.build.json +++ b/packages/cc/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/cc/tsconfig.json b/packages/cc/tsconfig.json index f79366a401b6..9e97b4633983 100644 --- a/packages/cc/tsconfig.json +++ b/packages/cc/tsconfig.json @@ -8,6 +8,6 @@ } ] }, - "include": ["maintenance/**/*.ts", "src/**/*.ts"], + "include": ["maintenance/**/*.ts", "maintenance/**/*.mts", "src/**/*.ts"], "exclude": ["build/**", "node_modules/**"] } diff --git a/packages/config/ava.config.cjs b/packages/config/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/config/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/config/maintenance/codegen.ts b/packages/config/maintenance/codegen.ts index b5ca1005827f..1690afec103b 100644 --- a/packages/config/maintenance/codegen.ts +++ b/packages/config/maintenance/codegen.ts @@ -1,8 +1,13 @@ import { formatWithDprint } from "@zwave-js/maintenance"; import * as fs from "node:fs"; -import * as path from "node:path"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import peggy from "peggy"; -import pegts from "ts-pegjs"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// @ts-expect-error ts-pegjs has incorrect types +const pegts = (await import("ts-pegjs")).default; // // Generate logic parser diff --git a/packages/config/maintenance/importConfig.ts b/packages/config/maintenance/importConfig.ts index 54d319847e64..e187f105ad30 100644 --- a/packages/config/maintenance/importConfig.ts +++ b/packages/config/maintenance/importConfig.ts @@ -18,8 +18,8 @@ import { readJSON, stringify, } from "@zwave-js/shared"; -import { composeObject } from "alcalzone-shared/objects"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +import { composeObject } from "alcalzone-shared/objects/index.js"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import * as JSONC from "comment-json"; import * as JSON5 from "json5"; import { AssertionError, ok } from "node:assert"; diff --git a/packages/config/maintenance/lintConfigFiles.ts b/packages/config/maintenance/lintConfigFiles.ts index d04bef72770c..9cbc5f644575 100644 --- a/packages/config/maintenance/lintConfigFiles.ts +++ b/packages/config/maintenance/lintConfigFiles.ts @@ -11,26 +11,30 @@ import { getErrorMessage, num2hex, } from "@zwave-js/shared"; -import { distinct } from "alcalzone-shared/arrays"; -import { wait } from "alcalzone-shared/async"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { green, red, white } from "ansi-colors"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { wait } from "alcalzone-shared/async/index.js"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import c from "ansi-colors"; +import esMain from "es-main"; import levenshtein from "js-levenshtein"; import type { RulesLogic } from "json-logic-js"; import * as path from "node:path"; -import type { ConditionalParamInfoMap, ParamInfoMap } from "../src"; -import { ConfigManager } from "../src/ConfigManager"; -import { parseLogic } from "../src/Logic"; +import { ConfigManager } from "../src/ConfigManager.js"; +import { parseLogic } from "../src/Logic.js"; import { ConditionalDeviceConfig, type DeviceConfig, -} from "../src/devices/DeviceConfig"; -import type { DeviceID } from "../src/devices/shared"; +} from "../src/devices/DeviceConfig.js"; +import { + type ConditionalParamInfoMap, + type ParamInfoMap, +} from "../src/devices/ParamInformation.js"; +import type { DeviceID } from "../src/devices/shared.js"; import { configDir, getDeviceEntryPredicate, versionInRange, -} from "../src/utils"; +} from "../src/utils.js"; const configManager = new ConfigManager(); @@ -886,7 +890,7 @@ description: ${description}`, ) } is invalid: min/maxValue is incompatible with valueSize ${value.valueSize} (min = ${limits.min}, max = ${limits.max}). Consider converting this parameter to unsigned using ${ - white( + c.white( `"unsigned": true`, ) }!`, @@ -1275,7 +1279,7 @@ export async function lintConfigFiles(): Promise { await lintDevices(); console.log(); - console.log(green("The config files are valid!")); + console.log(c.green("The config files are valid!")); console.log(); console.log(" "); } catch (e: any) { @@ -1285,9 +1289,9 @@ export async function lintConfigFiles(): Promise { lines.shift(); } const message = lines.join("\n"); - console.log(red(message)); + console.log(c.red(message)); } else { - console.log(red(e.message)); + console.log(c.red(e.message)); } console.log(); @@ -1297,4 +1301,4 @@ export async function lintConfigFiles(): Promise { } } -if (require.main === module) void lintConfigFiles(); +if (esMain(import.meta)) void lintConfigFiles(); diff --git a/packages/config/package.json b/packages/config/package.json index b4afdbd2a647..701e11921479 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -5,23 +5,24 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./package.json": "./package.json" }, "keywords": [], "files": [ - "build/**/*.{js,d.ts,map}", + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json", "config/" ], "author": { @@ -45,15 +46,16 @@ }, "scripts": { "codegen": "yarn ts maintenance/codegen.ts", - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:zwave": "yarn ts maintenance/lintConfigFiles.ts && eslint --cache --cache-location .eslintcache/config -c config/eslint.config.mjs", - "ts": "node -r esbuild-register --conditions=@@dev", + "ts": "tsx --conditions=@@dev", "lint:ts": "eslint --cache --cache-location .eslintcache/ts \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "dependencies": { "@zwave-js/core": "workspace:*", @@ -66,6 +68,7 @@ "winston": "^3.15.0" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/js-levenshtein": "^1.1.3", "@types/json-logic-js": "^2.0.7", @@ -76,18 +79,18 @@ "@types/xml2js": "^0.4.14", "@types/yargs": "^17.0.33", "@zwave-js/maintenance": "workspace:*", - "ava": "^6.1.3", "comment-json": "^4.2.5", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", + "es-main": "^1.3.0", "got": "^13.0.0", "js-levenshtein": "^1.1.6", "peggy": "^3.0.2", "proxyquire": "^2.1.3", "sinon": "^19.0.2", - "ts-pegjs": "^4.2.1", + "ts-pegjs": "patch:ts-pegjs@npm%3A4.2.1#~/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch", + "tsx": "^4.19.2", "typescript": "5.6.2", + "vitest": "^2.1.4", "xml2js": "^0.6.2", "yargs": "^17.7.2" } diff --git a/packages/config/src/ConfigManager.test.ts b/packages/config/src/ConfigManager.test.ts index 3a483f4765ff..08e9adbf5dbc 100644 --- a/packages/config/src/ConfigManager.test.ts +++ b/packages/config/src/ConfigManager.test.ts @@ -1,68 +1,71 @@ import { ZWaveLogContainer } from "@zwave-js/core"; import { pathExists } from "@zwave-js/shared"; -import ava, { type ExecutionContext, type TestFn } from "ava"; import fs from "node:fs/promises"; import { tmpdir } from "node:os"; import * as path from "node:path"; import semver from "semver"; -import { ConfigManager } from "./ConfigManager"; -import { ConfigLogger } from "./Logger"; -import { syncExternalConfigDir } from "./utils"; - -interface TestContext { - tempDir: string; - logContainer: ZWaveLogContainer; - logger: ConfigLogger; +import { type ExpectStatic, beforeEach, test as baseTest } from "vitest"; +import { ConfigManager } from "./ConfigManager.js"; +import { ConfigLogger } from "./Logger.js"; +import { syncExternalConfigDir } from "./utils.js"; + +interface LocalTestContext { + context: { + tempDir: string; + logContainer: ZWaveLogContainer; + logger: ConfigLogger; + }; } -const test = ava as TestFn; - // eslint-disable-next-line @typescript-eslint/no-require-imports const ownVersion = require("../package.json").version; -test.before(async (t) => { - const tempDir = path.join(tmpdir(), "zwavejs_test"); - await fs.mkdir(tempDir, { recursive: true }); - t.context.tempDir = tempDir; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const tempDir = path.join(tmpdir(), "zwavejs_test"); + await fs.mkdir(tempDir, { recursive: true }); - const logContainer = new ZWaveLogContainer({ enabled: false }); - t.context.logContainer = logContainer; + const logContainer = new ZWaveLogContainer({ enabled: false }); + const logger = new ConfigLogger(logContainer); - t.context.logger = new ConfigLogger(logContainer); -}); + // Run tests + await use({ tempDir, logContainer, logger }); -test.beforeEach(async (t) => { - await fs.rm(t.context.tempDir, { recursive: true, force: true }); - await fs.mkdir(t.context.tempDir, { recursive: true }); + // Teardown + await fs.rm(tempDir, { recursive: true, force: true }); + }, + { auto: true }, + ], }); -test.after.always(async (t) => { - await fs.rm(t.context.tempDir, { recursive: true, force: true }); +beforeEach(async ({ context, expect }) => { + await fs.rm(context.tempDir, { recursive: true, force: true }); + await fs.mkdir(context.tempDir, { recursive: true }); }); -test.serial( +test.sequential( "syncExternalConfigDir() syncs the external config dir if it does not exist", - async (t) => { - t.timeout(60000); - const { tempDir, logger } = t.context; + async ({ context, expect }) => { + const { tempDir, logger } = context; const configDir = path.join(tempDir, "extconfig"); process.env.ZWAVEJS_EXTERNAL_CONFIG = configDir; await syncExternalConfigDir(logger); - t.true(await pathExists(configDir)); - t.is( + expect(await pathExists(configDir)).toBe(true); + expect( await fs.readFile(path.join(configDir, "version"), "utf8"), - ownVersion, - ); + ).toBe(ownVersion); }, + 60000, ); -test.serial( +test.sequential( "syncExternalConfigDir() syncs the external config dir alone if it is from an incompatible version", - async (t) => { - t.timeout(60000); - const { tempDir, logger } = t.context; + async ({ context, expect }) => { + const { tempDir, logger } = context; const configDir = path.join(tempDir, "extconfig"); process.env.ZWAVEJS_EXTERNAL_CONFIG = configDir; @@ -77,20 +80,19 @@ test.serial( await syncExternalConfigDir(logger); - t.true(await pathExists(configDir)); + expect(await pathExists(configDir)).toBe(true); - t.is( + expect( await fs.readFile(path.join(configDir, "version"), "utf8"), - ownVersion, - ); + ).toBe(ownVersion); }, + 60000, ); -test.serial( +test.sequential( "syncExternalConfigDir() leaves the external config dir alone if it is from a newer compatible version", - async (t) => { - t.timeout(60000); - const { tempDir, logger } = t.context; + async ({ context, expect }) => { + const { tempDir, logger } = context; const configDir = path.join(tempDir, "extconfig"); process.env.ZWAVEJS_EXTERNAL_CONFIG = configDir; @@ -105,54 +107,58 @@ test.serial( await syncExternalConfigDir(logger); - t.true(await pathExists(configDir)); + expect(await pathExists(configDir)).toBe(true); - t.is( + expect( await fs.readFile(path.join(configDir, "version"), "utf8"), - otherVersion, - ); + ).toBe(otherVersion); }, + 60000, ); -test.serial("loading config files from the embedded config dir", async (t) => { - t.timeout(60000); - delete process.env.ZWAVEJS_EXTERNAL_CONFIG; +test.sequential( + "loading config files from the embedded config dir", + async ({ context, expect }) => { + delete process.env.ZWAVEJS_EXTERNAL_CONFIG; - const { logContainer } = t.context; - const cm = new ConfigManager({ logContainer }); - await cm.loadAll(); + const { logContainer } = context; + const cm = new ConfigManager({ logContainer }); + await cm.loadAll(); - // Load the Aeotec ZW100 Multisensor 6 - we know that it uses multiple imports that could fail validation - const device = await cm.lookupDevice(0x0086, 0x0002, 0x0064); - t.truthy(device); - t.true(device?.isEmbedded); -}); + // Load the Aeotec ZW100 Multisensor 6 - we know that it uses multiple imports that could fail validation + const device = await cm.lookupDevice(0x0086, 0x0002, 0x0064); + expect(device).toBeDefined(); + expect(device?.isEmbedded).toBe(true); + }, + 60000, +); -test.serial( +test.sequential( "loading config files from the ZWAVEJS_EXTERNAL_CONFIG", - async (t) => { - t.timeout(60000); - const { tempDir, logContainer } = t.context; + async ({ context, expect }) => { + const { tempDir, logContainer } = context; const configDir = path.join(tempDir, "extconfig"); process.env.ZWAVEJS_EXTERNAL_CONFIG = configDir; const cm = new ConfigManager({ logContainer }); await cm.loadAll(); - t.true(await pathExists(configDir)); + expect(await pathExists(configDir)).toBe(true); // Load the Aeotec ZW100 Multisensor 6 - we know that it uses multiple imports that could fail validation const device = await cm.lookupDevice(0x0086, 0x0002, 0x0064); - t.truthy(device); - t.true(device?.isEmbedded); // ZWAVEJS_EXTERNAL_CONFIG is still considered as an embedded config + expect(device).toBeDefined(); + expect(device?.isEmbedded).toBe(true); // ZWAVEJS_EXTERNAL_CONFIG is still considered as an embedded config }, + 60000, ); async function testDeviceConfigPriorityDir( - t: ExecutionContext, + expect: ExpectStatic, + context: LocalTestContext["context"], useExternalConfig: boolean, ): Promise { - const { tempDir } = t.context; + const { tempDir } = context; let externalConfigDir: string; if (useExternalConfig) { @@ -214,36 +220,35 @@ async function testDeviceConfigPriorityDir( await cm.loadAll(); if (useExternalConfig) { - t.true(await pathExists(externalConfigDir!)); + expect(await pathExists(externalConfigDir!)).toBe(true); } // Load the dummy device const device = await cm.lookupDevice(0x0086, 0x0002, 0x0064); - t.is(device?.paramInformation?.get({ parameter: 1 })?.label, "Test"); - t.false(device?.isEmbedded); // deviceConfigPriorityDir is considered a user-provided config + expect(device?.paramInformation?.get({ parameter: 1 })?.label).toBe("Test"); + expect(device?.isEmbedded).toBe(false); // deviceConfigPriorityDir is considered a user-provided config } -test.serial( +test.sequential( "loading config from the deviceConfigPriorityDir (without ZWAVEJS_EXTERNAL_CONFIG)", - async (t) => { - t.timeout(60000); - await testDeviceConfigPriorityDir(t, false); + async ({ context, expect }) => { + await testDeviceConfigPriorityDir(expect, context, false); }, + 60000, ); -test.serial( +test.sequential( "loading config from the deviceConfigPriorityDir (with ZWAVEJS_EXTERNAL_CONFIG)", - async (t) => { - t.timeout(60000); - await testDeviceConfigPriorityDir(t, true); + async ({ context, expect }) => { + await testDeviceConfigPriorityDir(expect, context, true); }, + 60000, ); -test.serial( +test.sequential( `config files with the "preferred" flag are preferred`, - async (t) => { - t.timeout(60000); - const { logContainer } = t.context; + async ({ context, expect }) => { + const { logContainer } = context; const cm = new ConfigManager({ logContainer }); await cm.loadAll(); @@ -252,7 +257,8 @@ test.serial( const preferred = await cm.lookupDevice(0x0330, 0x0300, 0xb302, "1.26"); // ZV9001K12-DIM-Z4 is the fallback config for the same IDs const fallback = await cm.lookupDevice(0x0330, 0x0300, 0xb302, "1.0"); - t.is(preferred?.manufacturer, "Vesternet"); - t.is(fallback?.manufacturer, "Sunricher"); + expect(preferred?.manufacturer).toBe("Vesternet"); + expect(fallback?.manufacturer).toBe("Sunricher"); }, + 60000, ); diff --git a/packages/config/src/ConfigManager.ts b/packages/config/src/ConfigManager.ts index ce0c5821920f..dd8fde6dc2b5 100644 --- a/packages/config/src/ConfigManager.ts +++ b/packages/config/src/ConfigManager.ts @@ -6,13 +6,13 @@ import { } from "@zwave-js/core"; import { getErrorMessage, pathExists } from "@zwave-js/shared"; import path from "node:path"; -import { ConfigLogger } from "./Logger"; +import { ConfigLogger } from "./Logger.js"; import { type ManufacturersMap, loadManufacturersInternal, saveManufacturersInternal, -} from "./Manufacturers"; -import { PACKAGE_VERSION } from "./_version"; +} from "./Manufacturers.js"; +import { PACKAGE_VERSION } from "./_version.js"; import { ConditionalDeviceConfig, type DeviceConfig, @@ -22,13 +22,13 @@ import { getDevicesPaths, loadDeviceIndexInternal, loadFulltextDeviceIndexInternal, -} from "./devices/DeviceConfig"; +} from "./devices/DeviceConfig.js"; import { configDir, externalConfigDir, getDeviceEntryPredicate, syncExternalConfigDir, -} from "./utils"; +} from "./utils.js"; export interface ConfigManagerOptions { logContainer?: ZWaveLogContainer; diff --git a/packages/config/src/JsonTemplate.test.ts b/packages/config/src/JsonTemplate.test.ts index 65e1d942d99b..0534aebe806e 100644 --- a/packages/config/src/JsonTemplate.test.ts +++ b/packages/config/src/JsonTemplate.test.ts @@ -1,9 +1,9 @@ import { ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; -import test from "ava"; import fs from "node:fs/promises"; import { tmpdir } from "node:os"; import * as path from "node:path"; -import { readJsonWithTemplate } from "./JsonTemplate"; +import { afterEach, beforeAll, test } from "vitest"; +import { readJsonWithTemplate } from "./JsonTemplate.js"; const mockDir = path.join(tmpdir(), `zwave-js-template-test`); @@ -21,14 +21,12 @@ mockFs.restore = async (): Promise => { await fs.rm(mockDir, { recursive: true, force: true }); }; -test.before(() => mockFs.restore()); -test.afterEach.always(() => mockFs.restore()); +beforeAll(() => mockFs.restore()); +afterEach(() => mockFs.restore()); -test.serial( +test.sequential( "readJsonWithTemplate() should read simple JSON files normally", async (t) => { - t.timeout(20000); - const file = { foo: "bar", baz: 1, @@ -40,15 +38,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, file); + t.expect(content).toStrictEqual(file); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should follow top-level whole-file $imports", async (t) => { - t.timeout(20000); - const test = { $import: "template.json", }; @@ -63,15 +60,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, template); + t.expect(content).toStrictEqual(template); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should overwrite keys that are present before the $import", async (t) => { - t.timeout(20000); - const test = { template: false, $import: "template.json", @@ -87,15 +83,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, template); + t.expect(content).toStrictEqual(template); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should preserve keys that are present after the $import", async (t) => { - t.timeout(20000); - const test = { $import: "template.json", template: false, @@ -113,15 +108,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should throw if the $import specifier is not a string", async (t) => { - t.timeout(20000); - const test = { $import: 1, }; @@ -132,19 +126,19 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_Invalid, }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should throw if the $import specifier is not valid", async (t) => { - t.timeout(20000); const tests = [ "no-extension", "wrong.extension", @@ -162,7 +156,7 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_Invalid, @@ -171,13 +165,12 @@ test.serial( ); } }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should throw if the $import target is not an object", async (t) => { - t.timeout(20000); - const test = { $import: "template.json#somewhere", }; @@ -190,49 +183,52 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_Invalid, }, ); }, + 20000, ); -test.serial("readJsonWithTemplate() should follow deep $imports", async (t) => { - t.timeout(20000); - - const test = { - toplevel: true, - nested: { - $import: "template.json", - }, - template: false, - }; - const template = { - template: true, - }; - const expected = { - toplevel: true, - nested: { +test.sequential( + "readJsonWithTemplate() should follow deep $imports", + async (t) => { + const test = { + toplevel: true, + nested: { + $import: "template.json", + }, + template: false, + }; + const template = { template: true, - }, - template: false, - }; - await mockFs({ - "/test.json": JSON.stringify(test), - "/template.json": JSON.stringify(template), - }); - - const content = await readJsonWithTemplate(path.join(mockDir, "test.json")); - t.deepEqual(content, expected); -}); - -test.serial( + }; + const expected = { + toplevel: true, + nested: { + template: true, + }, + template: false, + }; + await mockFs({ + "/test.json": JSON.stringify(test), + "/template.json": JSON.stringify(template), + }); + + const content = await readJsonWithTemplate( + path.join(mockDir, "test.json"), + ); + t.expect(content).toStrictEqual(expected); + }, + 20000, +); + +test.sequential( "readJsonWithTemplate() should follow deep $imports in arrays", async (t) => { - t.timeout(20000); - const test = { toplevel: true, nested: [ @@ -272,15 +268,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() file-based circular references should throw an error (direct, top-level)", async (t) => { - t.timeout(20000); - const test = { $import: "template.json", }; @@ -293,20 +288,19 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_CircularImport, }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() file-based circular references should throw an error (three-way)", async (t) => { - t.timeout(20000); - const test = { $import: "template1.json", }; @@ -323,20 +317,19 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_CircularImport, }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() file-based circular references should throw an error (three-way, nested)", async (t) => { - t.timeout(20000); - const test = { nested: { $import: "template1.json", @@ -366,20 +359,19 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_CircularImport, }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should be able to resolve relative paths", async (t) => { - t.timeout(20000); - const test = { $import: "../baz/template.json", }; @@ -394,15 +386,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "foo/bar/test.json"), ); - t.deepEqual(content, template); + t.expect(content).toStrictEqual(template); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should be able to resolve the root directory with ~/", async (t) => { - t.timeout(20000); - const test = { $import: "~/template.json", }; @@ -418,15 +409,14 @@ test.serial( path.join(mockDir, "foo/bar/test.json"), path.join(mockDir, "foo"), ); - t.deepEqual(content, template); + t.expect(content).toStrictEqual(template); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should throw when using a path that starts with ~/ when no root dir is configured", async (t) => { - t.timeout(20000); - const test = { $import: "~/foo/template.json", }; @@ -434,7 +424,7 @@ test.serial( "/foo/bar/test.json": JSON.stringify(test), }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "foo/bar/test.json")), { messageMatches: "import specifier cannot start with ~/", @@ -442,13 +432,12 @@ test.serial( }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should be able to resolve in-file selectors", async (t) => { - t.timeout(20000); - const test = { $import: "template.json#sub", }; @@ -467,15 +456,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should be able to resolve deep in-file selectors", async (t) => { - t.timeout(20000); - const test = { $import: "template.json#we/all/live/in/1/yellow/submarine", }; @@ -501,15 +489,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() selector based circular references should throw an error (three-way)", async (t) => { - t.timeout(20000); - const test = { $import: "template1.json#foo", }; @@ -536,20 +523,19 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_CircularImport, }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() unspecified self-references throw an error", async (t) => { - t.timeout(20000); - const test = { $import: "#", }; @@ -558,17 +544,17 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), {}, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() circular self-references throw an error", async (t) => { - t.timeout(20000); const test = { key1: { $import: "#key2", @@ -582,19 +568,19 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate(path.join(mockDir, "test.json")), { errorCode: ZWaveErrorCodes.Config_CircularImport, }, ); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() crazy stuff does work (part 1)", async (t) => { - t.timeout(20000); const test = { $import: "template1.json", }; @@ -632,14 +618,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() crazy stuff does work (part 2)", async (t) => { - t.timeout(20000); const test = { $import: "template1.json", }; @@ -677,15 +663,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() referencing partial parameters works", async (t) => { - t.timeout(20000); - const test = { paramInformation: { 1: { @@ -716,15 +701,14 @@ test.serial( const content = await readJsonWithTemplate( path.join(mockDir, "test.json"), ); - t.deepEqual(content, expected); + t.expect(content).toStrictEqual(expected); }, + 20000, ); -test.serial( +test.sequential( "readJsonWithTemplate() should throw when the referenced file is outside the rootDir", async (t) => { - t.timeout(20000); - const rootDir = "root/test"; const test = { $import: "../outside.json", @@ -734,7 +718,7 @@ test.serial( }); await assertZWaveError( - t, + t.expect, () => readJsonWithTemplate( path.join(mockDir, rootDir, "test.json"), @@ -746,4 +730,5 @@ test.serial( }, ); }, + 20000, ); diff --git a/packages/config/src/JsonTemplate.ts b/packages/config/src/JsonTemplate.ts index 8d05c9c3225f..2768a499936b 100644 --- a/packages/config/src/JsonTemplate.ts +++ b/packages/config/src/JsonTemplate.ts @@ -1,7 +1,7 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core/safe"; import { pathExists } from "@zwave-js/shared"; import { getErrorMessage } from "@zwave-js/shared/safe"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import JSON5 from "json5"; import fs from "node:fs/promises"; import * as path from "node:path"; diff --git a/packages/config/src/Logger.ts b/packages/config/src/Logger.ts index 6bbb1be649e4..b4cfcce56036 100644 --- a/packages/config/src/Logger.ts +++ b/packages/config/src/Logger.ts @@ -7,7 +7,7 @@ import { CONFIG_LABEL, CONFIG_LOGLEVEL, type ConfigLogContext, -} from "./Logger_safe"; +} from "./Logger_safe.js"; export class ConfigLogger extends ZWaveLoggerBase { constructor(loggers: ZWaveLogContainer) { diff --git a/packages/config/src/Logic.test.ts b/packages/config/src/Logic.test.ts index df9f632364b5..d06ebdb8e422 100644 --- a/packages/config/src/Logic.test.ts +++ b/packages/config/src/Logic.test.ts @@ -1,5 +1,5 @@ -import test from "ava"; -import { evaluate } from "./Logic"; +import { test } from "vitest"; +import { evaluate } from "./Logic.js"; const tests = [ { @@ -46,7 +46,7 @@ for (let i = 1; i <= tests.length; i++) { ) } --> ${logic} is ${expected}`, (t) => { - t.is(evaluate(logic, context), expected); + t.expect(evaluate(logic, context)).toBe(expected); }, ); } diff --git a/packages/config/src/Logic.ts b/packages/config/src/Logic.ts index b24fb08cc89b..66aa055aaf0d 100644 --- a/packages/config/src/Logic.ts +++ b/packages/config/src/Logic.ts @@ -1,7 +1,10 @@ import { padVersion } from "@zwave-js/shared"; -import { type RulesLogic, add_operation, apply } from "json-logic-js"; import * as semver from "semver"; -import { parse } from "./LogicParser"; +import { parse } from "./LogicParser.js"; + +// The types are not correct: +import { type RulesLogic, default as JsonLogic } from "json-logic-js"; +const { add_operation, apply } = JsonLogic; function tryOr any>( operation: T, diff --git a/packages/config/src/Manufacturers.test.ts b/packages/config/src/Manufacturers.test.ts index 0391edbc6b27..8aa75123cd31 100644 --- a/packages/config/src/Manufacturers.test.ts +++ b/packages/config/src/Manufacturers.test.ts @@ -1,100 +1,94 @@ -import test, { type ExecutionContext } from "ava"; -import proxyquire from "proxyquire"; -import sinon from "sinon"; - -const readFileStub = sinon.stub(); -const pathExistsStub = sinon.stub(); - -// load the ConfigManager with stubbed out filesystem -const { ConfigManager } = proxyquire( - "./ConfigManager", - { - "node:fs/promises": { - readFile: readFileStub, - "@global": true, - }, - "@zwave-js/shared": { - pathExists: pathExistsStub, - "@global": true, - }, - }, -); -type ConfigManager = import("./ConfigManager").ConfigManager; +import { pathExists } from "@zwave-js/shared"; +import { readFile } from "node:fs/promises"; +import { test, vi } from "vitest"; +import { ConfigManager } from "./ConfigManager.js"; + +vi.mock("node:fs/promises"); +vi.mock("@zwave-js/shared", async () => { + const original = await vi.importActual("@zwave-js/shared"); + return { + ...original, + pathExists: vi.fn(), + }; +}); + +const readFileStub = vi.mocked(readFile); +const pathExistsStub = vi.mocked(pathExists); { - async function prepareTest(t: ExecutionContext): Promise { - // Loading configuration may take a while on CI - t.timeout(30000); - - pathExistsStub.reset(); - readFileStub.reset(); - pathExistsStub.resolves(false); - readFileStub.rejects(new Error("File does not exist")); + async function prepareTest(): Promise { + pathExistsStub.mockClear(); + readFileStub.mockClear(); + pathExistsStub.mockResolvedValue(false); + readFileStub.mockRejectedValue(new Error("File does not exist")); const configManager = new ConfigManager(); await configManager.loadManufacturers(); return configManager; } - test.serial( + test.sequential( "lookupManufacturer (with missing file) does not throw", async (t) => { - const configManager = await prepareTest(t); - t.notThrows(() => configManager.lookupManufacturer(0)); + const configManager = await prepareTest(); + t.expect(() => configManager.lookupManufacturer(0)).not.toThrow(); }, + // Loading configuration may take a while on CI + 30000, ); - test.serial( + test.sequential( "lookupManufacturer (with missing file) returns undefined", async (t) => { - const configManager = await prepareTest(t); - t.is(configManager.lookupManufacturer(0x0e), undefined); - t.is(configManager.lookupManufacturer(0xff), undefined); + const configManager = await prepareTest(); + t.expect(configManager.lookupManufacturer(0x0e)).toBeUndefined(); + t.expect(configManager.lookupManufacturer(0xff)).toBeUndefined(); }, + // Loading configuration may take a while on CI + 30000, ); } { - async function prepareTest(t: ExecutionContext): Promise { - // Loading configuration may take a while on CI - t.timeout(30000); - - pathExistsStub.reset(); - readFileStub.reset(); - pathExistsStub.resolves(true); - readFileStub.resolves(`{"0x000e": ` as any); + async function prepareTest(): Promise { + pathExistsStub.mockClear(); + readFileStub.mockClear(); + pathExistsStub.mockResolvedValue(true); + readFileStub.mockResolvedValue(`{"0x000e": ` as any); const configManager = new ConfigManager(); await configManager.loadManufacturers(); return configManager; } - test.serial( + test.sequential( "lookupManufacturer (with invalid file) does not throw", async (t) => { - const configManager = await prepareTest(t); - t.notThrows(() => configManager.lookupManufacturer(0x0e)); + const configManager = await prepareTest(); + t.expect(() => configManager.lookupManufacturer(0x0e)).not + .toThrow(); }, + // Loading configuration may take a while on CI + 30000, ); - test.serial( + test.sequential( "lookupManufacturer (with invalid file) returns undefined", async (t) => { - const configManager = await prepareTest(t); - t.is(configManager.lookupManufacturer(0x0e), undefined); + const configManager = await prepareTest(); + t.expect(configManager.lookupManufacturer(0x0e)).toBeUndefined(); }, + // Loading configuration may take a while on CI + 30000, ); } { - async function prepareTest(t: ExecutionContext): Promise { - // Loading configuration may take a while on CI - t.timeout(30000); - - readFileStub.reset(); - pathExistsStub.reset(); - pathExistsStub.resolves(true); - readFileStub.resolves( + async function prepareTest(): Promise { + readFileStub.mockClear(); + pathExistsStub.mockClear(); + pathExistsStub.mockResolvedValue(true); + readFileStub.mockResolvedValue( JSON.stringify({ "0x000e": "Test", }) as any, @@ -105,12 +99,14 @@ type ConfigManager = import("./ConfigManager").ConfigManager; return configManager; } - test.serial( + test.sequential( "lookupManufacturer() returns the name belonging to the manufacturer ID if it is defined", async (t) => { - const configManager = await prepareTest(t); - t.is(configManager.lookupManufacturer(0x0e), "Test"); - t.is(configManager.lookupManufacturer(0xff), undefined); + const configManager = await prepareTest(); + t.expect(configManager.lookupManufacturer(0x0e)).toBe("Test"); + t.expect(configManager.lookupManufacturer(0xff)).toBeUndefined(); }, + // Loading configuration may take a while on CI + 30000, ); } diff --git a/packages/config/src/Manufacturers.ts b/packages/config/src/Manufacturers.ts index 41b589bbbf73..5cb25c4ba992 100644 --- a/packages/config/src/Manufacturers.ts +++ b/packages/config/src/Manufacturers.ts @@ -1,11 +1,11 @@ import { ZWaveError, ZWaveErrorCodes, isZWaveError } from "@zwave-js/core"; import { formatId, pathExists, stringify } from "@zwave-js/shared"; -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import JSON5 from "json5"; import fs from "node:fs/promises"; import path from "node:path"; -import { configDir, externalConfigDir } from "./utils"; -import { hexKeyRegex4Digits, throwInvalidConfig } from "./utils_safe"; +import { configDir, externalConfigDir } from "./utils.js"; +import { hexKeyRegex4Digits, throwInvalidConfig } from "./utils_safe.js"; export type ManufacturersMap = Map; diff --git a/packages/config/src/_version.ts b/packages/config/src/_version.ts index 7cf90ca675b5..9efb1ae1833b 100644 --- a/packages/config/src/_version.ts +++ b/packages/config/src/_version.ts @@ -1,2 +1,2 @@ // This file is auto-generated by the codegen maintenance script -export const PACKAGE_VERSION = "14.0.0-beta.0"; +export const PACKAGE_VERSION = "14.0.0-beta.1"; diff --git a/packages/config/src/devices/AssociationConfig.ts b/packages/config/src/devices/AssociationConfig.ts index 09d7ccaeaa98..29187fc313e1 100644 --- a/packages/config/src/devices/AssociationConfig.ts +++ b/packages/config/src/devices/AssociationConfig.ts @@ -1,11 +1,11 @@ import { type JSONObject, pick } from "@zwave-js/shared/safe"; -import { throwInvalidConfig } from "../utils_safe"; +import { throwInvalidConfig } from "../utils_safe.js"; import { type ConditionalItem, conditionApplies, validateCondition, -} from "./ConditionalItem"; -import type { DeviceID } from "./shared"; +} from "./ConditionalItem.js"; +import type { DeviceID } from "./shared.js"; export class ConditionalAssociationConfig implements ConditionalItem diff --git a/packages/config/src/devices/CompatConfig.ts b/packages/config/src/devices/CompatConfig.ts index 8c7491cf6d0d..c2b3dae88a80 100644 --- a/packages/config/src/devices/CompatConfig.ts +++ b/packages/config/src/devices/CompatConfig.ts @@ -6,10 +6,10 @@ import { stripUndefined, } from "@zwave-js/core/safe"; import { type JSONObject, pick } from "@zwave-js/shared/safe"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { throwInvalidConfig, tryParseCCId } from "../utils_safe"; -import { type ConditionalItem, conditionApplies } from "./ConditionalItem"; -import type { DeviceID } from "./shared"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { throwInvalidConfig, tryParseCCId } from "../utils_safe.js"; +import { type ConditionalItem, conditionApplies } from "./ConditionalItem.js"; +import type { DeviceID } from "./shared.js"; export class ConditionalCompatConfig implements ConditionalItem { private valueIdRegex = /^\$value\$\[.+\]$/; diff --git a/packages/config/src/devices/ConditionalDeviceConfig.test.ts b/packages/config/src/devices/ConditionalDeviceConfig.test.ts index 510ecb635221..dc5828c02b97 100644 --- a/packages/config/src/devices/ConditionalDeviceConfig.test.ts +++ b/packages/config/src/devices/ConditionalDeviceConfig.test.ts @@ -1,6 +1,6 @@ -import { isArray } from "alcalzone-shared/typeguards"; -import test from "ava"; -import { ConditionalDeviceConfig } from "./DeviceConfig"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; +import { test } from "vitest"; +import { ConditionalDeviceConfig } from "./DeviceConfig.js"; test("parses a simple device config", (t) => { const json = { @@ -22,10 +22,10 @@ test("parses a simple device config", (t) => { const condConfig = new ConditionalDeviceConfig("test.json", true, json); // Ensure that the config is parsed correctly - t.is(condConfig.manufacturer, "Silicon Labs"); - t.is(condConfig.label, "ZST10-700"); - t.is(condConfig.description, "700 Series-based Controller"); - t.deepEqual(condConfig.firmwareVersion, { + t.expect(condConfig.manufacturer).toBe("Silicon Labs"); + t.expect(condConfig.label).toBe("ZST10-700"); + t.expect(condConfig.description).toBe("700 Series-based Controller"); + t.expect(condConfig.firmwareVersion).toStrictEqual({ min: "0.0", max: "255.255", }); @@ -63,10 +63,10 @@ test("parses a device config with conditional manufacturer, label and descriptio const condConfig = new ConditionalDeviceConfig("test.json", true, json); // Ensure that the config is parsed correctly - t.is(condConfig.manufacturer.length, 2); - t.is(condConfig.label.length, 2); - t.is(condConfig.description.length, 2); - t.like(condConfig.firmwareVersion, { + t.expect(condConfig.manufacturer.length).toBe(2); + t.expect(condConfig.label.length).toBe(2); + t.expect(condConfig.description.length).toBe(2); + t.expect(condConfig.firmwareVersion).toMatchObject({ min: "0.0", max: "255.255", }); @@ -82,17 +82,17 @@ test("parses a device config with conditional manufacturer, label and descriptio ...deviceId, firmwareVersion: "0.5", }); - t.is(evaluated1.manufacturer, "Silicon Labs"); - t.is(evaluated1.label, "ZST10-700"); - t.is(evaluated1.description, "700 Series-based Controller"); + t.expect(evaluated1.manufacturer).toBe("Silicon Labs"); + t.expect(evaluated1.label).toBe("ZST10-700"); + t.expect(evaluated1.description).toBe("700 Series-based Controller"); const evaluated2 = condConfig.evaluate({ ...deviceId, firmwareVersion: "1.0", }); - t.is(evaluated2.manufacturer, "Z-Wave JS"); - t.is(evaluated2.label, "ZST10-700 rev. 2"); - t.is(evaluated2.description, "815 Series-based Controller"); + t.expect(evaluated2.manufacturer).toBe("Z-Wave JS"); + t.expect(evaluated2.label).toBe("ZST10-700 rev. 2"); + t.expect(evaluated2.description).toBe("815 Series-based Controller"); }); test("parses a device config with conditional metadata", (t) => { @@ -145,8 +145,8 @@ test("parses a device config with conditional metadata", (t) => { ...deviceId, firmwareVersion: "0.5", }); - t.is(evaluated1.metadata?.reset, "Press any key to continue..."); - t.deepEqual(evaluated1.metadata?.comments, [ + t.expect(evaluated1.metadata?.reset).toBe("Press any key to continue..."); + t.expect(evaluated1.metadata?.comments).toStrictEqual([ { level: "warning", text: "Join the dark side!", @@ -157,8 +157,8 @@ test("parses a device config with conditional metadata", (t) => { ...deviceId, firmwareVersion: "1.0", }); - t.is(evaluated2.metadata?.reset, undefined); - t.deepEqual(evaluated2.metadata?.comments, [ + t.expect(evaluated2.metadata?.reset).toBeUndefined(); + t.expect(evaluated2.metadata?.comments).toStrictEqual([ { level: "info", text: "Good, good...", @@ -202,7 +202,7 @@ test("parses a device config with conditional compat flags", (t) => { ...deviceId, firmwareVersion: "0.5", }); - t.deepEqual(evaluated1.compat, { + t.expect(evaluated1.compat).toStrictEqual({ mapBasicSet: "auto", }); @@ -210,7 +210,7 @@ test("parses a device config with conditional compat flags", (t) => { ...deviceId, firmwareVersion: "1.0", }); - t.is(evaluated2.compat, undefined); + t.expect(evaluated2.compat).toBeUndefined(); }); test("parses a device config with conditional config parameter options", (t) => { @@ -267,35 +267,37 @@ test("parses a device config with conditional config parameter options", (t) => ...deviceId, firmwareVersion: "0.5", }); - t.deepEqual(evaluated1.paramInformation?.get({ parameter: 1 })?.options, [ - { - label: "Yes", - value: 1, - }, - { - label: "No", - value: 2, - }, - { - label: "Maybe", - value: 3, - }, - ]); + t.expect(evaluated1.paramInformation?.get({ parameter: 1 })?.options) + .toStrictEqual([ + { + label: "Yes", + value: 1, + }, + { + label: "No", + value: 2, + }, + { + label: "Maybe", + value: 3, + }, + ]); const evaluated2 = condConfig.evaluate({ ...deviceId, firmwareVersion: "1.0", }); - t.deepEqual(evaluated2.paramInformation?.get({ parameter: 1 })?.options, [ - { - label: "Yes", - value: 1, - }, - { - label: "No", - value: 2, - }, - ]); + t.expect(evaluated2.paramInformation?.get({ parameter: 1 })?.options) + .toStrictEqual([ + { + label: "Yes", + value: 1, + }, + { + label: "No", + value: 2, + }, + ]); }); test("supports x.y.z firmware versions", (t) => { @@ -337,39 +339,35 @@ test("supports x.y.z firmware versions", (t) => { ...deviceId, firmwareVersion: "7.17", }); - t.is( + t.expect( isArray(evaluatedXY_warning.metadata?.comments) && evaluatedXY_warning.metadata?.comments.length, - 1, - ); + ).toBe(1); const evaluatedXY_ok = condConfig.evaluate({ ...deviceId, firmwareVersion: "7.18", }); - t.is( + t.expect( isArray(evaluatedXY_ok.metadata?.comments) && evaluatedXY_ok.metadata?.comments.length, - 0, - ); + ).toBe(0); const evaluatedXYZ_warning = condConfig.evaluate({ ...deviceId, firmwareVersion: "7.17.1", }); - t.is( + t.expect( isArray(evaluatedXYZ_warning.metadata?.comments) && evaluatedXYZ_warning.metadata?.comments.length, - 1, - ); + ).toBe(1); const evaluatedXYZ_ok = condConfig.evaluate({ ...deviceId, firmwareVersion: "7.17.2", }); - t.is( + t.expect( isArray(evaluatedXYZ_ok.metadata?.comments) && evaluatedXYZ_ok.metadata?.comments.length, - 0, - ); + ).toBe(0); }); diff --git a/packages/config/src/devices/ConditionalItem.ts b/packages/config/src/devices/ConditionalItem.ts index dc4ad601e535..873bfe884afb 100644 --- a/packages/config/src/devices/ConditionalItem.ts +++ b/packages/config/src/devices/ConditionalItem.ts @@ -1,9 +1,9 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core/safe"; import { ObjectKeyMap } from "@zwave-js/shared/safe"; -import { isArray } from "alcalzone-shared/typeguards"; -import { evaluate } from "../Logic"; -import { throwInvalidConfig } from "../utils_safe"; -import type { DeviceID } from "./shared"; +import { isArray } from "alcalzone-shared/typeguards/index.js"; +import { evaluate } from "../Logic.js"; +import { throwInvalidConfig } from "../utils_safe.js"; +import type { DeviceID } from "./shared.js"; /** A conditional config item */ export interface ConditionalItem { diff --git a/packages/config/src/devices/ConditionalPrimitive.ts b/packages/config/src/devices/ConditionalPrimitive.ts index 84c61703a3d0..3e573bec92a5 100644 --- a/packages/config/src/devices/ConditionalPrimitive.ts +++ b/packages/config/src/devices/ConditionalPrimitive.ts @@ -1,7 +1,7 @@ -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { throwInvalidConfig } from "../utils_safe"; -import { type ConditionalItem, conditionApplies } from "./ConditionalItem"; -import type { DeviceID } from "./shared"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { throwInvalidConfig } from "../utils_safe.js"; +import { type ConditionalItem, conditionApplies } from "./ConditionalItem.js"; +import type { DeviceID } from "./shared.js"; type ToPrimitive = T extends "string" ? string : T extends "number" ? number diff --git a/packages/config/src/devices/DeviceConfig.hash.test.ts b/packages/config/src/devices/DeviceConfig.hash.test.ts index 911080f60608..2e41f3b916ff 100644 --- a/packages/config/src/devices/DeviceConfig.hash.test.ts +++ b/packages/config/src/devices/DeviceConfig.hash.test.ts @@ -1,93 +1,104 @@ import { CommandClasses } from "@zwave-js/core"; import { isUint8Array } from "@zwave-js/shared"; -import test from "ava"; import path from "node:path"; -import { ConfigManager } from "../ConfigManager"; - -test("hash() works", async (t) => { +import { fileURLToPath } from "node:url"; +import { test } from "vitest"; +import { ConfigManager } from "../ConfigManager.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +test( + "hash() works", + async (t) => { + const configManager = new ConfigManager({ + deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), + }); + const config = (await configManager.lookupDevice( + 0xffff, + 0xcafe, + 0xbeef, + "1.0", + ))!; + t.expect(config).toBeDefined(); + + const hash = config.getHash(); + t.expect(isUint8Array(hash)).toBe(true); + }, // This test might take a while - t.timeout(60000); - - const configManager = new ConfigManager({ - deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), - }); - const config = (await configManager.lookupDevice( - 0xffff, - 0xcafe, - 0xbeef, - "1.0", - ))!; - t.not(config, undefined); - - const hash = config.getHash(); - t.true(isUint8Array(hash)); -}); - -test("hash() changes when changing a parameter info", async (t) => { + 60000, +); + +test( + "hash() changes when changing a parameter info", + async (t) => { + const configManager = new ConfigManager({ + deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), + }); + const config = (await configManager.lookupDevice( + 0xffff, + 0xcafe, + 0xbeef, + "1.0", + ))!; + t.expect(config).toBeDefined(); + + const hash1 = config.getHash(); + + // @ts-expect-error + config.paramInformation!.get({ parameter: 2 })!.unit = "lightyears"; + const hash2 = config.getHash(); + + t.expect(hash1).not.toStrictEqual(hash2); + }, // This test might take a while - t.timeout(60000); - - const configManager = new ConfigManager({ - deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), - }); - const config = (await configManager.lookupDevice( - 0xffff, - 0xcafe, - 0xbeef, - "1.0", - ))!; - t.not(config, undefined); - - const hash1 = config.getHash(); - - // @ts-expect-error - config.paramInformation!.get({ parameter: 2 })!.unit = "lightyears"; - const hash2 = config.getHash(); - - t.notDeepEqual(hash1, hash2); -}); - -test("hash() changes when removing a CC", async (t) => { + 60000, +); + +test( + "hash() changes when removing a CC", + async (t) => { + const configManager = new ConfigManager({ + deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), + }); + const config = (await configManager.lookupDevice( + 0xffff, + 0xcafe, + 0xbeef, + "1.0", + ))!; + t.expect(config).toBeDefined(); + + const hash1 = config.getHash(); + + const removeCCs = new Map(); + removeCCs.set(CommandClasses["All Switch"], "*"); + // @ts-expect-error + config.compat!.removeCCs = removeCCs; + + const hash2 = config.getHash(); + + t.expect(hash1).not.toStrictEqual(hash2); + }, // This test might take a while - t.timeout(60000); - - const configManager = new ConfigManager({ - deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), - }); - const config = (await configManager.lookupDevice( - 0xffff, - 0xcafe, - 0xbeef, - "1.0", - ))!; - t.not(config, undefined); - - const hash1 = config.getHash(); - - const removeCCs = new Map(); - removeCCs.set(CommandClasses["All Switch"], "*"); - // @ts-expect-error - config.compat!.removeCCs = removeCCs; - - const hash2 = config.getHash(); - - t.notDeepEqual(hash1, hash2); -}); - -test("hash() does not crash for devices with a proprietary field", async (t) => { + 60000, +); + +test( + "hash() does not crash for devices with a proprietary field", + async (t) => { + const configManager = new ConfigManager({ + deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), + }); + const config = (await configManager.lookupDevice( + 0xffff, + 0xdead, + 0xbeef, + "1.0", + ))!; + t.expect(config).toBeDefined(); + + config.getHash(); + }, // This test might take a while - t.timeout(60000); - - const configManager = new ConfigManager({ - deviceConfigPriorityDir: path.join(__dirname, "__fixtures/hash"), - }); - const config = (await configManager.lookupDevice( - 0xffff, - 0xdead, - 0xbeef, - "1.0", - ))!; - t.not(config, undefined); - - config.getHash(); -}); + 60000, +); diff --git a/packages/config/src/devices/DeviceConfig.ts b/packages/config/src/devices/DeviceConfig.ts index 7d8e46ea8007..93b346fc839c 100644 --- a/packages/config/src/devices/DeviceConfig.ts +++ b/packages/config/src/devices/DeviceConfig.ts @@ -10,41 +10,41 @@ import { pick, stringify, } from "@zwave-js/shared"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import JSON5 from "json5"; import { createHash } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; import semver from "semver"; -import { clearTemplateCache, readJsonWithTemplate } from "../JsonTemplate"; -import type { ConfigLogger } from "../Logger"; -import { configDir, externalConfigDir } from "../utils"; -import { hexKeyRegex4Digits, throwInvalidConfig } from "../utils_safe"; +import { clearTemplateCache, readJsonWithTemplate } from "../JsonTemplate.js"; +import type { ConfigLogger } from "../Logger.js"; +import { configDir, externalConfigDir } from "../utils.js"; +import { hexKeyRegex4Digits, throwInvalidConfig } from "../utils_safe.js"; import { type AssociationConfig, ConditionalAssociationConfig, -} from "./AssociationConfig"; -import { type CompatConfig, ConditionalCompatConfig } from "./CompatConfig"; -import { evaluateDeep, validateCondition } from "./ConditionalItem"; +} from "./AssociationConfig.js"; +import { type CompatConfig, ConditionalCompatConfig } from "./CompatConfig.js"; +import { evaluateDeep, validateCondition } from "./ConditionalItem.js"; import { type ConditionalPrimitive, parseConditionalPrimitive, -} from "./ConditionalPrimitive"; +} from "./ConditionalPrimitive.js"; import { ConditionalDeviceMetadata, type DeviceMetadata, -} from "./DeviceMetadata"; +} from "./DeviceMetadata.js"; import { ConditionalEndpointConfig, type EndpointConfig, -} from "./EndpointConfig"; +} from "./EndpointConfig.js"; import { type ConditionalParamInfoMap, type ParamInfoMap, type ParamInformation, parseConditionalParamInformationMap, -} from "./ParamInformation"; -import type { DeviceID, FirmwareVersionRange } from "./shared"; +} from "./ParamInformation.js"; +import type { DeviceID, FirmwareVersionRange } from "./shared.js"; export interface DeviceConfigIndexEntry { manufacturerId: string; diff --git a/packages/config/src/devices/DeviceMetadata.ts b/packages/config/src/devices/DeviceMetadata.ts index 80456f5d5349..b70fdf9f6a1b 100644 --- a/packages/config/src/devices/DeviceMetadata.ts +++ b/packages/config/src/devices/DeviceMetadata.ts @@ -1,16 +1,16 @@ import { type JSONObject, pick } from "@zwave-js/shared/safe"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { throwInvalidConfig } from "../utils_safe"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { throwInvalidConfig } from "../utils_safe.js"; import { type ConditionalItem, conditionApplies, evaluateDeep, -} from "./ConditionalItem"; +} from "./ConditionalItem.js"; import { type ConditionalPrimitive, parseConditionalPrimitive, -} from "./ConditionalPrimitive"; -import type { DeviceID } from "./shared"; +} from "./ConditionalPrimitive.js"; +import type { DeviceID } from "./shared.js"; export class ConditionalDeviceMetadata implements ConditionalItem diff --git a/packages/config/src/devices/EndpointConfig.ts b/packages/config/src/devices/EndpointConfig.ts index 5863ff95010f..3796c955d315 100644 --- a/packages/config/src/devices/EndpointConfig.ts +++ b/packages/config/src/devices/EndpointConfig.ts @@ -1,23 +1,23 @@ import type { JSONObject } from "@zwave-js/shared/safe"; -import { isObject } from "alcalzone-shared/typeguards"; -import { throwInvalidConfig } from "../utils_safe"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; +import { throwInvalidConfig } from "../utils_safe.js"; import { type AssociationConfig, ConditionalAssociationConfig, -} from "./AssociationConfig"; +} from "./AssociationConfig.js"; import { type ConditionalItem, conditionApplies, evaluateDeep, validateCondition, -} from "./ConditionalItem"; -import type { ConditionalDeviceConfig } from "./DeviceConfig"; +} from "./ConditionalItem.js"; +import type { ConditionalDeviceConfig } from "./DeviceConfig.js"; import { type ConditionalParamInfoMap, type ParamInfoMap, parseConditionalParamInformationMap, -} from "./ParamInformation"; -import type { DeviceID } from "./shared"; +} from "./ParamInformation.js"; +import type { DeviceID } from "./shared.js"; export class ConditionalEndpointConfig implements ConditionalItem diff --git a/packages/config/src/devices/ParamInformation.ts b/packages/config/src/devices/ParamInformation.ts index 7d26dc676d08..57f5c9aa5d8b 100644 --- a/packages/config/src/devices/ParamInformation.ts +++ b/packages/config/src/devices/ParamInformation.ts @@ -5,16 +5,16 @@ import { type ReadonlyObjectKeyMap, pick, } from "@zwave-js/shared/safe"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { throwInvalidConfig } from "../utils_safe"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { throwInvalidConfig } from "../utils_safe.js"; import { type ConditionalItem, conditionApplies, evaluateDeep, validateCondition, -} from "./ConditionalItem"; -import type { ConditionalDeviceConfig } from "./DeviceConfig"; -import type { DeviceID } from "./shared"; +} from "./ConditionalItem.js"; +import type { ConditionalDeviceConfig } from "./DeviceConfig.js"; +import type { DeviceID } from "./shared.js"; export class ConditionalParamInformation implements ConditionalItem diff --git a/packages/config/src/devices/lookupDevice.test.ts b/packages/config/src/devices/lookupDevice.test.ts index 2116e33a7b0b..31120f84af7a 100644 --- a/packages/config/src/devices/lookupDevice.test.ts +++ b/packages/config/src/devices/lookupDevice.test.ts @@ -1,45 +1,56 @@ -import test from "ava"; -import { ConfigManager } from "../ConfigManager"; +import { test } from "vitest"; +import { ConfigManager } from "../ConfigManager.js"; -test("Z-TRM3 with commandClasses.add compat should work", async (t) => { +test( + "Z-TRM3 with commandClasses.add compat should work", + async (t) => { + const configManager = new ConfigManager(); + const config = await configManager.lookupDevice( + 0x019b, + 0x0003, + 0x0203, + "4.0", + ); + t.expect(config).toBeDefined(); + t.expect(config?.compat?.addCCs?.get(49)?.endpoints.size).toBe(3); + }, // This test might take a while - t.timeout(60000); + 60000, +); - const configManager = new ConfigManager(); - const config = await configManager.lookupDevice( - 0x019b, - 0x0003, - 0x0203, - "4.0", - ); - t.not(config, undefined); - t.is(config?.compat?.addCCs?.get(49)?.endpoints.size, 3); -}); +test( + "Associations on endpoints should work - including imports", + async (t) => { + // Logic Group ZDB5100 -test("Associations on endpoints should work - including imports", async (t) => { + const configManager = new ConfigManager(); + const config = await configManager.lookupDevice( + 0x0234, + 0x0003, + 0x0121, + "0.0", + ); + t.expect(config).toBeDefined(); + t.expect(config?.endpoints?.get(0)?.associations?.get(2)).toMatchObject( + { + label: "Button 1 (Basic Report)", + maxNodes: 5, + }, + ); + t.expect(config?.endpoints?.get(1)?.associations?.get(1)).toMatchObject( + { + label: "Lifeline", + maxNodes: 5, + isLifeline: false, + }, + ); + t.expect(config?.endpoints?.get(4)?.associations?.get(3)).toMatchObject( + { + label: "Button 4 (Binary Switch Set)", + maxNodes: 5, + }, + ); + }, // This test might take a while - t.timeout(60000); - // Logic Group ZDB5100 - - const configManager = new ConfigManager(); - const config = await configManager.lookupDevice( - 0x0234, - 0x0003, - 0x0121, - "0.0", - ); - t.not(config, undefined); - t.like(config?.endpoints?.get(0)?.associations?.get(2), { - label: "Button 1 (Basic Report)", - maxNodes: 5, - }); - t.like(config?.endpoints?.get(1)?.associations?.get(1), { - label: "Lifeline", - maxNodes: 5, - isLifeline: false, - }); - t.like(config?.endpoints?.get(4)?.associations?.get(3), { - label: "Button 4 (Binary Switch Set)", - maxNodes: 5, - }); -}); + 60000, +); diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 5ce093187b8f..1264299118fb 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ -export * from "./ConfigManager"; -export * from "./Logger_safe"; -export * from "./Manufacturers"; -export { PACKAGE_VERSION } from "./_version"; -export * from "./devices/AssociationConfig"; -export * from "./devices/CompatConfig"; -export * from "./devices/DeviceConfig"; -export * from "./devices/DeviceMetadata"; -export * from "./devices/EndpointConfig"; -export * from "./devices/ParamInformation"; -export * from "./devices/shared"; -export { externalConfigDir } from "./utils"; +export * from "./ConfigManager.js"; +export * from "./Logger_safe.js"; +export * from "./Manufacturers.js"; +export { PACKAGE_VERSION } from "./_version.js"; +export * from "./devices/AssociationConfig.js"; +export * from "./devices/CompatConfig.js"; +export * from "./devices/DeviceConfig.js"; +export * from "./devices/DeviceMetadata.js"; +export * from "./devices/EndpointConfig.js"; +export * from "./devices/ParamInformation.js"; +export * from "./devices/shared.js"; +export { externalConfigDir } from "./utils.js"; diff --git a/packages/config/src/index_safe.ts b/packages/config/src/index_safe.ts index 8a8f4b15a917..709b2e58b9b3 100644 --- a/packages/config/src/index_safe.ts +++ b/packages/config/src/index_safe.ts @@ -1,4 +1,4 @@ /* @forbiddenImports external */ -export * from "./Logger_safe"; -export { PACKAGE_VERSION } from "./_version"; +export * from "./Logger_safe.js"; +export { PACKAGE_VERSION } from "./_version.js"; diff --git a/packages/config/src/utils.ts b/packages/config/src/utils.ts index fd404c2b4810..c6ca5022adee 100644 --- a/packages/config/src/utils.ts +++ b/packages/config/src/utils.ts @@ -1,10 +1,13 @@ import { copyFilesRecursive, formatId, padVersion } from "@zwave-js/shared"; import fs from "node:fs/promises"; +import { createRequire } from "node:module"; import path from "node:path"; import * as semver from "semver"; -import type { ConfigLogger } from "./Logger"; -import { PACKAGE_VERSION } from "./_version"; -import type { DeviceConfigIndexEntry } from "./devices/DeviceConfig"; +import type { ConfigLogger } from "./Logger.js"; +import { PACKAGE_VERSION } from "./_version.js"; +import type { DeviceConfigIndexEntry } from "./devices/DeviceConfig.js"; + +const require = createRequire(import.meta.url); /** The absolute path of the embedded configuration directory */ export const configDir = path.resolve( diff --git a/packages/config/tsconfig.build.json b/packages/config/tsconfig.build.json index 4bc6c0f40de6..0aba2689cc96 100644 --- a/packages/config/tsconfig.build.json +++ b/packages/config/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/core/ava.config.cjs b/packages/core/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/core/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/core/package.json b/packages/core/package.json index 1d3c7c6f3a39..ec98800c05c8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -6,27 +6,28 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./test": { "@@dev": "./src/index_test.ts", - "types": "./build/index_test.d.ts", - "default": "./build/index_test.js" + "import": "./build/esm/index_test.js", + "require": "./build/cjs/index_test.js" }, "./package.json": "./package.json" }, "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -48,13 +49,14 @@ "node": ">= 18" }, "scripts": { - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "dependencies": { "@alcalzone/jsonl-db": "^3.1.1", @@ -72,16 +74,16 @@ "winston-transport": "^4.8.0" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "@types/semver": "^7.5.8", "@types/sinon": "^17.0.3", "@types/triple-beam": "^1.3.5", - "ava": "^6.1.3", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", "sinon": "^19.0.2", - "typescript": "5.6.2" + "tsx": "^4.19.2", + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/core/src/capabilities/ControllerCapabilities.ts b/packages/core/src/capabilities/ControllerCapabilities.ts index 17d3f4641566..2806fd078507 100644 --- a/packages/core/src/capabilities/ControllerCapabilities.ts +++ b/packages/core/src/capabilities/ControllerCapabilities.ts @@ -1,6 +1,6 @@ -import { type NodeType } from "./NodeInfo"; -import { type ZWaveApiVersion } from "./ZWaveApiVersion"; -import { type UnknownZWaveChipType } from "./ZWaveChipTypes"; +import { type NodeType } from "./NodeInfo.js"; +import { type ZWaveApiVersion } from "./ZWaveApiVersion.js"; +import { type UnknownZWaveChipType } from "./ZWaveChipTypes.js"; // These flags are a mess and sometimes have a different meaning than their name implies export enum ControllerCapabilityFlags { diff --git a/packages/core/src/capabilities/NodeInfo.test.ts b/packages/core/src/capabilities/NodeInfo.test.ts index 3b13d6f168ac..0c0369fa712c 100644 --- a/packages/core/src/capabilities/NodeInfo.test.ts +++ b/packages/core/src/capabilities/NodeInfo.test.ts @@ -1,10 +1,10 @@ import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; -import { CommandClasses } from "./CommandClasses"; +import { test } from "vitest"; +import { CommandClasses } from "./CommandClasses.js"; import { parseApplicationNodeInformation, parseNodeUpdatePayload, -} from "./NodeInfo"; +} from "./NodeInfo.js"; test("parseApplicationNodeInformation() should parse correctly", (t) => { const payload = Bytes.from([ @@ -19,9 +19,9 @@ test("parseApplicationNodeInformation() should parse correctly", (t) => { ]); const eif = parseApplicationNodeInformation(payload); - t.is(eif.genericDeviceClass, 0x01); - t.is(eif.specificDeviceClass, 0x02); - t.deepEqual(eif.supportedCCs, [ + t.expect(eif.genericDeviceClass).toBe(0x01); + t.expect(eif.specificDeviceClass).toBe(0x02); + t.expect(eif.supportedCCs).toStrictEqual([ CommandClasses["Multi Channel"], CommandClasses["Multilevel Toggle Switch"], ]); @@ -40,12 +40,12 @@ test("parseNodeUpdatePayload() should parse correctly", (t) => { ]); const nup = parseNodeUpdatePayload(payload); - t.is(nup.nodeId, 5); - t.is(nup.basicDeviceClass, 3); - t.is(nup.genericDeviceClass, 1); - t.is(nup.specificDeviceClass, 2); + t.expect(nup.nodeId).toBe(5); + t.expect(nup.basicDeviceClass).toBe(3); + t.expect(nup.genericDeviceClass).toBe(1); + t.expect(nup.specificDeviceClass).toBe(2); - t.deepEqual(nup.supportedCCs, [ + t.expect(nup.supportedCCs).toStrictEqual([ CommandClasses["Multi Channel"], CommandClasses["Multilevel Toggle Switch"], ]); @@ -70,7 +70,7 @@ test("parseNodeUpdatePayload() parses extended CCs correctly", (t) => { ]); const nup = parseNodeUpdatePayload(payload); - t.deepEqual(nup.supportedCCs, [ + t.expect(nup.supportedCCs).toStrictEqual([ CommandClasses["Security Mark"], CommandClasses["Sensor Configuration"], CommandClasses.Supervision, diff --git a/packages/core/src/capabilities/NodeInfo.ts b/packages/core/src/capabilities/NodeInfo.ts index 5a1897eed2a9..82ab7d8f3c13 100644 --- a/packages/core/src/capabilities/NodeInfo.ts +++ b/packages/core/src/capabilities/NodeInfo.ts @@ -1,9 +1,9 @@ import { Bytes } from "@zwave-js/shared/safe"; import { sum } from "@zwave-js/shared/safe"; -import { NodeIDType } from "../consts"; -import { type BasicDeviceClass } from "../index_safe"; -import { validatePayload } from "../util/misc"; -import { CommandClasses } from "./CommandClasses"; +import { NodeIDType } from "../consts/index.js"; +import { type BasicDeviceClass } from "../index_safe.js"; +import { validatePayload } from "../util/misc.js"; +import { CommandClasses } from "./CommandClasses.js"; export interface ApplicationNodeInformation { genericDeviceClass: number; diff --git a/packages/core/src/capabilities/ZWaveChipTypes.ts b/packages/core/src/capabilities/ZWaveChipTypes.ts index 4845411e7695..b279f345c6b9 100644 --- a/packages/core/src/capabilities/ZWaveChipTypes.ts +++ b/packages/core/src/capabilities/ZWaveChipTypes.ts @@ -1,4 +1,4 @@ -import { type MaybeNotKnown } from "../values/Primitive"; +import { type MaybeNotKnown } from "../values/Primitive.js"; const chipTypes = Object.freeze({ [0x0102]: "ZW0102", diff --git a/packages/core/src/consts/Transmission.test.ts b/packages/core/src/consts/Transmission.test.ts index 910575f11f87..82a4f51e1ade 100644 --- a/packages/core/src/consts/Transmission.test.ts +++ b/packages/core/src/consts/Transmission.test.ts @@ -1,5 +1,5 @@ -import test from "ava"; -import { MessagePriority, isMessagePriority } from "./Transmission"; +import { test } from "vitest"; +import { MessagePriority, isMessagePriority } from "./Transmission.js"; test("isMessagePriority() should detect numbers in the enum range as a message priority", (t) => { const numericKeys = Object.keys(MessagePriority) @@ -8,13 +8,13 @@ test("isMessagePriority() should detect numbers in the enum range as a message p const minKey = Math.min(...numericKeys); const maxKey = Math.max(...numericKeys); for (let num = minKey - 2; num <= maxKey + 2; num++) { - t.is(isMessagePriority(num), num >= minKey && num <= maxKey); + t.expect(isMessagePriority(num)).toBe(num >= minKey && num <= maxKey); } }); test("isMessagePriority() should not detect anything else as a message priority", (t) => { const notAPriority: any[] = [null, undefined, "", [], {}, true, false]; for (const stuff of notAPriority) { - t.false(isMessagePriority(stuff)); + t.expect(isMessagePriority(stuff)).toBe(false); } }); diff --git a/packages/core/src/consts/Transmission.ts b/packages/core/src/consts/Transmission.ts index ba8c07ac2ca8..d7a50f43db36 100644 --- a/packages/core/src/consts/Transmission.ts +++ b/packages/core/src/consts/Transmission.ts @@ -1,9 +1,9 @@ import { num2hex } from "@zwave-js/shared/safe"; -import { isObject } from "alcalzone-shared/typeguards"; -import type { ProtocolDataRate } from "../capabilities/Protocols"; -import { type SecurityClass } from "../security/SecurityClass"; -import type { CCId } from "../traits/CommandClasses"; -import { Duration } from "../values/Duration"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; +import type { ProtocolDataRate } from "../capabilities/Protocols.js"; +import { type SecurityClass } from "../security/SecurityClass.js"; +import type { CCId } from "../traits/CommandClasses.js"; +import { Duration } from "../values/Duration.js"; /** The priority of messages, sorted from high (0) to low (>0) */ export enum MessagePriority { diff --git a/packages/core/src/consts/index.ts b/packages/core/src/consts/index.ts index 90c6f1c1ac78..0465e2fe27ab 100644 --- a/packages/core/src/consts/index.ts +++ b/packages/core/src/consts/index.ts @@ -33,10 +33,10 @@ export const HOMEID_BYTES = 4; /** How many repeaters can appear in a route */ export const MAX_REPEATERS = 4; -export { ControllerStatus } from "./ControllerStatus"; -export { InterviewStage } from "./InterviewStage"; -export { NodeStatus } from "./NodeStatus"; -export * from "./Transmission"; +export { ControllerStatus } from "./ControllerStatus.js"; +export { InterviewStage } from "./InterviewStage.js"; +export { NodeStatus } from "./NodeStatus.js"; +export * from "./Transmission.js"; export const MAX_SUPERVISION_SESSION_ID = 0b111111; diff --git a/packages/core/src/error/ZWaveError.test.ts b/packages/core/src/error/ZWaveError.test.ts index 47e7a55feed6..a58849a5a4de 100644 --- a/packages/core/src/error/ZWaveError.test.ts +++ b/packages/core/src/error/ZWaveError.test.ts @@ -1,6 +1,6 @@ -import test from "ava"; -import { assertZWaveError } from "../test/assertZWaveError"; -import { ZWaveError, ZWaveErrorCodes } from "./ZWaveError"; +import { test } from "vitest"; +import { assertZWaveError } from "../test/assertZWaveError.js"; +import { ZWaveError, ZWaveErrorCodes } from "./ZWaveError.js"; const err = new ZWaveError( "Test message", @@ -12,13 +12,12 @@ function thisThrows() { } test("ZWaveError should be of type Error", (t) => { - t.true(err instanceof Error); + t.expect(err instanceof Error).toBe(true); }); test("ZWaveError should contain an error code", (t) => { - assertZWaveError(t, thisThrows, { + assertZWaveError(t.expect, thisThrows, { messageMatches: "Test message", errorCode: ZWaveErrorCodes.PacketFormat_Invalid, }); - t.pass(); }); diff --git a/packages/core/src/error/ZWaveError.ts b/packages/core/src/error/ZWaveError.ts index 22eea51f4171..05bfbf7d7c28 100644 --- a/packages/core/src/error/ZWaveError.ts +++ b/packages/core/src/error/ZWaveError.ts @@ -1,4 +1,4 @@ -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; /** * Used to identify errors from this library without relying on the specific wording of the error message diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 32ad022aa963..5b756bbee481 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,50 +1,50 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ -export * from "./capabilities/CommandClasses"; -export * from "./capabilities/ControllerCapabilities"; -export * from "./capabilities/LibraryTypes"; -export * from "./capabilities/NodeInfo"; -export * from "./capabilities/Protocols"; -export * from "./capabilities/RFRegion"; -export * from "./capabilities/ZWaveApiVersion"; -export * from "./capabilities/ZWaveChipTypes"; -export * from "./consts"; -export * from "./error/ZWaveError"; -export * from "./log/Controller"; -export * from "./log/shared"; -export * from "./log/shared_safe"; -export * from "./registries/DeviceClasses"; -export * from "./registries/Indicators"; -export * from "./registries/Meters"; -export * from "./registries/Notifications"; -export * from "./registries/Scales"; -export * from "./registries/Sensors"; -export * from "./security/DSK"; -export * from "./security/Manager"; -export * from "./security/Manager2"; -export * from "./security/QR"; -export * from "./security/SecurityClass"; -export * from "./security/crypto"; -export * from "./security/ctr_drbg"; -export * from "./security/shared_safe"; -export * from "./test/assertZWaveError"; -export * from "./traits/CommandClasses"; -export * from "./traits/Endpoints"; -export * from "./traits/Nodes"; -export * from "./traits/SecurityManagers"; -export * from "./util/_Types"; -export * from "./util/compareVersions"; -export * from "./util/config"; -export * from "./util/crc"; -export * from "./util/date"; -export * from "./util/decorators"; -export * from "./util/firmware"; -export * from "./util/graph"; -export * from "./util/misc"; -export * from "./values/Cache"; -export * from "./values/CacheBackedMap"; -export * from "./values/Duration"; -export * from "./values/Metadata"; -export * from "./values/Primitive"; -export * from "./values/Timeout"; -export * from "./values/ValueDB"; -export * from "./values/_Types"; +export * from "./capabilities/CommandClasses.js"; +export * from "./capabilities/ControllerCapabilities.js"; +export * from "./capabilities/LibraryTypes.js"; +export * from "./capabilities/NodeInfo.js"; +export * from "./capabilities/Protocols.js"; +export * from "./capabilities/RFRegion.js"; +export * from "./capabilities/ZWaveApiVersion.js"; +export * from "./capabilities/ZWaveChipTypes.js"; +export * from "./consts/index.js"; +export * from "./error/ZWaveError.js"; +export * from "./log/Controller.js"; +export * from "./log/shared.js"; +export * from "./log/shared_safe.js"; +export * from "./registries/DeviceClasses.js"; +export * from "./registries/Indicators.js"; +export * from "./registries/Meters.js"; +export * from "./registries/Notifications.js"; +export * from "./registries/Scales.js"; +export * from "./registries/Sensors.js"; +export * from "./security/DSK.js"; +export * from "./security/Manager.js"; +export * from "./security/Manager2.js"; +export * from "./security/QR.js"; +export * from "./security/SecurityClass.js"; +export * from "./security/crypto.js"; +export * from "./security/ctr_drbg.js"; +export * from "./security/shared_safe.js"; +export * from "./test/assertZWaveError.js"; +export * from "./traits/CommandClasses.js"; +export * from "./traits/Endpoints.js"; +export * from "./traits/Nodes.js"; +export * from "./traits/SecurityManagers.js"; +export * from "./util/_Types.js"; +export * from "./util/compareVersions.js"; +export * from "./util/config.js"; +export * from "./util/crc.js"; +export * from "./util/date.js"; +export * from "./util/decorators.js"; +export * from "./util/firmware.js"; +export * from "./util/graph.js"; +export * from "./util/misc.js"; +export * from "./values/Cache.js"; +export * from "./values/CacheBackedMap.js"; +export * from "./values/Duration.js"; +export * from "./values/Metadata.js"; +export * from "./values/Primitive.js"; +export * from "./values/Timeout.js"; +export * from "./values/ValueDB.js"; +export * from "./values/_Types.js"; diff --git a/packages/core/src/index_safe.ts b/packages/core/src/index_safe.ts index 7c15660e1ae8..d4b7ff55c8da 100644 --- a/packages/core/src/index_safe.ts +++ b/packages/core/src/index_safe.ts @@ -1,40 +1,40 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ /* @forbiddenImports external */ -export * from "./capabilities/CommandClasses"; -export * from "./capabilities/ControllerCapabilities"; -export * from "./capabilities/LibraryTypes"; -export * from "./capabilities/NodeInfo"; -export * from "./capabilities/Protocols"; -export * from "./capabilities/RFRegion"; -export * from "./capabilities/ZWaveApiVersion"; -export * from "./capabilities/ZWaveChipTypes"; -export * from "./consts"; -export * from "./error/ZWaveError"; -export * from "./log/shared_safe"; -export * from "./registries/DeviceClasses"; -export * from "./registries/Indicators"; -export * from "./registries/Meters"; -export * from "./registries/Notifications"; -export * from "./registries/Scales"; -export * from "./registries/Sensors"; -export * from "./security/DSK"; -export * from "./security/SecurityClass"; -export * from "./security/shared_safe"; -export * from "./traits/CommandClasses"; -export * from "./traits/Endpoints"; -export * from "./traits/Endpoints"; -export * from "./traits/Nodes"; -export * from "./traits/SecurityManagers"; -export * from "./util/_Types"; -export * from "./util/config"; -export * from "./util/crc"; -export * from "./util/graph"; -export * from "./util/misc"; -export * from "./values/Cache"; -export * from "./values/CacheBackedMap"; -export * from "./values/Duration"; -export * from "./values/Metadata"; -export * from "./values/Primitive"; -export * from "./values/Timeout"; -export * from "./values/_Types"; +export * from "./capabilities/CommandClasses.js"; +export * from "./capabilities/ControllerCapabilities.js"; +export * from "./capabilities/LibraryTypes.js"; +export * from "./capabilities/NodeInfo.js"; +export * from "./capabilities/Protocols.js"; +export * from "./capabilities/RFRegion.js"; +export * from "./capabilities/ZWaveApiVersion.js"; +export * from "./capabilities/ZWaveChipTypes.js"; +export * from "./consts/index.js"; +export * from "./error/ZWaveError.js"; +export * from "./log/shared_safe.js"; +export * from "./registries/DeviceClasses.js"; +export * from "./registries/Indicators.js"; +export * from "./registries/Meters.js"; +export * from "./registries/Notifications.js"; +export * from "./registries/Scales.js"; +export * from "./registries/Sensors.js"; +export * from "./security/DSK.js"; +export * from "./security/SecurityClass.js"; +export * from "./security/shared_safe.js"; +export * from "./traits/CommandClasses.js"; +export * from "./traits/Endpoints.js"; +export * from "./traits/Endpoints.js"; +export * from "./traits/Nodes.js"; +export * from "./traits/SecurityManagers.js"; +export * from "./util/_Types.js"; +export * from "./util/config.js"; +export * from "./util/crc.js"; +export * from "./util/graph.js"; +export * from "./util/misc.js"; +export * from "./values/Cache.js"; +export * from "./values/CacheBackedMap.js"; +export * from "./values/Duration.js"; +export * from "./values/Metadata.js"; +export * from "./values/Primitive.js"; +export * from "./values/Timeout.js"; +export * from "./values/_Types.js"; diff --git a/packages/core/src/index_test.ts b/packages/core/src/index_test.ts index 7f08ddbfe8cd..0a81573811b2 100644 --- a/packages/core/src/index_test.ts +++ b/packages/core/src/index_test.ts @@ -1,2 +1,2 @@ -export * from "./test/SpyTransport"; -export * from "./test/assertZWaveError"; +export * from "./test/SpyTransport.js"; +export * from "./test/assertZWaveError.js"; diff --git a/packages/core/src/log/Colorizer.ts b/packages/core/src/log/Colorizer.ts index 9300fc98e2cc..2655e729bc43 100644 --- a/packages/core/src/log/Colorizer.ts +++ b/packages/core/src/log/Colorizer.ts @@ -1,7 +1,7 @@ import colors from "ansi-colors"; import { type TransformFunction, format } from "logform"; import winston from "winston"; -import type { ZWaveLogInfo } from "./shared_safe"; +import type { ZWaveLogInfo } from "./shared_safe.js"; const defaultColors = winston.config.npm.colors; // This is a placeholder diff --git a/packages/core/src/log/Controller.test.ts b/packages/core/src/log/Controller.test.ts index d22cf83739ea..fc408baa75e0 100644 --- a/packages/core/src/log/Controller.test.ts +++ b/packages/core/src/log/Controller.test.ts @@ -1,49 +1,57 @@ -import ava, { type TestFn } from "ava"; -import { CommandClasses } from "../capabilities/CommandClasses"; -import { InterviewStage } from "../consts/InterviewStage"; +import { beforeEach, test as baseTest } from "vitest"; +import { CommandClasses } from "../capabilities/CommandClasses.js"; +import { InterviewStage } from "../consts/InterviewStage.js"; import { SpyTransport, assertLogInfo, assertMessage, -} from "../test/SpyTransport"; -import { ControllerLogger } from "./Controller"; -import { ZWaveLogContainer, createDefaultTransportFormat } from "./shared"; +} from "../test/SpyTransport.js"; +import { ControllerLogger } from "./Controller.js"; +import { ZWaveLogContainer, createDefaultTransportFormat } from "./shared.js"; -interface TestContext { - controllerLogger: ControllerLogger; - spyTransport: SpyTransport; -} - -const test = ava as TestFn; +// Extend the test conte -// Replace all defined transports with a spy transport -test.before((t) => { - t.context.spyTransport = new SpyTransport(); - t.context.spyTransport.format = createDefaultTransportFormat(true, true); - t.context.controllerLogger = new ControllerLogger( - new ZWaveLogContainer({ - transports: [t.context.spyTransport], - }), - ); - // Uncomment this to debug the log outputs manually - // wasSilenced = unsilence(controllerLogger); -}); +interface LocalTestContext { + context: { + controllerLogger: ControllerLogger; + spyTransport: SpyTransport; + }; +} -// Don't spam the console when performing the other tests not related to logging -test.after.always((t) => { - t.context.controllerLogger?.container.updateConfiguration({ - enabled: false, - }); +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Replace all defined transports with a spy transport + const spyTransport = new SpyTransport(); + spyTransport.format = createDefaultTransportFormat(true, true); + const controllerLogger = new ControllerLogger( + new ZWaveLogContainer({ + transports: [spyTransport], + }), + ); + + // Uncomment this to debug the log outputs manually + // unsilence(controllerLogger); + + await use({ controllerLogger, spyTransport }); + + // Don't spam the console when performing the other tests not related to logging + controllerLogger.container.updateConfiguration({ + enabled: false, + }); + }, + { auto: true }, + ], }); -test.beforeEach((t) => { - t.context.spyTransport.spy.resetHistory(); +beforeEach(({ context }) => { + context.spyTransport.spy.resetHistory(); }); -test.serial( +test.sequential( "ControllerLogger.value() -> prints a short tag for the change type", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -52,7 +60,7 @@ test.serial( }; controllerLogger.value("added", { ...baseArgs, newValue: 1 }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[+]"), }); @@ -61,25 +69,23 @@ test.serial( prevValue: 7, newValue: 1, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[~]"), callNumber: 1, }); controllerLogger.value("removed", { ...baseArgs, prevValue: 7 }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[-]"), callNumber: 2, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints a tag including the CC name", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -88,18 +94,16 @@ test.serial( }; controllerLogger.value("added", { ...baseArgs, newValue: 1 }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Basic]"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints a tag including the Node ID", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -112,18 +116,16 @@ test.serial( nodeId: 5, newValue: 1, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Node 005]"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints a secondary tag including the CC endpoint", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -132,7 +134,7 @@ test.serial( }; controllerLogger.value("added", { ...baseArgs, newValue: 1 }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => !msg.includes("[Endpoint"), }); @@ -141,19 +143,17 @@ test.serial( newValue: 1, endpoint: 5, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Endpoint 5]"), callNumber: 1, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints a secondary tag if the value is internal", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -166,7 +166,7 @@ test.serial( newValue: true, internal: true, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[internal]"), }); @@ -174,19 +174,17 @@ test.serial( ...baseArgs, newValue: true, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => !msg.includes("[internal]"), callNumber: 1, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints the name of the property", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -202,20 +200,18 @@ test.serial( }); controllerLogger.value("removed", { ...baseArgs, prevValue: 7 }); for (let callNumber = 0; callNumber < 3; callNumber++) { - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("foo"), callNumber, }); } - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints the name and key of map-like properties", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -232,20 +228,18 @@ test.serial( }); controllerLogger.value("removed", { ...baseArgs, prevValue: 7 }); for (let callNumber = 0; callNumber < 3; callNumber++) { - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("bar[baz]"), callNumber, }); } - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.value() -> prints a the value change according to the change type", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -254,7 +248,7 @@ test.serial( }; controllerLogger.value("added", { ...baseArgs, newValue: 1 }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes(": 1"), }); @@ -263,7 +257,7 @@ test.serial( prevValue: false, newValue: "asdf", }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes(`: false => "asdf"`), callNumber: 1, }); @@ -272,17 +266,15 @@ test.serial( ...baseArgs, prevValue: 5, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("(was 5)"), callNumber: 2, }); - - t.pass(); }, ); -test.serial("ControllerLogger.value() -> stringifies objects", (t) => { - const { controllerLogger, spyTransport } = t.context; +test.sequential("ControllerLogger.value() -> stringifies objects", ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -294,17 +286,15 @@ test.serial("ControllerLogger.value() -> stringifies objects", (t) => { ...baseArgs, newValue: { foo: "bar" }, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes(`{"foo":"bar"}`), }); - - t.pass(); }); -test.serial( +test.sequential( "ControllerLogger.metadata() -> prints a tag including the CC name", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -313,18 +303,16 @@ test.serial( }; controllerLogger.metadataUpdated(baseArgs); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Basic]"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.metadata() -> prints a tag including the Node ID", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -336,18 +324,16 @@ test.serial( ...baseArgs, nodeId: 5, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Node 005]"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.metadata() -> prints a secondary tag including the CC endpoint", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -356,7 +342,7 @@ test.serial( }; controllerLogger.metadataUpdated(baseArgs); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => !msg.includes("[Endpoint"), }); @@ -364,19 +350,17 @@ test.serial( ...baseArgs, endpoint: 5, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Endpoint 5]"), callNumber: 1, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.metadata() -> prints a secondary tag if the value is internal", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -388,24 +372,22 @@ test.serial( ...baseArgs, internal: true, }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[internal]"), }); controllerLogger.metadataUpdated(baseArgs); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => !msg.includes("[internal]"), callNumber: 1, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.metadata() -> it prints the name of the property", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -414,16 +396,14 @@ test.serial( }; controllerLogger.metadataUpdated(baseArgs); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("foo"), }); - - t.pass(); }, ); -test.serial("ControllerLogger.metadata() -> prints the change type", (t) => { - const { controllerLogger, spyTransport } = t.context; +test.sequential("ControllerLogger.metadata() -> prints the change type", ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; const baseArgs = { nodeId: 1, @@ -432,124 +412,110 @@ test.serial("ControllerLogger.metadata() -> prints the change type", (t) => { }; controllerLogger.metadataUpdated(baseArgs); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.endsWith(": metadata updated"), }); - - t.pass(); }); -test.serial( +test.sequential( "ControllerLogger.interviewStage() -> includes a tag for the node ID", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.interviewStage({ id: 7 } as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Node 007]"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.interviewStage() -> logs the name of the interview stage", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.interviewStage({ id: 1, interviewStage: InterviewStage.CommandClasses, } as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("Interview stage completed: CommandClasses"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.interviewStage() -> prints a custom message when the interview is complete", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.interviewStage({ id: 5, interviewStage: InterviewStage.Complete, } as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: " [Node 005] Interview completed", }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.interviewStart() -> includes a tag for the node ID", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.interviewStart({ id: 7 } as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[Node 007]"), }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.interviewStart() -> logs the name of the last interview stage", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.interviewStart({ id: 5, interviewStage: InterviewStage.CommandClasses, } as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: " [Node 005] Beginning interview - last completed stage: CommandClasses", }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.logNode() -> logs short messages correctly", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.logNode(3, "Test"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` [Node 003] Test`, }); controllerLogger.logNode(3, { message: "Test2" }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` [Node 003] Test2`, callNumber: 1, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.logNode() -> logs long messages correctly", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.logNode( 3, "This is a very long message that should be broken into multiple lines maybe sometimes...", ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` [Node 003] This is a very long message that should be broken into multiple lin es maybe sometimes...`, @@ -559,110 +525,102 @@ test.serial( message: "This is a very long message that should be broken into multiple lines maybe sometimes...", }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` [Node 005] This is a very long message that should be broken into multiple lin es maybe sometimes...`, callNumber: 1, }); - - t.pass(); }, ); -test.serial( +test.sequential( "ControllerLogger.logNode() -> logs with the given loglevel", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.logNode(1, "Test", "warn"); - assertLogInfo(t, spyTransport, { level: "warn" }); + assertLogInfo(expect, spyTransport, { level: "warn" }); controllerLogger.logNode(1, { message: "Test", level: "warn", }); - assertLogInfo(t, spyTransport, { level: "warn", callNumber: 1 }); + assertLogInfo(expect, spyTransport, { level: "warn", callNumber: 1 }); }, ); -test.serial( +test.sequential( "ControllerLogger.logNode() -> has a default loglevel of info", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.logNode(3, "Test"); - assertLogInfo(t, spyTransport, { level: "info" }); + assertLogInfo(expect, spyTransport, { level: "info" }); controllerLogger.logNode(3, { message: "Test" }); - assertLogInfo(t, spyTransport, { level: "info", callNumber: 1 }); + assertLogInfo(expect, spyTransport, { level: "info", callNumber: 1 }); }, ); -test.serial("ControllerLogger.logNode() -> logs the direction prefix", (t) => { - const { controllerLogger, spyTransport } = t.context; +test.sequential("ControllerLogger.logNode() -> logs the direction prefix", ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.logNode(3, { message: "Test", direction: "inbound", }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: "« [Node 003] Test", }); controllerLogger.logNode(5, { message: "Test", direction: "outbound", }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: "» [Node 005] Test", callNumber: 1, }); - - t.pass(); }); -test.serial( +test.sequential( "ControllerLogger.print() -> logs short messages correctly", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.print("Test"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` Test`, }); - - t.pass(); }, ); -test.serial("ControllerLogger.print() -> logs long messages correctly", (t) => { - const { controllerLogger, spyTransport } = t.context; +test.sequential("ControllerLogger.print() -> logs long messages correctly", ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.print( "This is a very long message that should be broken into multiple lines maybe sometimes...", ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` This is a very long message that should be broken into multiple lines maybe so metimes...`, }); - - t.pass(); }); -test.serial("ControllerLogger.print() -> logs with the given loglevel", (t) => { - const { controllerLogger, spyTransport } = t.context; +test.sequential("ControllerLogger.print() -> logs with the given loglevel", ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.print("Test", "warn"); - assertLogInfo(t, spyTransport, { level: "warn" }); + assertLogInfo(expect, spyTransport, { level: "warn" }); }); -test.serial( +test.sequential( "ControllerLogger.print() -> has a default loglevel of info", - (t) => { - const { controllerLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { controllerLogger, spyTransport } = context; controllerLogger.print("Test"); - assertLogInfo(t, spyTransport, { level: "info" }); + assertLogInfo(expect, spyTransport, { level: "info" }); }, ); diff --git a/packages/core/src/log/Controller.ts b/packages/core/src/log/Controller.ts index a03a4f467d5e..b8d404b6479c 100644 --- a/packages/core/src/log/Controller.ts +++ b/packages/core/src/log/Controller.ts @@ -1,14 +1,14 @@ -import { isObject } from "alcalzone-shared/typeguards"; -import { CommandClasses } from "../capabilities/CommandClasses"; -import { InterviewStage } from "../consts/InterviewStage"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; +import { CommandClasses } from "../capabilities/CommandClasses.js"; +import { InterviewStage } from "../consts/InterviewStage.js"; import type { ValueAddedArgs, ValueID, ValueNotificationArgs, ValueRemovedArgs, ValueUpdatedArgs, -} from "../values/_Types"; -import { type ZWaveLogContainer, ZWaveLoggerBase, tagify } from "./shared"; +} from "../values/_Types.js"; +import { type ZWaveLogContainer, ZWaveLoggerBase, tagify } from "./shared.js"; import { type DataDirection, type LogContext, @@ -16,7 +16,7 @@ import { type ValueLogContext, getDirectionPrefix, getNodeTag, -} from "./shared_safe"; +} from "./shared_safe.js"; export const CONTROLLER_LABEL = "CNTRLR"; const CONTROLLER_LOGLEVEL = "info"; diff --git a/packages/core/src/log/shared.ts b/packages/core/src/log/shared.ts index 8cfac799f551..19d1b97e84aa 100644 --- a/packages/core/src/log/shared.ts +++ b/packages/core/src/log/shared.ts @@ -6,7 +6,7 @@ import winston from "winston"; import DailyRotateFile from "winston-daily-rotate-file"; import type Transport from "winston-transport"; import type { ConsoleTransportInstance } from "winston/lib/winston/transports"; -import { colorizer } from "./Colorizer"; +import { colorizer } from "./Colorizer.js"; import { CONTROL_CHAR_WIDTH, LOG_WIDTH, @@ -22,7 +22,7 @@ import { timestampFormatShort, timestampPadding, timestampPaddingShort, -} from "./shared_safe"; +} from "./shared_safe.js"; const { combine, timestamp, label } = winston.format; diff --git a/packages/core/src/log/shared_safe.ts b/packages/core/src/log/shared_safe.ts index 08c486a6444a..f46b8cc6e63c 100644 --- a/packages/core/src/log/shared_safe.ts +++ b/packages/core/src/log/shared_safe.ts @@ -1,8 +1,8 @@ -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import type { TransformableInfo } from "logform"; import type { Logger } from "winston"; import type Transport from "winston-transport"; -import type { ValueID } from "../values/_Types"; +import type { ValueID } from "../values/_Types.js"; export const timestampFormatShort = "HH:mm:ss.SSS"; export const timestampPaddingShort = " ".repeat( diff --git a/packages/core/src/registries/Indicators.test.ts b/packages/core/src/registries/Indicators.test.ts index 7289c2d7213a..74ba20190cb3 100644 --- a/packages/core/src/registries/Indicators.test.ts +++ b/packages/core/src/registries/Indicators.test.ts @@ -1,12 +1,12 @@ -import test from "ava"; -import { getIndicatorProperty } from "./Indicators"; +import { test } from "vitest"; +import { getIndicatorProperty } from "./Indicators.js"; test( "getIndicatorProperty() returns the property definition if it is defined", async (t) => { const test1 = getIndicatorProperty(0x01); - t.is(test1.label, "Multilevel"); + t.expect(test1.label).toBe("Multilevel"); - t.is(getIndicatorProperty(0xff), undefined); + t.expect(getIndicatorProperty(0xff)).toBeUndefined(); }, ); diff --git a/packages/core/src/registries/Indicators.ts b/packages/core/src/registries/Indicators.ts index afe0f38c307b..f75fb15b74e8 100644 --- a/packages/core/src/registries/Indicators.ts +++ b/packages/core/src/registries/Indicators.ts @@ -1,4 +1,4 @@ -import { type ValueType } from "../values/Metadata"; +import { type ValueType } from "../values/Metadata.js"; export enum Indicator { "Armed" = 0x01, diff --git a/packages/core/src/registries/Meters.test.ts b/packages/core/src/registries/Meters.test.ts index 84883b8c898a..414ba9aea0fc 100644 --- a/packages/core/src/registries/Meters.test.ts +++ b/packages/core/src/registries/Meters.test.ts @@ -1,13 +1,13 @@ -import test from "ava"; -import { getMeter, getMeterScale } from "./Meters"; +import { test } from "vitest"; +import { getMeter, getMeterScale } from "./Meters.js"; test( "getMeter() returns the meter definition if it is defined", async (t) => { const test1 = getMeter(0x01); - t.is(test1.name, "Electric"); + t.expect(test1.name).toBe("Electric"); - t.is(getMeter(0xff), undefined); + t.expect(getMeter(0xff)).toBeUndefined(); }, ); @@ -16,11 +16,11 @@ test( async (t) => { const test1 = getMeterScale(0x01, 0x01); - t.like(test1, { + t.expect(test1).toMatchObject({ key: 0x01, label: "kVAh", }); - t.is(getMeterScale(0xff, 0xff), undefined); + t.expect(getMeterScale(0xff, 0xff)).toBeUndefined(); }, ); diff --git a/packages/core/src/registries/Scales.test.ts b/packages/core/src/registries/Scales.test.ts index f8150fe3f242..86ab299acf4c 100644 --- a/packages/core/src/registries/Scales.test.ts +++ b/packages/core/src/registries/Scales.test.ts @@ -1,16 +1,16 @@ -import test from "ava"; -import { getNamedScale, getNamedScaleGroup } from "./Scales"; +import { test } from "vitest"; +import { getNamedScale, getNamedScaleGroup } from "./Scales.js"; test( "getNamedScaleGroup() returns the scale group if it is defined", async (t) => { const test1 = getNamedScaleGroup("temperature"); - t.like(test1[0x00], { + t.expect(test1[0x00]).toMatchObject({ label: "Celsius", }); // @ts-expect-error - t.throws(() => getNamedScaleGroup("foobar")); + t.expect(() => getNamedScaleGroup("foobar")).toThrow(); }, ); @@ -19,12 +19,12 @@ test( async (t) => { const test1 = getNamedScale("airPressure", 0x01); - t.like(test1, { + t.expect(test1).toMatchObject({ key: 0x01, unit: "inHg", }); // @ts-expect-error - t.throws(() => getNamedScale("foobar", 999)); + t.expect(() => getNamedScale("foobar", 999)).toThrow(); }, ); diff --git a/packages/core/src/registries/Scales.ts b/packages/core/src/registries/Scales.ts index c5709a6e2e59..ccb78013114d 100644 --- a/packages/core/src/registries/Scales.ts +++ b/packages/core/src/registries/Scales.ts @@ -1,5 +1,5 @@ import { num2hex } from "@zwave-js/shared/safe"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; export interface ScaleDefinition { readonly label: string; diff --git a/packages/core/src/registries/Sensors.test.ts b/packages/core/src/registries/Sensors.test.ts index 7750a0a55c35..9eef6af63620 100644 --- a/packages/core/src/registries/Sensors.test.ts +++ b/packages/core/src/registries/Sensors.test.ts @@ -1,13 +1,13 @@ -import test from "ava"; -import { getSensor, getSensorScale } from "./Sensors"; +import { test } from "vitest"; +import { getSensor, getSensorScale } from "./Sensors.js"; test( "getSensor() returns the sensor definition if it is defined", async (t) => { const test1 = getSensor(0x0a); - t.is(test1.label, "Solar radiation"); + t.expect(test1.label).toBe("Solar radiation"); - t.is(getSensor(0xff), undefined); + t.expect(getSensor(0xff)).toBeUndefined(); }, ); @@ -16,11 +16,11 @@ test( async (t) => { const test1 = getSensorScale(0x01, 0x01); - t.like(test1, { + t.expect(test1).toMatchObject({ key: 0x01, label: "Fahrenheit", }); - t.is(getSensorScale(0xff, 0xff), undefined); + t.expect(getSensorScale(0xff, 0xff)).toBeUndefined(); }, ); diff --git a/packages/core/src/registries/Sensors.ts b/packages/core/src/registries/Sensors.ts index ac18db9d247c..a037f20f29bd 100644 --- a/packages/core/src/registries/Sensors.ts +++ b/packages/core/src/registries/Sensors.ts @@ -4,7 +4,7 @@ import { type ScaleDefinition, type ScaleGroup, getNamedScaleGroup, -} from "./Scales"; +} from "./Scales.js"; export interface SensorDefinition { readonly label: string; diff --git a/packages/core/src/security/DSK.ts b/packages/core/src/security/DSK.ts index e72639c00ba3..3aa4ff5c70ac 100644 --- a/packages/core/src/security/DSK.ts +++ b/packages/core/src/security/DSK.ts @@ -1,7 +1,7 @@ import { Bytes } from "@zwave-js/shared/safe"; -import { padStart } from "alcalzone-shared/strings"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; -import { isValidDSK } from "./shared_safe"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { isValidDSK } from "./shared_safe.js"; export function dskToString(dsk: Uint8Array): string { if (dsk.length !== 16) { diff --git a/packages/core/src/security/Manager.test.ts b/packages/core/src/security/Manager.test.ts index bea9e97b5795..4b7a38027fae 100644 --- a/packages/core/src/security/Manager.test.ts +++ b/packages/core/src/security/Manager.test.ts @@ -1,9 +1,9 @@ /* eslint-disable no-restricted-globals -- crypto methods return Buffers */ import { isUint8Array } from "@zwave-js/shared"; -import test from "ava"; -import crypto, { randomBytes } from "node:crypto"; +import { randomBytes } from "node:crypto"; import sinon from "sinon"; -import { SecurityManager } from "./Manager"; +import { test, vi } from "vitest"; +import { SecurityManager } from "./Manager.js"; const networkKey = Uint8Array.from([ 1, @@ -26,25 +26,31 @@ const networkKey = Uint8Array.from([ const ownNodeId = 1; const options = { networkKey, ownNodeId, nonceTimeout: 500 }; +vi.mock("node:crypto", async () => { + const originalCrypto = await vi.importActual("node:crypto"); + return { + ...originalCrypto, + }; +}); + test("constructor() -> should set the network key, auth key and encryption key", (t) => { const man = new SecurityManager(options); - t.deepEqual(man.networkKey, networkKey); - t.true(isUint8Array(man.authKey)); - t.is(man.authKey.length, 16); - t.true(isUint8Array(man.encryptionKey)); - t.is(man.encryptionKey.length, 16); + t.expect(man.networkKey).toStrictEqual(networkKey); + t.expect(isUint8Array(man.authKey)).toBe(true); + t.expect(man.authKey.length).toBe(16); + t.expect(isUint8Array(man.encryptionKey)).toBe(true); + t.expect(man.encryptionKey.length).toBe(16); }); test("constructor() -> should throw if the network key doesn't have length 16", (t) => { - t.throws( + t.expect( () => new SecurityManager({ networkKey: new Uint8Array(), ownNodeId: 1, nonceTimeout: 500, }), - { message: /16 bytes/ }, - ); + ).toThrowError("16 bytes"); }); test("generateNonce() should return a random Buffer of the given length", (t) => { @@ -54,41 +60,42 @@ test("generateNonce() should return a random Buffer of the given length", (t) => const nonce2 = man.generateNonce(2, 8); const nonce3 = man.generateNonce(2, 8); - t.true(isUint8Array(nonce1)); - t.true(isUint8Array(nonce2)); - t.true(isUint8Array(nonce3)); + t.expect(isUint8Array(nonce1)).toBe(true); + t.expect(isUint8Array(nonce2)).toBe(true); + t.expect(isUint8Array(nonce3)).toBe(true); - t.is(nonce1.length, 8); - t.is(nonce2.length, 8); - t.is(nonce3.length, 8); + t.expect(nonce1.length).toBe(8); + t.expect(nonce2.length).toBe(8); + t.expect(nonce3.length).toBe(8); }); -test("generateNonce() -> should ensure that no collisions happen", (t) => { +test("generateNonce() -> should ensure that no collisions happen", async (t) => { const buf1a = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); const buf1b = Buffer.from([1, 2, 3, 4, 5, 6, 7, 9]); // has the same nonce id const buf2 = Buffer.from([2, 2, 3, 4, 5, 6, 7, 8]); - const fakeRandomBytes = sinon - .stub() - .onFirstCall() - .returns(buf1a) - .onSecondCall() - .returns(buf1b) - .onThirdCall() - .returns(buf2); - sinon.replace(crypto, "randomBytes", fakeRandomBytes); + const originalCrypto = await vi.importActual("node:crypto"); + const mockCrypto = await import("node:crypto"); + mockCrypto.randomBytes = vi.fn() + .mockImplementationOnce(() => buf1a) + .mockImplementationOnce(() => buf1b) + .mockImplementationOnce(() => buf2); + t.onTestFinished(() => { + // @ts-expect-error + mockCrypto.randomBytes = originalCrypto.randomBytes; + }); - // eslint-disable-next-line @typescript-eslint/no-require-imports - const SM: typeof SecurityManager = require("./Manager").SecurityManager; + const SM: typeof SecurityManager = + (await import("./Manager.js")).SecurityManager; const man = new SM(options); const nonce1 = man.generateNonce(2, 8); const nonce2 = man.generateNonce(2, 8); - t.deepEqual(nonce1, buf1a); - t.deepEqual(nonce2, buf2); + t.expect(nonce1).toStrictEqual(buf1a); + t.expect(nonce2).toStrictEqual(buf2); - t.deepEqual(man.getNonce(1), buf1a); - t.deepEqual(man.getNonce(2), buf2); + t.expect(man.getNonce(1)).toStrictEqual(buf1a); + t.expect(man.getNonce(2)).toStrictEqual(buf2); sinon.restore(); }); @@ -100,18 +107,15 @@ test("generateNonce() should store nonces for the current node id", (t) => { const nonce2 = man.generateNonce(2, 8); const nonce3 = man.generateNonce(2, 8); - t.is( + t.expect( man.getNonce({ issuer: 2, nonceId: man.getNonceId(nonce1) }), - undefined, - ); - t.is( + ).toBeUndefined(); + t.expect( man.getNonce({ issuer: 2, nonceId: man.getNonceId(nonce2) }), - undefined, - ); - t.is( + ).toBeUndefined(); + t.expect( man.getNonce({ issuer: 2, nonceId: man.getNonceId(nonce3) }), - undefined, - ); + ).toBeUndefined(); }); test("generateNonce() -> the nonces should expire after the given timeout", (t) => { @@ -119,9 +123,9 @@ test("generateNonce() -> the nonces should expire after the given timeout", (t) const man = new SecurityManager(options); const nonce = man.generateNonce(2, 8); const nonceId = nonce[0]; - t.deepEqual(man.getNonce(nonceId), nonce); + t.expect(man.getNonce(nonceId)).toStrictEqual(nonce); clock.tick(options.nonceTimeout + 50); - t.is(man.getNonce(nonceId), undefined); + t.expect(man.getNonce(nonceId)).toBeUndefined(); clock.restore(); }); @@ -129,7 +133,7 @@ test("generateNonce() -> the nonces should expire after the given timeout", (t) test(`generateNonce() -> should be marked as "reserved"`, (t) => { const man = new SecurityManager(options); man.generateNonce(2, 8); - t.is(man.getFreeNonce(ownNodeId), undefined); + t.expect(man.getFreeNonce(ownNodeId)).toBeUndefined(); }); test("getNonceId() -> should return the first byte of the nonce", (t) => { @@ -139,9 +143,9 @@ test("getNonceId() -> should return the first byte of the nonce", (t) => { const nonce2 = man.generateNonce(2, 8); const nonce3 = man.generateNonce(2, 8); - t.is(man.getNonceId(nonce1), nonce1[0]); - t.is(man.getNonceId(nonce2), nonce2[0]); - t.is(man.getNonceId(nonce3), nonce3[0]); + t.expect(man.getNonceId(nonce1)).toBe(nonce1[0]); + t.expect(man.getNonceId(nonce2)).toBe(nonce2[0]); + t.expect(man.getNonceId(nonce3)).toBe(nonce3[0]); }); test("getNonce() should return a previously generated nonce with the same id", (t) => { @@ -155,19 +159,19 @@ test("getNonce() should return a previously generated nonce with the same id", ( const nonceId2 = man.getNonceId(nonce2); const nonceId3 = man.getNonceId(nonce3); - t.deepEqual(nonce1, man.getNonce(nonceId1)); - t.deepEqual(nonce2, man.getNonce(nonceId2)); - t.deepEqual(nonce3, man.getNonce(nonceId3)); + t.expect(nonce1).toStrictEqual(man.getNonce(nonceId1)); + t.expect(nonce2).toStrictEqual(man.getNonce(nonceId2)); + t.expect(nonce3).toStrictEqual(man.getNonce(nonceId3)); }); test("setNonce() -> should store a given nonce to be retrieved later", (t) => { const man = new SecurityManager(options); - t.is(man.getNonce(1), undefined); + t.expect(man.getNonce(1)).toBeUndefined(); const nonce = randomBytes(8); nonce[0] = 1; man.setNonce(1, { nonce, receiver: 2 }); - t.deepEqual(man.getNonce(1), nonce); + t.expect(man.getNonce(1)).toStrictEqual(nonce); }); test("setNonce -> the nonces should timeout after the given timeout", (t) => { @@ -176,9 +180,9 @@ test("setNonce -> the nonces should timeout after the given timeout", (t) => { const nonce = randomBytes(8); const nonceId = nonce[0]; man.setNonce(nonceId, { nonce, receiver: 2 }); - t.deepEqual(man.getNonce(nonceId), nonce); + t.expect(man.getNonce(nonceId)).toStrictEqual(nonce); clock.tick(options.nonceTimeout + 50); - t.is(man.getNonce(nonceId), undefined); + t.expect(man.getNonce(nonceId)).toBeUndefined(); clock.restore(); }); @@ -195,8 +199,8 @@ test("setNonce -> should mark the nonce as free", (t) => { { nonce, receiver: options.ownNodeId }, ); // Wrong node - t.is(man.getFreeNonce(1), undefined); - t.deepEqual(man.getFreeNonce(2), nonce); + t.expect(man.getFreeNonce(1)).toBeUndefined(); + t.expect(man.getFreeNonce(2)).toStrictEqual(nonce); }); test("setNonce -> when a free nonce expires, it should no longer be free", (t) => { @@ -212,7 +216,7 @@ test("setNonce -> when a free nonce expires, it should no longer be free", (t) = ); clock.tick(options.nonceTimeout + 50); - t.is(man.getFreeNonce(2), undefined); + t.expect(man.getFreeNonce(2)).toBeUndefined(); clock.restore(); }); @@ -221,16 +225,16 @@ test("hasNonce() -> should return whether a nonce id is in the database", (t) => const man = new SecurityManager(options); // Manually set - t.false(man.hasNonce(1)); + t.expect(man.hasNonce(1)).toBe(false); const nonce1 = randomBytes(8); nonce1[0] = 1; man.setNonce(1, { nonce: nonce1, receiver: 2 }); - t.true(man.hasNonce(1)); + t.expect(man.hasNonce(1)).toBe(true); // And generated const nonce2 = man.generateNonce(2, 8); const nonceId2 = man.getNonceId(nonce2); - t.true(man.hasNonce(nonceId2)); + t.expect(man.hasNonce(nonceId2)).toBe(true); }); test("deleteNonce() -> should remove a nonce from the database", (t) => { @@ -240,8 +244,8 @@ test("deleteNonce() -> should remove a nonce from the database", (t) => { const nonceId = man.getNonceId(nonce); man.deleteNonce(nonceId); - t.is(man.getNonce(nonceId), undefined); - t.false(man.hasNonce(nonceId)); + t.expect(man.getNonce(nonceId)).toBeUndefined(); + t.expect(man.hasNonce(nonceId)).toBe(false); }); test("deleteNonce() -> and all other nonces that were created for the same receiver", (t) => { @@ -253,10 +257,10 @@ test("deleteNonce() -> and all other nonces that were created for the same recei const nonceId2 = man.getNonceId(nonce2); man.deleteNonce(nonceId1); - t.is(man.getNonce(nonceId1), undefined); - t.false(man.hasNonce(nonceId1)); - t.is(man.getNonce(nonceId2), undefined); - t.false(man.hasNonce(nonceId2)); + t.expect(man.getNonce(nonceId1)).toBeUndefined(); + t.expect(man.hasNonce(nonceId1)).toBe(false); + t.expect(man.getNonce(nonceId2)).toBeUndefined(); + t.expect(man.hasNonce(nonceId2)).toBe(false); }); test("deleteAllNoncesForReceiver -> should only delete the nonces for the given receiver", (t) => { @@ -271,12 +275,12 @@ test("deleteAllNoncesForReceiver -> should only delete the nonces for the given const nonceId3 = man.getNonceId(nonce3); man.deleteAllNoncesForReceiver(2); - t.is(man.getNonce(nonceId1), undefined); - t.false(man.hasNonce(nonceId1)); - t.is(man.getNonce(nonceId2), undefined); - t.false(man.hasNonce(nonceId2)); - t.not(man.getNonce(nonceId3), undefined); - t.true(man.hasNonce(nonceId3)); + t.expect(man.getNonce(nonceId1)).toBeUndefined(); + t.expect(man.hasNonce(nonceId1)).toBe(false); + t.expect(man.getNonce(nonceId2)).toBeUndefined(); + t.expect(man.hasNonce(nonceId2)).toBe(false); + t.expect(man.getNonce(nonceId3)).toBeDefined(); + t.expect(man.hasNonce(nonceId3)).toBe(true); }); test("getFreeNonce() -> should reserve the nonce", (t) => { @@ -290,8 +294,8 @@ test("getFreeNonce() -> should reserve the nonce", (t) => { }, { nonce, receiver: options.ownNodeId }, ); - t.deepEqual(man.getFreeNonce(2), nonce); - t.is(man.getFreeNonce(2), undefined); + t.expect(man.getFreeNonce(2)).toStrictEqual(nonce); + t.expect(man.getFreeNonce(2)).toBeUndefined(); }); test("nonces should be stored separately for each node", (t) => { @@ -304,10 +308,10 @@ test("nonces should be stored separately for each node", (t) => { nonce2[0] = nonceId1; const id2 = { issuer: 4, nonceId: nonceId1 }; - t.false(man.hasNonce(id2)); - t.is(man.getNonce(id2), undefined); + t.expect(man.hasNonce(id2)).toBe(false); + t.expect(man.getNonce(id2)).toBeUndefined(); man.setNonce(id2, { nonce: nonce2, receiver: 1 }); - t.true(man.hasNonce(id2)); - t.deepEqual(man.getNonce(id2), nonce2); + t.expect(man.hasNonce(id2)).toBe(true); + t.expect(man.getNonce(id2)).toStrictEqual(nonce2); }); diff --git a/packages/core/src/security/Manager.ts b/packages/core/src/security/Manager.ts index 9fba228c2373..1bf94da01411 100644 --- a/packages/core/src/security/Manager.ts +++ b/packages/core/src/security/Manager.ts @@ -1,8 +1,8 @@ /** Management class and utils for Security S0 */ import { randomBytes } from "node:crypto"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; -import { encryptAES128ECB } from "./crypto"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { encryptAES128ECB } from "./crypto.js"; const authKeyBase = new Uint8Array(16).fill(0x55); const encryptionKeyBase = new Uint8Array(16).fill(0xaa); diff --git a/packages/core/src/security/Manager2.test.ts b/packages/core/src/security/Manager2.test.ts index 4cef371fc1e8..25f2a810adf4 100644 --- a/packages/core/src/security/Manager2.test.ts +++ b/packages/core/src/security/Manager2.test.ts @@ -1,10 +1,10 @@ import { isUint8Array } from "@zwave-js/shared"; -import test from "ava"; import * as crypto from "node:crypto"; -import { ZWaveErrorCodes } from "../error/ZWaveError"; -import { assertZWaveError } from "../test/assertZWaveError"; -import { SecurityManager2 } from "./Manager2"; -import { SecurityClass } from "./SecurityClass"; +import { test } from "vitest"; +import { ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { assertZWaveError } from "../test/assertZWaveError.js"; +import { SecurityManager2 } from "./Manager2.js"; +import { SecurityClass } from "./SecurityClass.js"; function dummyInit( man: SecurityManager2, @@ -32,11 +32,10 @@ function dummyInit( test("nextNonce() -> should throw if the PRNG for the given receiver node has not been initialized", (t) => { const man = new SecurityManager2(); - assertZWaveError(t, () => man.nextNonce(2), { + assertZWaveError(t.expect, () => man.nextNonce(2), { errorCode: ZWaveErrorCodes.Security2CC_NotInitialized, messageMatches: "initialized", }); - t.pass(); }); test("nextNonce() -> should generate a 13-byte nonce otherwise", (t) => { @@ -47,8 +46,8 @@ test("nextNonce() -> should generate a 13-byte nonce otherwise", (t) => { }); const ret = man.nextNonce(2); - t.true(isUint8Array(ret)); - t.is(ret.length, 13); + t.expect(isUint8Array(ret)).toBe(true); + t.expect(ret.length).toBe(13); }); test("nextNonce() -> two nonces should be different", (t) => { @@ -60,14 +59,14 @@ test("nextNonce() -> two nonces should be different", (t) => { const nonce1 = man.nextNonce(2); const nonce2 = man.nextNonce(2); - t.notDeepEqual(nonce1, nonce2); + t.expect(nonce1).not.toStrictEqual(nonce2); }); test("initializeSPAN() -> should throw if either entropy input does not have length 16", (t) => { const man = new SecurityManager2(); const nodeId = 2; assertZWaveError( - t, + t.expect, () => man.initializeSPAN( nodeId, @@ -82,7 +81,7 @@ test("initializeSPAN() -> should throw if either entropy input does not have len ); assertZWaveError( - t, + t.expect, () => man.initializeSPAN( nodeId, @@ -95,14 +94,13 @@ test("initializeSPAN() -> should throw if either entropy input does not have len messageMatches: "16 bytes", }, ); - t.pass(); }); test("initializeSPAN() -> should throw if the node has not been assigned a security class", (t) => { const man = new SecurityManager2(); const nodeId = 2; assertZWaveError( - t, + t.expect, () => man.initializeSPAN( nodeId, @@ -115,14 +113,13 @@ test("initializeSPAN() -> should throw if the node has not been assigned a secur messageMatches: "security class", }, ); - t.pass(); }); test("initializeSPAN() -> should throw if the keys for the node's security class have not been set up", (t) => { const man = new SecurityManager2(); const nodeId = 2; assertZWaveError( - t, + t.expect, () => man.initializeSPAN( nodeId, @@ -135,7 +132,6 @@ test("initializeSPAN() -> should throw if the keys for the node's security class messageMatches: "network key", }, ); - t.pass(); }); test("initializeSPAN() -> should not throw otherwise", (t) => { @@ -145,36 +141,38 @@ test("initializeSPAN() -> should not throw otherwise", (t) => { nodeId, secClass: SecurityClass.S2_Authenticated, }); - t.notThrows(() => + t.expect(() => man.initializeSPAN( nodeId, SecurityClass.S2_Authenticated, new Uint8Array(16), new Uint8Array(16), ) - ); + ).not.toThrow(); }); test("setKeys() -> throws if the network key does not have length 16", (t) => { const man = new SecurityManager2(); assertZWaveError( - t, + t.expect, () => man.setKey(SecurityClass.S2_Authenticated, new Uint8Array(15)), { errorCode: ZWaveErrorCodes.Argument_Invalid, messageMatches: "16 bytes", }, ); - t.pass(); }); test("setKeys() -> throws if the security class is not valid", (t) => { const man = new SecurityManager2(); - assertZWaveError(t, () => man.setKey(-1 as any, new Uint8Array(16)), { - errorCode: ZWaveErrorCodes.Argument_Invalid, - messageMatches: "security class", - }); - t.pass(); + assertZWaveError( + t.expect, + () => man.setKey(-1 as any, new Uint8Array(16)), + { + errorCode: ZWaveErrorCodes.Argument_Invalid, + messageMatches: "security class", + }, + ); }); test("createMulticastGroup() -> should return a different group ID for a different node set", (t) => { @@ -189,7 +187,7 @@ test("createMulticastGroup() -> should return a different group ID for a differe SecurityClass.S2_Authenticated, ); - t.not(group1, group2); + t.expect(group1).not.toBe(group2); }); test("createMulticastGroup() -> should return a different group ID for a different node set for LR nodes", (t) => { @@ -204,7 +202,7 @@ test("createMulticastGroup() -> should return a different group ID for a differe SecurityClass.S2_Authenticated, ); - t.not(group1, group2); + t.expect(group1).not.toBe(group2); }); // @@ -221,7 +219,7 @@ test("createMulticastGroup() -> should return the same group ID for a previously SecurityClass.S2_Authenticated, ); - t.is(group1, group2); + t.expect(group1).toBe(group2); }); test("createMulticastGroup() -> should return the same group ID for a previously used LR node set", (t) => { @@ -236,25 +234,23 @@ test("createMulticastGroup() -> should return the same group ID for a previously SecurityClass.S2_Authenticated, ); - t.is(group1, group2); + t.expect(group1).toBe(group2); }); test("getMulticastKeyAndIV() -> should throw if the MPAN state for the given multicast group has not been initialized", (t) => { const man = new SecurityManager2(); - assertZWaveError(t, () => man.getMulticastKeyAndIV(1), { + assertZWaveError(t.expect, () => man.getMulticastKeyAndIV(1), { errorCode: ZWaveErrorCodes.Security2CC_NotInitialized, messageMatches: "does not exist", }); - t.pass(); }); test("getMulticastKeyAndIV() -> should throw if the multicast group has not been created", (t) => { const man = new SecurityManager2(); - assertZWaveError(t, () => man.getMulticastKeyAndIV(1), { + assertZWaveError(t.expect, () => man.getMulticastKeyAndIV(1), { errorCode: ZWaveErrorCodes.Security2CC_NotInitialized, messageMatches: "does not exist", }); - t.pass(); }); test("getMulticastKeyAndIV() -> should throw if the keys for the group's security class have not been set up", (t) => { @@ -263,11 +259,10 @@ test("getMulticastKeyAndIV() -> should throw if the keys for the group's securit [2, 3, 4], SecurityClass.S2_Authenticated, ); - assertZWaveError(t, () => man.getMulticastKeyAndIV(groupId), { + assertZWaveError(t.expect, () => man.getMulticastKeyAndIV(groupId), { errorCode: ZWaveErrorCodes.Security2CC_NotInitialized, messageMatches: "network key", }); - t.pass(); }); test("getMulticastKeyAndIV() -> should generate a 13-byte IV otherwise", (t) => { @@ -280,8 +275,8 @@ test("getMulticastKeyAndIV() -> should generate a 13-byte IV otherwise", (t) => const ret = man.getMulticastKeyAndIV(groupId).iv; - t.true(isUint8Array(ret)); - t.is(ret.length, 13); + t.expect(isUint8Array(ret)).toBe(true); + t.expect(ret.length).toBe(13); }); test("getMulticastKeyAndIV() -> two nonces for the same group should be different", (t) => { @@ -294,7 +289,8 @@ test("getMulticastKeyAndIV() -> two nonces for the same group should be differen const nonce1 = man.getMulticastKeyAndIV(groupId).iv; const nonce2 = man.getMulticastKeyAndIV(groupId).iv; - t.notDeepEqual(nonce1, nonce2); + + t.expect(nonce1).not.toStrictEqual(nonce2); }); test("getMulticastKeyAndIV() -> two nonces for different groups should be different", (t) => { @@ -311,5 +307,6 @@ test("getMulticastKeyAndIV() -> two nonces for different groups should be differ const nonce1 = man.getMulticastKeyAndIV(group1).iv; const nonce2 = man.getMulticastKeyAndIV(group2).iv; - t.notDeepEqual(nonce1, nonce2); + + t.expect(nonce1).not.toStrictEqual(nonce2); }); diff --git a/packages/core/src/security/Manager2.ts b/packages/core/src/security/Manager2.ts index cb4b6666a6ed..0b0c06541875 100644 --- a/packages/core/src/security/Manager2.ts +++ b/packages/core/src/security/Manager2.ts @@ -3,18 +3,19 @@ import { createWrappingCounter, getEnumMemberName } from "@zwave-js/shared"; import * as crypto from "node:crypto"; import { deflateSync } from "node:zlib"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; -import { MAX_NODES_LR, encodeBitMask } from "../index_safe"; -import { highResTimestamp } from "../util/date"; -import { type S2SecurityClass, SecurityClass } from "./SecurityClass"; -import { increment } from "./bufferUtils"; +import { MAX_NODES_LR } from "../consts/index.js"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { highResTimestamp } from "../util/date.js"; +import { encodeBitMask } from "../values/Primitive.js"; +import { type S2SecurityClass, SecurityClass } from "./SecurityClass.js"; +import { increment } from "./bufferUtils.js"; import { computeNoncePRK, deriveMEI, deriveNetworkKeys, encryptAES128ECB, -} from "./crypto"; -import { CtrDRBG } from "./ctr_drbg"; +} from "./crypto.js"; +import { CtrDRBG } from "./ctr_drbg.js"; interface NetworkKeys { pnk: Uint8Array; diff --git a/packages/core/src/security/QR.test.ts b/packages/core/src/security/QR.test.ts index 67d961d5b7c8..fe134be72b64 100644 --- a/packages/core/src/security/QR.test.ts +++ b/packages/core/src/security/QR.test.ts @@ -1,6 +1,8 @@ -import test from "ava"; -import { SecurityClass, ZWaveErrorCodes, assertZWaveError } from ".."; -import { QRCodeVersion, parseQRCodeString } from "./QR"; +import { test } from "vitest"; +import { ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { assertZWaveError } from "../test/assertZWaveError.js"; +import { QRCodeVersion, parseQRCodeString } from "./QR.js"; +import { SecurityClass } from "./SecurityClass.js"; function createDummyQR(firstDigits: string): string { return firstDigits + "0".repeat(52 - firstDigits.length); @@ -28,10 +30,9 @@ const cases = [ for (const { code, reason } of cases) { test(`QR code parsing -> throws when the QR code ${reason}`, (t) => { - assertZWaveError(t, () => parseQRCodeString(code), { + assertZWaveError(t.expect, () => parseQRCodeString(code), { errorCode: ZWaveErrorCodes.Security2CC_InvalidQRCode, }); - t.pass(); }); } @@ -39,7 +40,7 @@ test("QR code parsing -> Example case: Acme Light Dimmer", (t) => { const result = parseQRCodeString( "900132782003515253545541424344453132333435212223242500100435301537022065520001000000300578", ); - t.deepEqual(result, { + t.expect(result).toStrictEqual({ version: QRCodeVersion.SmartStart, securityClasses: [ SecurityClass.S2_Unauthenticated, @@ -64,7 +65,7 @@ test("QR code parsing -> Example case: Oscorp Door Lock w. UUID", (t) => { const result = parseQRCodeString( "9001346230075152535455414243444531323334352122232425001016387007680220655210100000017002880642002122232425414243444511121314153132333435", ); - t.deepEqual(result, { + t.expect(result).toStrictEqual({ version: QRCodeVersion.SmartStart, securityClasses: [ SecurityClass.S2_Unauthenticated, @@ -92,7 +93,7 @@ test("QR code parsing -> Example case: Acme Light Dimmer w/o SmartStart", (t) => const result = parseQRCodeString( "900032782003515253545541424344453132333435212223242500100435301537022065520001000000300578", ); - t.deepEqual(result, { + t.expect(result).toStrictEqual({ version: QRCodeVersion.S2, securityClasses: [ SecurityClass.S2_Unauthenticated, @@ -117,7 +118,7 @@ test("QR code parsing -> ignore surrounding whitespace", (t) => { const result = parseQRCodeString( " 900032782003515253545541424344453132333435212223242500100435301537022065520001000000300578 ", ); - t.deepEqual(result, { + t.expect(result).toStrictEqual({ version: QRCodeVersion.S2, securityClasses: [ SecurityClass.S2_Unauthenticated, diff --git a/packages/core/src/security/QR.ts b/packages/core/src/security/QR.ts index e5398bc20518..936c3f286dff 100644 --- a/packages/core/src/security/QR.ts +++ b/packages/core/src/security/QR.ts @@ -1,10 +1,10 @@ import { Bytes } from "@zwave-js/shared/safe"; import { createHash } from "node:crypto"; -import { Protocols } from "../capabilities/Protocols"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; -import { parseBitMask } from "../values/Primitive"; -import { dskToString } from "./DSK"; -import { SecurityClass } from "./SecurityClass"; +import { Protocols } from "../capabilities/Protocols.js"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { parseBitMask } from "../values/Primitive.js"; +import { dskToString } from "./DSK.js"; +import { SecurityClass } from "./SecurityClass.js"; function readNumber(qr: string, offset: number, length: number): number { return parseInt(qr.slice(offset, offset + length), 10); diff --git a/packages/core/src/security/SecurityClass.ts b/packages/core/src/security/SecurityClass.ts index cc4e46795593..2f441c295782 100644 --- a/packages/core/src/security/SecurityClass.ts +++ b/packages/core/src/security/SecurityClass.ts @@ -1,4 +1,4 @@ -import type { MaybeNotKnown } from "../values/Primitive"; +import type { MaybeNotKnown } from "../values/Primitive.js"; export enum SecurityClass { /** diff --git a/packages/core/src/security/crypto.test.ts b/packages/core/src/security/crypto.test.ts index 96c557163c16..3566c64f9bda 100644 --- a/packages/core/src/security/crypto.test.ts +++ b/packages/core/src/security/crypto.test.ts @@ -1,13 +1,13 @@ import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; import * as crypto from "node:crypto"; +import { test } from "vitest"; import { computeCMAC, computeMAC, decryptAES128OFB, encryptAES128ECB, encryptAES128OFB, -} from "./crypto"; +} from "./crypto.js"; test("encryptAES128OFB() / decryptAES128OFB() -> should be able to en- and decrypt the same data", (t) => { const plaintextIn = @@ -16,7 +16,7 @@ test("encryptAES128OFB() / decryptAES128OFB() -> should be able to en- and decry const iv = crypto.randomBytes(16); const ciphertext = encryptAES128OFB(Bytes.from(plaintextIn), key, iv); const plaintextOut = decryptAES128OFB(ciphertext, key, iv).toString(); - t.is(plaintextOut, plaintextIn); + t.expect(plaintextOut).toBe(plaintextIn); }); test("encryptAES128ECB() -> should work correctly", (t) => { @@ -24,7 +24,7 @@ test("encryptAES128ECB() -> should work correctly", (t) => { const key = Bytes.from("2b7e151628aed2a6abf7158809cf4f3c", "hex"); const plaintext = Bytes.from("6bc1bee22e409f96e93d7e117393172a", "hex"); const expected = Bytes.from("3ad77bb40d7a3660a89ecaf32466ef97", "hex"); - t.deepEqual(encryptAES128ECB(plaintext, key), expected); + t.expect(encryptAES128ECB(plaintext, key)).toStrictEqual(expected); }); test("encryptAES128OFB() -> should work correctly", (t) => { @@ -33,7 +33,7 @@ test("encryptAES128OFB() -> should work correctly", (t) => { const iv = Bytes.from("000102030405060708090a0b0c0d0e0f", "hex"); const plaintext = Bytes.from("6bc1bee22e409f96e93d7e117393172a", "hex"); const expected = Bytes.from("3b3fd92eb72dad20333449f8e83cfb4a", "hex"); - t.deepEqual(encryptAES128OFB(plaintext, key, iv), expected); + t.expect(encryptAES128OFB(plaintext, key, iv)).toStrictEqual(expected); }); test("encryptAES128OFB() -> should correctly decrypt a real packet", (t) => { @@ -57,7 +57,7 @@ test("encryptAES128OFB() -> should correctly decrypt a real packet", (t) => { "009803008685598e60725a845b7170807aef2526ef", "hex", ); - t.deepEqual(plaintext, expected); + t.expect(plaintext).toStrictEqual(expected); }); test("computeMAC() -> should work correctly", (t) => { @@ -68,7 +68,7 @@ test("computeMAC() -> should work correctly", (t) => { const plaintext = Bytes.from("6bc1bee22e409f96e93d7e117393172a", "hex"); const expected = Bytes.from("7649abac8119b246", "hex"); - t.deepEqual(computeMAC(plaintext, key, iv), expected); + t.expect(computeMAC(plaintext, key, iv)).toStrictEqual(expected); }); test("computeMAC() -> should work correctly (part 2)", (t) => { @@ -80,7 +80,7 @@ test("computeMAC() -> should work correctly (part 2)", (t) => { ); const expected = Bytes.from("2bc20a8aa9bbb371", "hex"); - t.deepEqual(computeMAC(plaintext, key), expected); + t.expect(computeMAC(plaintext, key)).toStrictEqual(expected); }); test("computeCMAC() -> should work correctly (part 1)", (t) => { @@ -89,7 +89,7 @@ test("computeCMAC() -> should work correctly (part 1)", (t) => { const plaintext = new Bytes(); const expected = Bytes.from("BB1D6929E95937287FA37D129B756746", "hex"); - t.deepEqual(computeCMAC(plaintext, key), expected); + t.expect(computeCMAC(plaintext, key)).toStrictEqual(expected); }); test("computeCMAC() -> should work correctly (part 2)", (t) => { @@ -98,7 +98,7 @@ test("computeCMAC() -> should work correctly (part 2)", (t) => { const plaintext = Bytes.from("6BC1BEE22E409F96E93D7E117393172A", "hex"); const expected = Bytes.from("070A16B46B4D4144F79BDD9DD04A287C", "hex"); - t.deepEqual(computeCMAC(plaintext, key), expected); + t.expect(computeCMAC(plaintext, key)).toStrictEqual(expected); }); test("computeCMAC() -> should work correctly (part 3)", (t) => { @@ -110,7 +110,7 @@ test("computeCMAC() -> should work correctly (part 3)", (t) => { ); const expected = Bytes.from("7D85449EA6EA19C823A7BF78837DFADE", "hex"); - t.deepEqual(computeCMAC(plaintext, key), expected); + t.expect(computeCMAC(plaintext, key)).toStrictEqual(expected); }); test("computeCMAC() -> should work correctly (part 4)", (t) => { @@ -122,5 +122,5 @@ test("computeCMAC() -> should work correctly (part 4)", (t) => { ); const expected = Bytes.from("51F0BEBF7E3B9D92FC49741779363CFE", "hex"); - t.deepEqual(computeCMAC(plaintext, key), expected); + t.expect(computeCMAC(plaintext, key)).toStrictEqual(expected); }); diff --git a/packages/core/src/security/crypto.ts b/packages/core/src/security/crypto.ts index cb5638f8309b..beb3fb7e11f1 100644 --- a/packages/core/src/security/crypto.ts +++ b/packages/core/src/security/crypto.ts @@ -1,6 +1,6 @@ import { Bytes } from "@zwave-js/shared/safe"; import * as crypto from "node:crypto"; -import { leftShift1, xor, zeroPad } from "./bufferUtils"; +import { leftShift1, xor, zeroPad } from "./bufferUtils.js"; function encrypt( algorithm: string, diff --git a/packages/core/src/security/ctr_drbg.test.ts b/packages/core/src/security/ctr_drbg.test.ts index dfb5ec243b40..add161f2d942 100644 --- a/packages/core/src/security/ctr_drbg.test.ts +++ b/packages/core/src/security/ctr_drbg.test.ts @@ -1,8 +1,11 @@ import { hexToUint8Array } from "@zwave-js/shared/safe"; -import test from "ava"; import * as fs from "node:fs"; -import * as path from "node:path"; -import { CtrDRBG } from "./ctr_drbg"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { test } from "vitest"; +import { CtrDRBG } from "./ctr_drbg.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); function getVectors(alg: string) { const text = fs.readFileSync( @@ -74,7 +77,7 @@ for (const df of [false, true]) { vector.AdditionalInput[1], ); - t.deepEqual(result, vector.ReturnedBits); + t.expect(result).toStrictEqual(vector.ReturnedBits); }, ); } diff --git a/packages/core/src/security/ctr_drbg.ts b/packages/core/src/security/ctr_drbg.ts index 29eddcc8242c..4db39f8f71bb 100644 --- a/packages/core/src/security/ctr_drbg.ts +++ b/packages/core/src/security/ctr_drbg.ts @@ -16,8 +16,8 @@ */ import { Bytes } from "@zwave-js/shared/safe"; -import { increment } from "./bufferUtils"; -import { encryptAES128ECB } from "./crypto"; +import { increment } from "./bufferUtils.js"; +import { encryptAES128ECB } from "./crypto.js"; const MAX_GENERATE_LENGTH = 65536; // const RESEED_INTERVAL = 0x1000000000000; diff --git a/packages/core/src/test/SpyTransport.ts b/packages/core/src/test/SpyTransport.ts index bce34f2432c2..8768bfeb9124 100644 --- a/packages/core/src/test/SpyTransport.ts +++ b/packages/core/src/test/SpyTransport.ts @@ -1,18 +1,18 @@ -import { ansiRegex, stripColor } from "ansi-colors"; -import type { Assertions } from "ava"; +import c from "ansi-colors"; import sinon from "sinon"; import { MESSAGE } from "triple-beam"; +import { type ExpectStatic } from "vitest"; import Transport from "winston-transport"; -import type { ZWaveLogInfo } from "../log/shared_safe"; +import type { ZWaveLogInfo } from "../log/shared_safe.js"; const timestampRegex = /\d{2}\:\d{2}\:\d{2}\.\d{3}/g; const timestampPrefixRegex = new RegExp( - `^(${ansiRegex.source})?${timestampRegex.source}(${ansiRegex.source})? `, + `^(${c.ansiRegex.source})?${timestampRegex.source}(${c.ansiRegex.source})? `, "gm", ); const channelRegex = /(SERIAL|CNTRLR|DRIVER|RFLCTN)/g; const channelPrefixRegex = new RegExp( - `(${ansiRegex.source})?${channelRegex.source}(${ansiRegex.source})? `, + `(${c.ansiRegex.source})?${channelRegex.source}(${c.ansiRegex.source})? `, "gm", ); @@ -36,7 +36,7 @@ export class SpyTransport extends Transport { /** Tests a printed log message */ export function assertMessage( - t: Assertions, + expect: ExpectStatic, transport: SpyTransport, options: Partial<{ message: string; @@ -51,13 +51,13 @@ export function assertMessage( }>, ): void { const callNumber = options.callNumber || 0; - t.true(transport.spy.callCount > callNumber); + expect(transport.spy.callCount > callNumber).toBe(true); const callArg = transport.spy.getCall(callNumber).args[0]; let actualMessage: string = callArg[MESSAGE]; // By default ignore the color codes const ignoreColor = options.ignoreColor !== false; if (ignoreColor) { - actualMessage = stripColor(actualMessage); + actualMessage = c.stripColor(actualMessage); } // By default, strip away the timestamp and placeholder if (options.ignoreTimestamp !== false) { @@ -73,17 +73,17 @@ export function assertMessage( } if (typeof options.message === "string") { if (ignoreColor) { - options.message = stripColor(options.message); + options.message = c.stripColor(options.message); } - t.is(actualMessage, options.message); + expect(actualMessage).toBe(options.message); } if (typeof options.predicate === "function") { - t.true(options.predicate(actualMessage)); + expect(options.predicate(actualMessage)).toBe(true); } } export function assertLogInfo( - t: Assertions, + expect: ExpectStatic, transport: SpyTransport, options: Partial<{ level: string; @@ -92,13 +92,13 @@ export function assertLogInfo( }>, ): void { const callNumber = options.callNumber || 0; - t.true(transport.spy.callCount > callNumber); + expect(transport.spy.callCount > callNumber).toBe(true); const callArg = transport.spy.getCall(callNumber).args[0]; if (typeof options.level === "string") { - t.is(callArg.level, options.level); + expect(callArg.level).toBe(options.level); } if (typeof options.predicate === "function") { - t.true(options.predicate(callArg)); + expect(options.predicate(callArg)).toBe(true); } } diff --git a/packages/core/src/test/assertZWaveError.ts b/packages/core/src/test/assertZWaveError.ts index ed18c8a6079d..8431bfc443bc 100644 --- a/packages/core/src/test/assertZWaveError.ts +++ b/packages/core/src/test/assertZWaveError.ts @@ -1,5 +1,5 @@ -import type { ExecutionContext } from "ava"; -import type { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; +import { type ExpectStatic } from "vitest"; +import type { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; export interface AssertZWaveErrorOptions { messageMatches?: string | RegExp; @@ -13,15 +13,15 @@ export interface AssertZWaveErrorOptions { * @param options Additional assertions */ export function assertZWaveError( - t: ExecutionContext, + expect: ExpectStatic, valueOrFactory: T, options: AssertZWaveErrorOptions = {}, ): T extends () => PromiseLike ? Promise : void { const { messageMatches, errorCode, context } = options; function _assertZWaveError(e: any): asserts e is ZWaveError { - t.is(e.constructor.name, "ZWaveError"); - t.is(typeof e.code, "number"); + expect(e.constructor.name).toBe("ZWaveError"); + expect(e.code).toBeTypeOf("number"); } function handleError(e: any): void { @@ -30,10 +30,10 @@ export function assertZWaveError( const regex = messageMatches instanceof RegExp ? messageMatches : new RegExp(messageMatches); - t.regex(e.message, regex); + expect(e.message).toMatch(regex); } - if (errorCode != undefined) t.is(e.code, errorCode); - if (context != undefined) t.is(e.context, context); + if (errorCode != undefined) expect(e.code).toBe(errorCode); + if (context != undefined) expect(e.context).toBe(context); } function fail(): never { // We should not be here diff --git a/packages/core/src/traits/CommandClasses.ts b/packages/core/src/traits/CommandClasses.ts index 924ab874dcdb..34dbd3dcb6dc 100644 --- a/packages/core/src/traits/CommandClasses.ts +++ b/packages/core/src/traits/CommandClasses.ts @@ -1,12 +1,12 @@ import type { CommandClassInfo, CommandClasses, -} from "../capabilities/CommandClasses"; +} from "../capabilities/CommandClasses.js"; import type { MulticastDestination, NODE_ID_BROADCAST, NODE_ID_BROADCAST_LR, -} from "../consts"; +} from "../consts/index.js"; /** Identifies which node and/or endpoint a CC is addressed to */ export interface CCAddress { diff --git a/packages/core/src/traits/Endpoints.ts b/packages/core/src/traits/Endpoints.ts index cfc505f789e7..99ec0840f444 100644 --- a/packages/core/src/traits/Endpoints.ts +++ b/packages/core/src/traits/Endpoints.ts @@ -1,4 +1,4 @@ -import { type MulticastDestination } from "../consts/Transmission"; +import { type MulticastDestination } from "../consts/Transmission.js"; /** Identifies an endpoint */ export interface EndpointId { diff --git a/packages/core/src/traits/Nodes.ts b/packages/core/src/traits/Nodes.ts index 80b6fbbac7c3..31fe43dd98f7 100644 --- a/packages/core/src/traits/Nodes.ts +++ b/packages/core/src/traits/Nodes.ts @@ -1,7 +1,7 @@ -import { type FLiRS } from "../capabilities/NodeInfo"; -import { type NodeStatus } from "../consts/NodeStatus"; -import { type MaybeNotKnown } from "../values/Primitive"; -import { type EndpointId, type VirtualEndpointId } from "./Endpoints"; +import { type FLiRS } from "../capabilities/NodeInfo.js"; +import { type NodeStatus } from "../consts/NodeStatus.js"; +import { type MaybeNotKnown } from "../values/Primitive.js"; +import { type EndpointId, type VirtualEndpointId } from "./Endpoints.js"; /** Identifies a node */ export interface NodeId extends EndpointId { diff --git a/packages/core/src/traits/SecurityManagers.ts b/packages/core/src/traits/SecurityManagers.ts index c366240633e5..41a7600d6369 100644 --- a/packages/core/src/traits/SecurityManagers.ts +++ b/packages/core/src/traits/SecurityManagers.ts @@ -1,5 +1,5 @@ -import { type SecurityManager } from "../security/Manager"; -import { type SecurityManager2 } from "../security/Manager2"; +import { type SecurityManager } from "../security/Manager.js"; +import { type SecurityManager2 } from "../security/Manager2.js"; /** Allows accessing the security manager instances */ export interface SecurityManagers { diff --git a/packages/core/src/util/compareVersions.ts b/packages/core/src/util/compareVersions.ts index 9315d0e05b24..50e8661bebfe 100644 --- a/packages/core/src/util/compareVersions.ts +++ b/packages/core/src/util/compareVersions.ts @@ -1,6 +1,6 @@ import { padVersion } from "@zwave-js/shared"; import semver from "semver"; -import { type MaybeNotKnown } from "../values/Primitive"; +import { type MaybeNotKnown } from "../values/Primitive.js"; /** Checks if the SDK version is greater than the given one */ export function sdkVersionGt( diff --git a/packages/core/src/util/crc.test.ts b/packages/core/src/util/crc.test.ts index a2d57c4b1734..92b8cf01c061 100644 --- a/packages/core/src/util/crc.test.ts +++ b/packages/core/src/util/crc.test.ts @@ -1,23 +1,25 @@ import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; -import { CRC16_CCITT } from "./crc"; +import { test } from "vitest"; +import { CRC16_CCITT } from "./crc.js"; // Test cases based on http://srecord.sourceforge.net/crc16-ccitt.html test("CRC16_CCITT() works correctly -> input: (empty)", (t) => { - t.is(CRC16_CCITT(new Bytes()), 0x1d0f); + t.expect(CRC16_CCITT(new Bytes())).toBe(0x1d0f); }); test("CRC16_CCITT() works correctly -> input: A", (t) => { - t.is(CRC16_CCITT(Bytes.from("A", "ascii")), 0x9479); + t.expect(CRC16_CCITT(Bytes.from("A", "ascii"))).toBe(0x9479); }); test("CRC16_CCITT() works correctly -> input: 123456789", (t) => { - t.is(CRC16_CCITT(Bytes.from("123456789", "ascii")), 0xe5cc); + t.expect(CRC16_CCITT(Bytes.from("123456789", "ascii"))).toBe(0xe5cc); }); test("CRC16_CCITT() works correctly -> input: A x 256", (t) => { - t.is(CRC16_CCITT(new Uint8Array(256).fill("A".charCodeAt(0))), 0xe938); + t.expect(CRC16_CCITT(new Uint8Array(256).fill("A".charCodeAt(0)))).toBe( + 0xe938, + ); }); test("CRC16_CCITT() works correctly -> chained with start values", (t) => { @@ -26,5 +28,5 @@ test("CRC16_CCITT() works correctly -> chained with start values", (t) => { for (let i = 0; i < input.length; i++) { crc = CRC16_CCITT(Bytes.from(input[i], "ascii"), crc); } - t.is(crc, 0xe5cc); + t.expect(crc).toBe(0xe5cc); }); diff --git a/packages/core/src/util/date.test.ts b/packages/core/src/util/date.test.ts index f265468c9524..57d47575b220 100644 --- a/packages/core/src/util/date.test.ts +++ b/packages/core/src/util/date.test.ts @@ -1,15 +1,17 @@ -import test from "ava"; -import { formatDate, getDSTInfo } from "./date"; +import { test } from "vitest"; +import { formatDate, getDSTInfo } from "./date.js"; test("formatDate() should work correctly", (t) => { - t.is(formatDate(new Date(2021, 5, 15), "YYYY-MM-DD"), "2021-06-15"); + t.expect(formatDate(new Date(2021, 5, 15), "YYYY-MM-DD")).toBe( + "2021-06-15", + ); }); if (Intl.DateTimeFormat().resolvedOptions().timeZone === "Europe/Berlin") { test("getDSTInfo() should work correctly", (t) => { let dstInfo = getDSTInfo(new Date("2021-05-15T01:00:00.000Z")); - t.deepEqual(dstInfo, { + t.expect(dstInfo).toStrictEqual({ dstOffset: 120, endDate: new Date("2021-10-31T01:00:00.000Z"), standardOffset: 60, @@ -17,7 +19,7 @@ if (Intl.DateTimeFormat().resolvedOptions().timeZone === "Europe/Berlin") { }); dstInfo = getDSTInfo(new Date("2020-11-12T01:00:00.000Z")); - t.deepEqual(dstInfo, { + t.expect(dstInfo).toStrictEqual({ dstOffset: 120, endDate: new Date("2020-10-25T01:00:00.000Z"), standardOffset: 60, diff --git a/packages/core/src/util/firmware.ts b/packages/core/src/util/firmware.ts index 9e2d8fdda7a6..c0063a226893 100644 --- a/packages/core/src/util/firmware.ts +++ b/packages/core/src/util/firmware.ts @@ -1,10 +1,14 @@ import { getErrorMessage, isUint8Array } from "@zwave-js/shared"; import { Bytes } from "@zwave-js/shared/safe"; import * as crypto from "node:crypto"; -import MemoryMap from "nrf-intel-hex"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; -import type { Firmware, FirmwareFileFormat } from "./_Types"; -import { CRC16_CCITT } from "./crc"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; +import type { Firmware, FirmwareFileFormat } from "./_Types.js"; +import { CRC16_CCITT } from "./crc.js"; + +// This package has an incorrect type declaration +import MemoryMap_ from "nrf-intel-hex"; +const MemoryMap = + MemoryMap_ as unknown as typeof import("nrf-intel-hex").default; const firmwareIndicators = { // All aeotec updater exes contain this text diff --git a/packages/core/src/util/graph.test.ts b/packages/core/src/util/graph.test.ts index 4bbca980f7ed..d7bc97041f4b 100644 --- a/packages/core/src/util/graph.test.ts +++ b/packages/core/src/util/graph.test.ts @@ -1,5 +1,5 @@ -import test from "ava"; -import { GraphNode, topologicalSort } from "./graph"; +import { test } from "vitest"; +import { GraphNode, topologicalSort } from "./graph.js"; test("topologicalSort() -> should sort correctly (Test 1)", (t) => { const nodes = [ @@ -13,7 +13,7 @@ test("topologicalSort() -> should sort correctly (Test 1)", (t) => { nodes[1].edges.add(nodes[3]); nodes[2].edges.add(nodes[3]); - t.deepEqual(topologicalSort(nodes), [4, 2, 3, 1]); + t.expect(topologicalSort(nodes)).toStrictEqual([4, 2, 3, 1]); }); test("topologicalSort() -> should sort correctly (Test 2)", (t) => { @@ -28,7 +28,7 @@ test("topologicalSort() -> should sort correctly (Test 2)", (t) => { nodes[3].edges.add(nodes[1]); nodes[2].edges.add(nodes[3]); - t.deepEqual(topologicalSort(nodes), [2, 4, 3, 1]); + t.expect(topologicalSort(nodes)).toStrictEqual([2, 4, 3, 1]); }); test("topologicalSort() -> should throw when there are circular dependencies", (t) => { @@ -43,5 +43,5 @@ test("topologicalSort() -> should throw when there are circular dependencies", ( nodes[3].edges.add(nodes[2]); nodes[2].edges.add(nodes[0]); - t.throws(() => topologicalSort(nodes)); + t.expect(() => topologicalSort(nodes)).toThrow(); }); diff --git a/packages/core/src/util/misc.test.ts b/packages/core/src/util/misc.test.ts index e8f7e9377e87..180dc7d21d4c 100644 --- a/packages/core/src/util/misc.test.ts +++ b/packages/core/src/util/misc.test.ts @@ -1,13 +1,13 @@ -import test from "ava"; -import { ZWaveErrorCodes } from "../error/ZWaveError"; -import { assertZWaveError } from "../test/assertZWaveError"; +import { test } from "vitest"; +import { ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { assertZWaveError } from "../test/assertZWaveError.js"; import { getLegalRangeForBitMask, getMinimumShiftForBitMask, isConsecutiveArray, stripUndefined, validatePayload, -} from "./misc"; +} from "./misc.js"; test("isConsecutiveArray() -> returns true for consecutive arrays", (t) => { const tests = [ @@ -17,12 +17,12 @@ test("isConsecutiveArray() -> returns true for consecutive arrays", (t) => { [-2, -1, 0], ]; for (const test of tests) { - t.true(isConsecutiveArray(test)); + t.expect(isConsecutiveArray(test)).toBe(true); } }); test("isConsecutiveArray() -> returns true for empty arrays", (t) => { - t.true(isConsecutiveArray([])); + t.expect(isConsecutiveArray([])).toBe(true); }); test("isConsecutiveArray() -> returns false otherwise", (t) => { @@ -31,7 +31,7 @@ test("isConsecutiveArray() -> returns false otherwise", (t) => { [1, 2, 3, 2], ]; for (const test of tests) { - t.false(isConsecutiveArray(test)); + t.expect(isConsecutiveArray(test)).toBe(false); } }); @@ -41,7 +41,7 @@ test("stripUndefined() -> keeps objects with no undefined properties as-is", (t) bar: 1, baz: true, }; - t.deepEqual(stripUndefined(obj), obj); + t.expect(stripUndefined(obj)).toStrictEqual(obj); }); test("stripUndefined() -> removes undefined properties from objects", (t) => { @@ -54,7 +54,7 @@ test("stripUndefined() -> removes undefined properties from objects", (t) => { foo: "bar", baz: true, }; - t.deepEqual(stripUndefined(obj), expected); + t.expect(stripUndefined(obj)).toStrictEqual(expected); }); test("stripUndefined() -> does not touch nested properties", (t) => { @@ -63,40 +63,40 @@ test("stripUndefined() -> does not touch nested properties", (t) => { bar: { sub: undefined }, baz: true, }; - t.deepEqual(stripUndefined(obj), obj); + t.expect(stripUndefined(obj)).toStrictEqual(obj); }); test("validatePayload() -> passes when no arguments were given", (t) => { validatePayload(); - t.pass(); }); test("validatePayload() -> passes when all arguments are truthy", (t) => { validatePayload(1); validatePayload(true, "true"); validatePayload({}); - t.pass(); }); test("validatePayload() -> throws a ZWaveError with PacketFormat_InvalidPayload otherwise", (t) => { for (const args of [[false], [true, 0, true]]) { - assertZWaveError(t, () => validatePayload(...args), { + assertZWaveError(t.expect, () => validatePayload(...args), { errorCode: ZWaveErrorCodes.PacketFormat_InvalidPayload, }); } - t.pass(); }); test("validatePayload() -> The error message should contain the rejection reason", (t) => { - assertZWaveError(t, () => validatePayload.withReason("NOPE")(false), { - errorCode: ZWaveErrorCodes.PacketFormat_InvalidPayload, - context: "NOPE", - }); - t.pass(); + assertZWaveError( + t.expect, + () => validatePayload.withReason("NOPE")(false), + { + errorCode: ZWaveErrorCodes.PacketFormat_InvalidPayload, + context: "NOPE", + }, + ); }); test("getMinimumShiftForBitMask() -> returns 0 if the mask is 0", (t) => { - t.is(getMinimumShiftForBitMask(0), 0); + t.expect(getMinimumShiftForBitMask(0)).toBe(0); }); test("getMinimumShiftForBitMask() -> returns the correct bit shift for sensible bit masks", (t) => { @@ -111,13 +111,13 @@ test("getMinimumShiftForBitMask() -> returns the correct bit shift for sensible { input: 0b1011, expected: 0 }, ]; for (const { input, expected } of tests) { - t.is(getMinimumShiftForBitMask(input), expected); + t.expect(getMinimumShiftForBitMask(input)).toBe(expected); } }); test("getLegalRangeForBitMask() -> returns [0,0] if the mask is 0", (t) => { - t.deepEqual(getLegalRangeForBitMask(0, true), [0, 0]); - t.deepEqual(getLegalRangeForBitMask(0, false), [0, 0]); + t.expect(getLegalRangeForBitMask(0, true)).toStrictEqual([0, 0]); + t.expect(getLegalRangeForBitMask(0, false)).toStrictEqual([0, 0]); }); test("getLegalRangeForBitMask returns the correct ranges otherwise", (t) => { @@ -133,7 +133,9 @@ test("getLegalRangeForBitMask returns the correct ranges otherwise", (t) => { { mask: 0b1011, expSigned: [-8, 7], expUnsigned: [0, 15] }, ]; for (const { mask, expSigned, expUnsigned } of tests) { - t.deepEqual(getLegalRangeForBitMask(mask, true), expUnsigned); - t.deepEqual(getLegalRangeForBitMask(mask, false), expSigned); + t.expect(getLegalRangeForBitMask(mask, true)).toStrictEqual( + expUnsigned, + ); + t.expect(getLegalRangeForBitMask(mask, false)).toStrictEqual(expSigned); } }); diff --git a/packages/core/src/util/misc.ts b/packages/core/src/util/misc.ts index a369fe9ef3de..9b3fa3c298b6 100644 --- a/packages/core/src/util/misc.ts +++ b/packages/core/src/util/misc.ts @@ -1,4 +1,4 @@ -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; /** Ensures that the values array is consecutive */ export function isConsecutiveArray(values: number[]): boolean { diff --git a/packages/core/src/values/Cache.test.ts b/packages/core/src/values/Cache.test.ts index 3229fa17d698..0b527f8d498d 100644 --- a/packages/core/src/values/Cache.test.ts +++ b/packages/core/src/values/Cache.test.ts @@ -1,36 +1,36 @@ -import test from "ava"; -import { deserializeCacheValue, serializeCacheValue } from "./Cache"; -import { Duration } from "./Duration"; +import { test } from "vitest"; +import { deserializeCacheValue, serializeCacheValue } from "./Cache.js"; +import { Duration } from "./Duration.js"; test("serializeCacheValue() -> leaves numbers untouched", (t) => { const tests = [1, 2, 6, 7, -1, 0.15]; for (const val of tests) { - t.is(serializeCacheValue(val), val); + t.expect(serializeCacheValue(val)).toBe(val); } }); test("serializeCacheValue() -> leaves strings untouched", (t) => { const tests = ["1", "2", "6", "7", "-1", "0.15"]; for (const val of tests) { - t.is(serializeCacheValue(val), val); + t.expect(serializeCacheValue(val)).toBe(val); } }); test("serializeCacheValue() -> leaves booleans untouched", (t) => { - t.true(serializeCacheValue(true)); + t.expect(serializeCacheValue(true)).toBe(true); }); test("serializeCacheValue() -> leaves arrays untouched", (t) => { const tests = [[], [1, 2, "3"], [false]]; for (const val of tests) { - t.is(serializeCacheValue(val), val); + t.expect(serializeCacheValue(val)).toBe(val); } }); test("serializeCacheValue() -> leaves objects untouched", (t) => { const tests = [{}, { foo: "bar", baz: "inga" }, { 0: 1 }]; for (const val of tests) { - t.deepEqual(serializeCacheValue(val), val); + t.expect(serializeCacheValue(val)).toStrictEqual(val); } }); @@ -40,7 +40,7 @@ test("serializeCacheValue() -> converts Maps into objects", (t) => { [0, 1], ]); const expected = { foo: "bar", 0: 1, $$type$$: "map" }; - t.deepEqual(serializeCacheValue(input), expected); + t.expect(serializeCacheValue(input)).toStrictEqual(expected); }); test("serializeCacheValue() -> converts Durations into objects", (t) => { @@ -50,37 +50,37 @@ test("serializeCacheValue() -> converts Durations into objects", (t) => { value: 2, $$type$$: "duration", }; - t.deepEqual(serializeCacheValue(input), expected); + t.expect(serializeCacheValue(input)).toStrictEqual(expected); }); test("deserializeCacheValue() -> leaves numbers untouched", (t) => { const tests = [1, 2, 6, 7, -1, 0.15]; for (const val of tests) { - t.is(deserializeCacheValue(val), val); + t.expect(deserializeCacheValue(val)).toBe(val); } }); test("deserializeCacheValue() -> leaves strings untouched", (t) => { const tests = ["1", "2", "6", "7", "-1", "0.15"]; for (const val of tests) { - t.is(deserializeCacheValue(val), val); + t.expect(deserializeCacheValue(val)).toBe(val); } }); test("deserializeCacheValue() -> leaves booleans untouched", (t) => { - t.true(deserializeCacheValue(true)); + t.expect(deserializeCacheValue(true)).toBe(true); }); test("deserializeCacheValue() -> leaves arrays untouched", (t) => { const tests = [[], [1, 2, "3"], [false]]; for (const val of tests) { - t.is(deserializeCacheValue(val), val); + t.expect(deserializeCacheValue(val)).toBe(val); } }); test("deserializeCacheValue() -> leaves objects untouched", (t) => { const tests = [{}, { foo: "bar", baz: "inga" }, { 0: 1 }]; for (const val of tests) { - t.deepEqual(deserializeCacheValue(val), val); + t.expect(deserializeCacheValue(val)).toStrictEqual(val); } }); @@ -90,7 +90,7 @@ test("deserializeCacheValue() -> Restores Maps", (t) => { [0, 1], ["foo", "bar"], ]); - t.deepEqual(deserializeCacheValue(input), expected); + t.expect(deserializeCacheValue(input)).toStrictEqual(expected); }); test("deserializeCacheValue() -> restores Durations", (t) => { @@ -99,5 +99,5 @@ test("deserializeCacheValue() -> restores Durations", (t) => { unit: "default", $$type$$: "duration", }; - t.deepEqual(deserializeCacheValue(input), expected); + t.expect(deserializeCacheValue(input)).toStrictEqual(expected); }); diff --git a/packages/core/src/values/Cache.ts b/packages/core/src/values/Cache.ts index 9a61123b00e2..0f53e603be24 100644 --- a/packages/core/src/values/Cache.ts +++ b/packages/core/src/values/Cache.ts @@ -4,11 +4,11 @@ import { isUint8Array, uint8ArrayToHex, } from "@zwave-js/shared/safe"; -import { composeObject } from "alcalzone-shared/objects"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { Duration } from "./Duration"; -import type { ValueMetadata } from "./Metadata"; -import type { ValueID } from "./_Types"; +import { composeObject } from "alcalzone-shared/objects/index.js"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { Duration } from "./Duration.js"; +import type { ValueMetadata } from "./Metadata.js"; +import type { ValueID } from "./_Types.js"; // export type SerializableValue = number | string | boolean | Map | JSONObject; export type SerializedValue = diff --git a/packages/core/src/values/Duration.test.ts b/packages/core/src/values/Duration.test.ts index bc525b6ad7fa..23230827433f 100644 --- a/packages/core/src/values/Duration.test.ts +++ b/packages/core/src/values/Duration.test.ts @@ -1,7 +1,7 @@ -import test from "ava"; -import { ZWaveErrorCodes } from "../error/ZWaveError"; -import { assertZWaveError } from "../test/assertZWaveError"; -import { Duration } from "./Duration"; +import { test } from "vitest"; +import { ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { assertZWaveError } from "../test/assertZWaveError.js"; +import { Duration } from "./Duration.js"; test("constructor() -> should remember the given value and unit", (t) => { const tests = [ @@ -10,8 +10,8 @@ test("constructor() -> should remember the given value and unit", (t) => { ] as const; for (const { unit, value } of tests) { const duration = new Duration(value, unit as any); - t.is(duration.unit, unit); - t.is(duration.value, value); + t.expect(duration.unit).toBe(unit); + t.expect(duration.value).toBe(value); } }); @@ -22,31 +22,31 @@ test("constructor() -> should set the duration to zero for unknown and default", ] as const; for (const { unit, value } of tests) { const duration = new Duration(value, unit as any); - t.is(duration.unit, unit); - t.is(duration.value, 0); + t.expect(duration.unit).toBe(unit); + t.expect(duration.value).toBe(0); } }); test("constructor() -> should change 0 minutes to 0 seconds", (t) => { const duration = new Duration(0, "minutes"); - t.is(duration.unit, "seconds"); - t.is(duration.value, 0); + t.expect(duration.unit).toBe("seconds"); + t.expect(duration.value).toBe(0); }); test("parseReport() -> should correctly parse unknown durations", (t) => { const duration = Duration.parseReport(0xfe); - t.is(duration!.unit, "unknown"); - t.is(duration!.value, 0); + t.expect(duration!.unit).toBe("unknown"); + t.expect(duration!.value).toBe(0); }); test("parseReport() -> should return undefined when undefined is passed", (t) => { const duration = Duration.parseReport(undefined); - t.is(duration, undefined); + t.expect(duration).toBeUndefined(); }); test("parseReport() -> should return undefined when a reserved value is passed", (t) => { const duration = Duration.parseReport(0xff); - t.is(duration, undefined); + t.expect(duration).toBeUndefined(); }); test("parseReport() -> should correctly parse valid durations", (t) => { @@ -58,19 +58,19 @@ test("parseReport() -> should correctly parse valid durations", (t) => { ] as const; for (const { payload, unit, value } of tests) { const duration = Duration.parseReport(payload); - t.is(duration!.unit, unit); - t.is(duration!.value, value); + t.expect(duration!.unit).toBe(unit); + t.expect(duration!.value).toBe(value); } }); test("parseSet() -> should correctly parse default durations", (t) => { const duration = Duration.parseSet(0xff); - t.is(duration!.unit, "default"); - t.is(duration!.value, 0); + t.expect(duration!.unit).toBe("default"); + t.expect(duration!.value).toBe(0); }); test("parseSet() -> should return undefined when undefined is passed", (t) => { const duration = Duration.parseSet(undefined); - t.is(duration, undefined); + t.expect(duration).toBeUndefined(); }); test("parseSet() -> should correctly parse valid durations", (t) => { @@ -85,22 +85,21 @@ test("parseSet() -> should correctly parse valid durations", (t) => { ] as const; for (const { payload, unit, value } of tests) { const duration = Duration.parseSet(payload); - t.is(duration!.unit, unit); - t.is(duration!.value, value); + t.expect(duration!.unit).toBe(unit); + t.expect(duration!.value).toBe(value); } }); test("serializeSet() -> should correctly parse default durations", (t) => { const payload = Duration.default().serializeSet(); - t.is(payload, 0xff); + t.expect(payload).toBe(0xff); }); test("serializeSet() -> should throw for unknown durations", (t) => { const duration = Duration.unknown(); - assertZWaveError(t, () => duration.serializeSet(), { + assertZWaveError(t.expect, () => duration.serializeSet(), { errorCode: ZWaveErrorCodes.CC_Invalid, }); - t.pass(); }); test("serializeSet() -> should correctly serialize valid durations", (t) => { @@ -112,13 +111,13 @@ test("serializeSet() -> should correctly serialize valid durations", (t) => { ]; for (const { expected, unit, value } of tests) { const actual = new Duration(value, unit as any).serializeSet(); - t.is(actual, expected); + t.expect(actual).toBe(expected); } }); test(`toJSON() -> should return a string for "unknown" and "default"`, (t) => { - t.is(new Duration(1, "default").toJSON(), "default"); - t.is(new Duration(1, "unknown").toJSON(), "unknown"); + t.expect(new Duration(1, "default").toJSON()).toBe("default"); + t.expect(new Duration(1, "unknown").toJSON()).toBe("unknown"); }); test("toJSON() -> should return an object with the value and unit otherwise", (t) => { @@ -131,49 +130,68 @@ test("toJSON() -> should return an object with the value and unit otherwise", (t for (const test of tests) { const { unit, value } = test; const actual = new Duration(value, unit).toJSON(); - t.deepEqual(actual, test); + t.expect(actual).toStrictEqual(test); } }); test("parseString() -> should return undefined for unknown or unrepresentable values", (t) => { - t.is(Duration.parseString(""), undefined); - t.is(Duration.parseString("15"), undefined); - t.is(Duration.parseString("33h"), undefined); - t.is(Duration.parseString("not_a_number"), undefined); + t.expect(Duration.parseString("")).toBeUndefined(); + t.expect(Duration.parseString("15")).toBeUndefined(); + t.expect(Duration.parseString("33h")).toBeUndefined(); + t.expect(Duration.parseString("not_a_number")).toBeUndefined(); }); test("parseString() -> should return a duration for seconds", (t) => { - t.deepEqual(Duration.parseString("10s"), new Duration(10, "seconds")); - t.deepEqual(Duration.parseString("25s"), new Duration(25, "seconds")); - t.deepEqual(Duration.parseString("33S"), new Duration(33, "seconds")); + t.expect(Duration.parseString("10s")).toStrictEqual( + new Duration(10, "seconds"), + ); + t.expect(Duration.parseString("25s")).toStrictEqual( + new Duration(25, "seconds"), + ); + t.expect(Duration.parseString("33S")).toStrictEqual( + new Duration(33, "seconds"), + ); }); test(`parseString() -> should return a duration for minutes`, (t) => { - t.deepEqual(Duration.parseString("17m"), new Duration(17, "minutes")); - t.deepEqual(Duration.parseString("22m"), new Duration(22, "minutes")); - t.deepEqual(Duration.parseString("99M"), new Duration(99, "minutes")); + t.expect(Duration.parseString("17m")).toStrictEqual( + new Duration(17, "minutes"), + ); + t.expect(Duration.parseString("22m")).toStrictEqual( + new Duration(22, "minutes"), + ); + t.expect(Duration.parseString("99M")).toStrictEqual( + new Duration(99, "minutes"), + ); }); test("parseString() -> should return a duration for hours", (t) => { - t.deepEqual(Duration.parseString("2h"), new Duration(120, "minutes")); - t.deepEqual(Duration.parseString("1h8s"), new Duration(60, "minutes")); + t.expect(Duration.parseString("2h")).toStrictEqual( + new Duration(120, "minutes"), + ); + t.expect(Duration.parseString("1h8s")).toStrictEqual( + new Duration(60, "minutes"), + ); }); test("parseString() -> should return the nearest possible duration for combined seconds and minutes", (t) => { - t.deepEqual(Duration.parseString("19m18s"), new Duration(19, "minutes")); - t.deepEqual( + t.expect(Duration.parseString("19m18s")).toStrictEqual( + new Duration(19, "minutes"), + ); + t.expect( Duration.parseString("1m10s"), - new Duration(60 + 10, "seconds"), + ).toStrictEqual(new Duration(60 + 10, "seconds")); + t.expect(Duration.parseString("0m9s")).toStrictEqual( + new Duration(9, "seconds"), ); - t.deepEqual(Duration.parseString("0m9s"), new Duration(9, "seconds")); }); test("from() -> should return a duration when a string is passed", (t) => { - t.is(Duration.from(""), undefined); - t.deepEqual(Duration.from("88s"), new Duration(88, "seconds")); + t.expect(Duration.from("")).toBeUndefined(); + t.expect(Duration.from("88s")).toStrictEqual(new Duration(88, "seconds")); }); test("from() -> should return the passed duration when a duration instance is passed", (t) => { const duration = new Duration(137, "minutes"); - t.deepEqual(Duration.from(duration), duration); + t.expect(Duration.from(duration)).toStrictEqual(duration); }); diff --git a/packages/core/src/values/Duration.ts b/packages/core/src/values/Duration.ts index 28446c0229e0..c556064f99f4 100644 --- a/packages/core/src/values/Duration.ts +++ b/packages/core/src/values/Duration.ts @@ -1,6 +1,6 @@ import type { JSONObject } from "@zwave-js/shared"; -import { clamp } from "alcalzone-shared/math"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; +import { clamp } from "alcalzone-shared/math/index.js"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; export type DurationUnit = "seconds" | "minutes" | "unknown" | "default"; diff --git a/packages/core/src/values/Metadata.test.ts b/packages/core/src/values/Metadata.test.ts index f9d168755c06..5c90a1eed89a 100644 --- a/packages/core/src/values/Metadata.test.ts +++ b/packages/core/src/values/Metadata.test.ts @@ -1,5 +1,5 @@ -import test from "ava"; -import { enumValuesToMetadataStates } from "./Metadata"; +import { test } from "vitest"; +import { enumValuesToMetadataStates } from "./Metadata.js"; enum TestEnum { "Easy" = 0x00, @@ -16,7 +16,7 @@ test("enumValuesToMetadataStates() -> should translate the whole enum by default 8: "2 lets have some numbers", 9: "8 and one more", }; - t.deepEqual(actual, expected); + t.expect(actual).toStrictEqual(expected); }); test("enumValuesToMetadataStates() -> should correctly translate a subset if requested", (t) => { @@ -25,5 +25,5 @@ test("enumValuesToMetadataStates() -> should correctly translate a subset if req 0: "Easy", 9: "8 and one more", }; - t.deepEqual(actual, expected); + t.expect(actual).toStrictEqual(expected); }); diff --git a/packages/core/src/values/Metadata.ts b/packages/core/src/values/Metadata.ts index bd6ecfaa4886..401a8afbb5a9 100644 --- a/packages/core/src/values/Metadata.ts +++ b/packages/core/src/values/Metadata.ts @@ -1,6 +1,6 @@ import { getEnumMemberName } from "@zwave-js/shared/safe"; -import type { Duration } from "./Duration"; -import { IntegerLimits } from "./Primitive"; +import type { Duration } from "./Duration.js"; +import { IntegerLimits } from "./Primitive.js"; const isIntegerRegex = /^\d+$/; diff --git a/packages/core/src/values/Primitive.test.ts b/packages/core/src/values/Primitive.test.ts index eb4bde0fe6b2..a4bab766253b 100644 --- a/packages/core/src/values/Primitive.test.ts +++ b/packages/core/src/values/Primitive.test.ts @@ -1,7 +1,7 @@ import { Bytes } from "@zwave-js/shared"; -import test from "ava"; -import { ZWaveErrorCodes } from "../error/ZWaveError"; -import { assertZWaveError } from "../test/assertZWaveError"; +import { test } from "vitest"; +import { ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { assertZWaveError } from "../test/assertZWaveError.js"; import { UNKNOWN_STATE, encodeBitMask, @@ -15,66 +15,66 @@ import { parseMaybeNumber, parseNumber, parsePartial, -} from "./Primitive"; +} from "./Primitive.js"; test("parseBoolean() -> should return false when the value is 0", (t) => { - t.false(parseBoolean(0)); + t.expect(parseBoolean(0)).toBe(false); }); test("parseBoolean() -> should return true when the value is 0xff", (t) => { - t.true(parseBoolean(0xff)); + t.expect(parseBoolean(0xff)).toBe(true); }); test("parseBoolean() -> should return undefined otherwise", (t) => { - t.is(parseBoolean(0x80), undefined); + t.expect(parseBoolean(0x80)).toBeUndefined(); }); test("parseMaybeBoolean() -> should return false when the value is 0", (t) => { - t.false(parseMaybeBoolean(0)); + t.expect(parseMaybeBoolean(0)).toBe(false); }); test("parseMaybeBoolean() -> should return true when the value is 0xff", (t) => { - t.true(parseMaybeBoolean(0xff)); + t.expect(parseMaybeBoolean(0xff)).toBe(true); }); test("parseMaybeBoolean() -> should return unknown when the value is 0xfe", (t) => { - t.is(parseMaybeBoolean(0xfe), UNKNOWN_STATE); + t.expect(parseMaybeBoolean(0xfe)).toBe(UNKNOWN_STATE); }); test("parseMaybeBoolean() -> should return undefined otherwise", (t) => { - t.is(parseMaybeBoolean(0x80), undefined); + t.expect(parseMaybeBoolean(0x80)).toBeUndefined(); }); test("parseNumber() -> should return the value when it is in the range 0..99", (t) => { for (let i = 0; i <= 99; i++) { - t.is(parseNumber(i), i); + t.expect(parseNumber(i)).toBe(i); } }); test("parseNumber() -> should return 99 when the value is 0xff", (t) => { - t.is(parseNumber(0xff), 99); + t.expect(parseNumber(0xff)).toBe(99); }); test("parseNumber() -> should return undefined otherwise", (t) => { - t.is(parseNumber(0x80), undefined); + t.expect(parseNumber(0x80)).toBeUndefined(); }); test("parseMaybeNumber() -> should return the value when it is in the range 0..99", (t) => { for (let i = 0; i <= 99; i++) { - t.is(parseMaybeNumber(i), i); + t.expect(parseMaybeNumber(i)).toBe(i); } }); test("parseMaybeNumber() -> should return 99 when the value is 0xff", (t) => { - t.is(parseMaybeNumber(0xff), 99); + t.expect(parseMaybeNumber(0xff)).toBe(99); }); test("parseMaybeNumber() -> should return unknown when the value is 0xfe", (t) => { - t.is(parseMaybeNumber(0xfe), UNKNOWN_STATE); + t.expect(parseMaybeNumber(0xfe)).toBe(UNKNOWN_STATE); }); test("parseMaybeNumber() -> should return undefined otherwise", (t) => { - t.is(parseMaybeNumber(0x80), undefined); + t.expect(parseMaybeNumber(0x80)).toBeUndefined(); }); test("parseFloatWithScale() -> should correctly extract the scale", (t) => { @@ -85,7 +85,7 @@ test("parseFloatWithScale() -> should correctly extract the scale", (t) => { { payload: Uint8Array.from([0b00011001, 0]), expected: 0b11 }, ]; for (const { payload, expected } of tests) { - t.is(parseFloatWithScale(payload).scale, expected); + t.expect(parseFloatWithScale(payload).scale).toBe(expected); } }); @@ -105,7 +105,7 @@ test("parseFloatWithScale() -> should correctly extract the value", (t) => { for (const { payload, expected, numDigits } of tests) { const diff = Math.abs(expected - parseFloatWithScale(payload).value); const allowed = 10 ** -numDigits / 2; - t.true(diff < allowed); + t.expect(diff < allowed).toBe(true); } }); @@ -133,7 +133,9 @@ test("encodeFloatWithScale() -> should correctly encode the scale", (t) => { }, ]; for (const { scale, value, expected } of tests) { - t.true(encodeFloatWithScale(value, scale).equals(expected)); + t.expect(encodeFloatWithScale(value, scale).equals(expected)).toBe( + true, + ); } }); @@ -147,7 +149,7 @@ test("encodeFloatWithScale() -> should correctly determine the minimum necessary { value: 32768, expected: 4 }, ]; for (const { value, expected } of tests) { - t.is(encodeFloatWithScale(value, 0).length, expected + 1); + t.expect(encodeFloatWithScale(value, 0).length).toBe(expected + 1); } }); @@ -165,7 +167,7 @@ test("encodeFloatWithScale() -> should correctly detect the necessary precision }, ]; for (const { scale, value, expected } of tests) { - t.deepEqual(encodeFloatWithScale(value, scale), expected); + t.expect(encodeFloatWithScale(value, scale)).toStrictEqual(expected); } }); @@ -192,7 +194,9 @@ test("encodeFloatWithScale() -> should use the specified override options", (t) }, ]; for (const { scale, value, override, expected } of tests) { - t.deepEqual(encodeFloatWithScale(value, scale, override), expected); + t.expect(encodeFloatWithScale(value, scale, override)).toStrictEqual( + expected, + ); } }); @@ -206,15 +210,17 @@ test("encodeFloatWithScale() -> should fall back to sane options when the overri }, ]; for (const { scale, value, override, expected } of tests) { - t.deepEqual(encodeFloatWithScale(value, scale, override), expected); + t.expect(encodeFloatWithScale(value, scale, override)).toStrictEqual( + expected, + ); } }); test("encodeFloatWithScale() -> should throw when the value cannot be represented in 4 bytes", (t) => { - assertZWaveError(t, () => encodeFloatWithScale(0xffffffff, 0), { + assertZWaveError(t.expect, () => encodeFloatWithScale(0xffffffff, 0), { errorCode: ZWaveErrorCodes.Arithmetic, }); - assertZWaveError(t, () => encodeFloatWithScale(Number.NaN, 0), { + assertZWaveError(t.expect, () => encodeFloatWithScale(Number.NaN, 0), { errorCode: ZWaveErrorCodes.Arithmetic, }); }); @@ -224,7 +230,7 @@ test("parseBitMask() -> should correctly convert a bit mask into a numeric array { mask: Uint8Array.from([0b11, 0b110]), expected: [1, 2, 10, 11] }, ]; for (const { mask, expected } of tests) { - t.deepEqual(parseBitMask(mask), expected); + t.expect(parseBitMask(mask)).toStrictEqual(expected); } }); @@ -252,7 +258,7 @@ test("parseBitMask() -> should take the 2nd parameter into account when calculat }, ]; for (const { mask, startValue, expected } of tests) { - t.deepEqual(parseBitMask(mask, startValue), expected); + t.expect(parseBitMask(mask, startValue)).toStrictEqual(expected); } }); @@ -270,7 +276,7 @@ test("encodeBitMask() -> should correctly convert a numeric array into a bit mas }, ]; for (const { values, max, expected } of tests) { - t.deepEqual(encodeBitMask(values, max), expected); + t.expect(encodeBitMask(values, max)).toStrictEqual(expected); } }); @@ -280,7 +286,7 @@ test("encodeBitMask() -> should respect the maxValue argument for determining th { values: [1, 2, 10, 11], max: 3, expectedLength: 1 }, ]; for (const { values, max, expectedLength } of tests) { - t.is(encodeBitMask(values, max).length, expectedLength); + t.expect(encodeBitMask(values, max).length).toBe(expectedLength); } }); @@ -300,34 +306,36 @@ test("encodeBitMask() -> should respect the startValue too", (t) => { }, ]; for (const { values, max, startValue, expected } of tests) { - t.deepEqual(encodeBitMask(values, max, startValue), expected); + t.expect(encodeBitMask(values, max, startValue)).toStrictEqual( + expected, + ); } }); test("getMinIntegerSize(signed) -> should return 1 for numbers from -128 to 127", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, true), 1); + t.expect(getMinIntegerSize(val, true)).toBe(1); } [-128, -1, 0, 1, 127].forEach(test); }); test("getMinIntegerSize(signed) -> should return 2 for numbers from -32768 to 32767", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, true), 2); + t.expect(getMinIntegerSize(val, true)).toBe(2); } [-32768, -129, 128, 32767].forEach(test); }); test("getMinIntegerSize(signed) -> should return 4 for numbers from -2147483648 to 2147483647", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, true), 4); + t.expect(getMinIntegerSize(val, true)).toBe(4); } [-2147483648, -32769, 32768, 2147483647].forEach(test); }); test("getMinIntegerSize(signed) -> should return undefined for larger and smaller numbers", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, true), undefined); + t.expect(getMinIntegerSize(val, true)).toBeUndefined(); } [ Number.MIN_SAFE_INTEGER, @@ -339,28 +347,28 @@ test("getMinIntegerSize(signed) -> should return undefined for larger and smalle test("getMinIntegerSize(unsigned) -> should return 1 for numbers from 0 to 255", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, false), 1); + t.expect(getMinIntegerSize(val, false)).toBe(1); } [0, 1, 254, 255].forEach(test); }); test("getMinIntegerSize(unsigned) -> should return 2 for numbers from 256 to 65535", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, false), 2); + t.expect(getMinIntegerSize(val, false)).toBe(2); } [256, 257, 65534, 65535].forEach(test); }); test("getMinIntegerSize(unsigned) -> should return 4 for numbers from 65536 to 4294967295", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, false), 4); + t.expect(getMinIntegerSize(val, false)).toBe(4); } [65536, 65537, 4294967294, 4294967295].forEach(test); }); test("getMinIntegerSize(unsigned) -> should return undefined for larger and smaller numbers", (t) => { function test(val: number) { - t.is(getMinIntegerSize(val, false), undefined); + t.expect(getMinIntegerSize(val, false)).toBeUndefined(); } [Number.MIN_SAFE_INTEGER, -1, 4294967296, Number.MAX_SAFE_INTEGER].forEach( test, @@ -381,7 +389,7 @@ test("parsePartial() -> should work correctly for unsigned partials", (t) => { }, ]; for (const { value, bitMask, expected } of tests) { - t.is(parsePartial(value, bitMask, false), expected); + t.expect(parsePartial(value, bitMask, false)).toBe(expected); } }); @@ -409,7 +417,7 @@ test("parsePartial() -> should work correctly for signed partials", (t) => { }, ]; for (const { value, bitMask, expected } of tests) { - t.is(parsePartial(value, bitMask, true), expected); + t.expect(parsePartial(value, bitMask, true)).toBe(expected); } }); @@ -436,6 +444,8 @@ test("encodePartial() -> should work correctly for signed and unsigned partials" }, ]; for (const { fullValue, partialValue, bitMask, expected } of tests) { - t.is(encodePartial(fullValue, partialValue, bitMask), expected); + t.expect(encodePartial(fullValue, partialValue, bitMask)).toBe( + expected, + ); } }); diff --git a/packages/core/src/values/Primitive.ts b/packages/core/src/values/Primitive.ts index e951bb8b772b..398d349f870c 100644 --- a/packages/core/src/values/Primitive.ts +++ b/packages/core/src/values/Primitive.ts @@ -3,13 +3,13 @@ import { MAX_NODES_LR, NUM_LR_NODES_PER_SEGMENT, NUM_NODEMASK_BYTES, -} from "../consts"; -import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; +} from "../consts/index.js"; +import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError.js"; import { getBitMaskWidth, getMinimumShiftForBitMask, validatePayload, -} from "../util/misc"; +} from "../util/misc.js"; /** Indicates that value is not known (yet). */ export const NOT_KNOWN = undefined; diff --git a/packages/core/src/values/Timeout.ts b/packages/core/src/values/Timeout.ts index e1180e27ddb6..1d6c6333aa0c 100644 --- a/packages/core/src/values/Timeout.ts +++ b/packages/core/src/values/Timeout.ts @@ -1,5 +1,5 @@ import type { JSONObject } from "@zwave-js/shared"; -import { clamp } from "alcalzone-shared/math"; +import { clamp } from "alcalzone-shared/math/index.js"; export type TimeoutUnit = "seconds" | "minutes" | "none" | "infinite"; diff --git a/packages/core/src/values/ValueDB.test.ts b/packages/core/src/values/ValueDB.test.ts index 29b0987159e6..b036509da526 100644 --- a/packages/core/src/values/ValueDB.test.ts +++ b/packages/core/src/values/ValueDB.test.ts @@ -1,12 +1,12 @@ import { pick } from "@zwave-js/shared/safe"; -import test from "ava"; import sinon from "sinon"; -import { CommandClasses } from "../capabilities/CommandClasses"; -import { ZWaveErrorCodes } from "../error/ZWaveError"; -import { assertZWaveError } from "../test/assertZWaveError"; -import { ValueMetadata } from "./Metadata"; -import { ValueDB, dbKeyToValueIdFast } from "./ValueDB"; -import type { ValueID } from "./_Types"; +import { test } from "vitest"; +import { CommandClasses } from "../capabilities/CommandClasses.js"; +import { ZWaveErrorCodes } from "../error/ZWaveError.js"; +import { assertZWaveError } from "../test/assertZWaveError.js"; +import { ValueMetadata } from "./Metadata.js"; +import { ValueDB, dbKeyToValueIdFast } from "./ValueDB.js"; +import type { ValueID } from "./_Types.js"; function setup(): { valueDB: ValueDB; @@ -51,17 +51,17 @@ test("setValue() -> first add", (t) => { const cbArg = onValueAdded.getCall(0).args[0]; // The callback arg should contain the CC - t.is(typeof cbArg, "object"); - t.is(cbArg.commandClass, CommandClasses["Alarm Sensor"]); + t.expect(typeof cbArg).toBe("object"); + t.expect(cbArg.commandClass).toBe(CommandClasses["Alarm Sensor"]); // The callback arg should contain the endpoint - t.is(cbArg.endpoint, 4); + t.expect(cbArg.endpoint).toBe(4); // The callback arg should contain the property name - t.is(cbArg.property, "foo"); + t.expect(cbArg.property).toBe("foo"); // The callback arg should contain the new value - t.is(cbArg.newValue, "bar"); + t.expect(cbArg.newValue).toBe("bar"); }); test("setValue() -> consecutive adds", (t) => { @@ -80,20 +80,20 @@ test("setValue() -> consecutive adds", (t) => { const cbArg = onValueUpdated.getCall(0).args[0]; // The callback arg should contain the CC - t.is(typeof cbArg, "object"); - t.is(cbArg.commandClass, CommandClasses["Wake Up"]); + t.expect(typeof cbArg).toBe("object"); + t.expect(cbArg.commandClass).toBe(CommandClasses["Wake Up"]); // The callback arg should contain the endpoint - t.is(cbArg.endpoint, 0); + t.expect(cbArg.endpoint).toBe(0); // The callback arg should contain the property name - t.is(cbArg.property, "prop"); + t.expect(cbArg.property).toBe("prop"); // The callback arg should contain the previous value - t.is(cbArg.prevValue, "foo"); + t.expect(cbArg.prevValue).toBe("foo"); // The callback arg should contain the new value - t.is(cbArg.newValue, "bar"); + t.expect(cbArg.newValue).toBe("bar"); }); test("setValue()/removeValue() -> with the noEvent parameter set to true", (t) => { @@ -130,8 +130,6 @@ test("setValue()/removeValue() -> with the noEvent parameter set to true", (t) = sinon.assert.notCalled(onValueAdded); sinon.assert.notCalled(onValueUpdated); sinon.assert.notCalled(onValueRemoved); - - t.pass(); }); test("getValue()/setValue() -> should distinguish values by property key", (t) => { @@ -158,50 +156,46 @@ test("getValue()/setValue() -> should distinguish values by property key", (t) = ); // treat different property keys as distinct values", () => { - t.is( + t.expect( valueDB.getValue({ commandClass: cc, endpoint: 0, property: "prop", propertyKey: "foo", }), - 1, - ); - t.is( + ).toBe(1); + t.expect( valueDB.getValue({ commandClass: cc, endpoint: 0, property: "prop", propertyKey: "bar", }), - 2, - ); + ).toBe(2); // the value added callback should have been called for each added value", () => { sinon.assert.calledTwice(onValueAdded); - t.is(onValueAdded.getCall(0).args[0].propertyKey, "foo"); - t.is(onValueAdded.getCall(1).args[0].propertyKey, "bar"); + t.expect(onValueAdded.getCall(0).args[0].propertyKey).toBe("foo"); + t.expect(onValueAdded.getCall(1).args[0].propertyKey).toBe("bar"); // after clearing the value DB, the values should all be removed", () => { valueDB.clear(); - t.is( + t.expect( valueDB.getValue({ commandClass: cc, endpoint: 0, property: "prop", propertyKey: "foo", }), - undefined, - ); - t.is( + ).toBeUndefined(); + t.expect( valueDB.getValue({ commandClass: cc, endpoint: 0, property: "prop", propertyKey: "bar", }), - undefined, - ); + ).toBeUndefined(); }); test("removeValue()", (t) => { @@ -226,17 +220,17 @@ test("removeValue()", (t) => { const cbArg = onValueRemoved.getCall(0).args[0]; // The callback arg should contain the CC - t.is(typeof cbArg, "object"); - t.is(cbArg.commandClass, CommandClasses["Alarm Sensor"]); + t.expect(typeof cbArg).toBe("object"); + t.expect(cbArg.commandClass).toBe(CommandClasses["Alarm Sensor"]); // The callback arg should contain the endpoint - t.is(cbArg.endpoint, 1); + t.expect(cbArg.endpoint).toBe(1); // The callback arg should contain the property name - t.is(cbArg.property, "bar"); + t.expect(cbArg.property).toBe("bar"); // The callback arg should contain the previous value - t.is(cbArg.prevValue, "foo"); + t.expect(cbArg.prevValue).toBe("foo"); // If the value was not in the DB, the value removed event should not be emitted onValueRemoved.resetHistory(); @@ -253,7 +247,7 @@ test("removeValue()", (t) => { endpoint: 9, property: "test", }); - t.false(retValNotFound); + t.expect(retValNotFound).toBe(false); valueDB.setValue( { @@ -268,7 +262,7 @@ test("removeValue()", (t) => { endpoint: 0, property: "test", }); - t.true(retValFound); + t.expect(retValFound).toBe(true); // After removing a value, getValue should return undefined const actual = valueDB.getValue({ @@ -276,7 +270,7 @@ test("removeValue()", (t) => { endpoint: 1, property: "bar", }); - t.is(actual, undefined); + t.expect(actual).toBeUndefined(); }); test("clear()", (t) => { @@ -302,18 +296,18 @@ test("clear()", (t) => { const cbArgs = onValueRemoved.getCalls().map((c) => c.args[0]); // The callback should contain the removed values - t.is(typeof cbArgs[0], "object"); - t.is(cbArgs[0].prevValue, "foo"); - t.is(typeof cbArgs[1], "object"); - t.is(cbArgs[1].prevValue, "bar"); + t.expect(typeof cbArgs[0]).toBe("object"); + t.expect(cbArgs[0].prevValue).toBe("foo"); + t.expect(typeof cbArgs[1]).toBe("object"); + t.expect(cbArgs[1].prevValue).toBe("bar"); // After clearing, getValue should return undefined let actual: unknown; actual = valueDB.getValue(valueId1); - t.is(actual, undefined); + t.expect(actual).toBeUndefined(); actual = valueDB.setValue(valueId2, "bar"); - t.is(actual, undefined); + t.expect(actual).toBeUndefined(); }); test("getValue() should return the value stored for the same combination of CC, endpoint and property", (t) => { @@ -349,7 +343,7 @@ test("getValue() should return the value stored for the same combination of CC, valueDB.setValue(valueId, value); } for (const { value, ...valueId } of tests) { - t.is(valueDB.getValue(valueId), value); + t.expect(valueDB.getValue(valueId)).toBe(value); } }); @@ -390,8 +384,8 @@ test("getValues() should return all values stored for the given CC", (t) => { } const actual = valueDB.getValues(requestedCC); - t.is(actual.length, expected.length); - t.deepEqual(actual, expected); + t.expect(actual.length).toBe(expected.length); + t.expect(actual).toStrictEqual(expected); }); test("getValues() should ignore values from another node", (t) => { @@ -439,8 +433,8 @@ test("getValues() should ignore values from another node", (t) => { valueDB["_index"] = valueDB["buildIndex"](); const actual = valueDB.getValues(requestedCC); - t.is(actual.length, expected.length); - t.deepEqual(actual, expected); + t.expect(actual.length).toBe(expected.length); + t.expect(actual).toStrictEqual(expected); }); test("hasValue() -> should return false if no value is stored for the same combination of CC, endpoint and property", (t) => { @@ -473,9 +467,9 @@ test("hasValue() -> should return false if no value is stored for the same combi ]; for (const { value, ...valueId } of tests) { - t.false(valueDB.hasValue(valueId)); + t.expect(valueDB.hasValue(valueId)).toBe(false); valueDB.setValue(valueId, value); - t.true(valueDB.hasValue(valueId)); + t.expect(valueDB.hasValue(valueId)).toBe(true); } }); @@ -511,10 +505,9 @@ test("findValues() -> should return all values whose id matches the given predic for (const { value, ...valueId } of values) { valueDB.setValue(valueId, value); } - t.deepEqual( + t.expect( valueDB.findValues((id) => id.endpoint === 2), - values.filter((v) => v.endpoint === 2), - ); + ).toStrictEqual(values.filter((v) => v.endpoint === 2)); }); test("findValues() -> should ignore values from another node", (t) => { @@ -558,10 +551,9 @@ test("findValues() -> should ignore values from another node", (t) => { // The node has nodeID 2 const { nodeId, ...expected } = values[1]; - t.deepEqual( + t.expect( valueDB.findValues((id) => id.endpoint === 2), - [expected], - ); + ).toStrictEqual([expected]); }); test("Metadata is assigned to a specific combination of endpoint, property name (and property key)", (t) => { @@ -572,10 +564,11 @@ test("Metadata is assigned to a specific combination of endpoint, property name property: "3", }; valueDB.setMetadata(valueId, ValueMetadata.Any); - t.true(valueDB.hasMetadata(valueId)); - t.false(valueDB.hasMetadata({ ...valueId, propertyKey: 4 })); - t.is(valueDB.getMetadata(valueId), ValueMetadata.Any); - t.is(valueDB.getMetadata({ ...valueId, propertyKey: 4 }), undefined); + t.expect(valueDB.hasMetadata(valueId)).toBe(true); + t.expect(valueDB.hasMetadata({ ...valueId, propertyKey: 4 })).toBe(false); + t.expect(valueDB.getMetadata(valueId)).toBe(ValueMetadata.Any); + t.expect(valueDB.getMetadata({ ...valueId, propertyKey: 4 })) + .toBeUndefined(); }); test("Metadata is cleared together with the values", (t) => { @@ -587,12 +580,12 @@ test("Metadata is cleared together with the values", (t) => { }; valueDB.setMetadata(valueId, ValueMetadata.Any); valueDB.clear(); - t.false(valueDB.hasMetadata(valueId)); + t.expect(valueDB.hasMetadata(valueId)).toBe(false); }); test("getAllMetadata() -> returns all metadata for a given CC", (t) => { const { valueDB } = setup(); - t.is(valueDB.getAllMetadata(1).length, 0); + t.expect(valueDB.getAllMetadata(1).length).toBe(0); valueDB.setMetadata( { @@ -602,7 +595,7 @@ test("getAllMetadata() -> returns all metadata for a given CC", (t) => { }, ValueMetadata.Any, ); - t.is(valueDB.getAllMetadata(1).length, 1); + t.expect(valueDB.getAllMetadata(1).length).toBe(1); valueDB.setMetadata( { @@ -612,8 +605,8 @@ test("getAllMetadata() -> returns all metadata for a given CC", (t) => { }, ValueMetadata.Any, ); - t.is(valueDB.getAllMetadata(1).length, 1); - t.is(valueDB.getAllMetadata(55).length, 1); + t.expect(valueDB.getAllMetadata(1).length).toBe(1); + t.expect(valueDB.getAllMetadata(55).length).toBe(1); valueDB.setMetadata( { @@ -623,8 +616,8 @@ test("getAllMetadata() -> returns all metadata for a given CC", (t) => { }, ValueMetadata.Any, ); - t.is(valueDB.getAllMetadata(1).length, 1); - t.is(valueDB.getAllMetadata(55).length, 2); + t.expect(valueDB.getAllMetadata(1).length).toBe(1); + t.expect(valueDB.getAllMetadata(55).length).toBe(2); }); test("getAllMetadata() -> should ignore values from another node", (t) => { @@ -675,8 +668,8 @@ test("getAllMetadata() -> should ignore values from another node", (t) => { valueDB["_index"] = valueDB["buildIndex"](); const actual = valueDB.getAllMetadata(requestedCC); - t.is(actual.length, expected.length); - t.deepEqual(actual, expected); + t.expect(actual.length).toBe(expected.length); + t.expect(actual).toStrictEqual(expected); }); test("updating dynamic metadata", (t) => { @@ -696,17 +689,17 @@ test("updating dynamic metadata", (t) => { const cbArg = onMetadataUpdated.getCall(0).args[0]; // The callback arg should contain the CC - t.is(typeof cbArg, "object"); - t.is(cbArg.commandClass, 1); + t.expect(typeof cbArg).toBe("object"); + t.expect(cbArg.commandClass).toBe(1); // The callback arg should contain the endpoint - t.is(cbArg.endpoint, 2); + t.expect(cbArg.endpoint).toBe(2); // The callback arg should contain the property - t.is(cbArg.property, "3"); + t.expect(cbArg.property).toBe("3"); // The callback arg should contain the new metadata - t.is(cbArg.metadata, ValueMetadata.Any); + t.expect(cbArg.metadata).toBe(ValueMetadata.Any); }); test("findMetadata() -> should return all metadata whose id matches the given predicate", (t) => { @@ -750,10 +743,9 @@ test("findMetadata() -> should return all metadata whose id matches the given pr metadata: meta, })); - t.deepEqual( + t.expect( valueDB.findMetadata((id) => id.endpoint === 2), - expected, - ); + ).toStrictEqual(expected); }); test("findMetadata() -> should ignore metadata from another node", (t) => { @@ -802,10 +794,9 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { ...pick(expectedMeta, ["commandClass", "endpoint", "property"]), metadata: expectedMeta.meta, }; - t.deepEqual( + t.expect( valueDB.findMetadata((id) => id.endpoint === 2), - [expected], - ); + ).toStrictEqual([expected]); }); { @@ -823,7 +814,7 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - assertZWaveError(t, () => valueDB.getValue(valueId as any), { + assertZWaveError(t.expect, () => valueDB.getValue(valueId as any), { errorCode: ZWaveErrorCodes.Argument_Invalid, }); } @@ -833,9 +824,13 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - assertZWaveError(t, () => valueDB.setValue(valueId as any, 0), { - errorCode: ZWaveErrorCodes.Argument_Invalid, - }); + assertZWaveError( + t.expect, + () => valueDB.setValue(valueId as any, 0), + { + errorCode: ZWaveErrorCodes.Argument_Invalid, + }, + ); } }); @@ -843,7 +838,7 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - assertZWaveError(t, () => valueDB.hasValue(valueId as any), { + assertZWaveError(t.expect, () => valueDB.hasValue(valueId as any), { errorCode: ZWaveErrorCodes.Argument_Invalid, }); } @@ -853,9 +848,13 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - assertZWaveError(t, () => valueDB.removeValue(valueId as any), { - errorCode: ZWaveErrorCodes.Argument_Invalid, - }); + assertZWaveError( + t.expect, + () => valueDB.removeValue(valueId as any), + { + errorCode: ZWaveErrorCodes.Argument_Invalid, + }, + ); } }); @@ -863,9 +862,13 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - assertZWaveError(t, () => valueDB.getMetadata(valueId as any), { - errorCode: ZWaveErrorCodes.Argument_Invalid, - }); + assertZWaveError( + t.expect, + () => valueDB.getMetadata(valueId as any), + { + errorCode: ZWaveErrorCodes.Argument_Invalid, + }, + ); } }); @@ -874,7 +877,7 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { for (const valueId of invalidValueIDs) { assertZWaveError( - t, + t.expect, () => valueDB.setMetadata(valueId as any, {} as any), { errorCode: ZWaveErrorCodes.Argument_Invalid, @@ -887,9 +890,13 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - assertZWaveError(t, () => valueDB.hasMetadata(valueId as any), { - errorCode: ZWaveErrorCodes.Argument_Invalid, - }); + assertZWaveError( + t.expect, + () => valueDB.hasMetadata(valueId as any), + { + errorCode: ZWaveErrorCodes.Argument_Invalid, + }, + ); } }); } @@ -909,20 +916,20 @@ test("findMetadata() -> should ignore metadata from another node", (t) => { test(`invalid value IDs should be ignored by the setXYZ methods when the "noThrow" parameter is true -> setValue()`, (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - t.notThrows(() => + t.expect(() => valueDB.setValue(valueId as any, 0, { noThrow: true }) - ); + ).not.toThrow(); } }); test(`invalid value IDs should be ignored by the setXYZ methods when the "noThrow" parameter is true -> setMetadata()`, (t) => { const { valueDB } = setup(); for (const valueId of invalidValueIDs) { - t.notThrows(() => + t.expect(() => valueDB.setMetadata(valueId as any, {} as any, { noThrow: true, }) - ); + ).not.toThrow(); } }); } @@ -961,7 +968,7 @@ test("dbKeyToValueIdFast() -> should work correctly", (t) => { ]; for (const test of tests) { - t.deepEqual(dbKeyToValueIdFast(JSON.stringify(test)), test); + t.expect(dbKeyToValueIdFast(JSON.stringify(test))).toStrictEqual(test); } }); @@ -982,6 +989,6 @@ test("keys that are invalid JSON should not cause a crash", (t) => { ]) as any, ); - t.deepEqual(valueDB.getAllMetadata(44), []); - t.is(valueDB["_index"].size, 0); + t.expect(valueDB.getAllMetadata(44)).toStrictEqual([]); + t.expect(valueDB["_index"].size).toBe(0); }); diff --git a/packages/core/src/values/ValueDB.ts b/packages/core/src/values/ValueDB.ts index 99778b95819e..009a5fe9e3f4 100644 --- a/packages/core/src/values/ValueDB.ts +++ b/packages/core/src/values/ValueDB.ts @@ -1,8 +1,12 @@ import type { JsonlDB } from "@alcalzone/jsonl-db"; import { TypedEventEmitter } from "@zwave-js/shared"; -import type { CommandClasses } from "../capabilities/CommandClasses"; -import { ZWaveError, ZWaveErrorCodes, isZWaveError } from "../error/ZWaveError"; -import type { ValueMetadata } from "../values/Metadata"; +import type { CommandClasses } from "../capabilities/CommandClasses.js"; +import { + ZWaveError, + ZWaveErrorCodes, + isZWaveError, +} from "../error/ZWaveError.js"; +import type { ValueMetadata } from "../values/Metadata.js"; import type { MetadataUpdatedArgs, SetValueOptions, @@ -11,7 +15,7 @@ import type { ValueNotificationArgs, ValueRemovedArgs, ValueUpdatedArgs, -} from "./_Types"; +} from "./_Types.js"; type ValueAddedCallback = (args: ValueAddedArgs) => void; type ValueUpdatedCallback = (args: ValueUpdatedArgs) => void; diff --git a/packages/core/src/values/_Types.ts b/packages/core/src/values/_Types.ts index 1e434fc9eac3..797541f4d09f 100644 --- a/packages/core/src/values/_Types.ts +++ b/packages/core/src/values/_Types.ts @@ -1,5 +1,5 @@ -import type { CommandClasses } from "../capabilities/CommandClasses"; -import type { ValueMetadata } from "./Metadata"; +import type { CommandClasses } from "../capabilities/CommandClasses.js"; +import type { ValueMetadata } from "./Metadata.js"; /** Uniquely identifies to which CC, endpoint and property a value belongs to */ export interface ValueID { diff --git a/packages/core/tsconfig.build.json b/packages/core/tsconfig.build.json index 7a15e1866cd6..e7ac09c8e991 100644 --- a/packages/core/tsconfig.build.json +++ b/packages/core/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Some @internal members need to be accessed from other modules in this monorepo "stripInternal": false, // Do not use the @@dev export for compiling diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 2cebae12162a..b769a7953496 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -8,7 +8,8 @@ "main": "build/index.js", "module": "build/index.js", "files": [ - "build/**/*.js" + "build/**/*.js", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -37,6 +38,7 @@ "lint:ts:fix": "yarn run lint:ts --fix" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@types/eslint": "^9.6.1", "@typescript-eslint/utils": "^8.8.1", "@zwave-js/core": "workspace:*", diff --git a/packages/eslint-plugin/src/rules/no-forbidden-imports.ts b/packages/eslint-plugin/src/rules/no-forbidden-imports.ts index 36c64dab8144..ea7b5d133a57 100644 --- a/packages/eslint-plugin/src/rules/no-forbidden-imports.ts +++ b/packages/eslint-plugin/src/rules/no-forbidden-imports.ts @@ -6,15 +6,15 @@ import ts from "typescript"; // Whitelist some imports that are known not to import forbidden modules const whitelistedImports = [ "reflect-metadata", - "alcalzone-shared/arrays", - "alcalzone-shared/async", - "alcalzone-shared/comparable", - "alcalzone-shared/deferred-promise", - "alcalzone-shared/math", - "alcalzone-shared/objects", - "alcalzone-shared/sorted-list", - "alcalzone-shared/strings", - "alcalzone-shared/typeguards", + "alcalzone-shared/arrays/index.js", + "alcalzone-shared/async/index.js", + "alcalzone-shared/comparable/index.js", + "alcalzone-shared/deferred-promise/index.js", + "alcalzone-shared/math/index.js", + "alcalzone-shared/objects/index.js", + "alcalzone-shared/sorted-list/index.js", + "alcalzone-shared/strings/index.js", + "alcalzone-shared/typeguards/index.js", ]; // Whitelist some more imports that should be ignored in the checking diff --git a/packages/eslint-plugin/src/utils.ts b/packages/eslint-plugin/src/utils.ts index 199774fd83f3..8263ce90d80d 100644 --- a/packages/eslint-plugin/src/utils.ts +++ b/packages/eslint-plugin/src/utils.ts @@ -7,11 +7,9 @@ import { CommandClasses } from "@zwave-js/core"; import { type Rule as ESLintRule } from "eslint"; import { type AST as JSONC_AST, type RuleListener } from "jsonc-eslint-parser"; import path from "node:path"; - -import { dirname } from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export type ReportFixGenerator = ( fixer: ESLintRule.RuleFixer, diff --git a/packages/flash/bin/flash.js b/packages/flash/bin/flash.js deleted file mode 100644 index 89394a709020..000000000000 --- a/packages/flash/bin/flash.js +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -require("../build/cli.js"); diff --git a/packages/flash/bin/flash.mjs b/packages/flash/bin/flash.mjs new file mode 100644 index 000000000000..6d0be3ad0a66 --- /dev/null +++ b/packages/flash/bin/flash.mjs @@ -0,0 +1,2 @@ +#!/usr/bin/env node +await import("../build/cli.js"); diff --git a/packages/flash/package.json b/packages/flash/package.json index a6a4e76f7d10..61c2f9e776ad 100644 --- a/packages/flash/package.json +++ b/packages/flash/package.json @@ -6,13 +6,14 @@ "publishConfig": { "access": "public" }, + "type": "module", "main": "build/cli.js", - "type": "commonjs", "files": [ "bin/", - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], - "bin": "bin/flash.js", + "bin": "bin/flash.mjs", "author": { "name": "AlCalzone", "email": "d.griesel@gmx.net" diff --git a/packages/flash/src/cli.ts b/packages/flash/src/cli.ts index e05f3e446d95..793fe3d59729 100644 --- a/packages/flash/src/cli.ts +++ b/packages/flash/src/cli.ts @@ -1,8 +1,9 @@ import { ZWaveErrorCodes, isZWaveError } from "@zwave-js/core/safe"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import fs from "node:fs/promises"; import path from "node:path"; import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; import { ControllerFirmwareUpdateStatus, Driver, @@ -11,7 +12,7 @@ import { guessFirmwareFileFormat, } from "zwave-js"; -const argv = yargs.parseSync(); +const argv = yargs(hideBin(process.argv)).parseSync(); const [port, filename] = argv._.map(String); if (!port || !filename) { diff --git a/packages/host/package.json b/packages/host/package.json index 94b9fcd7e67c..846a1a5b03ba 100644 --- a/packages/host/package.json +++ b/packages/host/package.json @@ -6,22 +6,23 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./package.json": "./package.json" }, "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -43,7 +44,8 @@ "node": ">= 18" }, "scripts": { - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", @@ -56,6 +58,7 @@ "alcalzone-shared": "^4.0.8" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "del-cli": "^6.0.0", diff --git a/packages/host/src/ZWaveHost.ts b/packages/host/src/ZWaveHost.ts index ad60c0001502..f684c7da267c 100644 --- a/packages/host/src/ZWaveHost.ts +++ b/packages/host/src/ZWaveHost.ts @@ -13,7 +13,7 @@ import type { ValueDB, ValueID, } from "@zwave-js/core"; -import type { ZWaveHostOptions } from "./ZWaveHostOptions"; +import type { ZWaveHostOptions } from "./ZWaveHostOptions.js"; /** Allows querying the home ID and node ID of the host */ export interface HostIDs { diff --git a/packages/host/src/index.ts b/packages/host/src/index.ts index c4a7340a2742..4fed45e686d2 100644 --- a/packages/host/src/index.ts +++ b/packages/host/src/index.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ -export * from "./FileSystem"; -export * from "./ZWaveHost"; -export * from "./ZWaveHostOptions"; -export * from "./mocks"; +export * from "./FileSystem.js"; +export * from "./ZWaveHost.js"; +export * from "./ZWaveHostOptions.js"; +export * from "./mocks.js"; diff --git a/packages/host/src/index_safe.ts b/packages/host/src/index_safe.ts index a08ef095ba6a..ec8ea79bf3fa 100644 --- a/packages/host/src/index_safe.ts +++ b/packages/host/src/index_safe.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ /* @forbiddenImports external */ -export * from "./FileSystem"; -export * from "./ZWaveHost"; -export * from "./ZWaveHostOptions"; +export * from "./FileSystem.js"; +export * from "./ZWaveHost.js"; +export * from "./ZWaveHostOptions.js"; diff --git a/packages/host/src/mocks.ts b/packages/host/src/mocks.ts index b851a29271b9..0996b80934f6 100644 --- a/packages/host/src/mocks.ts +++ b/packages/host/src/mocks.ts @@ -21,7 +21,7 @@ import type { GetValueDB, HostIDs, LogNode, -} from "./ZWaveHost"; +} from "./ZWaveHost.js"; export interface CreateTestingHostOptions extends HostIDs, GetDeviceConfig {} diff --git a/packages/host/tsconfig.build.json b/packages/host/tsconfig.build.json index 5ddf97f9f1c7..716e9efb8bc3 100644 --- a/packages/host/tsconfig.build.json +++ b/packages/host/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/maintenance/package.json b/packages/maintenance/package.json index c88465d82eda..aaa5681bae9b 100644 --- a/packages/maintenance/package.json +++ b/packages/maintenance/package.json @@ -4,10 +4,12 @@ "description": "zwave-js: maintenance scripts", "private": true, "keywords": [], + "type": "module", "main": "src/index.ts", "types": "src/index.d.ts", "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -29,13 +31,14 @@ "node": ">= 18" }, "scripts": { - "ts": "node -r esbuild-register --conditions=@@dev", + "ts": "tsx --conditions=@@dev", "build": "tsc -b tsconfig.build.json --pretty", "clean": "del-cli build/ \"*.tsbuildinfo\"", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@dprint/formatter": "^0.4.1", "@dprint/json": "^0.19.4", "@dprint/markdown": "^0.17.8", @@ -50,14 +53,14 @@ "cli-highlight": "^2.1.11", "del-cli": "^6.0.0", "dprint": "^0.47.2", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", + "es-main": "^1.3.0", "execa": "^5.1.1", "globrex": "^0.1.2", "json5": "^2.2.3", "piscina": "^4.7.0", "reflect-metadata": "^0.2.2", "ts-morph": "^24.0.0", + "tsx": "^4.19.2", "typescript": "5.6.2", "yargs": "^17.7.2" } diff --git a/packages/maintenance/src/codefind.ts b/packages/maintenance/src/codefind.ts index 253ba94dc880..1a14500b1475 100644 --- a/packages/maintenance/src/codefind.ts +++ b/packages/maintenance/src/codefind.ts @@ -10,12 +10,14 @@ import { redBright, yellow, } from "ansi-colors"; -import highlight, { fromJson as themeFromJson } from "cli-highlight"; +import { fromJson as themeFromJson, highlight } from "cli-highlight"; +import esMain from "es-main"; import globrex from "globrex"; import path from "node:path"; import ts from "typescript"; import yargs from "yargs"; -import { loadTSConfig, projectRoot } from "./tsAPITools"; +import { hideBin } from "yargs/helpers"; +import { loadTSConfig, projectRoot } from "./tsAPITools.js"; function relativeToProject(filename: string): string { return path.relative(projectRoot, filename).replaceAll("\\", "/"); @@ -357,8 +359,9 @@ export function codefind(query: CodeFindQuery): Result[] { return results; } -if (require.main === module) { - const argv = yargs +if (esMain(import.meta)) { + const yargsInstance = yargs(hideBin(process.argv)); + const argv = yargsInstance .usage("Code search utility\n\nUsage: $0 [options]") .options({ include: { @@ -407,7 +410,7 @@ if (require.main === module) { default: 3, }, }) - .wrap(Math.min(100, yargs.terminalWidth())) + .wrap(Math.min(100, yargsInstance.terminalWidth())) .demandOption("search", "Please specify a search query") .parseSync(); diff --git a/packages/maintenance/src/convert-json.ts b/packages/maintenance/src/convert-json.ts index a47747ea576f..e1f53efa5a51 100644 --- a/packages/maintenance/src/convert-json.ts +++ b/packages/maintenance/src/convert-json.ts @@ -4,10 +4,14 @@ */ import { enumFilesRecursive } from "@zwave-js/shared"; +import esMain from "es-main"; import fs from "node:fs/promises"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { Project, ts } from "ts-morph"; -import { formatWithDprint } from "./dprint"; +import { formatWithDprint } from "./dprint.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); async function main() { const project = new Project(); @@ -103,6 +107,6 @@ async function main() { } } -if (require.main === module) { +if (esMain(import.meta)) { void main(); } diff --git a/packages/maintenance/src/dprint.ts b/packages/maintenance/src/dprint.ts index b4b2842d157d..1926b9fc5e6b 100644 --- a/packages/maintenance/src/dprint.ts +++ b/packages/maintenance/src/dprint.ts @@ -1,4 +1,4 @@ -import { repoRoot } from "./tsAPITools"; +import { repoRoot } from "./tsAPITools.js"; import { formatWithDprint as format } from "@zwave-js/fmt"; diff --git a/packages/maintenance/src/esmImports.ts b/packages/maintenance/src/esmImports.ts new file mode 100644 index 000000000000..59c4eb6c5e8e --- /dev/null +++ b/packages/maintenance/src/esmImports.ts @@ -0,0 +1,52 @@ +import fs from "node:fs/promises"; +import { Project } from "ts-morph"; + +async function main() { + const project = new Project({ + tsConfigFilePath: "packages/maintenance/tsconfig.json", + }); + // project.addSourceFilesAtPaths("packages/cc/src/cc/**/*CC.ts"); + + const sourceFiles = project.getSourceFiles(); + for (const file of sourceFiles) { + // const filePath = path.relative(process.cwd(), file.getFilePath()); + + const relativeExports = file.getExportDeclarations().filter((exp) => { + return exp.getModuleSpecifierValue()?.startsWith(".") + && !exp.getModuleSpecifierValue()?.endsWith(".js"); + }); + + for (const exp of relativeExports) { + const oldPath = exp.getModuleSpecifierValue(); + const newPath = oldPath + ".js"; + exp.setModuleSpecifier(newPath); + } + + const relativeImports = file.getImportDeclarations().filter((imp) => { + return imp.getModuleSpecifierValue()?.startsWith(".") + && !imp.getModuleSpecifierValue()?.endsWith(".js"); + }); + + for (const imp of relativeImports) { + const oldPath = imp.getModuleSpecifierValue(); + const newPath = oldPath + ".js"; + imp.setModuleSpecifier(newPath); + } + + if (relativeImports.length === 0 && relativeExports.length === 0) { + continue; + } + + await file.save(); + } +} + +void main().catch(async (e) => { + await fs.writeFile(`${e.filePath}.old`, e.oldText); + await fs.writeFile(`${e.filePath}.new`, e.newText); + console.error(`Error refactoring file ${e.filePath} + old text: ${e.filePath}.old + new text: ${e.filePath}.new`); + + process.exit(1); +}); diff --git a/packages/maintenance/src/generateTypedDocs.ts b/packages/maintenance/src/generateTypedDocs.ts index 2bdbd0654d53..00456ea7c111 100644 --- a/packages/maintenance/src/generateTypedDocs.ts +++ b/packages/maintenance/src/generateTypedDocs.ts @@ -4,11 +4,13 @@ import { CommandClasses, getCCName } from "@zwave-js/core"; import { enumFilesRecursive, num2hex } from "@zwave-js/shared"; -import { red, yellow } from "ansi-colors"; +import c from "ansi-colors"; +import esMain from "es-main"; import fs from "node:fs/promises"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { isMainThread } from "node:worker_threads"; -import Piscina from "piscina"; +import { Piscina } from "piscina"; import { type CommentRange, type ExportedDeclarations, @@ -27,12 +29,23 @@ import { type TypeLiteralNode, type ts, } from "ts-morph"; -import { formatWithDprint } from "./dprint"; +import { formatWithDprint } from "./dprint.js"; import { getCommandClassFromClassDeclaration, projectRoot, tsConfigFilePathForDocs as tsConfigFilePath, -} from "./tsAPITools"; +} from "./tsAPITools.js"; + +// Support directly loading this file in a worker +import { register } from "tsx/esm/api"; +register(); + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const exportDeclarationCache = new Map< + string, + ReadonlyMap +>(); export function findSourceNode( program: Project, @@ -40,8 +53,13 @@ export function findSourceNode( identifier: string, ): ExportedDeclarations | undefined { // Scan all source files - const file = program.getSourceFile(exportingFile); - return file?.getExportedDeclarations().get(identifier)?.[0]; + if (!exportDeclarationCache.has(exportingFile)) { + const decls = program.getSourceFile(exportingFile) + ?.getExportedDeclarations(); + if (decls) exportDeclarationCache.set(exportingFile, decls); + } + return exportDeclarationCache.get(exportingFile) + ?.get(identifier)?.[0]; } export function stripComments( @@ -235,7 +253,7 @@ function stripQuotes(str: string): string { function expectLiteralString(strType: string, context: string): void { if (strType === "string") { console.warn( - yellow( + c.yellow( `WARNING: Received type "string" where a string literal was expected. Make sure to define this string or the entire object using "as const". Context: ${context}`, @@ -247,7 +265,7 @@ function expectLiteralString(strType: string, context: string): void { function expectLiteralNumber(numType: string, context: string): void { if (numType === "number") { console.warn( - yellow( + c.yellow( `WARNING: Received type "number" where a number literal was expected. Make sure to define this number or the entire object using "as const". Context: ${context}`, @@ -278,7 +296,7 @@ export async function processDocFile( ); if (!sourceNode) { console.error( - red( + c.red( `${docFile}: Cannot find symbol ${range.symbol} in module ${range.module}!`, ), ); @@ -658,7 +676,7 @@ async function generateCCDocs( const indexAutoGenStart = indexFileContent.indexOf(indexAutoGenToken); if (indexAutoGenStart === -1) { console.error( - red(`Marker for auto-generation in CCs/index.md missing!`), + c.red(`Marker for auto-generation in CCs/index.md missing!`), ); return false; } @@ -702,7 +720,7 @@ async function generateCCDocs( const sidebarAutoGenStart = sidebarFileContent.indexOf(sidebarAutoGenToken); if (sidebarAutoGenStart === -1) { console.error( - red(`Marker for CC auto-generation in _sidebar.md missing!`), + c.red(`Marker for CC auto-generation in _sidebar.md missing!`), ); return false; } @@ -723,7 +741,7 @@ async function generateCCDocs( async function main(): Promise { const piscina = new Piscina({ - filename: path.join(__dirname, "generateTypedDocsWorker.js"), + filename: path.join(__dirname, "generateTypedDocs.ts"), maxThreads: 4, }); @@ -764,7 +782,10 @@ export async function processCC( const program = getProgram(); const sourceFile = program.getSourceFileOrThrow(filename); const dtsFile = program.addSourceFileAtPath( - filename.replace("/src/", "/build/").replace(/(? + f.getFilePath().endsWith("JsonTemplate.test.ts") + ) */; + + const setupReplacements = { + "test.before": "beforeAll", + "test.beforeEach": "beforeEach", + "test.after": "afterAll", + "test.afterEach": "afterEach", + "test.afterEach.always": "afterEach", + }; + const testReplacements = { + "test.serial": "test.sequential", + "test.failing": "test.fails", + }; + + for (const file of sourceFiles) { + const avaImport = file.getImportDeclaration((decl) => + decl.getModuleSpecifierValue() === "ava" + ); + if (!avaImport) continue; + + // debugger; + + // Find setup and teardown + const setups = file.getDescendantsOfKind(SyntaxKind.CallExpression) + .map((c) => { + const fn = c.getExpressionIfKind( + SyntaxKind.PropertyAccessExpression, + ); + const fnName = fn?.getText(); + if ( + !fn + || !fnName?.startsWith("test.") + || !(fnName in setupReplacements) + ) return; + return [ + fn, + (setupReplacements as any)[fnName] as string, + ] as const; + }).filter((f) => f != undefined); + + // Find tests + const tests = file.getDescendantsOfKind(SyntaxKind.CallExpression) + .filter((c) => + c.getExpressionIfKind(SyntaxKind.Identifier)?.getText() + === "test" + || c.getExpressionIfKind(SyntaxKind.PropertyAccessExpression) + ?.getExpressionIfKind(SyntaxKind.Identifier)?.getText() + === "test" + ).filter((f) => + f.getArguments().length >= 2 + && f.getArguments()[1].asKind(SyntaxKind.ArrowFunction) + ?.getParameters().length === 1 + ); + + const testMethods = tests.map((t) => + t.getExpressionIfKind(SyntaxKind.PropertyAccessExpression) + ) + .filter((p) => p != undefined) + .map((prop) => { + const replacement = (testReplacements as any)[prop.getText()] as + | string + | undefined; + if (!replacement) return; + return [prop, replacement] as const; + }).filter((f) => f != undefined); + + const testsAndContexts = tests.map((t) => { + const context = + t.getArguments()[1].asKind(SyntaxKind.ArrowFunction)! + .getParameters()[0]; + return [t, context] as const; + }); + const testsAndContextUsages = testsAndContexts.map(( + [t, c], + ) => [t, c.findReferencesAsNodes()]); + + const contextUsages = testsAndContextUsages.flatMap(([, usages]) => + usages + ); + + if ( + testMethods.length === 0 + && contextUsages.length === 0 + && setups.length === 0 + ) continue; + + for (const [propAccess, newName] of testMethods) { + propAccess.replaceWithText(newName); + } + + const additionalImports = new Set(); + for (const [propAccess, newName] of setups) { + additionalImports.add(newName); + propAccess.replaceWithText(newName); + } + + const allImports = ["test", ...additionalImports].join(", "); + avaImport.replaceWithText(`import { ${allImports} } from "vitest";`); + + for (const t of contextUsages) { + // Do simple replacements first + const ident = t.asKind(SyntaxKind.Identifier); + const propAccess = ident?.getParentIfKind( + SyntaxKind.PropertyAccessExpression, + ); + const callExpr = propAccess?.getParentIfKind( + SyntaxKind.CallExpression, + ); + + if (!!ident && !!propAccess && !!callExpr) { + const methodName = propAccess.getName(); + if (methodName === "is") { + replaceAssertion_is(ident, propAccess, callExpr); + } else if (methodName === "true" || methodName === "false") { + replaceAssertion_staticValue( + ident, + propAccess, + callExpr, + methodName, + ); + } else if (methodName === "truthy") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toBeTruthy", + ); + } else if (methodName === "falsy") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toBeFalsy", + ); + } else if (methodName === "deepEqual") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toStrictEqual", + ); + } else if (methodName === "like") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toMatchObject", + ); + } else if (methodName === "notThrows") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "not.toThrow", + ); + } else if (methodName === "teardown") { + propAccess.replaceWithText( + `${ident.getText()}.onTestFinished`, + ); + } else if (methodName === "timeout") { + // Translate timeout call to an additional argument of the test method + replaceTestTimeout(ident, propAccess, callExpr); + } + } + } + + await file.save(); + } +} + +function replaceAssertion_is( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, +) { + // Check the 2nd argument for more specific assertions + const arg1 = callExpr.getArguments()[1]?.getText(); + propAccess.replaceWithText(`${ident.getText()}.expect`); + if (arg1) callExpr.removeArgument(1); + switch (arg1) { + case "undefined": + callExpr.replaceWithText( + `${callExpr.getText()}.toBeUndefined()`, + ); + break; + case "null": + callExpr.replaceWithText( + `${callExpr.getText()}.toBeNull()`, + ); + break; + default: + callExpr.replaceWithText( + `${callExpr.getText()}.toBe(${arg1 ?? ""})`, + ); + break; + } +} + +function replaceAssertion_staticValue( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, + value: string, +) { + propAccess.replaceWithText(`${ident.getText()}.expect`); + callExpr.replaceWithText( + `${callExpr.getText()}.toBe(${value})`, + ); +} + +function replaceAssertion_staticAssertion( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, + assertion: string, +) { + propAccess.replaceWithText(`${ident.getText()}.expect`); + const arg1 = callExpr.getArguments()[1]?.getText(); + if (arg1) callExpr.removeArgument(1); + callExpr.replaceWithText( + `${callExpr.getText()}.${assertion}(${arg1 ?? ""})`, + ); +} + +function replaceTestTimeout( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, +) { + const timeout = callExpr.getArguments()[0]?.getText(); + if (!timeout) return; + + const stmt = callExpr.getParentIfKind(SyntaxKind.ExpressionStatement); + if (!stmt) return; + + const testMethodCall = stmt.getFirstAncestorByKind( + SyntaxKind.CallExpression, + ); + if (!testMethodCall?.getExpression().getText().startsWith("test.")) return; + + testMethodCall.addArgument(timeout); + stmt.remove(); +} + +void main().catch(async (e) => { + debugger; + await fs.writeFile(`${e.filePath}.old`, e.oldText); + await fs.writeFile(`${e.filePath}.new`, e.newText); + console.error(`Error refactoring file ${e.filePath} + old text: ${e.filePath}.old + new text: ${e.filePath}.new + +Reason: ${e.message}`); + + process.exit(1); +}); diff --git a/packages/maintenance/src/refactorTests.02.ts b/packages/maintenance/src/refactorTests.02.ts new file mode 100644 index 000000000000..2e9626362969 --- /dev/null +++ b/packages/maintenance/src/refactorTests.02.ts @@ -0,0 +1,113 @@ +import fs from "node:fs/promises"; +import { + type CallExpression, + type Identifier, + Project, + type PropertyAccessExpression, + SyntaxKind, +} from "ts-morph"; + +async function main() { + const project = new Project(); + project.addSourceFilesAtPaths("packages/**/*.test.ts"); + + const sourceFiles = project.getSourceFiles() /*.filter((f) => + f.getFilePath().endsWith("JsonTemplate.test.ts") + ) */; + + for (const file of sourceFiles) { + // Find tests + const tests = file.getDescendantsOfKind(SyntaxKind.CallExpression) + .filter((c) => + c.getExpressionIfKind(SyntaxKind.Identifier)?.getText() + === "test" + || c.getExpressionIfKind(SyntaxKind.PropertyAccessExpression) + ?.getExpressionIfKind(SyntaxKind.Identifier)?.getText() + === "test" + ).filter((f) => + f.getArguments().length >= 2 + && f.getArguments()[1].asKind(SyntaxKind.ArrowFunction) + ?.getParameters().length === 1 + ); + + const testsAndContexts = tests.map((t) => { + const context = + t.getArguments()[1].asKind(SyntaxKind.ArrowFunction)! + .getParameters()[0]; + return [t, context] as const; + }); + const testsAndContextUsages = testsAndContexts.map(( + [t, c], + ) => [t, c.findReferencesAsNodes()]); + + const contextUsages = testsAndContextUsages.flatMap(([, usages]) => + usages + ); + + if (contextUsages.length === 0) continue; + + let didSomething = false; + + for (const t of contextUsages) { + // Do simple replacements first + const ident = t.asKind(SyntaxKind.Identifier); + const propAccess = ident?.getParentIfKind( + SyntaxKind.PropertyAccessExpression, + ); + const callExpr = propAccess?.getParentIfKind( + SyntaxKind.CallExpression, + ); + + if (!!ident && !!propAccess && !!callExpr) { + const methodName = propAccess.getName(); + if (methodName === "not") { + replaceAssertion_not(ident, propAccess, callExpr); + didSomething = true; + } + } + } + + if (didSomething) await file.save(); + } +} + +function replaceAssertion_not( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, +) { + // Check the 2nd argument for more specific assertions + const arg1 = callExpr.getArguments()[1]?.getText(); + propAccess.replaceWithText(`${ident.getText()}.expect`); + if (arg1) callExpr.removeArgument(1); + switch (arg1) { + case "undefined": + callExpr.replaceWithText( + `${callExpr.getText()}.toBeDefined()`, + ); + break; + case "null": + callExpr.replaceWithText( + `${callExpr.getText()}.not.toBeNull()`, + ); + break; + default: + callExpr.replaceWithText( + `${callExpr.getText()}.not.toBe(${arg1 ?? ""})`, + ); + break; + } +} + +void main().catch(async (e) => { + debugger; + await fs.writeFile(`${e.filePath}.old`, e.oldText); + await fs.writeFile(`${e.filePath}.new`, e.newText); + console.error(`Error refactoring file ${e.filePath} + old text: ${e.filePath}.old + new text: ${e.filePath}.new + +Reason: ${e.message}`); + + process.exit(1); +}); diff --git a/packages/maintenance/src/refactorTests.03.ts b/packages/maintenance/src/refactorTests.03.ts new file mode 100644 index 000000000000..f8855ba6f87b --- /dev/null +++ b/packages/maintenance/src/refactorTests.03.ts @@ -0,0 +1,246 @@ +import fs from "node:fs/promises"; +import { + type CallExpression, + type Identifier, + Project, + type PropertyAccessExpression, + SyntaxKind, +} from "ts-morph"; + +async function main() { + const project = new Project(); + project.addSourceFilesAtPaths("packages/**/*.test.ts"); + + const sourceFiles = project.getSourceFiles() /*.filter((f) => + f.getFilePath().endsWith("JsonTemplate.test.ts") + ) */; + + for (const file of sourceFiles) { + // Find integration tests + const testBodies = file.getDescendantsOfKind( + SyntaxKind.PropertyAssignment, + ) + .filter((c) => c.getName() === "testBody") + .map((t) => t.getInitializerIfKind(SyntaxKind.ArrowFunction)) + .filter((f) => f != undefined); + + const testBodies2 = file.getDescendantsOfKind( + SyntaxKind.MethodDeclaration, + ).filter((m) => m.getName() === "testBody"); + + const contextUsages = [...testBodies, ...testBodies2].map((t) => + t.getParameters()[0] + ) + .filter((p) => p != undefined) + .flatMap((p) => p.findReferencesAsNodes()); + + if (contextUsages.length === 0) continue; + + for (const t of contextUsages) { + // Do simple replacements first + const ident = t.asKind(SyntaxKind.Identifier); + const propAccess = ident?.getParentIfKind( + SyntaxKind.PropertyAccessExpression, + ); + const callExpr = propAccess?.getParentIfKind( + SyntaxKind.CallExpression, + ); + + if (!!ident && !!propAccess && !!callExpr) { + const methodName = propAccess.getName(); + if (methodName === "is") { + replaceAssertion_is(ident, propAccess, callExpr); + } else if (methodName === "not") { + replaceAssertion_not(ident, propAccess, callExpr); + } else if (methodName === "true" || methodName === "false") { + replaceAssertion_staticValue( + ident, + propAccess, + callExpr, + methodName, + ); + } else if (methodName === "truthy") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toBeTruthy", + ); + } else if (methodName === "falsy") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toBeFalsy", + ); + } else if (methodName === "deepEqual") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toStrictEqual", + ); + } else if (methodName === "notDeepEqual") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "not.toStrictEqual", + ); + } else if (methodName === "like") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toMatchObject", + ); + } else if (methodName === "throws") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "toThrow", + ); + } else if (methodName === "notThrows") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "not.toThrow", + ); + } else if (methodName === "throwsAsync") { + replaceAssertion_staticAssertion( + ident, + propAccess, + callExpr, + "rejects.toThrow", + ); + } else if (methodName === "teardown") { + propAccess.replaceWithText( + `${ident.getText()}.onTestFinished`, + ); + } else if (methodName === "timeout") { + // Translate timeout call to an additional argument of the test method + replaceTestTimeout(ident, propAccess, callExpr); + } + } + } + + await file.save(); + } +} + +function replaceAssertion_is( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, +) { + // Check the 2nd argument for more specific assertions + const arg1 = callExpr.getArguments()[1]?.getText(); + propAccess.replaceWithText(`${ident.getText()}.expect`); + if (arg1) callExpr.removeArgument(1); + switch (arg1) { + case "undefined": + callExpr.replaceWithText( + `${callExpr.getText()}.toBeUndefined()`, + ); + break; + case "null": + callExpr.replaceWithText( + `${callExpr.getText()}.toBeNull()`, + ); + break; + default: + callExpr.replaceWithText( + `${callExpr.getText()}.toBe(${arg1 ?? ""})`, + ); + break; + } +} + +function replaceAssertion_not( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, +) { + // Check the 2nd argument for more specific assertions + const arg1 = callExpr.getArguments()[1]?.getText(); + propAccess.replaceWithText(`${ident.getText()}.expect`); + if (arg1) callExpr.removeArgument(1); + switch (arg1) { + case "undefined": + callExpr.replaceWithText( + `${callExpr.getText()}.toBeDefined()`, + ); + break; + case "null": + callExpr.replaceWithText( + `${callExpr.getText()}.not.toBeNull()`, + ); + break; + default: + callExpr.replaceWithText( + `${callExpr.getText()}.not.toBe(${arg1 ?? ""})`, + ); + break; + } +} + +function replaceAssertion_staticValue( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, + value: string, +) { + propAccess.replaceWithText(`${ident.getText()}.expect`); + callExpr.replaceWithText( + `${callExpr.getText()}.toBe(${value})`, + ); +} + +function replaceAssertion_staticAssertion( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, + assertion: string, +) { + propAccess.replaceWithText(`${ident.getText()}.expect`); + const arg1 = callExpr.getArguments()[1]?.getText(); + if (arg1) callExpr.removeArgument(1); + callExpr.replaceWithText( + `${callExpr.getText()}.${assertion}(${arg1 ?? ""})`, + ); +} + +function replaceTestTimeout( + ident: Identifier, + propAccess: PropertyAccessExpression, + callExpr: CallExpression, +) { + const timeout = callExpr.getArguments()[0]?.getText(); + if (!timeout) return; + + const stmt = callExpr.getParentIfKind(SyntaxKind.ExpressionStatement); + if (!stmt) return; + + const testMethodCall = stmt.getFirstAncestorByKind( + SyntaxKind.CallExpression, + ); + if (!testMethodCall?.getExpression().getText().startsWith("test.")) return; + + testMethodCall.addArgument(timeout); + stmt.remove(); +} + +void main().catch(async (e) => { + debugger; + await fs.writeFile(`${e.filePath}.old`, e.oldText); + await fs.writeFile(`${e.filePath}.new`, e.newText); + console.error(`Error refactoring file ${e.filePath} + old text: ${e.filePath}.old + new text: ${e.filePath}.new + +Reason: ${e.message}`); + + process.exit(1); +}); diff --git a/packages/maintenance/src/remove-unnecessary.ts b/packages/maintenance/src/remove-unnecessary.ts index 4f2575c144a5..ef8c99a42d90 100644 --- a/packages/maintenance/src/remove-unnecessary.ts +++ b/packages/maintenance/src/remove-unnecessary.ts @@ -2,9 +2,13 @@ import { enumFilesRecursive } from "@zwave-js/shared"; import * as JSONC from "comment-json"; +import esMain from "es-main"; import fs from "node:fs/promises"; import path from "node:path"; -import { formatWithDprint } from "./dprint"; +import { fileURLToPath } from "node:url"; +import { formatWithDprint } from "./dprint.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); async function main() { const devicesDir = path.join(__dirname, "../../config/config/devices"); @@ -47,6 +51,6 @@ async function main() { } } -if (require.main === module) { +if (esMain(import.meta)) { void main(); } diff --git a/packages/maintenance/src/reportProblem.ts b/packages/maintenance/src/reportProblem.ts index 7ba608daf7d1..11b5699345b6 100644 --- a/packages/maintenance/src/reportProblem.ts +++ b/packages/maintenance/src/reportProblem.ts @@ -1,4 +1,4 @@ -import { red, yellow } from "ansi-colors"; +import c from "ansi-colors"; interface ReportProblemOptions { severity: "warn" | "error"; @@ -26,7 +26,7 @@ export function reportProblem({ } else { console.log(`${filename}${line != undefined ? `:${line}` : ""}:`); console.log( - (severity === "warn" ? yellow : red)( + (severity === "warn" ? c.yellow : c.red)( `[${severity.toUpperCase()}] ${message}\n`, ), ); diff --git a/packages/maintenance/src/resolveDirtyTests.ts b/packages/maintenance/src/resolveDirtyTests.ts index f036cb194a77..e9df30ba7113 100644 --- a/packages/maintenance/src/resolveDirtyTests.ts +++ b/packages/maintenance/src/resolveDirtyTests.ts @@ -3,12 +3,13 @@ * anything they are not supposed to. */ +import esMain from "es-main"; import execa from "execa"; import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import ts from "typescript"; -import { loadTSConfig, projectRoot, repoRoot } from "./tsAPITools"; +import { loadTSConfig, projectRoot, repoRoot } from "./tsAPITools.js"; const reportFile = path.join(repoRoot, ".tmp", "dirty-tests.json"); @@ -338,7 +339,7 @@ async function runDirtyTests(diffBase?: string): Promise { }); } -if (require.main === module) { +if (esMain(import.meta)) { const args = process.argv.slice(2); const run = args.includes("--run"); // Resolve dirty tests by default, unless --run is specified diff --git a/packages/maintenance/src/tsAPITools.ts b/packages/maintenance/src/tsAPITools.ts index fdcc6a6c0eb5..97a09207633f 100644 --- a/packages/maintenance/src/tsAPITools.ts +++ b/packages/maintenance/src/tsAPITools.ts @@ -1,7 +1,10 @@ import { CommandClasses } from "@zwave-js/core"; -import * as path from "node:path"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import ts from "typescript"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + // Find this project's root dir export const projectRoot = process.cwd(); export const repoRoot = path.normalize( diff --git a/packages/maintenance/tsconfig.build.json b/packages/maintenance/tsconfig.build.json index 0060030da691..1c12babeaa3a 100644 --- a/packages/maintenance/tsconfig.build.json +++ b/packages/maintenance/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/nvmedit/ava.config.cjs b/packages/nvmedit/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/nvmedit/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/nvmedit/package.json b/packages/nvmedit/package.json index 9c1ae2d53760..6adc009af01c 100644 --- a/packages/nvmedit/package.json +++ b/packages/nvmedit/package.json @@ -6,23 +6,24 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./package.json": "./package.json" }, "files": [ "bin/", - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "bin": "bin/nvmedit.js", "author": { @@ -53,23 +54,24 @@ "yargs": "^17.7.2" }, "scripts": { - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "@types/semver": "^7.5.8", "@types/yargs": "^17.0.33", - "ava": "^6.1.3", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", - "typescript": "5.6.2" + "tsx": "^4.19.2", + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/nvmedit/src/__snapshots__/convert.test.ts.snap b/packages/nvmedit/src/__snapshots__/convert.test.ts.snap new file mode 100644 index 000000000000..bc906bb83ab7 --- /dev/null +++ b/packages/nvmedit/src/__snapshots__/convert.test.ts.snap @@ -0,0 +1,8801 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`500 to 700 series JSON conversion -> ctrlr_backup_500_static_6.8x.json 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationVersion": "1.2", + "commandClasses": { + "includedInsecurely": [ + 33, + 32, + 134, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "genericDeviceClass": 2, + "homeId": "0xced44428", + "isListening": true, + "lastNodeId": 4, + "maxNodeId": 4, + "nodeId": 1, + "optionalFunctionality": false, + "preferredRepeaters": [], + "protocolVersion": "6.07", + "reservedId": 0, + "specificDeviceClass": 1, + "staticControllerNodeId": 1, + "sucLastIndex": 5, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [ + 94, + 85, + 159, + 108, + 134, + 114, + 90, + 115, + 49, + 67, + 64, + 66, + 68, + 69, + 112, + 133, + 142, + 89, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 94, + 38, + 51, + 112, + 133, + 89, + 114, + 134, + 122, + 115, + 152, + 90, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 85, + 159, + 108, + 134, + 114, + 90, + 115, + 49, + 67, + 64, + 66, + 68, + 69, + 112, + 133, + 142, + 89, + 122, + ], + }, + ], + "systemState": 0, + }, + "format": 0, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 3, + 4, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "3": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 4, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "4": { + "appRouteLock": false, + "genericDeviceClass": 8, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 3, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 6, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`500-series, binary to JSON -> ctrlr_backup_500_static_6.8x.bin 1`] = ` +{ + "controller": { + "applicationData": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationVersion": "1.2", + "commandClasses": [ + 33, + 32, + 134, + ], + "controllerConfiguration": 60, + "lastNodeId": 4, + "learnedHomeId": null, + "maxNodeId": 4, + "nodeId": 0, + "ownHomeId": "0xced44428", + "preferredRepeaters": [], + "protocolVersion": "6.07", + "reservedId": 0, + "rfConfig": { + "powerLevelLow": [ + 255, + 255, + 255, + ], + "powerLevelNormal": [ + 255, + 255, + 255, + ], + "powerMode": 255, + "powerModeExtintEnable": 255, + "powerModeWutTimeout": 4294967295, + }, + "staticControllerNodeId": 1, + "sucLastIndex": 5, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [ + 94, + 85, + 159, + 108, + 134, + 114, + 90, + 115, + 49, + 67, + 64, + 66, + 68, + 69, + 112, + 133, + 142, + 89, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 94, + 38, + 51, + 112, + 133, + 89, + 114, + 134, + 122, + 115, + 152, + 90, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 85, + 159, + 108, + 134, + 114, + 90, + 115, + 49, + 67, + 64, + 66, + 68, + 69, + 112, + 133, + 142, + 89, + 122, + ], + }, + ], + "systemState": 0, + "watchdogStarted": 0, + }, + "format": 500, + "meta": { + "firmwareID": 90, + "library": "static", + "manufacturerID": 134, + "productID": 90, + "productType": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 3, + 4, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "3": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 4, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "4": { + "appRouteLock": false, + "genericDeviceClass": 8, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 3, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 6, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.11.bin 1`] = ` +{ + "controller": { + "applicationData": "a11d19000200001e3212270efd213a04fa1d00020000000000000000fd39277c022e000100000000000000000199445b8fcb3e537977d642e808b6568700000000000000000000000000000000000000000000008756e008a3cc6f339248ef5d663f50e136e12e8fe7432265349446d6c5541bf3c500be6567027beeb0e7712b11e21ddf53d86f0b134c00a3bdcd24963a89ef0d753a35b3033f64d1b759077a24d59b45da0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "applicationName": null, + "applicationVersion": "7.0.0", + "commandClasses": { + "includedInsecurely": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": null, + "genericDeviceClass": 2, + "homeId": "0xfbfedd24", + "isListening": true, + "lastNodeId": 6, + "lastNodeIdLR": null, + "maxNodeId": 6, + "maxNodeIdLR": null, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": [], + "primaryLongRangeChannelId": null, + "protocolVersion": "7.11.0", + "reservedId": 0, + "reservedIdLR": null, + "rfConfig": { + "enablePTI": null, + "maxTXPower": null, + "measured0dBm": 3.3, + "nodeIdType": null, + "rfRegion": 5, + "txPower": 0, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": 0, + "sucLastIndex": 7, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 116, + 115, + 114, + 134, + 108, + 135, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 5, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 6, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 135, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 116, + 115, + 114, + 134, + 108, + 135, + 138, + ], + }, + ], + "systemState": 0, + }, + "format": 0, + "meta": { + "deviceFamily": 2047, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 6, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 2, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "3": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "4": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "5": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "6": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 0, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.12.bin 1`] = ` +{ + "controller": { + "applicationData": "a11d19000200001e321b9884fdec8bdd380e00020000000000000000fd8e8c480f1700010000000000000000014c72cc54358f3dc9ce70ac752beb3e7a0000000000000000000000000000000000000000000000873206e7a00af5746fbc07ba927a6bde014d36396481ce9cce689ceba3f12841d85ffcc430bddb814dad5874aa73866b6a1361c9802cac47fc4df1627838f5857eb334b1bb0a8565a09d46bb8e722ac7910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "applicationName": null, + "applicationVersion": "7.12.0", + "commandClasses": { + "includedInsecurely": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": null, + "genericDeviceClass": 2, + "homeId": "0xd79ed9ef", + "isListening": true, + "lastNodeId": 12, + "lastNodeIdLR": null, + "maxNodeId": 12, + "maxNodeIdLR": null, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": [], + "primaryLongRangeChannelId": null, + "protocolVersion": "7.12.0", + "reservedId": 0, + "reservedIdLR": null, + "rfConfig": { + "enablePTI": null, + "maxTXPower": null, + "measured0dBm": 3.3, + "nodeIdType": null, + "rfRegion": 33, + "txPower": 0, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": 0, + "sucLastIndex": 21, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 5, + "supportedCCs": [ + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 6, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 7, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 8, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 8, + "supportedCCs": [ + 94, + 108, + 85, + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 8, + "supportedCCs": [ + 94, + 108, + 85, + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 9, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 10, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 11, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 12, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 85, + 86, + 34, + 159, + 152, + 116, + 108, + 138, + ], + }, + ], + "systemState": 0, + }, + "format": 1, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 6, + 8, + 9, + 10, + 11, + 12, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 12, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "10": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "11": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "12": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + 8, + 9, + 10, + 11, + 12, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "3": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + 8, + 9, + 10, + 11, + 12, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "4": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + 8, + 9, + 10, + 11, + 12, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "5": { + "appRouteLock": false, + "genericDeviceClass": 15, + "isFrequentListening": false, + "isListening": true, + "isRouting": false, + "isVirtual": true, + "lwr": null, + "neighbors": [ + 6, + 8, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 2, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": false, + "supportsSecurity": false, + }, + "6": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "8": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + ], + "nlwr": null, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.15.bin 1`] = ` +{ + "controller": { + "applicationData": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "applicationName": null, + "applicationVersion": "7.15.4", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 152, + 85, + 134, + 89, + 90, + 159, + 108, + 116, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xd7db5d96", + "isListening": true, + "lastNodeId": 5, + "lastNodeIdLR": 255, + "maxNodeId": 5, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 0, + "protocolVersion": "7.15.4", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": 3.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 0, + }, + "specificDeviceClass": 1, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 19, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [ + 37, + 50, + 114, + 134, + 32, + 113, + 112, + 39, + 133, + 135, + 117, + 86, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 94, + 134, + 114, + 89, + 133, + 115, + 113, + 132, + 128, + 48, + 49, + 112, + 152, + 122, + 90, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 135, + 115, + 128, + 159, + 48, + 112, + 113, + 49, + 132, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 135, + 115, + 128, + 159, + 48, + 112, + 113, + 49, + 132, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 94, + 134, + 114, + 89, + 133, + 115, + 113, + 132, + 128, + 48, + 49, + 112, + 122, + 90, + ], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 85, + 159, + 108, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 85, + 159, + 108, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 152, + 85, + 134, + 89, + 90, + 159, + 108, + 116, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 152, + 85, + 134, + 89, + 90, + 159, + 108, + 116, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 5, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 135, + 115, + 128, + 159, + 48, + 112, + 113, + 49, + 132, + 108, + 122, + ], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 94, + 134, + 114, + 89, + 133, + 115, + 113, + 132, + 128, + 48, + 49, + 112, + 152, + 122, + 90, + ], + }, + ], + "systemState": 0, + }, + "format": 2, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 3, + 5, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 16, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 3, + ], + }, + "neighbors": [ + 3, + 5, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "3": { + "appRouteLock": false, + "genericDeviceClass": 33, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "5": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.16_1.bin 1`] = ` +{ + "controller": { + "applicationData": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "applicationName": null, + "applicationVersion": "7.16.2", + "commandClasses": { + "includedInsecurely": [], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xdbf13d9e", + "isListening": true, + "lastNodeId": 28, + "lastNodeIdLR": 255, + "maxNodeId": 28, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": false, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 0, + "protocolVersion": "7.16.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": 3.3, + "nodeIdType": null, + "rfRegion": 1, + "txPower": 0, + }, + "specificDeviceClass": 1, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 60, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 1, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [ + 94, + 85, + 152, + 159, + 108, + 38, + 112, + 133, + 89, + 142, + 134, + 114, + 90, + 115, + 117, + 34, + 122, + 91, + 135, + 96, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [ + 94, + 85, + 152, + 159, + 108, + 38, + 112, + 133, + 89, + 142, + 134, + 114, + 90, + 115, + 117, + 34, + 122, + 91, + 135, + 96, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 3, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 4, + "supportedCCs": [ + 94, + 85, + 152, + 159, + 108, + 38, + 112, + 133, + 89, + 142, + 134, + 114, + 90, + 115, + 117, + 34, + 122, + 91, + 135, + 96, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 5, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 5, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 6, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 6, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 7, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 7, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 8, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 8, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 9, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 10, + "supportedCCs": [ + 94, + 85, + 152, + 159, + 108, + 38, + 112, + 133, + 89, + 142, + 134, + 114, + 90, + 115, + 117, + 34, + 122, + 91, + 135, + 96, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 10, + "supportedCCs": [ + 94, + 85, + 152, + 159, + 108, + 38, + 112, + 133, + 89, + 142, + 134, + 114, + 90, + 115, + 117, + 34, + 122, + 91, + 135, + 96, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 11, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 11, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 11, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 12, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 12, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 13, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 13, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 13, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 12, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 9, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 14, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 14, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 15, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 15, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 16, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 16, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 17, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 17, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 18, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 18, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 15, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 16, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 17, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 19, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 19, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 19, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 20, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 20, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 21, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 21, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 20, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 22, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 22, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 50, + 91, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 23, + "supportedCCs": [ + 152, + 114, + 134, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 24, + "supportedCCs": [ + 94, + 133, + 89, + 128, + 112, + 90, + 122, + 135, + 114, + 142, + 113, + 115, + 152, + 159, + 121, + 108, + 85, + 134, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 24, + "supportedCCs": [ + 94, + 133, + 89, + 128, + 112, + 90, + 122, + 135, + 114, + 142, + 113, + 115, + 152, + 159, + 121, + 108, + 85, + 134, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 25, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 25, + "supportedCCs": [ + 94, + 112, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 152, + 159, + 37, + 108, + 117, + 34, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 26, + "supportedCCs": [ + 94, + 86, + 134, + 114, + 90, + 133, + 89, + 115, + 37, + 39, + 112, + 44, + 43, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 26, + "supportedCCs": [ + 94, + 86, + 134, + 114, + 90, + 133, + 89, + 115, + 37, + 39, + 112, + 44, + 43, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 27, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 28, + "supportedCCs": [ + 94, + 86, + 134, + 114, + 90, + 133, + 89, + 115, + 37, + 39, + 112, + 44, + 43, + 122, + ], + }, + ], + "systemState": 0, + }, + "format": 3, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 4, + 14, + 21, + 22, + 23, + 24, + 26, + 27, + 28, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 2, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "10": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 4, + 24, + ], + }, + "neighbors": [ + 14, + 22, + 23, + 24, + 25, + 28, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 0, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "14": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 4, + 10, + 21, + 23, + 24, + 25, + 27, + 28, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "21": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + }, + "neighbors": [ + 1, + 4, + 14, + 22, + 23, + 24, + 26, + 27, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "22": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 28, + ], + }, + "neighbors": [ + 1, + 4, + 10, + 21, + 23, + 24, + 26, + 27, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "23": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + 4, + 10, + 14, + 21, + 22, + 24, + 26, + 27, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "24": { + "appRouteLock": false, + "genericDeviceClass": 3, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + }, + "neighbors": [ + 1, + 4, + 10, + 14, + 21, + 22, + 23, + 26, + 27, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "25": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 22, + 10, + ], + }, + "neighbors": [ + 1, + 10, + 14, + 22, + 26, + 28, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 14, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "26": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 10, + ], + }, + "neighbors": [ + 1, + 4, + 21, + 22, + 23, + 24, + 25, + 27, + 28, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "27": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 4, + 14, + 21, + 22, + 23, + 24, + 26, + 28, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 24, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 4, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "28": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 4, + 10, + 14, + 21, + 22, + 25, + 26, + 27, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "4": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 14, + 21, + 22, + 23, + 24, + 26, + 27, + 28, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 0, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.16_2.bin 1`] = ` +{ + "controller": { + "applicationData": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "applicationName": null, + "applicationVersion": "255.0.0", + "commandClasses": { + "includedInsecurely": [ + 94, + 134, + 114, + 122, + 115, + 34, + 133, + 89, + 112, + 86, + 90, + 108, + 85, + 122, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xcc137774", + "isListening": true, + "lastNodeId": 62, + "lastNodeIdLR": 255, + "maxNodeId": 62, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 0, + "protocolVersion": "7.16.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": 3.3, + "nodeIdType": null, + "rfRegion": 1, + "txPower": 0, + }, + "specificDeviceClass": 1, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 5, + "sucUpdateEntries": [ + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 59, + "supportedCCs": [ + 94, + 37, + 50, + 39, + 44, + 43, + 112, + 133, + 89, + 114, + 134, + 122, + 115, + 90, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 60, + "supportedCCs": [ + 94, + 37, + 50, + 39, + 44, + 43, + 112, + 133, + 89, + 114, + 134, + 122, + 115, + 90, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 61, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 96, + 159, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 62, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 128, + 159, + 113, + 135, + 48, + 112, + 132, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 62, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 128, + 159, + 113, + 135, + 48, + 112, + 132, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 32, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 32, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 33, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 34, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 35, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 36, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 37, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 38, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 39, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 40, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 41, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 41, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 41, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 42, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 42, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 43, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 43, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 44, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 44, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 45, + "supportedCCs": [ + 94, + 37, + 133, + 89, + 85, + 134, + 114, + 90, + 115, + 159, + 108, + 122, + 128, + 38, + 112, + 135, + 142, + 106, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 33, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 36, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 39, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 46, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 46, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 46, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 46, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 47, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 48, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 48, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 49, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 48, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 50, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 50, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 2, + "supportedCCs": [], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 6, + "supportedCCs": [], + }, + { + "changeType": 3, + "controlledCCs": [], + "nodeId": 7, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 51, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 51, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 51, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 51, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 52, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 52, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 53, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 53, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 53, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 53, + "supportedCCs": [], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 53, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 54, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 54, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 55, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 55, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 56, + "supportedCCs": [ + 94, + 37, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 112, + 113, + 50, + 159, + 96, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 27, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 57, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 128, + 159, + 113, + 135, + 48, + 112, + 132, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 57, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 128, + 159, + 113, + 135, + 48, + 112, + 132, + 108, + 122, + ], + }, + { + "changeType": 2, + "controlledCCs": [], + "nodeId": 57, + "supportedCCs": [], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 58, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 128, + 159, + 113, + 135, + 48, + 112, + 132, + 108, + 122, + ], + }, + { + "changeType": 1, + "controlledCCs": [], + "nodeId": 58, + "supportedCCs": [ + 94, + 133, + 142, + 89, + 85, + 134, + 114, + 90, + 115, + 128, + 159, + 113, + 135, + 48, + 112, + 132, + 108, + 122, + ], + }, + ], + "systemState": 0, + }, + "format": 3, + "meta": { + "deviceFamily": 42, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + 4, + 6, + 7, + 11, + 22, + 23, + 30, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 59, + 60, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "10": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 11, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 11, + 12, + 16, + 17, + 18, + 19, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 45, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "11": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 9, + 10, + 12, + 14, + 16, + 17, + 19, + 20, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 59, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "12": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 18, + 2, + ], + }, + "neighbors": [ + 1, + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 14, + 18, + 20, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 59, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 2, + 18, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "14": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 5, + 2, + ], + }, + "neighbors": [ + 5, + 7, + 8, + 12, + 16, + 20, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 60, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + 5, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "16": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 10, + 11, + ], + }, + "neighbors": [ + 1, + 4, + 7, + 10, + 11, + 14, + 20, + 23, + 30, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 59, + 60, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "17": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11, + 18, + 19, + 20, + 22, + 30, + 31, + 32, + 34, + 37, + 38, + 44, + 45, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 19, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "18": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 5, + 9, + 10, + 12, + 17, + 19, + 20, + 22, + 30, + 31, + 32, + 34, + 37, + 38, + 43, + 44, + 45, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "19": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11, + 17, + 18, + 22, + 30, + 31, + 32, + 38, + 43, + 45, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 11, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 17, + 18, + 19, + 20, + 22, + 23, + 26, + 28, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 45, + 49, + 50, + 58, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "20": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 1, + 2, + 4, + 6, + 11, + 12, + 14, + 16, + 17, + 18, + 21, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 43, + 44, + 45, + 59, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "21": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 11, + 20, + ], + }, + "neighbors": [ + 20, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "22": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 17, + 18, + 19, + 20, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "23": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 1, + 2, + 4, + 5, + 6, + 7, + 8, + 10, + 11, + 12, + 16, + 20, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "26": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 10, + 11, + 17, + 18, + 19, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + 3, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "28": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 12, + 49, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 17, + 18, + 19, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "29": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 11, + 3, + ], + }, + "neighbors": [ + 3, + 4, + 7, + 17, + 18, + 19, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "3": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 2, + 4, + 5, + 6, + 7, + 10, + 11, + 17, + 18, + 19, + 26, + 28, + 29, + 30, + 31, + 32, + 34, + 37, + 38, + 45, + 58, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "30": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 16, + 17, + 18, + 19, + 20, + 31, + 32, + 34, + 37, + 43, + 44, + 45, + 58, + 62, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "31": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 11, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 17, + 18, + 19, + 20, + 30, + 32, + 34, + 37, + 40, + 45, + 58, + 62, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 4, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "32": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 17, + 18, + 19, + 20, + 30, + 31, + 34, + 37, + 40, + 43, + 44, + 45, + 58, + 62, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "34": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 6, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 17, + 18, + 20, + 30, + 31, + 32, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "37": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 17, + 18, + 20, + 30, + 31, + 32, + 34, + 38, + 40, + 43, + 44, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "38": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 3, + 11, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 17, + 18, + 19, + 20, + 30, + 31, + 34, + 37, + 40, + 43, + 44, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "4": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 6, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 16, + 17, + 18, + 19, + 20, + 22, + 23, + 26, + 28, + 29, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 58, + 59, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "40": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + }, + "neighbors": [ + 1, + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 31, + 32, + 34, + 37, + 38, + 43, + 44, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "41": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 43, + 45, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 11, + 6, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "42": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 43, + 44, + 45, + 60, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "43": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + 2, + 4, + 5, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 18, + 19, + 20, + 21, + 30, + 32, + 34, + 37, + 38, + 40, + 41, + 42, + 44, + 45, + 59, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 11, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "44": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 1, + 4, + 6, + 7, + 8, + 9, + 11, + 12, + 14, + 16, + 17, + 18, + 20, + 21, + 30, + 32, + 34, + 37, + 38, + 40, + 42, + 43, + 45, + 59, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "45": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 17, + 18, + 19, + 20, + 21, + 30, + 31, + 32, + 38, + 41, + 42, + 43, + 44, + 59, + 60, + ], + "nlwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "49": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 10, + ], + }, + "neighbors": [ + 2, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 11, + 61, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "5": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + 4, + 6, + 7, + 8, + 9, + 10, + 11, + 14, + 17, + 18, + 19, + 22, + 23, + 30, + 32, + 34, + 37, + 38, + 40, + 43, + 45, + 60, + ], + "nlwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 4, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "50": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 2, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "56": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 14, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "58": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 16, + 5, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 19, + 30, + 31, + 32, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "59": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 4, + 11, + 12, + 16, + 20, + 30, + 43, + 44, + 45, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "6": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 11, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 7, + 8, + 10, + 11, + 12, + 17, + 19, + 20, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 41, + 44, + 45, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 11, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "60": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 7, + 8, + 11, + 12, + 14, + 16, + 20, + 21, + 30, + 31, + 34, + 37, + 38, + 40, + 41, + 42, + 43, + 44, + 45, + 59, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "61": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + 2, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 17, + 18, + 19, + 20, + 49, + 59, + 60, + 62, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "62": { + "appRouteLock": false, + "genericDeviceClass": 7, + "isFrequentListening": false, + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 2, + 3, + 17, + 18, + 19, + 30, + 31, + 32, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "7": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + 3, + ], + }, + "neighbors": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9, + 10, + 11, + 12, + 14, + 16, + 17, + 18, + 19, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 41, + 42, + 43, + 44, + 45, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 1, + "repeaterNodeIDs": [ + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "8": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + }, + "neighbors": [ + 1, + 2, + 4, + 5, + 6, + 7, + 9, + 10, + 12, + 14, + 17, + 19, + 22, + 23, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 60, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 4, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 17, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 3, + "repeaterNodeIDs": [ + 2, + ], + }, + "neighbors": [ + 2, + 3, + 4, + 5, + 7, + 8, + 10, + 11, + 12, + 18, + 20, + 22, + 30, + 31, + 32, + 34, + 37, + 38, + 40, + 43, + 44, + 45, + 61, + ], + "nlwr": { + "beaming": false, + "protocolRate": 2, + "repeaterNodeIDs": [ + 2, + ], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.17.2.bin 1`] = ` +{ + "applicationFileFormat": 4, + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.17.2", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.17.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 4, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.18.1.bin 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.18.1", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.17.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 4, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.18.2.bin 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.18.2", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.17.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 4, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.18.3.bin 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.18.3", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.17.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 4, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.18.4.bin 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.18.4", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.17.2", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 4, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.19.0.bin 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.19.0", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.19.0", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 5, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; + +exports[`700-series, binary to JSON -> ctrlr_backup_700_7.19.1.bin 1`] = ` +{ + "controller": { + "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "applicationName": null, + "applicationVersion": "7.19.1", + "commandClasses": { + "includedInsecurely": [ + 94, + 34, + 133, + 112, + 86, + 122, + 114, + 115, + 85, + 134, + 89, + 90, + 108, + 116, + 152, + 159, + ], + "includedSecurelyInsecureCCs": [], + "includedSecurelySecureCCs": [], + }, + "controllerConfiguration": 60, + "dcdcConfig": 255, + "genericDeviceClass": 2, + "homeId": "0xc5b9bc28", + "isListening": true, + "lastNodeId": 13, + "lastNodeIdLR": 255, + "maxNodeId": 13, + "maxNodeIdLR": 0, + "nodeId": 1, + "optionalFunctionality": true, + "preferredRepeaters": null, + "primaryLongRangeChannelId": 1, + "protocolVersion": "7.19.0", + "reservedId": 0, + "reservedIdLR": 0, + "rfConfig": { + "enablePTI": 0, + "maxTXPower": 14, + "measured0dBm": -2.3, + "nodeIdType": null, + "rfRegion": 0, + "txPower": 9.9, + }, + "specificDeviceClass": 7, + "staticControllerNodeId": 1, + "sucAwarenessPushNeeded": null, + "sucLastIndex": 34, + "sucUpdateEntries": [], + "systemState": 0, + }, + "format": 5, + "meta": { + "deviceFamily": 46, + "memoryMapped": true, + "pageSize": 2048, + "sharedFileSystem": false, + "writeSize": 1, + }, + "nodes": { + "1": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": null, + "neighbors": [ + 2, + ], + "nlwr": null, + "nodeType": 0, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 255, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "13": { + "appRouteLock": false, + "genericDeviceClass": 64, + "isFrequentListening": "1000ms", + "isListening": false, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": "1000ms", + "protocolRate": 2, + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 3, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "2": { + "appRouteLock": false, + "genericDeviceClass": 2, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [ + 1, + ], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 0, + "optionalFunctionality": false, + "pendingDiscovery": false, + "protocolVersion": 3, + "routeSlaveSUC": true, + "specificDeviceClass": 7, + "sucPendingUpdate": false, + "sucUpdateIndex": 26, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + "9": { + "appRouteLock": false, + "genericDeviceClass": 16, + "isFrequentListening": false, + "isListening": true, + "isRouting": true, + "isVirtual": false, + "lwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "neighbors": [], + "nlwr": { + "beaming": false, + "protocolRate": 0, + "repeaterNodeIDs": [], + }, + "nodeType": 1, + "optionalFunctionality": true, + "pendingDiscovery": true, + "protocolVersion": 3, + "routeSlaveSUC": false, + "specificDeviceClass": 1, + "sucPendingUpdate": false, + "sucUpdateIndex": 254, + "supportedDataRates": [ + 40000, + 100000, + ], + "supportsBeaming": true, + "supportsSecurity": false, + }, + }, +} +`; diff --git a/packages/nvmedit/src/cli.ts b/packages/nvmedit/src/cli.ts index 806182f4591e..724be36b920a 100644 --- a/packages/nvmedit/src/cli.ts +++ b/packages/nvmedit/src/cli.ts @@ -1,8 +1,9 @@ import { readJSON } from "@zwave-js/shared"; -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import fs from "node:fs/promises"; import "reflect-metadata"; import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; import { json500To700, json700To500, @@ -11,16 +12,17 @@ import { migrateNVM, nvm500ToJSON, nvmToJSON, -} from "./convert"; -import "./index"; +} from "./convert.js"; -void yargs +const yargsInstance = yargs(hideBin(process.argv)); + +void yargsInstance .env("NVMEDIT") .strict() .usage("Z-Wave JS NVM converter utility\n\nUsage: $0 [options]") .alias("h", "help") .alias("v", "version") - .wrap(Math.min(100, yargs.terminalWidth())) + .wrap(Math.min(100, yargsInstance.terminalWidth())) .options({ verbose: { alias: "vv", diff --git a/packages/nvmedit/src/convert.test.ts b/packages/nvmedit/src/convert.test.ts index 11b71389b5c6..b13fd1daae87 100644 --- a/packages/nvmedit/src/convert.test.ts +++ b/packages/nvmedit/src/convert.test.ts @@ -1,26 +1,30 @@ import { readJSON } from "@zwave-js/shared"; import { cloneDeep } from "@zwave-js/shared/safe"; -import test, { type ExecutionContext } from "ava"; import fs from "node:fs"; import fsp from "node:fs/promises"; import path from "node:path"; -import { jsonToNVM, migrateNVM } from "."; +import { fileURLToPath } from "node:url"; +import { type ExpectStatic, test } from "vitest"; import { type NVMJSON, json500To700, json700To500, + jsonToNVM, jsonToNVM500, + migrateNVM, nvm500ToJSON, nvmToJSON, -} from "./convert"; -import type { NVM500JSON } from "./nvm500/NVMParser"; +} from "./convert.js"; +import type { NVM500JSON } from "./nvm500/NVMParser.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); function bufferEquals( - t: ExecutionContext, + expect: ExpectStatic, actual: Uint8Array, expected: Uint8Array, ) { - t.deepEqual(actual.buffer, expected.buffer); + expect(actual.buffer).toStrictEqual(expected.buffer); } { @@ -33,7 +37,7 @@ function bufferEquals( test(`${suite} -> ${file}`, async (t) => { const data = await fsp.readFile(path.join(fixturesDir, file)); const json = await nvmToJSON(data); - t.snapshot(json); + t.expect(json).toMatchSnapshot(); }); } } @@ -57,7 +61,7 @@ function bufferEquals( // @ts-expect-error if (!("meta" in jsonInput)) delete jsonOutput.meta; - t.deepEqual(jsonOutput, jsonInput); + t.expect(jsonOutput).toStrictEqual(jsonInput); }); } } @@ -79,7 +83,7 @@ function bufferEquals( const json = await nvmToJSON(nvmIn); const nvmOut = await jsonToNVM(json, version); - bufferEquals(t, nvmOut, nvmIn); + bufferEquals(t.expect, nvmOut, nvmIn); }); } } @@ -94,7 +98,7 @@ function bufferEquals( test(`${suite} -> ${file}`, async (t) => { const data = await fsp.readFile(path.join(fixturesDir, file)); const json = await nvm500ToJSON(data); - t.snapshot(json); + t.expect(json).toMatchSnapshot(); }); } } @@ -135,7 +139,7 @@ function bufferEquals( json.controller.protocolVersion, ); - bufferEquals(t, nvmOut, nvmIn); + bufferEquals(t.expect, nvmOut, nvmIn); }); } } @@ -152,7 +156,7 @@ function bufferEquals( path.join(fixturesDir, file), ); const json700 = json500To700(json500, true); - t.snapshot(json700); + t.expect(json700).toMatchSnapshot(); }); } } @@ -187,7 +191,7 @@ function bufferEquals( .applicationData.slice(0, 1024); } } - t.deepEqual(output, expected); + t.expect(output).toStrictEqual(expected); }); } } @@ -205,5 +209,5 @@ test("700 to 700 migration shortcut", async (t) => { ); const converted = await migrateNVM(nvmSource, nvmTarget); - bufferEquals(t, converted, nvmSource); + bufferEquals(t.expect, converted, nvmSource); }); diff --git a/packages/nvmedit/src/convert.test.ts.md b/packages/nvmedit/src/convert.test.ts.md deleted file mode 100644 index 826824858ac9..000000000000 --- a/packages/nvmedit/src/convert.test.ts.md +++ /dev/null @@ -1,8833 +0,0 @@ -# Snapshot report for `src/convert.test.ts` - -The actual snapshot is saved in `convert.test.ts.snap`. - -Generated by [AVA](https://avajs.dev). - -## 700-series, binary to JSON -> ctrlr_backup_700_7.11.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'a11d19000200001e3212270efd213a04fa1d00020000000000000000fd39277c022e000100000000000000000199445b8fcb3e537977d642e808b6568700000000000000000000000000000000000000000000008756e008a3cc6f339248ef5d663f50e136e12e8fe7432265349446d6c5541bf3c500be6567027beeb0e7712b11e21ddf53d86f0b134c00a3bdcd24963a89ef0d753a35b3033f64d1b759077a24d59b45da0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - applicationName: null, - applicationVersion: '7.0.0', - commandClasses: { - includedInsecurely: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: null, - genericDeviceClass: 2, - homeId: '0xfbfedd24', - isListening: true, - lastNodeId: 6, - lastNodeIdLR: null, - maxNodeId: 6, - maxNodeIdLR: null, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: [], - primaryLongRangeChannelId: null, - protocolVersion: '7.11.0', - reservedId: 0, - reservedIdLR: null, - rfConfig: { - enablePTI: null, - maxTXPower: null, - measured0dBm: 3.3, - nodeIdType: null, - rfRegion: 5, - txPower: 0, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: 0, - sucLastIndex: 7, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 116, - 115, - 114, - 134, - 108, - 135, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 2, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 5, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 6, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 135, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 116, - 115, - 114, - 134, - 108, - 135, - 138, - ], - }, - ], - systemState: 0, - }, - format: 0, - meta: { - deviceFamily: 2047, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 6, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 2, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 3: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 4: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 5: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 6: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 0, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.12.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'a11d19000200001e321b9884fdec8bdd380e00020000000000000000fd8e8c480f1700010000000000000000014c72cc54358f3dc9ce70ac752beb3e7a0000000000000000000000000000000000000000000000873206e7a00af5746fbc07ba927a6bde014d36396481ce9cce689ceba3f12841d85ffcc430bddb814dad5874aa73866b6a1361c9802cac47fc4df1627838f5857eb334b1bb0a8565a09d46bb8e722ac7910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - applicationName: null, - applicationVersion: '7.12.0', - commandClasses: { - includedInsecurely: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: null, - genericDeviceClass: 2, - homeId: '0xd79ed9ef', - isListening: true, - lastNodeId: 12, - lastNodeIdLR: null, - maxNodeId: 12, - maxNodeIdLR: null, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: [], - primaryLongRangeChannelId: null, - protocolVersion: '7.12.0', - reservedId: 0, - reservedIdLR: null, - rfConfig: { - enablePTI: null, - maxTXPower: null, - measured0dBm: 3.3, - nodeIdType: null, - rfRegion: 33, - txPower: 0, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: 0, - sucLastIndex: 21, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 2, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 5, - supportedCCs: [ - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 6, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 7, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 8, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 8, - supportedCCs: [ - 94, - 108, - 85, - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 8, - supportedCCs: [ - 94, - 108, - 85, - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 9, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 10, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 11, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 12, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 85, - 86, - 34, - 159, - 152, - 116, - 108, - 138, - ], - }, - ], - systemState: 0, - }, - format: 1, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 6, - 8, - 9, - 10, - 11, - 12, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 12, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 10: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 11: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 12: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - 8, - 9, - 10, - 11, - 12, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 3: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - 8, - 9, - 10, - 11, - 12, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 4: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - 8, - 9, - 10, - 11, - 12, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 5: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: true, - lwr: null, - neighbors: [ - 6, - 8, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 2, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: false, - supportsSecurity: false, - }, - 6: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 8: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.15.bin - -> Snapshot 1 - - { - controller: { - applicationData: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - applicationName: null, - applicationVersion: '7.15.4', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 152, - 85, - 134, - 89, - 90, - 159, - 108, - 116, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xd7db5d96', - isListening: true, - lastNodeId: 5, - lastNodeIdLR: 255, - maxNodeId: 5, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 0, - protocolVersion: '7.15.4', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: 3.3, - nodeIdType: null, - rfRegion: 0, - txPower: 0, - }, - specificDeviceClass: 1, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 19, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 2, - supportedCCs: [ - 37, - 50, - 114, - 134, - 32, - 113, - 112, - 39, - 133, - 135, - 117, - 86, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 94, - 134, - 114, - 89, - 133, - 115, - 113, - 132, - 128, - 48, - 49, - 112, - 152, - 122, - 90, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 135, - 115, - 128, - 159, - 48, - 112, - 113, - 49, - 132, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 135, - 115, - 128, - 159, - 48, - 112, - 113, - 49, - 132, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 4, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 94, - 134, - 114, - 89, - 133, - 115, - 113, - 132, - 128, - 48, - 49, - 112, - 122, - 90, - ], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 2, - supportedCCs: [], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 3, - supportedCCs: [], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 2, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 85, - 159, - 108, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 85, - 159, - 108, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 4, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 152, - 85, - 134, - 89, - 90, - 159, - 108, - 116, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 152, - 85, - 134, - 89, - 90, - 159, - 108, - 116, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 5, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 135, - 115, - 128, - 159, - 48, - 112, - 113, - 49, - 132, - 108, - 122, - ], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 3, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 94, - 134, - 114, - 89, - 133, - 115, - 113, - 132, - 128, - 48, - 49, - 112, - 152, - 122, - 90, - ], - }, - ], - systemState: 0, - }, - format: 2, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 3, - 5, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 16, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 3, - ], - }, - neighbors: [ - 3, - 5, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 3: { - appRouteLock: false, - genericDeviceClass: 33, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 5: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.16_1.bin - -> Snapshot 1 - - { - controller: { - applicationData: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - applicationName: null, - applicationVersion: '7.16.2', - commandClasses: { - includedInsecurely: [], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xdbf13d9e', - isListening: true, - lastNodeId: 28, - lastNodeIdLR: 255, - maxNodeId: 28, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: false, - preferredRepeaters: null, - primaryLongRangeChannelId: 0, - protocolVersion: '7.16.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: 3.3, - nodeIdType: null, - rfRegion: 1, - txPower: 0, - }, - specificDeviceClass: 1, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 60, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 1, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 2, - supportedCCs: [ - 94, - 85, - 152, - 159, - 108, - 38, - 112, - 133, - 89, - 142, - 134, - 114, - 90, - 115, - 117, - 34, - 122, - 91, - 135, - 96, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 2, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 94, - 85, - 152, - 159, - 108, - 38, - 112, - 133, - 89, - 142, - 134, - 114, - 90, - 115, - 117, - 34, - 122, - 91, - 135, - 96, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 3, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 85, - 152, - 159, - 108, - 38, - 112, - 133, - 89, - 142, - 134, - 114, - 90, - 115, - 117, - 34, - 122, - 91, - 135, - 96, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 5, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 5, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 6, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 6, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 7, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 7, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 8, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 8, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 9, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 10, - supportedCCs: [ - 94, - 85, - 152, - 159, - 108, - 38, - 112, - 133, - 89, - 142, - 134, - 114, - 90, - 115, - 117, - 34, - 122, - 91, - 135, - 96, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 10, - supportedCCs: [ - 94, - 85, - 152, - 159, - 108, - 38, - 112, - 133, - 89, - 142, - 134, - 114, - 90, - 115, - 117, - 34, - 122, - 91, - 135, - 96, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 11, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 11, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 11, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 12, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 12, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 13, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 13, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 13, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 12, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 9, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 14, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 14, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 15, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 15, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 16, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 16, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 17, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 17, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 18, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 18, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 15, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 16, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 17, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 19, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 19, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 19, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 20, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 20, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 21, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 21, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 20, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 22, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 22, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 50, - 91, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 23, - supportedCCs: [ - 152, - 114, - 134, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 24, - supportedCCs: [ - 94, - 133, - 89, - 128, - 112, - 90, - 122, - 135, - 114, - 142, - 113, - 115, - 152, - 159, - 121, - 108, - 85, - 134, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 24, - supportedCCs: [ - 94, - 133, - 89, - 128, - 112, - 90, - 122, - 135, - 114, - 142, - 113, - 115, - 152, - 159, - 121, - 108, - 85, - 134, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 25, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 25, - supportedCCs: [ - 94, - 112, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 152, - 159, - 37, - 108, - 117, - 34, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 26, - supportedCCs: [ - 94, - 86, - 134, - 114, - 90, - 133, - 89, - 115, - 37, - 39, - 112, - 44, - 43, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 26, - supportedCCs: [ - 94, - 86, - 134, - 114, - 90, - 133, - 89, - 115, - 37, - 39, - 112, - 44, - 43, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 27, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 28, - supportedCCs: [ - 94, - 86, - 134, - 114, - 90, - 133, - 89, - 115, - 37, - 39, - 112, - 44, - 43, - 122, - ], - }, - ], - systemState: 0, - }, - format: 3, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 4, - 14, - 21, - 22, - 23, - 24, - 26, - 27, - 28, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 2, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 10: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 4, - 24, - ], - }, - neighbors: [ - 14, - 22, - 23, - 24, - 25, - 28, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 0, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 14: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 4, - 10, - 21, - 23, - 24, - 25, - 27, - 28, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 21: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - }, - neighbors: [ - 1, - 4, - 14, - 22, - 23, - 24, - 26, - 27, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 22: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 28, - ], - }, - neighbors: [ - 1, - 4, - 10, - 21, - 23, - 24, - 26, - 27, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 23: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - 4, - 10, - 14, - 21, - 22, - 24, - 26, - 27, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 24: { - appRouteLock: false, - genericDeviceClass: 3, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - }, - neighbors: [ - 1, - 4, - 10, - 14, - 21, - 22, - 23, - 26, - 27, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 25: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 22, - 10, - ], - }, - neighbors: [ - 1, - 10, - 14, - 22, - 26, - 28, - ], - nlwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 14, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 26: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 10, - ], - }, - neighbors: [ - 1, - 4, - 21, - 22, - 23, - 24, - 25, - 27, - 28, - ], - nlwr: { - beaming: false, - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 27: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 4, - 14, - 21, - 22, - 23, - 24, - 26, - 28, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 24, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 4, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 28: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 4, - 10, - 14, - 21, - 22, - 25, - 26, - 27, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 4: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 14, - 21, - 22, - 23, - 24, - 26, - 27, - 28, - ], - nlwr: { - beaming: false, - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 0, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.16_2.bin - -> Snapshot 1 - - { - controller: { - applicationData: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - applicationName: null, - applicationVersion: '255.0.0', - commandClasses: { - includedInsecurely: [ - 94, - 134, - 114, - 122, - 115, - 34, - 133, - 89, - 112, - 86, - 90, - 108, - 85, - 122, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xcc137774', - isListening: true, - lastNodeId: 62, - lastNodeIdLR: 255, - maxNodeId: 62, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 0, - protocolVersion: '7.16.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: 3.3, - nodeIdType: null, - rfRegion: 1, - txPower: 0, - }, - specificDeviceClass: 1, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 5, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 59, - supportedCCs: [ - 94, - 37, - 50, - 39, - 44, - 43, - 112, - 133, - 89, - 114, - 134, - 122, - 115, - 90, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 60, - supportedCCs: [ - 94, - 37, - 50, - 39, - 44, - 43, - 112, - 133, - 89, - 114, - 134, - 122, - 115, - 90, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 61, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 96, - 159, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 62, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 128, - 159, - 113, - 135, - 48, - 112, - 132, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 62, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 128, - 159, - 113, - 135, - 48, - 112, - 132, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 32, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 32, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 33, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 34, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 35, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 36, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 37, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 38, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 39, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 40, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 41, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 41, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 41, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 42, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 42, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 43, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 43, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 44, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 44, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 45, - supportedCCs: [ - 94, - 37, - 133, - 89, - 85, - 134, - 114, - 90, - 115, - 159, - 108, - 122, - 128, - 38, - 112, - 135, - 142, - 106, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 33, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 36, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 39, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 46, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 46, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 46, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 46, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 47, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 48, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 48, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 49, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 48, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 50, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 50, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 2, - supportedCCs: [], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 6, - supportedCCs: [], - }, - { - changeType: 3, - controlledCCs: [], - nodeId: 7, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 51, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 51, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 51, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 51, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 52, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 52, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 53, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 53, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 53, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 53, - supportedCCs: [], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 53, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 54, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 54, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 55, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 55, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 56, - supportedCCs: [ - 94, - 37, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 112, - 113, - 50, - 159, - 96, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 27, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 57, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 128, - 159, - 113, - 135, - 48, - 112, - 132, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 57, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 128, - 159, - 113, - 135, - 48, - 112, - 132, - 108, - 122, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 57, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 58, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 128, - 159, - 113, - 135, - 48, - 112, - 132, - 108, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 58, - supportedCCs: [ - 94, - 133, - 142, - 89, - 85, - 134, - 114, - 90, - 115, - 128, - 159, - 113, - 135, - 48, - 112, - 132, - 108, - 122, - ], - }, - ], - systemState: 0, - }, - format: 3, - meta: { - deviceFamily: 42, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - 4, - 6, - 7, - 11, - 22, - 23, - 30, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 59, - 60, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 10: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 11, - ], - }, - neighbors: [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 11, - 12, - 16, - 17, - 18, - 19, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 45, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 11: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 9, - 10, - 12, - 14, - 16, - 17, - 19, - 20, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 59, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 12: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 18, - 2, - ], - }, - neighbors: [ - 1, - 2, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 14, - 18, - 20, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 59, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 2, - 18, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 14: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 5, - 2, - ], - }, - neighbors: [ - 5, - 7, - 8, - 12, - 16, - 20, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 60, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - 5, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 16: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 10, - 11, - ], - }, - neighbors: [ - 1, - 4, - 7, - 10, - 11, - 14, - 20, - 23, - 30, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 59, - 60, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 17: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 10, - 11, - 18, - 19, - 20, - 22, - 30, - 31, - 32, - 34, - 37, - 38, - 44, - 45, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 19, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 18: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 2, - 3, - 4, - 5, - 9, - 10, - 12, - 17, - 19, - 20, - 22, - 30, - 31, - 32, - 34, - 37, - 38, - 43, - 44, - 45, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 19: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 10, - 11, - 17, - 18, - 22, - 30, - 31, - 32, - 38, - 43, - 45, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 11, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 3, - 4, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 17, - 18, - 19, - 20, - 22, - 23, - 26, - 28, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 45, - 49, - 50, - 58, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 20: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 1, - 2, - 4, - 6, - 11, - 12, - 14, - 16, - 17, - 18, - 21, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 43, - 44, - 45, - 59, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 21: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 11, - 20, - ], - }, - neighbors: [ - 20, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 22: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 17, - 18, - 19, - 20, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 23: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 1, - 2, - 4, - 5, - 6, - 7, - 8, - 10, - 11, - 12, - 16, - 20, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 26: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 2, - 3, - 4, - 10, - 11, - 17, - 18, - 19, - ], - nlwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 2, - 3, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 28: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 12, - 49, - ], - }, - neighbors: [ - 2, - 3, - 4, - 17, - 18, - 19, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 29: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 11, - 3, - ], - }, - neighbors: [ - 3, - 4, - 7, - 17, - 18, - 19, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 3: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 2, - 4, - 5, - 6, - 7, - 10, - 11, - 17, - 18, - 19, - 26, - 28, - 29, - 30, - 31, - 32, - 34, - 37, - 38, - 45, - 58, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 30: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 16, - 17, - 18, - 19, - 20, - 31, - 32, - 34, - 37, - 43, - 44, - 45, - 58, - 62, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 31: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 11, - ], - }, - neighbors: [ - 2, - 3, - 4, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 17, - 18, - 19, - 20, - 30, - 32, - 34, - 37, - 40, - 45, - 58, - 62, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 4, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 32: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 17, - 18, - 19, - 20, - 30, - 31, - 34, - 37, - 40, - 43, - 44, - 45, - 58, - 62, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 34: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 6, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 17, - 18, - 20, - 30, - 31, - 32, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 37: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 17, - 18, - 20, - 30, - 31, - 32, - 34, - 38, - 40, - 43, - 44, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 38: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 3, - 11, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 17, - 18, - 19, - 20, - 30, - 31, - 34, - 37, - 40, - 43, - 44, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 4: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 6, - ], - }, - neighbors: [ - 1, - 2, - 3, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 16, - 17, - 18, - 19, - 20, - 22, - 23, - 26, - 28, - 29, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 58, - 59, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 40: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - }, - neighbors: [ - 1, - 2, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 31, - 32, - 34, - 37, - 38, - 43, - 44, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 41: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 43, - 45, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 11, - 6, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 42: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 43, - 44, - 45, - 60, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 43: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - 2, - 4, - 5, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 18, - 19, - 20, - 21, - 30, - 32, - 34, - 37, - 38, - 40, - 41, - 42, - 44, - 45, - 59, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 11, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 44: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 1, - 4, - 6, - 7, - 8, - 9, - 11, - 12, - 14, - 16, - 17, - 18, - 20, - 21, - 30, - 32, - 34, - 37, - 38, - 40, - 42, - 43, - 45, - 59, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 45: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 17, - 18, - 19, - 20, - 21, - 30, - 31, - 32, - 38, - 41, - 42, - 43, - 44, - 59, - 60, - ], - nlwr: { - beaming: '1000ms', - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 49: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 10, - ], - }, - neighbors: [ - 2, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 11, - 61, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 5: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - 4, - 6, - 7, - 8, - 9, - 10, - 11, - 14, - 17, - 18, - 19, - 22, - 23, - 30, - 32, - 34, - 37, - 38, - 40, - 43, - 45, - 60, - ], - nlwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 4, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 50: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 2, - ], - nlwr: { - beaming: false, - protocolRate: 2, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 56: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 14, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 58: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 16, - 5, - ], - }, - neighbors: [ - 2, - 3, - 4, - 19, - 30, - 31, - 32, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 59: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 4, - 11, - 12, - 16, - 20, - 30, - 43, - 44, - 45, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 6: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 11, - ], - }, - neighbors: [ - 2, - 3, - 4, - 7, - 8, - 10, - 11, - 12, - 17, - 19, - 20, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 41, - 44, - 45, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 11, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 60: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 7, - 8, - 11, - 12, - 14, - 16, - 20, - 21, - 30, - 31, - 34, - 37, - 38, - 40, - 41, - 42, - 43, - 44, - 45, - 59, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 61: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - 2, - ], - }, - neighbors: [ - 2, - 3, - 4, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 14, - 17, - 18, - 19, - 20, - 49, - 59, - 60, - 62, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 62: { - appRouteLock: false, - genericDeviceClass: 7, - isFrequentListening: false, - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 2, - 3, - 17, - 18, - 19, - 30, - 31, - 32, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 7: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - 3, - ], - }, - neighbors: [ - 1, - 2, - 3, - 4, - 5, - 6, - 8, - 9, - 10, - 11, - 12, - 14, - 16, - 17, - 18, - 19, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 41, - 42, - 43, - 44, - 45, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 1, - repeaterNodeIDs: [ - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 8: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 2, - 4, - 5, - 6, - 7, - 9, - 10, - 12, - 14, - 17, - 19, - 22, - 23, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 60, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 4, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 17, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - repeaterNodeIDs: [ - 2, - ], - }, - neighbors: [ - 2, - 3, - 4, - 5, - 7, - 8, - 10, - 11, - 12, - 18, - 20, - 22, - 30, - 31, - 32, - 34, - 37, - 38, - 40, - 43, - 44, - 45, - 61, - ], - nlwr: { - beaming: false, - protocolRate: 2, - repeaterNodeIDs: [ - 2, - ], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.17.2.bin - -> Snapshot 1 - - { - applicationFileFormat: 4, - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.17.2', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.17.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 4, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.18.1.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.18.1', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.17.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 4, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.18.2.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.18.2', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.17.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 4, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.18.3.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.18.3', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.17.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 4, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.18.4.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.18.4', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.17.2', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 4, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.19.0.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.19.0', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.19.0', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 5, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 700-series, binary to JSON -> ctrlr_backup_700_7.19.1.bin - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationName: null, - applicationVersion: '7.19.1', - commandClasses: { - includedInsecurely: [ - 94, - 34, - 133, - 112, - 86, - 122, - 114, - 115, - 85, - 134, - 89, - 90, - 108, - 116, - 152, - 159, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - dcdcConfig: 255, - genericDeviceClass: 2, - homeId: '0xc5b9bc28', - isListening: true, - lastNodeId: 13, - lastNodeIdLR: 255, - maxNodeId: 13, - maxNodeIdLR: 0, - nodeId: 1, - optionalFunctionality: true, - preferredRepeaters: null, - primaryLongRangeChannelId: 1, - protocolVersion: '7.19.0', - reservedId: 0, - reservedIdLR: 0, - rfConfig: { - enablePTI: 0, - maxTXPower: 14, - measured0dBm: -2.3, - nodeIdType: null, - rfRegion: 0, - txPower: 9.9, - }, - specificDeviceClass: 7, - staticControllerNodeId: 1, - sucAwarenessPushNeeded: null, - sucLastIndex: 34, - sucUpdateEntries: [], - systemState: 0, - }, - format: 5, - meta: { - deviceFamily: 46, - memoryMapped: true, - pageSize: 2048, - sharedFileSystem: false, - writeSize: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: null, - neighbors: [ - 2, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 13: { - appRouteLock: false, - genericDeviceClass: 64, - isFrequentListening: '1000ms', - isListening: false, - isRouting: true, - isVirtual: false, - lwr: { - beaming: '1000ms', - protocolRate: 2, - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 3, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 2: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [ - 1, - ], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: true, - specificDeviceClass: 7, - sucPendingUpdate: false, - sucUpdateIndex: 26, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 9: { - appRouteLock: false, - genericDeviceClass: 16, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - neighbors: [], - nlwr: { - beaming: false, - protocolRate: 0, - repeaterNodeIDs: [], - }, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: true, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 500-series, binary to JSON -> ctrlr_backup_500_static_6.8x.bin - -> Snapshot 1 - - { - controller: { - applicationData: '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationVersion: '1.2', - commandClasses: [ - 33, - 32, - 134, - ], - controllerConfiguration: 60, - lastNodeId: 4, - learnedHomeId: null, - maxNodeId: 4, - nodeId: 0, - ownHomeId: '0xced44428', - preferredRepeaters: [], - protocolVersion: '6.07', - reservedId: 0, - rfConfig: { - powerLevelLow: [ - 255, - 255, - 255, - ], - powerLevelNormal: [ - 255, - 255, - 255, - ], - powerMode: 255, - powerModeExtintEnable: 255, - powerModeWutTimeout: 4294967295, - }, - staticControllerNodeId: 1, - sucLastIndex: 5, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 2, - supportedCCs: [ - 94, - 85, - 159, - 108, - 134, - 114, - 90, - 115, - 49, - 67, - 64, - 66, - 68, - 69, - 112, - 133, - 142, - 89, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 94, - 38, - 51, - 112, - 133, - 89, - 114, - 134, - 122, - 115, - 152, - 90, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 2, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 85, - 159, - 108, - 134, - 114, - 90, - 115, - 49, - 67, - 64, - 66, - 68, - 69, - 112, - 133, - 142, - 89, - 122, - ], - }, - ], - systemState: 0, - watchdogStarted: 0, - }, - format: 500, - meta: { - firmwareID: 90, - library: 'static', - manufacturerID: 134, - productID: 90, - productType: 1, - }, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: false, - lwr: null, - neighbors: [ - 3, - 4, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 3: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 4, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 4: { - appRouteLock: false, - genericDeviceClass: 8, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 3, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 6, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } - -## 500 to 700 series JSON conversion -> ctrlr_backup_500_static_6.8x.json - -> Snapshot 1 - - { - controller: { - applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - applicationVersion: '1.2', - commandClasses: { - includedInsecurely: [ - 33, - 32, - 134, - ], - includedSecurelyInsecureCCs: [], - includedSecurelySecureCCs: [], - }, - controllerConfiguration: 60, - genericDeviceClass: 2, - homeId: '0xced44428', - isListening: true, - lastNodeId: 4, - maxNodeId: 4, - nodeId: 1, - optionalFunctionality: false, - preferredRepeaters: [], - protocolVersion: '6.07', - reservedId: 0, - specificDeviceClass: 1, - staticControllerNodeId: 1, - sucLastIndex: 5, - sucUpdateEntries: [ - { - changeType: 1, - controlledCCs: [], - nodeId: 2, - supportedCCs: [ - 94, - 85, - 159, - 108, - 134, - 114, - 90, - 115, - 49, - 67, - 64, - 66, - 68, - 69, - 112, - 133, - 142, - 89, - 122, - ], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 3, - supportedCCs: [ - 94, - 38, - 51, - 112, - 133, - 89, - 114, - 134, - 122, - 115, - 152, - 90, - ], - }, - { - changeType: 2, - controlledCCs: [], - nodeId: 2, - supportedCCs: [], - }, - { - changeType: 1, - controlledCCs: [], - nodeId: 4, - supportedCCs: [ - 94, - 85, - 159, - 108, - 134, - 114, - 90, - 115, - 49, - 67, - 64, - 66, - 68, - 69, - 112, - 133, - 142, - 89, - 122, - ], - }, - ], - systemState: 0, - }, - format: 0, - nodes: { - 1: { - appRouteLock: false, - genericDeviceClass: 2, - isFrequentListening: false, - isListening: true, - isRouting: false, - isVirtual: false, - lwr: null, - neighbors: [ - 3, - 4, - ], - nlwr: null, - nodeType: 0, - optionalFunctionality: false, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 255, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 3: { - appRouteLock: false, - genericDeviceClass: 15, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 4, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 1, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - 4: { - appRouteLock: false, - genericDeviceClass: 8, - isFrequentListening: false, - isListening: true, - isRouting: true, - isVirtual: false, - lwr: { - beaming: false, - protocolRate: 3, - }, - neighbors: [ - 1, - 3, - ], - nlwr: null, - nodeType: 1, - optionalFunctionality: true, - pendingDiscovery: false, - protocolVersion: 3, - routeSlaveSUC: false, - specificDeviceClass: 6, - sucPendingUpdate: false, - sucUpdateIndex: 254, - supportedDataRates: [ - 40000, - 100000, - ], - supportsBeaming: true, - supportsSecurity: false, - }, - }, - } diff --git a/packages/nvmedit/src/convert.test.ts.snap b/packages/nvmedit/src/convert.test.ts.snap deleted file mode 100644 index ed38022ea37489369297bf17599118c8ac5650c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42175 zcmX7v1ymbN+lH|q!QHjEySo%A?i6>2;94X&6e$#UiWIlv9w<<}6xRfIf)psF?VtDi z_nghyd3I)=*~y;Go$H=eFjinN@UjK@xp@0C1PTFBk&MwSy!#A|3`0G|l@7imkw5#= ze2vr)t5E9H=bLV*rl3#3MEc)`dQlu?VW_$~F@&vQ_Hn0*Yv6K`i~#L|DNsR0o-9!B zBkR`!yMogs*N2_3>+O5#(~#Th0=Li-wgIu-3tlEEa`L#;r1T5=i1GYi#dn2%^TkqI zQpYoOZJEhuiyQ%u4J#|Tt0peapACU3{>7c07Utxny82dCO~sVD*0dQiZfgrsCsxQ+ zKRZY}h&7g~45-{#Ka(V5)lpOlR#*1d^*3o)8i>{Q4qn9@QKj};$?y)&5V`xy<)=3I zab{qVAPGf>A(Q84XU({oesl129nf4c^!N8yULiGOb9fM34;?mgN@{4&(zJSOX=H6~ zsaM{pauk&^vuBZFWES9A)ob-{SNkM7sqJo9J9{IvW3aQr%=5U;Ewxiyb>2A!r}G;$ zdk${yoY)4Y;mY#_ylI5`a6K&oiy9brsBRlWdDKqq8@=Y4|LtM&~?Yzz= zg}!Sh(cYJD$p@L0W0elsXtuYx4H}w@oFw1Qo)#A?+n%02cE>t+npLoJa13(ml^cz- zxn}!p90)dYGRpGuatO#WvM@5LXBigc<&|-Br0{7OvTJ-%Pg3VpDXLSh=h1U9;&ik~ z(yvW5a1(Y+x+yrQ6jVtPlr1+b*PY09(Gc;$;!wXiJ0S7QSNx>$-eiI;XN+rae>#&$ zc#6o#E?Kcke}ct@$UuXLNaXAdwa!HI{-e%Qeja;#9aqP5=ya1J-?7uc?U#;#!(}6_ z_7=|9gr634=B}sab><$bmb0_ZIJHWF0hYyHIii`zK7Z90YI^G$!tInAtvX@I3~z{g zr$wp?^pz&C;f0?Y7gus}AC|Sb_?FKCM3dVHN`bk)g+Uj&ym+>1{iilU$omlQqd!4#Pq>I(K9 z73<9dQs>&vlKI-b=Sv}VOQWhr7iI?AV_gGtOKZ!wmW)rS*%7CVy`TDx&1)KqtCx$Y z@hjBlgIt{O!}7V?*4aJWrg3(dqAbtczEmAL^88BbSXdrtva+;p^6PyqN9#59afgtRCXR>K0v`i%h)vva&^}W9%)JT)k3XTQ*;s z7&V*ECq?LqwIgOiqRz^)*>mv+shP80;cK~-zh_goz){C*2Onb^&s+^p$AHTj#q`9Ga@9R8d|JM~y6E#BOm zcAzexl&@Yg2?=sFCar1i?F%vLA53nVts}ZO3Ye`Y`e{Tj(yX!A*dv+Ro`CfL%96SG zLcU^_10kAS*pR62G?p=Nde?LSg_cYA{o#?wJ{VLQoC>4w-1n{ zXrLLW(q~BXQp41E@N(4fL!_Y+;_sg~jTbJR4lylh7*`0#B_LX9Epvo)ezEwpu!dK` zQVJEs?*qXS+ASkkC4OM4vF>40^1MTo z6ia9ecK-#6b#K%bDU$``JZV!vTt^eUk}LcixZ{;^i2hcr`-he;C8u7`CN5s@NTJul zI<4KdZLE}LK*H}W+Y~A3E4=HTm>JXx8JjN{GY?UubZ|cWrwvqT8OB*+4QW6&AyIZ$ z7-XQNWs_Jt44h3K8!{r#mv;aV3mp;U6F&hohbXXlC*H?@*x{e0HVzrh+JRSzb^FJB z^a4-0Bu(vk>8{{)mZ3rowoUgZhd23?X^&g zS*h3Y^Lw`opC<28*?{M{0;l4EvAIukK_Z$G<3d@T8kYLyw6dYP(>j77RiWc2t)uld z?(XJS3sw5{P41tU-AD>{;@6wAI%WiAS*=JMf^E`E%>1GcbF@6y)h@^G&KZ5QyP8UU zO5(kCa?e@W@{2V^*>wMr_Z4e)vJv?E)fa0%d}wkh=L-dtiwzWO=6vD`TqJK^C6zi) z=?hTddUvB_`Teaor-@G`;#U8#jQew=2=T+mGk-@u#O%k>d~RJ|yiwLzM{aCUF|)Gj z(0LdjX;r;(H|2g#y+q36-qMg4@po@y+M#57zAwu&yEA;RGSlr_=4S&VzmGTBOO|KV z*gR&yFKyyN5rZo(^}>fn#J_V^vyF9rtju|Ypz$fwW{ z*%AwPu77fX>!-=Sxk-~Ry=c> zmp5)HayZul*TOO8DL|>MUY4$%Fr%KIESf8kappriu$A0zjXa_L-9H`u&KKxtz21dv zg$5^>Tg!HNbysY^wd)^x#D5)@?-3#tc1B}v{c8yzy?I&edK9ym2#Tp8| z4K_l!3L1gymVoicBO)v-MYbw-9%&-GSB!5?DA)pNXt92M;D4pxZG)95Bk|^yZ2`?7VH=~q&^7>wh`GpK?M=yhpNOQ&XLs%1}qLt~|BF@oXWuYfoJN3staBkV(tHEr|(0&=SPR_)3+f>h|2~thy zhjA?GO*z!YTU_~j#r-9*E%%#Ox}+RskmvK~=I=vxVnhtT)I9mJ8r{*a7KO7)!(<{` zNg`bE0mm+Wx)j9Qtibrkk^rajmM@+pIM%j!1#yrt&rddMY)^e=?6G5Ck`$d~x`WuDJlKIQcnu@s23HVoARux{b z=X=MNcFip3c$QQ}FYg!ryjqQH6=Gr{E@dLyGZ@nkPxdD&VUo;`PjA1pcQLI?cR6~4 z*O5w{d{6EAykeR8{XO}&K!|;>yCe6~SBO^RSr|Xr%2&u=(_ld|tMs^eJJ_n}Nga|L zfSqJ~{+O55_}~F77~&1UF&s7peB`ppLAf#<76e@A4yyzD+1Ww-<-_V0OGUp7;5CuJ zzbXWK9*T+e?3F1*McE6MuH0j@u>|;fY86DGoQ$djd#;L!UF?-=SX3;+n2Npm1bbYV zKK({mL0q=^M4eo)N+K(L2qjB+4O+c8JTaz4TrD+b#7CC`W7&tFZO*i{6zeN;h5Pnn z4HV$h!ia}AK4Rble@*kkh8K~J`a2k&j^QYMpO*0bW_$`oi`^h;8p4}vZx$Ru80=+a z%GLyQ|7rx=VrA^ygXrz79j;XK2F~VW{(I_Z@+Wd*)mYKo-rf9OF7gT;`}LP@z(_LL zBSW5^sJ4Hq#Yo~T?@L^`QVw7DYayMC6g($3N@wzKq?eplyuZhj&HiOQs!1^g?Y&Lg z;-CyKpDZ>T?oUbGS_hqekV<_sSxKf8#A%MVEx{R+;0OLHj4LzA7 z?u0k+gnME)`KoBSK* zA+x9fI524)k@_}Ws-yfbO|$1Xe*!6%Dfc447cAxS_#(}Mu_)`}YKqZLV*ee!``*u~ zZe11VVVvF29NH6Nl>9eq0f~)b56z(1rpKTUCBDQLd|V8D!v^w?cW|aS#u54orB)x# zm_TthJ;I?bvh5P0@r!3GhV9P5JB7l}aCRj|&73p(q6)Fmy5%denS11Oun)S2DahG< zqBY3#U?^feUx-}%)3K#bP%tc@GUP3OaV{nld%)}_P(4>eV4QsuXoJ*ai(v)#cFQJ* zy1_5Tc?(J{1`0|L4zg`fVj1D6y3)PE3+fq-2nt@M<(6icL=6p-kH*k^jQTBO(}mH0 ziCiqhI7J*E2Jz4_y~NT9fkXxn%2|P@5HhXSD&rJTWd-UYr-6f42cXV;@Z0!cZ;CVA z!yQnc*u`D^j~$zJT*bbTNiY6(>V^yS^uU<;vCpO7iL$k2p)k~1*|MAHuyC6i{C+5^ z^{=Qca_~FGALPmJV7%6A``F%35c=K|dO3<|aFLY$&i+ z`6p(Aq8J7q%w#aMm%)?{4I>7+s{mIaSPM#6x+=TE>k3F{+=eY*!BvAWuaILxnxapt&7| z<$%^Uy2)V^Ab2W)VUC93Lu%9o=4X$Whe%G8IpruvX8-iqdo>Dbtbh-2dFG+=N}ZuIvBF{-)>TU%k8w0N-!82R>bKSg3{^aVv8 z4eFge)D-7LR%d-oF`WBg0)m_BeNmc5YMArJFoGCc?yI60;NC#K1LewKxM@7-s+4P3 z11nl%QeUx(h|Ul~$kP7_Erf=B-^PQ+f*7NIA1#}dJkj9Cz=P*o14{;Ntw+u$i&EqL zC8mOazokhA*d%h)9RxK;P3b)6^pU*Uo=)KgMH?$m)#4pNdxd*TMZ^VrOV2FAUu$R8 zT#^koGi?$L+OxjxtdQb<0BI+k?8v@%Hqp`UXvzLy;B+LBYtnEu2$7RrY+VDb(&v}nYHX;;V&i4N; z*#6f-lE34By*bwe{!dEw{;vZ$%3MV8@ORdYicojJL}3P^xizBMZBKy5JYLtJw3ke$ zGeT^Nb`Ab+>+ML@92{b!xx|{kkL?PDkjub4bU+$0SFRZu=zkXfR=jZ8FP8D+HtED1 zx`KqY)&!Vlhi+d}^%tU(of72XQJyv)S#xM6Ec$n|(5_UEjxs41L>_MYKe5w#geti3 zovhX`zi?Fzl=YKutz(Nmg4t9Oh5t>d4nXAwhGkJJgls^s>wlR{36)8rUQI_8Q^Jcd zKO9;A(m@Z;LT<_@D8+guXg)o(*ds|yC1|U_dNCiHtCDySTs*hy0MW^Z76UlU_*vgX zp}k?iHRG4U&T$<1&K;~28>`MB=Qu)dMzBCF7^-CJjZDN5J#&RCb{{V?0E6won=q3; z$p1aTEq<0)qd!^2(D;o>P=)5JMBm+k?{S8z^AMe`oXG5~ajgALVTZip83G;D-7$&! z%$#BV8?yb*R@FMViSI=R3Nw5Aze@)v0)6SphEv3!!MEcIXv?yOt)PbCNaSC^80C{acRb_sEj@g_tcmn zsJ46Zd5lr7lNY_|F(2__jT9&JD((kRVQ~4URrz2)h8Jgs7v3memD7iq;Q)eI9KowR zHVqw0G|Cv8H3oJ%Gy{y0R1}v6_CL`IEiMEegpz5*K{oXCXz6(1T#S)~7-)imO)+lC z`uOloCXUKFK_RZ0;slD`=!wVVeEhd{ektm!sd&fr7E2_uBr0u(QTugx-GUGJGpya? ziIbWFM>~emg?|h`elR9A+D%XC%7#LYf-^3S#co0(#`el4kI#Qe%~u0A-ZKUkyP(Hq zwVaDS>K+5j8iC*0WE{(P(bz92>xCNPjUCEcm+v#{J?GJ|&qPnrbn{|d%|>UVxU{jq zGr^;ojIN1IGf+OQ@q_-Md1A%jPKY`uz@)RosUxXk!;SvJ$ZvRJ`ctluQbVSaR^6q^ z6WuF}t|(zs3Fg_Zdm{UVHosgjz90rtiO|v)VT0@3B%K|pU`D(@9PPSK)d($~Uw)C0 z9|LwXmD=+8XvWU%fgd;ER1WtGWADZl!-#uhyF!q{R$b9w7fWo$z}P1<3|a0hg3IW zfcYpoW4rF!t|-t~=82_UH<9MQ{|1S>$e(5vY#le*DJmG!3gW=#UQ$k~j#mJV$)9>} z?EcE{vkazok9CpeKKTk{WfkWQf1a*#5_w6<#0t!Cp-zgd&hl^R4K^ktA2|d1&)^Y} zfB0Z1%R}DuEw0bk){NI(A_wDZh;AW< z*zt%`NQ;#&NZm{g|1ZbWQz^KVJk~;=Z1M3Hx-b2tPT-3;b7(*8gM*gls!F!_B#ac_w{>gQ)M6*V7t0v>T?0)YAHm-r zmZX=yW0a;3JsQmjXP-(q3%3UlvXUeo(@uI%CYayZD#&`wBq;rYH;0QC<69q$u7`tY zyc-xcVo`1|(GtpT2t?^JCq~O|_#>nZ(-O|dM+f$8mxI@2=;$c%`O*{8$47PcM>>a1 zYay|V;>4aetQ%v*1T_8F3}r|pfD9v~Pe6Hdq#r=&3W}*AQXw`}4O!X%$(wxG1i-*0 z%v$K6=-O7cG}S{Ojm_9Vpbup1BLJdBbFiX4kN}KH72h##SzzLmLY@`H*)cVR7+Z2( zaw16~*l}<##&Ao_92KZB8ly@XCs;ux!y3&X8Ct;9U4v;%HqyjoUq#9K(J4uTo)^rP z0_|XW`hpq318yQ7_C^`gj%vW-_eJ@r9rcXGAB4hPgjC2%!FB1W=xVKZ3c~{VqV)44 z?-U~KYDdj|g<9d1f6dUxS^vsENWqy5>$S@>!KqJ9&3+In_mBGQA0$A-9nY2m`)T*o zPZ7a~9wzcsuTUGm<3>@1o=R0+3lkOL)~Dv8by0Nf4Bq!P9@Q2pG8|2D3%17HttidFfMf{P;D@!e1l5vCQ^Y2Lq^*B1mp?Tbz2B}NhNvq zCZfva8oXOElJUA}jCR-}g>=v3kLXtn^r-&*+Sa^szASK+=3|Y!|CddUebYx;#cq1S zz(M9u7p;!1&*_9g!^e?OO6gt7!D}2wP`*silZ_A+#2`WT&~2fnTMt`uFLahIy(4(UroA% zNvVw|q>aX{fL58M6e>4@g zly*C}?+>(!AD%0BE zr_4x*lB?$`7Q!-GUHSfSCy)Da%XuHgd5WhfhW5tx%vEGm2YSJ{f#jp#yG<_5NaBC) z4a|=329w39-0gGV9IFcpHwzZA-KgKyDgU7)*zW`Pa&0Y=1_pT^;$Y_gG`EClnzVdL zunD8E!#8>WbqyeOkd^bAU)bi#(6lB@T*6es#69upH%G-D;C(VDc>N$BBsmPspeQtq zNl=sr#$-U09Y)@s&C53A_0tnfbQZbECyEpg{t-3&9LXy!;{>xOP4^NrNE{-m8oWd} z=!=HWc5;Zuq7CXIz6bz|6+sbY#uD2PEb2$HYm~3Wl?H^ky`_it+Q;uWnJgGa0k@WA zIOZDRy9QKBFY1W)&^70(GiHC^KX%=hTSV?HM2;On)1l`YfcTNNUR>g*?dODW3S$W zlfSefIx|O04}xal2rRkv*4k`uw@nUVN(70zFNXQ6c4l=tORYz$NVNwuOz&RLTz@&3 zxsAe>^b40y5GtI_e}mHG;7q2Y>6$LomGRJqI~VROk3HA_4>I?nji@l6e~HTHO~=V* z#88O=$&hCU#umtTGZI|k$BIO^blrILnNZJn{bnJ!01vZa+JPBfo$yWRiAZDKf^A+C zaAShsDL_gSJ2UYWdxajX@WIwG!+lcBLF5dU%o+Vxx(l>T=Xle-qlAQe4AK2Nv^%GG zZFB?+sG&(UKPBEU0A$K4F}Ai)SMH+>n8vhFLTWI=*H9Z`7?~-a(Xk11uqv4;SOKH7 zBP|>hB?OGy%mmxtqe?N9RtXY;(H8{Bdu-8~!00-HJaQB%MW`7e5qoqv9g6jNZ=9k9 zI}SNM^#x%|5bJ)~*$z=)%&l4t;#Aaqu^t-TZnMdjq)hL7sg zcz%qc1|m4z<5bSyA!FR#htPF{Ewu=Nc=eQL#{RNE2b{Y(>gM=8))fPZ4bk#(Z!ngL3~JK-B_5w$9ex;Rjfa6$g?12N_ILa}wd1pu^v@`sp_!Bi5B| zU%APTTDoEHHl}l3;QwT>!yS3CDTbP}up_A@1JqHDnK3oMPs}H|Xd&wS0$5JWBbVwe z;#i%`BdyHAyjVNx;Aa2h+4^A>#~0O#;-uU-OTeLJj1fUCxP)_3PoW%GXT+}xc&xSQ z06u(%3Xt~KfpyRvA6P$10HKD+BvW zP)e(Yn>iL(NW%>nMM(t>Qj@w181{IHC_e!0^=<7qXEfua3>1R87dj2aKLGhEAz`&} zPfq_ctScGD2DZxk*ozYWK{mtt*z-`xfJ|yqa2~^6z|A+k_Z#73x-Z!>w(oQniXm_Z zo!|ks@D<{Sb1cgr!+f|Tt_xDQudAY2aj6zd8r{ z4*uNl%{O@k_%&do!PnhMzV!p!_#Rw505#+bt|bp&z#hB?tWZMpkztezLa4ri@3Ywo zbeo8-mmoOovr)Y`-7KhN4#VR(;vbQ9oQF?wp1jeEW|1Z|F{ff&nbU8t;G=sZu#NXo!!4foEzM(X8Cr*ODa8ncjh}+6o zvArh27;QG5IRdrj((Zs9q+gv zrCbZM=tcg7aLqbhYg6yKmZZE~GEuOa3TqZoP?~bBRZ;Hy#bXiR3K}^`5n6u=#67Xcz&}S)ek@r#VW8>59tUqAh(V08G+_cs9D{Swux!`&cm5DS6l!;tE5Uz^rKQX;< zTK#t0uQJPdTKXLP5;pWJfZ_-ef0~CqD@h*6ZARs+ns0+S?RUzk&nqLNyolyFjm1=Q zcGty{*dqLap`z{(jSznts!kccO)1@AQ%0)U1_l^|)_}4uIW%^$BAV`+cs`RgaPW@5|EW)j zIA#6!jFn;9?ZekxoN>zP`GQti6$1yuG_F7_`WtN1LVdMF{l8NrM46v6hF-&; z+B_m5k}3#+W#=j~Y01UUH*Js*#b?Duc$8p4G8FAJR_~0+G~#R%YW0d4(`VU#I|cZl zUl6|zi2qhsqjV>!gpy4AIsiRno3?P3g(~n5#WKt3`9)E|YVCc%D)lnU`T3xyG25Gk zYnzf2oa{MJsSpi$yM$Vn1p;$hOUA@tvs>B}VbAzRf8}jt=~0t9L7A|Gs*^u;VfSC6 zl=cn>@q#)9U@?VUXx)mHT+BU+Ia~+b5DF7^pEwPZJQz@{2O`tdGD*793&ArHzW}E9 zK(L$O)m-6AdE9$qCM|)e&SLO@7=E$DpcpGJ{z=@|eIsaMc^BxoUi=fdSN<`-yjrGk zJ4Kz+gV%6N0%BITpzo=}Vd!#w3T#0j5QcXUW*|nK)V;qq3!!Rc(4r;v*y0GOCVs8Xxg)*)_KKMdFVX_Ok$JJRCC-$>1Uh0fN8C8?tp z5V3{(cN3T99m6t)uq^*7#>(&EeOY)l{tFbmbFgKH{O=+5?r(59{ryc$ zQUs{0wCqlxc5Wa7w1&TPi|QV!`#j1X`S~sZ&K{585<+~ry%^NL5ywyf}J~H#E4Qj zVT@*u!)y4!BRpvOit@xLLGi;^1i>t55yU9D+*TjXF6e-;@(g0&4@Fx?c4->mbplw0 zA~;sTf&vEz;bX&X>>0lQwzVO}n*vc#k~F8i0hJE-~OP&W1GQu}U&sW#p9} zT#rQjwUV1KiSnq(_ZDHQK$TIU@9+p=(=mBXoP+UU5rGy#^pdn_Z@XbGvPJuHVdI5g zwT8#Et^9ms4`UGXR-48s5CBJCz6YhrV3_GY@AMA%WQ44sK~Wj2!NP3_!D0!o{EwmU zp%q(e1f(U!K*aNiF$(vghvEyKvjOP|mBAD=_>MOqEotu51h#$HbTCLKY6)$Db=VTC zg$>zCD{7Y*t$6oMz=K+BqB2D$<_}_9BPQugOlP7IK`d!%F-=?z@GWyNJ60O&NIr9m zakM_b-Uu`RT=@*;$S%7xIeh~h}$|TGx4$7L*ku&LEE9`8`r6vc8)3z^SRUif_SxB>%O5i zqK?z9YMzKQ0v(7mh5rRF!Vtl4XX}WL2b~Q%i*RLd5kZGGF@F`M2l{Pewr%$SseEn& z6aQuMbAJ`FcRmA6Crx~VO0N40!TC&^aNc8yIZjeJc%Nc&DxnopBupDQf+ zGJc(<4EU?az4NJSI%(!>S|&xk|7sHORsNk`339JDU7(;@Z_}Ekb;Gv>ISK!-BE5Dk zgHOp#6cv0MPT(uzA;f~1YOZ)nn_jzag~BEZTZUS$*Hq&7|9^}&y2dToo@y`mU>cQJZH}OC1MTj*ceU14t zg^O-9{ZVq~b8xQ}f03$Xf@^g@hh_MA5XFD5e!w+be0LjUe^sIg++f}Cc{uqE$q75;`W z|ETT)&snrkh;Qx+BWKZY2X4q&^7xSt72vT zO(`9KFAeOi8hz)Y``$}L=OdG*Dw`B%%mI|^~*d2#ELJO z9!+Oo_DF%eXpX``hw5k#?G$LS#gS%JWTw26Dy2j%O+)T$B@iG(PxItqj5uy<)fFJS zqQu@Dhx}kt&b%JHtFebow?c*SNcL?`#E}IJQEDkLI`*L>J}u5P{p^a&`Dap*5_p63 z7<9ifKH`7615CPLRf^I(9gOaUi+{v#PRWr1L%+HCnFt*BqbP$*h(07^KYA{8@1t{t2+zT|6$HI7g+ zU=jz*AwqzgCw~7c+*sg+Q_<-SgOwZHL@9?Vc^OpvHp+r6n%ij9O+>mbUdSyY8M>7FT8h#~{UoegA05KvR6^2ji5eyXPevbH{kaOv!>FXF zA~SqTQ4>e`HjmHl=#4;F2gnq=rUPD2)<1sNNzZ|EDE2fIcsg}gA8%H~5 z=*pBR>vWFvzGX2Z%0(AO+g=XW8} z%ts5-1gA1NeImJgVh(m93KziY%~5jbiCSm+io=;;d&u8GbCf+ANZ4+f98yhV#hGyJ z|Bfxjw=HU&~qdAJ06s`#9XLAWPg`5@wpK4LIxBxuqYF|vNjTN0(-Zu#6 zJbzZM>m;f+gj`lEO;mMm8)JoW!aisO_Ylc8#L{z)^a7>p8Tx_x_3uSw8C%z&oD_P1 zWg}2zcG*w$Q_}~-k#f%9w;3;d-%NL!!1#5;6>l@1-z(R7s);BYDZLfJsg192``i>S zu?(^nX=oB%d1z4HEO8Sz#BEOAD9K8Lt-56_N4-gHT{>o2!K#h^Of}gQT}P#Go3iM$ zWsZu!JlspQW{s+|H0&+{cg20tM-4Pc75Qr}h*w%mAWSM)1KhC6NmCLcWz~suN2~qE zMmaHH04uL;apvr2(ugoRGndnj+pSSteG9LTTYEd%5J%XdtB)Pf0rG2XU0G$Z5BW@% zvjnMqtFTW^luAaw0yzeciLnqxHUp+5F&l`P2U%#9h9oI0F!s;OD)5>bW5UjCRA?_6 zVhjS{`o*o|T`W0L1{kF)(E&2bOW1FBKUigr{N%5o(>PCM8Dje&-ALC|oAC7~$l_!8 zYe|y<1AO|G(Z`=Q%Sd#%1S?1!xZ?$~A6=%rqF}hX%Sex6m<6(KFuH#RXXWVsO>2_! z?Itc<0o7D9Cc_ncFkiXqFf2?VhzqPySQhS%pqeQ}udg1ta)nO{2Zt22uKZK$hmN|! ze+jn~^SZn=`*VN)!5ATVU+BgC6FX_C^+&mjq{SW&9hPT z%C&N86MHhmC{AEIR)^Wx4+uAfb!k4<+zIlM-(p+cI!@1GFCk8xHXr*#2zH^VaIUl1 ziZ%nzFw2mhHofJ`Y{e-7ymC_b$*pkaz1S+vk4-iU)@p~sxr0N=ib??giUE-`C<*HX z{F|ox*F>pP>tzMFJ?((hNVN$8KT!)g>MP>P5|NxxEVjgk;_b9g7TThyU4IC&ejun- zV#{+a0%7S-HM?TOnKua}kQ)EznX3IVMF2B&B0o`y~PV zhsMv8(N4RNeeGoA&!&3$%?yI41#fU0KXrSOc>J`Prk+tK--{R3%b*@iD~yB8UzS4y zKS{99476&IT--yKoyu*345Zj&cO25B?5x7rJv`X}F{C9P)BvTaFZeTxwv)4$Wx5gV z672m;qQH0y9BYIpn`geEP<}<`*S&xGp!@WVo5bR{bCjIKZ&rb^1_Ax%6V)#(ZQyZ* zo3BT92$-G7fSp~PF^cfUqcV`rCcF5_Na3vF$YE!oZsNc!4GCFiD%dt<+p1j`J}^K_ zqVI)pj+Z?@K`Sxn#jxWRq!790X^+ZUIy^~=aCM#$_;4m|N(wO}lf_46x;uzb72cAy z>zXbjj->Vwys;kn&xxe z{i96SV9f2+_Vm=*C#BNk82LRZ6OfR^)nUb2t ziBjX!l%q(0oK@8<3-!)lzTWbGbQq$m(hFT3?qR3#q6rEA@F_Py_*!1Gb542c7b;SH zNr8dnmlqrx>*hu3ybw6~%tIh-(`024z`uVFe>DBE&(!G3TH3q({?7OJG4bf@+Kxsa zqE*sNu2t zrCL!E_Bbc*=n3Be(TC0dV{801)4Ap~TFL8kIuxis-%o`5@A1#i7qJf_OJgw6d6eiZ(69sXo5E6y8L1|S$hdghJV0_b)k zRr5t{k_}e?S{$QqlENNXC&dd~`~<%rG2!iJF|2 z6YQ`~K4CgoIPt_wq}cA*nRZY-aL22XkN)F{PbVMMNf`;m3g(NRWXb46i|38rW8n|L z+UiE5GevRFrO1MdC_r|V&7+b!89uxWvVa`0qzBNn`J(x9hSyo3-6Y@~#TWgPJ`&$t z#dZC>K@u-(;F}!CN)^b1L%NG($IMN0un&u9gmptv^GjUP!O&Zv95b#OGc##@QOS2nA^fJw zi*e{X`4;b0Zj6(JFn2=Fv@Ohc?F$VaUqVgp=;J5OMoKV*^4x@Yoo4*N zUMoYlz$HcKdk#Y;pE)uq7qoyB^awOfNiv@hws72uPJ z!a8T(AkfPkkYYS?WCU^`m2L;_yaiY{39@E+fHmvX;+JhYsJ2X$PTbVYaAQoAM%+GI z;I1~tht%6HyREfT(V62mH^ir#jOx^n1mXraM^B1mbfU*M39$b7ftK%obE|2Jx*@XA zf_~H#9p`TIgG#&~y~GUFyD^$?Wq4f#+D(SCs`&Euq>Jo!1v1vbZ_l$exRR&LN6aj! zLX@%!nd)fq<0*QJ{m%-Uz9H^<75q~YZh-+iX9%FhvBChHm$}i-m|;9N#w?%P%u5FQ z7YihD6Ei>OxtzOKG!Ci#{kJkwcn-Y_fNx5+SmXaaS7@aRZBEcTS7@iBS{dE?*E5ZnMN$?H#+7zQXMY83+jP)6bChQ0~a)pZrX|* z=oMu^4Xwh3kDx!w&)PMA1!oE2i|-sXI_;tDVx=BfhvWRUJo6!LBl?Q;&7S zSL@4Rz6-T`g=bMx=S@Ycwr4z>=xBW*ENd1%?bNb~B5TgzgzexF4KtS?0JwDxYnemK zd0K3-X|_;wJfp=rhmXzQryALSl|QKMb@AA=k`{F-J~n1_lRkUL37D6MbIoi3gS_IZ z%xyP~#Ro~P)_~XEao$~uHJ;E;T*XextUMcV>|5sY4fNAZn@Lgj4Rn!BXuK!rpQvdc z?t^E{MAu0DCN#?veka&DK7D2Lyp!7i$3B~9-fmBF?hQa;(8za7_!e)lGkJIiwnN`Y zNS8no2dkQ4GIQ^BJbXK&jk+yJX~gUE7Vhe0d`O?|ve()GHQhQc-*r5G&}e$!NFaXj zb@Zf6Mkhx6g#fFbBUm|At-=N0a&tD?a2w zVM=y#2V?(H;ZU|af_`QbqyAy!>K%Mi)}H7mtD2_JchPO-O-*9YcFixA_7#_Ji9J`X zyJzk2SgE{8P%kX4b}+mzV&)%4ntzv_N5D7nTYodU%e~*iulijcA-B~=e{`LY`Wpt1 z2o9Ai+QI*~jURa-hSxjvjU?5aS(pYdY7-e#7D*k$28v7(gv3f8<&HPJjbZZ(dCdn& zn=XnRe>fi%j(BxW5|a*t@q(d}Mz~sFl_YgjQ)I`h?ne6?QX4)59-|vhP)!$GhzE(m zu-#S=2N9G=V>Z*r&f`IvG0LYI;ZkVHN*Mu|uj#;xO1hDg!AL>*6+Y>)<2(t_Ii;2Z z0uLFq3H*_}1n9OBe3r3A8mB3N@rj?AHXb>_cFQ);m!e4mCx|}&Fu``h)}HFIpu(p# zcKq8Y{K+=>kUu<}B0?7D_SM2ArZRoBm8#7eA-gP!LHcm2Ds<#k%U?_yaTFc8=+*RL zXVv$vTi(gzF+@~Dbja&^AW5KtDkF^jUJ4kZYP+bH7eaC+4t$daS@{IIV3&?0*^vV7 z(g3FIp`ke7bjlyWlO(BtYAW&qHw$h``9%RWDRha6GB|}HeT>8ebkM%#h~h#9J)Jhj zByD730$O9wAcrSA!T2nGFNrsrrgY=8kIXHgVxJ#7zO>K(M|>-khKw#@b^yd#5h$OH?9*bzKzO ztPQ>(5ib?2Ze1Zs{YgY6qpdK;p(X>6s40V!7?y%1YW|iE+~Fne1^<3JRyfsi4IEL_ zOST~=3^P%_uv3y(0T8xOORb5Fe|BZfxgQh$q1n-OZ)zv3@`;s7#Lc7it60!P@fPLlJzIp>XD$OG*FpmfT|@GN*?->;*L zcI72R-e|+DS7J-Q0II#CS!7pjQ(80+rUxwt7YKfUC9EvuSf98tg{h--#>g9V4>|T@&r@$GzxMTEEn_m-;`-zQV7`?|WR3 z*apIgF}k~vRC;ttcMgy)C6yA`07(Hsqz6cMcML_4ZbWJ-Avr|4e!M^5zu@=UUiY3o z_ndprx#!&H*>>(ZSJ^8j=?7{pKz+rFG2kW_-Sa8>B(s6R$ulOVbwKn7CU?KiU7CKG zq_kyVY=6DwVMw6DIf+Zp!=C{PKS`(?AHEFei(}X%U+qal1d0oUhY@x)Jd|6)vE6&a zCcS>fplAQz{qjxjq#ak&4`65j8k;NZ%EiCv$`}x}>8r>Wh+fLAvw8AzCKvC(U}e!` z1=tCJ+O7?MiIBcIs#D$U&-Dr7$}zO3pW#liw(A|aF0&O=OaG3a{=Vp$YZ7P$-~WA) z;IhWK@v;2VKjBjSdm5_`PBd&tH#G9b*tnDbdgQ@EGb9Z{GoS@>BU+|;8{Zv^(xx_aPdyIxxFO)MoZ(d17-J}s`AE?@vM$J$?`@UWOZ83m1Ork z#oALR3qxm}Tyg*TS@Zv2z`CcL51!W{Go|8Ltdl2mO{y`G=0GR@b+EK+MojnBOnTMY zv+@N#UH;4DI&mNP#=eBc!oc+ghd%nlRxG>f1dbvcd}Y5!Pce8*4|`rC?O(> zf?O>@gK3djCd4kPF81=Fd(5L}8d}5JTIv(@61;rAmpjG9h$=+SP;ju8UGhP`RIDfa zB=I((HXh^W>(()q(eR~ZEHFeeWvlJRQ=V&v@IZ97_6I3VdP>&2^dGDPThzNFo+GK{ z!{)%tr6!r?mJaWq&O85%J>U=bJ?xqos_LSw1AL}QzAY&^1gp2isGMT6WJ5ejP4`e$ z50#%PcoSxBJlLgQ4<_^pK!DY@e*$=tuyt%60f@$=^*?wgIqzG3l*#XUEsOv!rThK3 zf|h_SPx@WIXy1{1Xtyq_6b*W+^hQ+qsZxR{aX@taxbOr`o?oiER`kzO^zvk=a9w7sd> zFOYX9+ROC39}*UbZz;*WMS${}Tz=Hi*{>)0NvCtlM^EvO`x)ZjzZ9OgKy#j=X$uZV zj^Fb?^d2u?PTao^@AiA8i77>Z<7o9gjy=u<4^d8mDLu{MtastrGSi}|G3?Hc>|9?q!Z@Ww!+F1baxO0BbkyD!_Syhu@^ZI{e`VAV$>s}l zGI{CNTGf>w5}>j*EMt+{Q|(D^V5s_RDAB}FmQ(zRztJFK9Qfx?d!cxUR52H^&Oydw z5y^~4B;Rm8J&xhH7r0r2=Hs$X?dZDNjeWzfwuJXpGD)AYFaCf-uROI@yn2;9c zH@p=lmU155A^ytoe%#X3(zbP?s-~u=rdw^b<1*S7Bwp!mcaCE+(dGZ>#D5}lPJDVH z{rDT(cW?kak2iaXVEAWl>p1hP1oPbf(_(XLhEVJ9{4RfjVcU;$G{2h#)9xF+mGYj7 zv=IqpZ`C~|cvU&JL;SaEWTRSiDBIn{d1zaw@u||O>W2wS=XZfJy1CTaS4Km=X4X;f zC+@j2$TA(hZ}^*Go{Mr7=e?);Z02fWs%vZ7@pAR4Qc1({>|0D-XOiQBp*!&75ZuXfF{)@P@`Dh3|T!Jqq|w>`Z!V4%Nd8L|~=Hr2^)J&JjD zJ2}Hdehn{{PdJXDxviUIVmyjzzQxALdthU#Z?Q;u`hPLMZhgj?YObQJAG{}d6Ndw) ze$f1|K;uCZ(Hk!uVde)0xXgSHN(lP89+*)*sKj0W^dLz3fdqbEDGpZW!8PRrXWaGV z2i#-;uLwOsa0MZ(S|OGgF&_b@0~|#Nvx8L$(Z3Zk833gC=x+)^a^QJFv|2@SWOY}_r+sJr z(540_*sU*}RCk!Bo8i&85 zB_JBG)1eNbCJ08a!>G^aBPE)do2mHA@tI~Li<i`==U(X?DJL>8LJ<5n;b|XV&0X2lOyZsMO*8jY& zYh=7O(S7?$nQo?2&ZvxZ>I7~U8dN6NWzKXu9}|DlUyozt{UGI0f%n59*9W__eX9gm zwTET%;HP4UsYh^grJ!CE`7uIbQ}+=@S;@x>?}WC$PgS^^tjY^7o3{T})u)GSQ4MCt z?iY`En^O0byhR1wuFgF}T}U^uJ}6vTPkt=vIciEbV3~+faHxA5`HnmGZDbR-8701Z z(Rva0A{{=osIL~-}*7Xx@qWL2qd!<=QcG*cb78vvz0z< zzMG=Yb0PVWJ@9sOeG)g)LLrT6vJ=0!`HhOedN-9%F}_q2;$6mMC5N^vaH0ueEr9XR z;wb4T-ez8vt1htTb6ElzSoBYuU`_ZI7eIo|xTW*!YqYej(dYBRo#I{7w5QF{mDQ-% zblZyrkC*!XN?;Y~I7+%DHm4+f8XmPZAum1QdX||}RP#;9F;7f(3pUu&$AwUFzaUsT zbCzVjDQbUzJw%%O2V+)C%;!_#)^73{9lGP@Q*1!+d5i4(?FT4^0xd%7IUK6MH>J{j zUm5Id3EO6ID*O-u3~(bgvn4XQ9l%%VNG&eFA)c%>k4Sfu2-7y6sC0j0?)u0xpK1!D zJ!1V_l&v%M3JsNCw0JJu*ZI6!H0Y~>5ixOG#Dxe}l{kd%p`=5B1(d_-mFFmlHFFD* zV?ac@wVfJN>N`HY14@-&`712nj2c1|?|`{6JLjRI?}WLSZm&Q}0+7y~=z|)cno9B+ zUAjhXdZV}~rx(I9B#cQ>t-tKT>8+9;Zh3(x9~E{e_Ie4I(seC8It`3+U+L?W_S+%( zxB^!RJg@5{7uBOXHVZs&mTo(JLmbA!ZIIBG1tR zMX&^*gCtTT%5H`E+#a06fOi1Ylf}v6R7l37PJ2*EVdspSqw`>*A1q6qN;nYNk6p4` zls9|(-G=UX(~dg@fb$ld4G<;A{83)a0(>RMxUmLtD2}mjzr%A#vwKeNp%Y1=vHp=b zW%%7Y;_t&)g9h@(c!|x0VIO9i8m_22@U}P}Cvk*YOkXq$_5v*R1kdXc&Khd+1-BzH zQY{7@qlEda=fgyB5~H{V7xv5~Z!DGA^c}EU5k7xOZAC}G!UImjb>*q!#-A_gQ{$O+OtypfrFP!1#DbNhQCrU@Q0v;Bb=n935t}8w3P7;f09c)+D_Fv7wIC zW0`<|*xj5=Mb;$=vJxXw9PIv32YC};3lq?P zg`Jyii&JqXBIg{^GtHMWrN5%L95B~rWx^y+lcV&1*&Rs*`O|wa5XvV-Y5nR8mJwqj z9T*(=c~loBb1ls1!KE;S7n}RQfs0#&%gv!C=Ycy{-zm_?3)d(YP|XROR?ZYBW6TA3 zKSQigU>4r4ivqK>Ba1bJoyn{6@d)ojL`({Zv4LVZG(=g@}|KJ=*AJ#j- zaryV)->V1HjBnaW`wU6@zLNHp6ZScP#IkU2O8atnusf8C^7u76IKAbXqx7DmErzIL zBlUbxvJSG^5VKWoC;14sMDdsFq%Unk4gpa~f9K5lS64ep2DfK1j5F}RerD1P0opO5 zGwGSf%_7}S3Kuk!js(QHI9g79mo#q*iPI1V&(gTJf+UPUi zJ*<3b=T4F{hLit&(ouqaH2QmEdS9c+p+ytQcs~dn~IAv_n8IWUKHOyuwMy>GRnx3%HcK;*zGZyu67IPZj+N~LV=7*e{P{tTRz z6Pb|bYAiSUnRnb(VU!ZGAZJGW+OGvi4#HTG%rok)TWb0sVlNp2V z^p6>1xEN#hlLy{@?Z*HCuW_?vaJuu~G;!HYQD9doe0~Fc%z!L>s0Gc;2J$>}V5bTC zd-{$^bjX2xJ|a#RHp9iTp<#B(-gUyh7fdcF3w)*%aD zJTabp0dcH~+^AfSGS(ce{o8(Lh0kRgG2&L%OG{84O;ZUUb6f19?J>(Jhjc9O3{jpHDBJy3}73rPwTDi~5@XB+4U)((TebeU@ht$-xrPAk| zTuH;~j8FROu5bVCJMdB`|H%kO94%%Dh(6Ng`%7>2Ot$UEzLNEc{6~*l16QTmx0vl_-&CHK5>f;L|*27dKI^s{;K@yzAE(Kzc&o@#H(h`D2TjZ2ZxZ53a} zBy>bJDvU6_QJu?r%EUIOf^X?hy!Uq8>E+KC)>DeM{8#*!`GWpbf6l8|ni_{F|I17f za$|lI&0>AD*ch$$Vx0APo>Fi7gn99R@8#@HTnE$V>3z}ws;L{s46pp+#vy&{DJ9!~ zuNXfY+IrOTz5WxQ=C9%%dSq-prDl7rVai`5^t$&!hmP+!>%QNYmzO`;t?Rq~+vjSg zXghmDpYFw%+ZekL&z%16OG}6S^UxQCHQSZ{?WDc=_hq2N9uhir%rUutV#Ah-C z<=T#$JNfd#UnM;BNX=SA;l7V=sa_PQMs;^e((A@JUQVC${5KF74A76lizjW&OTzhrXz(SyZ;Y)-z3* zhfeIq>6{bMw*G< z@Uef#!N0RS9vX88a@9>H)aRiWG$p>aXJ)%6KYnF6SiJl;36D~HUZ&fjRkG3im`TJ> zDb7`4D#1G3`Jr<8zu!&8@0(E729GJ!5_QHi--Q$XT^TP}Gjk2dbdRpN>PXb4&R(uo z8@Xn?O= zZy&CV_~z`b{222YraSV{a9X>toy04e&FM4x(azN&!c8r2O2F~Y6O&8M$K8@+Qhx*Fgg=Cp+GVcQqdi12*TT2LqAynIJ|_33k&dn& zQV}0_-j5*pxYr%|y^!s=^P+FB1ErA3ZfBks(d>|b~9YO)emuL696K@tBTEbh{M{AgVKlDu_1tFdsJ>(muih6ZKcqTe} zN`){#jtiY)blxI7K8l2UU7`MyLgql}KPg_F#9Z`U&&A-Qt@hdeBWfQ}yJrq~j7a_) zae+(*AuirSoJRVsFb@Brx1W5y=#$y}g$oZmxxYXab)j}&BEP?IkQ0_%GGiY7NcTUE zn(6*Gd2I-4)vJV>#_vrndLS?J-&~$=h7_Ex8elUf1x(5W2u?EYt2-tgY02$B^rZmHu@s4+kIqH_HAY=bRfuX)zp=@o<>p%3nh856> zJdXb#h6{z25VZ)s@P+|U^Ou62hF@XPm#dcFDjP(ZGCL3W!JC%Shfha$;Ae*hHr3Ym z6MA+4SaCL$({n!L1@G*39z31B%O!j2(+b%M$K9#vJdU`GSiy(gOdoWToUG84-=!Fn z^3C3jR($2USYZw`V4i)OZ-#22p4F1Chu!EZ+`z;1^7*NEH1b#d%kHFSl0V2b!)}sg z81KZG$~@)y&Z`e6{wGPGT;qTEp}!kL3IcAr)}c=FtuRlKvflIS|6{rH^3{Fh%Xy(f zW@pHY1^DeD|Ax*D8q~-E55vTV*sYohk9PNT?F!!owq%aqPXDjrW+cQ;?(g#m;UD4t z|B)n&`u8-TJv1_}!qZ7deS3Mqo6h$dCE2_=6CXWWbvF;mB^|}sLIJ)@3xN!qcjIEe z>TCa}>y%gSVZ!-*)SFbnRsR`fg6#k7h$8sjj%H->(e#ZApvEtDc@6i~Jx5{Qa>7iD zmdvA3XXfx0>e2Yq`-*+^@L+^+li~`5Xx|F^&%T~G-~G3$0w10)-QIKB)vJ*Cu;+iv z>Q_&DKD_5lb#r*__rv3nHA)$0IXmR{m%f`1|5MWH*U^0Wcci1ir1wkxjrY9_UgOu* z5GO74^+D^!*vDQ0@Fol4|BQ8m@J=U_;j_ap#lVNtsgNchY(u#j68B&c#g&X{>=YE45F1j-TGDHM0)6&BqNm2JB-k_l2ed2 z&3CPT5OgXN}14H6v#TX>vH}VJIn~5d~@D@Wvr#@J#Q5(B<#L&vylx zLGId|*AEQC-^|JP4Kl40&J|Y;{vIT?J7zPwBeS>#0Off(A!3|{;fOsZOgj_&D%nR{ zyu3=J{s}Qj3~CeZ5>6e>Xrf)=qTN6`a6M3WARO|VI?Pz7!d;s_>CF!^fIO~slEMzz z7j`{|$9Dk!C%C)GeG6*qIc^4q4nI#Rf^P6m!Xp{w6*qO`G|C1Yhjr_IaxG#h=+A+I zm7Ew_irON*TW)0rW!e8d-! zhHzwag+_SdaEUGaYpu^;Qy(dOoKng(McOoz(t-gV>Q|u6{79%#nsVZBk|Fjxk5n*d z`I*v?>leq^!QuheSlLH3rSM_bAY*Zjsmzc7+S8n9t<_d=ke^60W^U^M`fUfkC^0i$zQPvr9R53^msz8-fZ0M3cvn_QwVDoV&Q% zT@Q4v-kb^bwN{K7RF9<-`5fb(+aR{%Cl3ql8?D?$k65)k0q%n6l6Y*9+i}_a=B5hw z3*fboVx^Ywd8+*}V%}+qW2hZ(!ZwoO!+M+B@%#Cb&(D3ji2FaF2A)#~nAe*ZH4nEF z6A2FReZVx1_-Ho2Qg#0oguh&?@EH=@jq7SknZ4C4K~&SHWV$}aSGNVqG4-^WUTV9; zSq)c+k}ud|dUq0Ie;hZziIQJWkzenYU;iP$9_M!4F+X_4Yt#nPse$!Y3LjP2AD7H; zrc`2o8!rYy!n#0`#@T^Q5|A3jboa@>w8T9GGc`OChpwJ^T?D$eQTq$)=i=Nitm`lI z+zmIL;@QNUF2EQ4hx9!q+&uGoNQ7)+bZZC7ch`fI>c1B@1G{igk_97=)H`vAjI#G> z=_a7weeRNWzaE|M5M28`6kL9jD%pRfGc-KOIT#dBgo)2Fzps`5ssz^ zM|a3$isUiz@)&Hs&#i7HAqlieAh-^&++p&q&ku7}( zgnA$_5@>chctm2|v}({7)$>Kw^J!HndxzDyn=G4~71i?rRV)vSa)zG8-$V)dBMtW3SByjU+ z3-a*u^T?PR1T`1e)fZ!pH87>AXk;o(!?OQ}37`%_y9nC%K+3hCeJtUr)pdO)X0Ci) z_Ix28?yHf9;sWQ>CX3#DR!xv^OFRPSirLw!0Wd>pRAp}a)&T8Zs zO58HY{|*e^Llgy|RiyjpZLsxF+8fp%P2kl}}3a zkJG!ciQPWKHr!hUWlw56or|L;M-^jzh0m_z2Ynl&gwcwbyUbOFviY+?r|qXqoeN&|^CY2U%r_VDlVzV4*0DCsP?Q84T7*oP?l+x z?QPb7z9OctZHmO^REGS>GTH#%?cAE-3!8R#wl=-KWMPIfwzEN0rv0nN*g(iqCvTpR zyUZ1FAY|Ga=~{y(H-#rw)~y;Z?(pvULc#(dHEkdgFW3`FR7v*aqR#ej&VPXv)60l* zFLaa_+D#JkND>~O-TqBp?51}?M{1k%8dJjERpA+|5{Rnk)LU3t-W5+=XgPp62f`7Z zKTo1F&b}O=9|vM+0x_O}@R&}YK5MBzf>yrJ94#P33yAuJ*fxNDFhCa=ptlXs2?pqC z1N6)%M5`w7ht@~F&hkI$-kQL*59Bo;$V0UFc5Y`|+Ra^2Ij) ze^)EpWy%gj_``PqoMi-H0cf?7UWs1BKQWz0{uRV849Xy8#hQ%aR5SC7$CkI@`oDoY0| zmCXCA?{kfr9PLyeSv+m2nry5RF0K-;sS+-&!n&AazBHh(o+EWfKx-c$VSIecynOF@ zxr}(YW(B#L___RqoNETv(%OH&M902FFTX^0yo@V+yc7_2`(dGb1CbAz*bvLB&7kl~ zr{GP8W_>V~F`WzwV6d{GHnE|$waK)!399PC8oa_p{Y5)(Aep`qIgbz-fi+FR6(+)_ zdKzheo|{CA~79N%L|k@CKu#RadTr$ui}?7ri$bx z%H`!tiEQ>%ujY3&p=#jE4knok3M+2FIzGoleM7_Nd<8t|KAYB^LB5@X6nkK7wy3CD z@S!^+4~)XKxb_`}PiC91>dcsRZoUOxTkA7vDpeg+Q+X6JVp?}XQE>tEyrG;p5ziYT zIi{GtM(~88?d9R=`Ph#9y6?J+zqsg+DFiQo0mg{O#)tx5SP?HQh8GqBfjdGl5xnR^ zUbLYxVxa<%T>-E)B}+09G5w)ebZQU5SU^x7#w-;Tg)J!(q&JnIx5h{j<1tyu`Jg;Q zV>2V;pvDRxg_C9FU+w6*3UqZvWUzRDZ5CKx$3>0ThuoY)w(Y>|{aGqI-dS6l*;ohFbhO_eqf@`RvV&He zLpsbs=Ej;Xe6Y~vYkc`|-`X+pi?UxrVt=6omqemBkO_fiE17+vu5F>NEuoN~LLpm1 zIY-djf6(QJc)br;SQT8znEi;rskjIc9N4orb*%SJY=uQI^BxJ91RqfP5Rr`&X<4vN z=Tg(s93Tdy+#v+r;38ck;+7aCwB#AiWB)9pMMkSBq z9OX;OT9K?S84JUpijunO5+8#T`pTodeMrt?0Wp%7ZL2^cmVBS3v2niBYs)Wo& zMOtRA({UnVfMWxQHenVK?I93F!vJCfj`oG4JK^XWVT@g-53hC`8E4x(Iq$+_(^a(r zShWSL+X5CMpyF@qDOWO2-rx@8qpUs33h6S_3aZYi>&@`dIa#*NP6lCM={_v1RxV_M zenimwZwVq8*t51eR;wU6t3|Nj9to5LNmM$3%*I4oBG&0x5Nd!iHbfhMMFch!2X0_P zY>=US$Bqx)s8_`iS64;DP zuh>#f+}dH9qiUI_I-RFVTA&hKpxWC7Jl_R~?*LN#5lQ}tFn`4CQ}p|%=$}u~6;IK- z{)jPugseZp!5^XJkJs4&``7`~vqtG#qm-;!dTN9lYOo5{aD8h`c?a6vAF1Pytlb5v z?Si1Ypq7(S%MVrEzsk9cs<@QrDJ~ZbEhLq*TX{|p<|l}axGi|rY7i<9>n4j4o!j+E zG|fLgLGYd6U0uSyU&0bEVUD3FhftJlC`)sX@TZ=-ww}6*9_;H-xNj(2Hxy$QiZKZ7 zuZhqri2%n0hf7S{{^J+?|n}NXe-NB4S0Rr=a;#&|g!~A5zdM>XRmfqf$(Bwd7e9-0AV38+C4raJY9&KtU(GFBZX^`KVL-zRPTPGLhr^csLZ}nL{Fqc#g?;J z9)rgZ;P^fQw2ycf080yiX-mWHq*=OiUo~xs0Y9!j%UpRDRFX^n=ana2Kr=;;3m3h9 zS5Lvw>-t=u>Ri2+?w=A2LEH&Nl7Hx*ygdAI;8LiMfccHEyHj8sMQj0cH zb2e>Lt1_1(S;QRyU>Ruu83W>gff9eWX`gmRF>_YYY_Wg&xRQ3F@+n{<0NfG)epZ%e zyO4L9#DIVHUw#LcuA<4VBJhH~`X0BVKV^e7Xha$`;ZM1`&%L+9O~1#Tv%|f-&D|D2 z&KpSX=1-pGPu>wgP7p}`SQ^;)6gcwqBcDyJ_3S=-*RsaqipF_$TH(2lr{J62x@dds@Wr<_Q*4Pq^>>k&>ksTkIt`;3^whrtpraQyG$8x&l{`n@Fx6mtMMvQ zwSHy_S2V?ZsX;qiL;SOw_HU~zed;Uipw0)c?tlKZOZ7`Wb79~r{>+ot>MA2W7Ei&L zKwQMjC$t((5 z`Q$qCYXvd4f=KQJsu@q@yD-gV>a^65&=q8UCy{9f5s56~r7R*#7BMJ`cqWUul|?i$qGuV=QL>0RS%lMY72L5;ryb1>P{v*HL z=8!t2`gTSY8BC<#jU4Yr;&dbL0oQIMM>kTu8+p<_W_&pH+rix%9_Wox_U`|bTo_U- z!GsD$JPk$6hmOh~E(9H{s8LUwf_$3^ z#oeU860Q71P932ef>icdJQ-JSM|KI1&|7g^hhwtRs9>fUm9xL}?LrrihHiS*58_`x zp?3FpNjfZS@_wi~^FA~BN6Qq~s=Bf2GPkO_k&`UXzi#=#>P!wuB`=kZdbCJuVQD>@ z=YPQjPg?DZ{})&gQ;#-I-^s8{d0yo+VSE~^VP3wRRXW*AU}^AbY?9}N8Ei>!Lq~Vz ztHZA^|1^u-f0i{>CFrxMadI_#l=qCelm_cJg&NenaOgf7lNl5&Ib%6#30HzmgsG&0 zpPyS;$ZM&e7rT&WQHL?kv65Sy2&E!ix{nHOGv3uzN|7g7D#J$Kuxemu=t!CDfWY85 zHcXWY`#(lAcA)XULGy~AzEVUIoFyi&E`KbGT(hD^J({zU|v52Q{RZ{f^ zuzU<}Gu~mnUa;>q$09g2zPy{{8YU-~xTn_XJ|d+`nUrX!CMQq3C!M(`l?ZA4%u3!t z!V`^{Wx40R*M%JRZ?N}Xfa^(nb!y33a&nS;(z4ZaRS^#AO`_p}I1%?OxlwX*6DplZ zcu!qFEBPrzClaIiswb12n7^%rQUjKW(ag680^{$+R*6^lVX`3x_74d3qocm0U>j7} z_xQ6A7O#Ife0guT4N$$uZ(D8q3D8o{w4n#`39$A%Ii|2HZzu94H{lV9#&h<+Lzc$z z+?QwZoT!%7bGmr-SWSUw#A^AMG(Fhi#z3Kl@V}p}R4G2~F64Xv2J>7q-huN>*ny|7 ze~sUdVFwSIVxOI&o4B7N(Jv|M_s2T^f?bx`tDCuy0fng4&`I{1!hWCY?-f!hnc=79 z2zPlc!amAdf~Q1faxc4V_mLV^ie9Ln2)h`QClELRQA5w)lho;n7EzNgIhny=1~1sP zh3@gyWX#2YCy&w|#XF)jokZA`oh?|2j#Sbn6})Bsn;!FXloWZ5B|Fjc#yEBqYPHQK z<6htQ>=_C3uTU9AvJhRxaiUV-?IWz@mx=c}0Xpzck*USAMbu{u!9LaBTVJ_kQd2CV zG@cD^*iW7VCVgHSlh`n$R5}$>6qDOAHDI%{jj8hbht-#Otxn^gulC$OKPJCpqNt){ zV!(D~i>%<_7+`Sr3a|1?2KGLbvBTe>(UY;`5p{IjbUQ@ZgE zwE4|y%guUMez{3+{J#CQOJL5?%=f_`W$Q0mucl<#p2$97;d{cSy0BJFY;E3CSHq7A zc&^dR=Q&r?WY{@vv#&|m%*QZS<7d)2t+M~kz|Az{9#Y!Z)NSSqovq<73V8nf9!i8T z^7`fR`q}XMt@8TG@%lYC+WuCNkUmoFQn>YbkUZyFR!jiW&;ZLT`~AJ_ce>s%UwNu? zWvX*&s zme8)3=h05KMtHx}R`@DeFv(d0fgVQsifm@XHTgaydq-VvA zY&N`Xa=dKm#;PI4s@F!U6%`5Rl?j>ZVm7!sIW$5MoZ|@}6tt{!h@p}C$de=MbuV*x zR@WWQ0lo1-j?saY(Sc^=@~evFSLMqWWy{7U?Z?LL$A;~d6)(4HUqTCBLaSav3tvJj zUOJaw8D@9-hgaD29enREZvwrI0liHIX*`FJ+d|0YA*l}_sdkW5JqY>8v#7P!b#(_G z)oV&sv9ugCO}!yay(!HLJ(?HSR|zij!kU!{E(aJHW7RGrRgkSLU+rT9{pX*R3tupc zq`1(lYqQe|*_9lP1d%$^_9mS9aGE5Z`IKCIJYpQj^Nw(*CL09(qE+>DK)!gyHf^T= zq!sPQwC(<#q7Qo&t#(k(SB;?=$Va;Jnl1tj&RJtN@ursXGuI{Zm`i@({sP)}_=@E* zb6ykWU}&}g_@srLOLr?Yc|hy`nyBb>!4xBd6rcUv;WCQa#k9I$tw(e1*rAF` zw&u%ZVB4CkyJ@slr1K{F)>iXB?giu6Xz493j4M$Ea!%+^NCTIC8E zCK3PiBK{dg{4#V)<{^^Sh(9rn8^06V2GqO=1NMZsOkl=_>`B`TZ#XQ+lj=6c%rE9BcNjj z_`EjYwzL{`r=Z*8PfGeR1~hYOn-{Pu`wc|%IKJ-0TGa8Dl&v~7;gc&o`!-X8w%t0<&y)Dbwo}Avp{ml<73ZP?nbPDfOgB~zHCDbcQm(9s z%@V$M&FUyMy})(*x!MLnf9`(4hj<(O%LFh}HGltEtny@}T39x%=H-=_8Kh{pE8 z+ZyE2Rjph>^Kc;D&+tDu)lMswSOzD~$BCs0Z?%8%IIzwHealqf_qp1&W_lyQ(1F0! zsRQYhfyVBzk6~n+{H}NNKw|`bIzPV}i(3+Gj$#Dn?L$qFuXcd3x}m5=t$c#$jQMv0 z__9hoZSi{^Tqk!$n<#aAE%5ufm77aFw$@Kv*bm?Q96k~$Y^(2}{Dty)_!a$S&d0~xz|S51d`+qT>d z($^Zm`^*oQ$0BBy+k-3nj7=hrjU$c?BWAibY?ScF@jN4>KkGci=B~cH^IqN?d3gUP zWL2VyBnY31>Q>OBM8NXeb-MR>eZkLw>X%M3Yge@`g0QzFZ90fCyN3Pl3OQgPWU&=i zw;H)_zGFpi+T?rG6LK_eFc6E9G+mAAZvP~#bGo!D#^elIv-??|B$__=V$hVq`TF22 zkO8#vz2@VBbfqgFdW%#0tvJa<3C@U=Og87ELCkltNSYYunTFCAK`q-2TOaRF2^F?l z%`KrU)aah4!q9VHb5>&?Rb*w0jcGY#J*u#Ab6({WN_6#_)~2xg)jY547O`M4a$xpI zC?T>_!D#|5cEdLTC$g;%G#U2OAD$h>Jr0f-%+WsV)pa5>*^4rI>|W+b)f1w3{>*r$ z`n&a=Mc${$94qQ9s&lLUa93wHM4VID+HWznaj;zaRd1ZV6H*l=)KAv?wt#q@KzAY%sO6Q~D?KfshWwCZE?M zi#J5pSn8>9o0M@~F6X&61#T%Yu>{Ca0z8^Q%(|lAyP|)(+HWp?U#|bYW;It(SpuAR zMzNa5xtGaFpUIh%!)cYxDWwbLeFjCB5b2Z>)z2XNXON?R&{cmn6;}?xP4CH@W*h#X zf6X92ln^m#L*?=X>GK40@&y-1!Cg*(TT#TND56Cau_}sqPlGO|K}XVTMrf_E)RmGi z`fd=z_le;*#PA=)m~0yKTN?BnP2{mQ>Zdk~UkO;&FgBNmIFHA1oU*|gG~x`J7^9RJ zr3{!5gJS#%$>b_xl|+$jqR3-WBzYs=p*gINAJxx~y5UD1^20y#!~gQbr}*J>{FoDS zbcQ*4)f|0fj!rj^RBCCDeH;kZe+JPPw8V~4xjiQuYe2Snu!vX=eWQBWfP{QUAAd(j zdtlN$Fr6M4?G_(COYU?wqhYe0-+*f0QI+?-QL%9qv3XBmz4UO$B&GM<=wSr`yppzR1=skn|>q za1+!!4)GclhwAT>uwEZxTi-}u3#da5pXy?BxQw#7W^=ikK63rb;v&xG($3);&F7L4 z(KVCQJrBymZpdJUWH4wM)bEh~;2yA)t&7;2RY;$=){Z2U0l>(T$YfC$&d(etAe@(bAq*lLCb(NdzgM2~c_oQZ7>gd*TtXDzJDJSgQ(bniams3O{AVq^R62tbY8e zW}F*(edVajd?mpmnpVdfPfdkW&kJJZF2ofqgTy%YsY^80wHfbvrQ@Y40Kl*}>|k{m zbJaoT{DRxsl3TN2v%mLBg}1eZO~XWvbUU!&*OTzyX%n&&q2q@#XCHkJm$#(PK-pA8 z!B8S00jgCS{*d}b>(4$EWNgM{sY2&lMD-Ww;S2O)2nHR3$qHd%vpqNN(R(LUH3n_j zAky6;s@))B+9bLghvE_;&T%pCaRbRpKgLp5$4ONxWa=@Ga)Wd5(UG{A9$dIegq|U@ zj1}{>ZUi|itc8f>fc0{qU9}KzwGezC0FwMKpdy3HpUsRvk7*&KGXPo{0EiZ1 zUkl-!0SLEZ4QWz7_j>#P8v72Qrn+cdq=bati}a!(B_KsQD4+^b|Keb%C@ zGJ0<#l2KtK?@|QYGiWb2>aiA?tv3?37BLcsvwDU{zLz$pZ#-5CdR>IyH^8CtvB^)! zFzS32dh0gA(IQMk5=`I3nB0Z`@c_3NQy&GgK^?cJjypkO7bxZ)W;pQMWr!@LU&I6p zGx;-t#`&Qy<6u5YK(7Q}N?cIG%pQ6_`;ynX);V zvLl&tIhit9oOM-`|m-zGhvGW{()Xy99kw5^zfg@#hw{@)maM)($^dlK$>P=Doe3?#yK1nGT|i zSv`{(`<@w#V8*V9BI-pENKwR@2~gAom~H}$EujmlRrm8n;#Vlz8;#zBuU!xq`Tm13 zJ&6vIFCQzRgZ!X_G|N|q6v4WK3X%EPQ-kbsBflCWzh)ysoe`nMXuaN`tduGI8&g*) zQ$gu#R?o=D_pgfI|4vlj)Perg!G$JbixaU)iP&6GqzQy#x0I>H{Ei=nA;$zn0s-Zk zfD%kVCZ!Ckr3~&?w|-wQRqoDdes{PXn4ErS_3D@0NZzhvGcF@~)gQ{Q*y^R0%RI79zBXZu%|y{&$m<(LYD zeI>TG6mP09_w%jBuQ<0i>b?gv0zQLs`w_hkSYrollN2sV3YRUFU84I{l<|u&W01}5 zCYx2TZB1kdlW|*XA7Zy3ktM5seiQdu7CYsFcrp%*kyRhMiTft2zIQX*>tmVsNBs5G zkFwZ87X;4)uzh8RIO8_)YTBWd$1mS7?FHq8me+9Xu~)WDy<~-@JjSvv$MUf_tGftm zkRiAP%<9~a?CwLF^dV3BkeEKQ-D>qib7-46^w9hS=ao~8I%bKFriw%g@8pcjRT2&oGarh|m}AYt0b#jh|{SZ-tpr}2FsWLcSd z9Y)<$pKsI%7;6NSFahow0c{{a>n%hNT)h>JeYJ&%+(L+6M?~F1q>qDI&DOxY6Pj%S z2`yx|13wty(BmNHEkrmRYq*7&7zgouW4vsB2DFs;j$sWiVI8uR(6y2nFqe2y%DQ8E zeXFvLV_0uaG*Y(qYPN|Nhd518N|dtBn@gPAHJRhFN)7xP4E#zB2xSHY-+VgL6&5h& zY*6sLi#OXO@ssH-L1WOG5oiQW>Xazis#901W2%44wV2@;0+KKW1s5?~n%&w)Ghoq3 z)iLaQXI~I)nzpIyc&f*E{r3{@A~UBr=rm(7lCl_yE=Il?!9W6}U15)&C5f?sQ~GN{1({u%zpnO@qwsZOijt!+ z=0MJIAX()oJlvTs%k>GnkN93Ee5%uCtI?MCO^^&sSez9cSP-0T?6o@Akp`iu8FcP} z9MTcfPqFst2opKbt_QHw8;g$z zi}kEnQ~i_`)?6C2HJ~_=4u_<{A*pb88QrtWL99tS8Ae?FH%s;v3-pi$`ilj+$^xBd z!6k`fH7pPn;_7oOxIJ+!+5&M>3%r`D>4qIN{h3@CC? zFLjTB7`G7pTZno%Hb)UB2fzL<4Sj;bo1*YKD7-ZaZ;V>BlF%HZyx2niJi_MrLmitN z30#g0KB@4X>x^UQsMw}#>z-m(cMNONIOWzBvdbSg<&Qh^$1VHg&iu2xA?-EB@^G}I zJ6h5W{i(^gXHI0c(%7_RERdKsz1MG)H`gDn*J$kb8jbIR;4l_QOf7{fwYqK?%pgp% z;6chPujL$Xo*b}N7Dz^ood#rQKk#dK;8)si)n)G}^+j?k;8)4Ps}54tmvpKwbV06k z>NTLq83c3&;av-ot^p0XVb9&L%`*t*8AO^Jwqpj7TnpNDWo((e?dQhIU)%V6kzJa7 znEl1!447&f96bltodR1nTJ_9=XIrdH8>~!gttMNn{2Uwcg@3T!GsxXqN)-+=i(JVn zeYOc<%jtFS@*B7yX6hsMC~8a;fJT1Ax22g4d5)__dl@O^EO+Bml2<;G}sDFgX~gH@|6&xOlS!zh_^3r zBWi2{fVS`j`ielVoXSLI)xwyg##AeR?=g>cc5$hrmiT|z9!=8V*gK00omVcVX>fyF z*up4>l=g*KB~lD(2f`9&{QX&bj;R?nL}-^OTm%wGH9a(aM|bkhfS%YHhZsr;`9=wu z&fFgg=qLB3c;ZXJ9JN9hwo-$_?x3)gQ4aAboF(+(MVD_1@!yv0s@gX{ps=-3W2Rw= z3*hWEurIoj3Nmh`&eQ4quHBgchDO`LTiTs}fuY5A@a*=@X)E<8J9tsMh;K41!A`cr z_NWbSDFkEVt>)cgBcvFX6I3(jQ!8n)Br!}eRNWd-C zMr7994%l7V^k`aKPz2I?&-B(GmPdCWwCsrIv*Nl_;+DClENtibyDVNzXa@jV$(Qm( z6p{}>GdCh-ql}RcEau#^J!|pNc4n_wM$J2HgJ;#6YnfQ70q9{LN}D^7j{s4Oih3Kj zFM1AuOHz3k7%OR19x$LwNCPCV+u{4ZRjBhJ7Je9G zdf2eXu58e5kqf}sKSPx&gKv0zm+qgBZ}HsETvIo>lg&+iv<<6!$i;^WkU{ll6(pN40PS^AD481a@iiR@yA}bB0 zIj24_cuO-%qy+7aem5M_(H$Cm*8fFzCQeyG!e#tg*eo}KhC}5w;m1@FdyxWrOi9L; zw72(;X?pxp4}4(zqCoCaMixZZS{VXr``D&&pBhhEb?!5nl zP-?S(XcI5-O=l8b}GhWeM2VaV^i$u?jOKUYNdW{P!R$##lj6L0V-l zE>22yFfL))XrYvK#*>CEGxe?z+}+xz@?bpwiZ$wuo{pD}*9Yj9NmAffhBZa$Yd7^W zW*itMpaye&GOXu@r6!yTl!OYa&Yqd41Wa#_I0@16nC&z2aB- ztKfa*!uKVvYn)C#HPQ~|TQmM%%0dqvUZTot~m2N#tu7L+=Dyf*W+}4^`M&{{ z(1dntEGArM+C=JS!`=uF&?4XIeFY(%G;q7wbld=YtSy9XmK{(H#hbI8vjHM;l6NiR zMl?{`ul?nJBRVQze#)FJ6cJy6Z0t9r`FUlDccMam0Vf%6@MzwL310t;CMtj%dOXPl z!aTyt#nJKPQ?c8z?avCQFp(YPWXV%-f4I(ac|RxHS0*|t{7Eje+HP@=jllbeU20nL1x!q{3;Wfy4$Q*+9ywT!HxLV8c`|bLqukuKj;z3J z@gAjXS=$p90+x8s6XwpD*VV4!StkCB{g-pyy!)H%xy)rn195&?0R?f1&QvJ{f$r3d zT)_~+FAXcesL4*1Nc ztPS)S4{a6?e;YmvEmC;eFmNjId~j&cJMRs5yOP@jpSSDknqHPMZ*9Y+;X6l_(v@Ql z^FkePiIWgHuDIi6D3B1EaoJIk!G5QR-CHPcRnTe3*HL0$nIv{?e>I)Y-LZY@X@rM= znthA+sl&2LtRGR~Qh_w?miVdpv-e**kyV+JR?kWXldbspZ-L8WdV2f&`UZyJ1u}u! z?*6{nHxGY6K4f@X*#y4?nx`8dI8~|CKqFMq-EcXyQebKI-9~DmRg&Qyx;P=rrRmQL zgB-2vg5?^TIm=e=+b?8xZIedG;ZNTZ63pQa@uS6!VLF>vHG)S7!m>h9Ym70AOt|^fJ=tUbb}Ck(QN-mlg?l>YgxDN8(^B%gb>HY+XqsFl61nVf{E{*eKHzP}&|zmkPXKoV(~k2XzZ#%_3n> z`Oii4_gthK=dxSaCkvJ7MHsJR-w^cRi7!8~{oqjd*Rb>OjSL*sB9FKOHz3KMyqrE9 z3Vt{HtgY&XalLaKy6_h(*CI~Uqp8+&5XPY9_ls8bD9kok zevHSFpz%db>?Gn*u-`DxJ9G9=qeOnZL^Y&s-Z${ZM1lb9!%&z#FO$z;unYh@f8S4t zuIXKt2c6{)*{iz}KzFKljqkDqfzC2l+3D^LTv0yqgxI?p79v%#&X*boJX)Dogor0M zxiRP6y=vZ<_V41ZCO1N_*k1frgK+$fEwg2lWLythXiRC z59ifgA<|#!ylSLA5p8FDiyRae8n`CC6lMxJq`IfDD=qRm;ItZ5czAo2WSuP4ctpEL z$KrwH`<=8a!bABC4w@lY4{d}H7Iy)|$Aq-dOWr0fsP*DK(YkL>+QfWgJ`QFesQUr& zFiwvf^jr%o6lb;1gVU$uAhXZqy+y&I^&pU`iGj>UGt@&yu*Qow`C$jwPdzT`)(_#B z+;(n~wa&ICww~C~M~PSOrKtWwsLo{p0rt32(-d|}xo&Kq=_Cgw<~z2ql=HC%rR9rI zOUja}HhUJrcVe8UTa#~k)T>jAEF5C0mgicGwgywoSLGc5+L=X%bcHM2#TRPTst2%%?QTh>Xvk!& zBr`;QfrfPo`h|-Ht=d6drjFve`3Ik|Bxi7R=A_i*5^*)1UEBAHEvR=9?oO<0Fd1t) zww4Hjxe?FC6S){=vV@IyGcHb%`dRJGJUKdhMI4YylpQH)Np`Qqu~u=r7`+iGDNWBJ zs9v-w($4GY!LJ+#yh1PDX`VZGK3P|8!XwD-{Wxqw z-$8l1n|t~0G4L*TG7oo`0QUDRi~TQFr(aIe8&8ytIJKN;FMn`GtjfP0d0NYu%f%gI zU$-i+>CKt8{BN~PceVn}py$gN4R6kFqf|X_PLxCKsyvNqk!-i;lGxaPip4B7l>8sL z|I##O$D32&UyQleBYzO?5fRI5*ML9&Vf?Sq|1{~oYkYh3TA`^@g_yAC&V!yA@=vP& zLo6n@4(#%e3jYQAU#)V_IJ+PJtDfB4Yo+WN98Ug`bBxA+hyIt%Q#TPL+x^qb$0cTY zF~QuMQ)tMb^gond7XH@%-=Y6yTL*W0p8m+Qk6Ff#{ckI2Owy45Q!9AAzPq->yXBY9 z`2N#E|B3OeYANd<#XW%)*EHRZ2G@+=&5C9J!or)|(2 z4Q=;bU2o2u|Epc?i*>&$#0*tfcyp3xj;1ZkdnR35>|Zx&d0LJCPx}&5y*QmvCJ@N$RWA5eWUr(GH z1=oj*bMuqGF1t_-i@NTw>m6h^9K23E)%c{<*Dsvp4R6Ck#sHeVZSv@6vp`1@K2$xg zef*6XpMq#kg$mFN4ZT9Q!znl2s(Vh4YHs-Lk2`?(oc#Mwl5Z&GM$=Mp9cz-*o&$?} z97-}ZNgAIAg$l_1J^egTKjO{xbfw2fly(62BV%;?@OH+VeMC$J@+@$sYIJHUX8f1i zh^K36rTML=zAt_cdJ3+sIw)1n1jw3b&&GN~d>nPGz1$0Pk6y~cB<|NTrVd{RmtyAN zW?Zf)Lf-u5IVV%`_t_T}meWpbkEy)Gcr(?Co7V!QC^l+=xg6hbT6c@3&kna|N^mOi za``cVPnSq1J2hWqqKqzY^ZU>UAbF}hMl3B>)<*0ij<=vZ?;vjXgz0c*@Q_z7FOJKb zGLsK?x3789jZk(S6FW)xm9e^Rkp*v(U2WvQjFyGfTr5HLlr5QPDVLyb%F4{NyWL^6 z%wiBWD6$CBQ>I?T{G|-51zCR;_VZrdIKX$tHkUfc$uNA|fo z;Iw_?VsSGFW~e5t@4NA8(m_kjua2i_j`nhdcInKQO#1Z8JkQV$ZOkR?ZLqMRZ=_@! zoc1I_=&WP+tnvADj#T3ANkr^f2W=EI!hyKuNdTPu?a=!s`~&_#C}? zFn$BJMkEZOaw~=&5q;$%k|+w}D91_w+G=l5^oqaV+F_kVAt2f6=g0n1)QZ3`x2xc{8^8Kec@o%~yxRN%66+hEFJ z?aQCc`5GGz9}}!ca2g^>VwZXg%9zfy_QdW46z?>9kz^=Ca;T{dbB#J!x8PUOy`U!4;m&6so&x-`lyzr!cM*Y5FQTgYptF0}5Wh!r z*!+=uH*2}WyjIM8fnmPEP^p&tX9KQa)%18AktPvO;@SzX`=*zTr!a2(>JY z%(r6RpG_NV55ZzBL$Ml(JZ|Uv-$&x((?V8$YHLS|vw2fCW@Mz^ZC&Yqn#^`Ut&qws z?|4ST8Z+g@gr{88;l;Rw*RPl_x05)fShTF1hX_FwoIl-7qY`%Guvm$1{2f|&-7Mi=LkZ6EW8I@m5FgZ1{CN_IhEeAZ7qF6mP&5zyU~tu`$w^glqWA&$7~NVR1z; zf-Hq&Jy_( zS~ZEk7Ghl`^1C&wlYa?mZ5W)2>oqtN7IFF8)51YfR`uS6lZcxU0A!Sd6q*73AYAmRE!?Eib;jFUIs; zT|=ztCS@kNkqy1s{xrZ{w9@6cihDPXh0P`OP7=6pw^D4estv{B03%`EvT_I&XYteA zW5=8ZOc4i{wUPfLv0!GKN#?ql>+vVNefSmf1LnQ=Nov+|~DQ=&xj)Oh?Bjo@FTD9*Q&qXIoBu6QnEN~2>12yX3n0IQp zHK75i%n&nZB{O$9wjbixO<`l+j^2<1-COqv)4wOb0FZXm%9acYqpom;HBu){+M=jy zW){sj&U*noQ;SL*q*HwJG#cBm0vX$l%<#o7gjTC#S<`UIV;#d55= J5G9ck{Vz{TfC~Ts diff --git a/packages/nvmedit/src/convert.ts b/packages/nvmedit/src/convert.ts index e94f7a408662..acb6fdb3a63b 100644 --- a/packages/nvmedit/src/convert.ts +++ b/packages/nvmedit/src/convert.ts @@ -18,24 +18,28 @@ import { num2hex, pick, } from "@zwave-js/shared/safe"; -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import semver from "semver"; -import { MAX_PROTOCOL_FILE_FORMAT, SUC_MAX_UPDATES } from "./consts"; -import { NVM3, type NVM3Meta } from "./lib/NVM3"; -import { NVM500 } from "./lib/NVM500"; +import { MAX_PROTOCOL_FILE_FORMAT, SUC_MAX_UPDATES } from "./consts.js"; +import { NVM3, type NVM3Meta } from "./lib/NVM3.js"; +import { NVM500 } from "./lib/NVM500.js"; import { type Route, type RouteCache, getEmptyRoute, -} from "./lib/common/routeCache"; -import { type SUCUpdateEntry } from "./lib/common/sucUpdateEntry"; -import { NVMMemoryIO } from "./lib/io/NVMMemoryIO"; -import { NVM3Adapter } from "./lib/nvm3/adapter"; +} from "./lib/common/routeCache.js"; +import { type SUCUpdateEntry } from "./lib/common/sucUpdateEntry.js"; +import { NVMMemoryIO } from "./lib/io/NVMMemoryIO.js"; +import { NVM3Adapter } from "./lib/nvm3/adapter.js"; import { ZWAVE_APPLICATION_NVM_SIZE, ZWAVE_PROTOCOL_NVM_SIZE, ZWAVE_SHARED_NVM_SIZE, -} from "./lib/nvm3/consts"; +} from "./lib/nvm3/consts.js"; +import { + type ApplicationNameFile, + ApplicationNameFileID, +} from "./lib/nvm3/files/ApplicationNameFile.js"; import { ApplicationCCsFile, ApplicationCCsFileID, @@ -90,22 +94,18 @@ import { nodeIdToRouteCacheFileIDV0, nodeIdToRouteCacheFileIDV1, sucUpdateIndexToSUCUpdateEntriesFileIDV5, -} from "./lib/nvm3/files"; -import { - type ApplicationNameFile, - ApplicationNameFileID, -} from "./lib/nvm3/files/ApplicationNameFile"; -import type { NVM3Object } from "./lib/nvm3/object"; -import { dumpNVM, mapToObject } from "./lib/nvm3/utils"; -import { NVM500Adapter } from "./lib/nvm500/adapter"; -import { nvm500Impls } from "./lib/nvm500/impls"; -import { resolveLayout } from "./lib/nvm500/shared"; +} from "./lib/nvm3/files/index.js"; +import type { NVM3Object } from "./lib/nvm3/object.js"; +import { dumpNVM, mapToObject } from "./lib/nvm3/utils.js"; +import { NVM500Adapter } from "./lib/nvm500/adapter.js"; +import { nvm500Impls } from "./lib/nvm500/impls/index.js"; +import { resolveLayout } from "./lib/nvm500/shared.js"; import { type NVM500JSON, type NVM500JSONController, type NVM500JSONNode, type NVM500Meta, -} from "./nvm500/NVMParser"; +} from "./nvm500/NVMParser.js"; export interface NVMJSON { format: number; // protocol file format diff --git a/packages/nvmedit/src/index.ts b/packages/nvmedit/src/index.ts index 5b92de7b5d99..b3d8d5e40553 100644 --- a/packages/nvmedit/src/index.ts +++ b/packages/nvmedit/src/index.ts @@ -8,7 +8,7 @@ export { migrateNVM, nvm500ToJSON, nvmToJSON, -} from "./convert"; +} from "./convert.js"; export type { NVMJSON, NVMJSONController, @@ -16,10 +16,14 @@ export type { NVMJSONNode, NVMJSONNodeWithInfo, NVMJSONVirtualNode, -} from "./convert"; -export { NVM3, type NVM3EraseOptions, type NVM3Meta } from "./lib/NVM3"; -export { NVM500, type NVM500EraseOptions, type NVM500Info } from "./lib/NVM500"; -export { NVMAccess } from "./lib/common/definitions"; +} from "./convert.js"; +export { NVM3, type NVM3EraseOptions, type NVM3Meta } from "./lib/NVM3.js"; +export { + NVM500, + type NVM500EraseOptions, + type NVM500Info, +} from "./lib/NVM500.js"; +export { NVMAccess } from "./lib/common/definitions.js"; export type { ControllerNVMProperty, ControllerNVMPropertyToDataType, @@ -32,24 +36,24 @@ export type { NVMPropertyToDataType, NodeNVMProperty, NodeNVMPropertyToDataType, -} from "./lib/common/definitions"; -export { BufferedNVMReader } from "./lib/io/BufferedNVMReader"; -export { NVMFileIO } from "./lib/io/NVMFileIO"; -export { NVM3Adapter } from "./lib/nvm3/adapter"; +} from "./lib/common/definitions.js"; +export { BufferedNVMReader } from "./lib/io/BufferedNVMReader.js"; +export { NVMFileIO } from "./lib/io/NVMFileIO.js"; +export { NVM3Adapter } from "./lib/nvm3/adapter.js"; export { FragmentType, ObjectType, PageStatus, PageWriteSize, -} from "./lib/nvm3/consts"; +} from "./lib/nvm3/consts.js"; export { ControllerInfoFile, ControllerInfoFileID, NVMFile, -} from "./lib/nvm3/files"; -export type { NVM3Object } from "./lib/nvm3/object"; -export type { NVM3Page, NVM3PageHeader } from "./lib/nvm3/page"; -export { NVM500Adapter } from "./lib/nvm500/adapter"; +} from "./lib/nvm3/files/index.js"; +export type { NVM3Object } from "./lib/nvm3/object.js"; +export type { NVM3Page, NVM3PageHeader } from "./lib/nvm3/page.js"; +export { NVM500Adapter } from "./lib/nvm500/adapter.js"; export type { NVM500JSON, NVM500JSONController, @@ -58,4 +62,4 @@ export type { NVM500JSONNodeWithInfo, NVM500JSONVirtualNode, NVM500Meta, -} from "./nvm500/NVMParser"; +} from "./nvm500/NVMParser.js"; diff --git a/packages/nvmedit/src/index_safe.ts b/packages/nvmedit/src/index_safe.ts index fcd7e330e671..2da1a76f1223 100644 --- a/packages/nvmedit/src/index_safe.ts +++ b/packages/nvmedit/src/index_safe.ts @@ -9,10 +9,10 @@ export type { NVMJSONNode, NVMJSONNodeWithInfo, NVMJSONVirtualNode, -} from "./convert"; -export type { NVM3EraseOptions, NVM3Meta } from "./lib/NVM3"; -export type { NVM500EraseOptions, NVM500Info } from "./lib/NVM500"; -export { NVMAccess } from "./lib/common/definitions"; +} from "./convert.js"; +export type { NVM3EraseOptions, NVM3Meta } from "./lib/NVM3.js"; +export type { NVM500EraseOptions, NVM500Info } from "./lib/NVM500.js"; +export { NVMAccess } from "./lib/common/definitions.js"; export type { ControllerNVMProperty, ControllerNVMPropertyToDataType, @@ -25,15 +25,15 @@ export type { NVMPropertyToDataType, NodeNVMProperty, NodeNVMPropertyToDataType, -} from "./lib/common/definitions"; +} from "./lib/common/definitions.js"; export { FragmentType, ObjectType, PageStatus, PageWriteSize, -} from "./lib/nvm3/consts"; -export type { NVM3Object } from "./lib/nvm3/object"; -export type { NVM3Page, NVM3PageHeader } from "./lib/nvm3/page"; +} from "./lib/nvm3/consts.js"; +export type { NVM3Object } from "./lib/nvm3/object.js"; +export type { NVM3Page, NVM3PageHeader } from "./lib/nvm3/page.js"; export type { NVM500JSON, NVM500JSONController, @@ -42,4 +42,4 @@ export type { NVM500JSONNodeWithInfo, NVM500JSONVirtualNode, NVM500Meta, -} from "./nvm500/NVMParser"; +} from "./nvm500/NVMParser.js"; diff --git a/packages/nvmedit/src/lib/NVM3.ts b/packages/nvmedit/src/lib/NVM3.ts index 721f2e1ea98c..69e440340f9f 100644 --- a/packages/nvmedit/src/lib/NVM3.ts +++ b/packages/nvmedit/src/lib/NVM3.ts @@ -1,7 +1,11 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import { Bytes, getEnumMemberName, num2hex } from "@zwave-js/shared"; -import { type NVM, NVMAccess, type NVMIO } from "./common/definitions"; -import { nvmReadBuffer, nvmReadUInt32LE, nvmWriteBuffer } from "./common/utils"; +import { type NVM, NVMAccess, type NVMIO } from "./common/definitions.js"; +import { + nvmReadBuffer, + nvmReadUInt32LE, + nvmWriteBuffer, +} from "./common/utils.js"; import { FLASH_MAX_PAGE_SIZE_700, FLASH_MAX_PAGE_SIZE_800, @@ -25,12 +29,12 @@ import { PageStatus, PageWriteSize, ZWAVE_APPLICATION_NVM_SIZE, -} from "./nvm3/consts"; +} from "./nvm3/consts.js"; import { ApplicationVersionFile800ID, type NVMSection, getNVMSectionByFileID, -} from "./nvm3/files"; +} from "./nvm3/files/index.js"; import { type NVM3Object, type NVM3ObjectHeader, @@ -39,13 +43,13 @@ import { getObjectHeader, getRequiredSpace, serializeObject, -} from "./nvm3/object"; +} from "./nvm3/object.js"; import { type NVM3PageHeader, pageSizeFromBits, serializePageHeader, -} from "./nvm3/page"; -import { validateBergerCode, validateBergerCodeMulti } from "./nvm3/utils"; +} from "./nvm3/page.js"; +import { validateBergerCode, validateBergerCodeMulti } from "./nvm3/utils.js"; // TODO: Possible optimizations: // Investigate if there is a better way to determine whether the NVM diff --git a/packages/nvmedit/src/lib/NVM500.ts b/packages/nvmedit/src/lib/NVM500.ts index 3c49169b36e7..12223ece01fd 100644 --- a/packages/nvmedit/src/lib/NVM500.ts +++ b/packages/nvmedit/src/lib/NVM500.ts @@ -6,14 +6,18 @@ import { parseBitMask, } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import { type NVM, NVMAccess, type NVMIO } from "./common/definitions"; -import { type Route, encodeRoute, parseRoute } from "./common/routeCache"; +import { type NVM, NVMAccess, type NVMIO } from "./common/definitions.js"; +import { type Route, encodeRoute, parseRoute } from "./common/routeCache.js"; import { type SUCUpdateEntry, encodeSUCUpdateEntry, parseSUCUpdateEntry, -} from "./common/sucUpdateEntry"; -import { nvmReadBuffer, nvmReadUInt16BE, nvmWriteBuffer } from "./common/utils"; +} from "./common/sucUpdateEntry.js"; +import { + nvmReadBuffer, + nvmReadUInt16BE, + nvmWriteBuffer, +} from "./common/utils.js"; import { type NVM500NodeInfo, type NVMDescriptor, @@ -24,8 +28,8 @@ import { parseNVM500NodeInfo, parseNVMDescriptor, parseNVMModuleDescriptor, -} from "./nvm500/EntryParsers"; -import { nvm500Impls } from "./nvm500/impls"; +} from "./nvm500/EntryParsers.js"; +import { nvm500Impls } from "./nvm500/impls/index.js"; import { CONFIGURATION_VALID_0, CONFIGURATION_VALID_1, @@ -39,7 +43,7 @@ import { ROUTECACHE_VALID, type ResolvedNVMEntry, type ResolvedNVMLayout, -} from "./nvm500/shared"; +} from "./nvm500/shared.js"; export interface NVM500Info { layout: ResolvedNVMLayout; diff --git a/packages/nvmedit/src/lib/common/definitions.ts b/packages/nvmedit/src/lib/common/definitions.ts index 6a0e13e17451..2d0c9faee7bc 100644 --- a/packages/nvmedit/src/lib/common/definitions.ts +++ b/packages/nvmedit/src/lib/common/definitions.ts @@ -7,9 +7,9 @@ import { type ControllerInfoFile, type LRNodeInfo, type NodeInfo, -} from "../nvm3/files"; -import { type Route } from "./routeCache"; -import { type SUCUpdateEntry } from "./sucUpdateEntry"; +} from "../nvm3/files/index.js"; +import { type Route } from "./routeCache.js"; +import { type SUCUpdateEntry } from "./sucUpdateEntry.js"; export enum NVMAccess { None, diff --git a/packages/nvmedit/src/lib/common/sucUpdateEntry.ts b/packages/nvmedit/src/lib/common/sucUpdateEntry.ts index cdfc8a2fa7e9..d613d48a49e8 100644 --- a/packages/nvmedit/src/lib/common/sucUpdateEntry.ts +++ b/packages/nvmedit/src/lib/common/sucUpdateEntry.ts @@ -6,7 +6,10 @@ import { parseCCList, } from "@zwave-js/core/safe"; import { Bytes } from "@zwave-js/shared"; -import { SUC_UPDATE_ENTRY_SIZE, SUC_UPDATE_NODEPARM_MAX } from "../../consts"; +import { + SUC_UPDATE_ENTRY_SIZE, + SUC_UPDATE_NODEPARM_MAX, +} from "../../consts.js"; export interface SUCUpdateEntry { nodeId: number; diff --git a/packages/nvmedit/src/lib/common/utils.ts b/packages/nvmedit/src/lib/common/utils.ts index cdf877a694eb..944a37ab7762 100644 --- a/packages/nvmedit/src/lib/common/utils.ts +++ b/packages/nvmedit/src/lib/common/utils.ts @@ -1,5 +1,5 @@ import { Bytes } from "@zwave-js/shared/safe"; -import type { NVMIO } from "./definitions"; +import type { NVMIO } from "./definitions.js"; export async function nvmReadUInt32LE( io: NVMIO, diff --git a/packages/nvmedit/src/lib/io/BufferedNVMReader.ts b/packages/nvmedit/src/lib/io/BufferedNVMReader.ts index 7b41faebf423..fe74a5077eb2 100644 --- a/packages/nvmedit/src/lib/io/BufferedNVMReader.ts +++ b/packages/nvmedit/src/lib/io/BufferedNVMReader.ts @@ -1,5 +1,5 @@ import { Bytes } from "@zwave-js/shared/safe"; -import { type NVMAccess, type NVMIO } from "../common/definitions"; +import { type NVMAccess, type NVMIO } from "../common/definitions.js"; interface BufferedChunk { offset: number; diff --git a/packages/nvmedit/src/lib/io/NVMFileIO.ts b/packages/nvmedit/src/lib/io/NVMFileIO.ts index 2accfd2a3951..925953313e61 100644 --- a/packages/nvmedit/src/lib/io/NVMFileIO.ts +++ b/packages/nvmedit/src/lib/io/NVMFileIO.ts @@ -1,6 +1,6 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import fs, { type FileHandle } from "node:fs/promises"; -import { NVMAccess, type NVMIO } from "../common/definitions"; +import { NVMAccess, type NVMIO } from "../common/definitions.js"; /** An implementation of NVMIO for the filesystem */ export class NVMFileIO implements NVMIO { diff --git a/packages/nvmedit/src/lib/io/NVMMemoryIO.ts b/packages/nvmedit/src/lib/io/NVMMemoryIO.ts index 7596a7a18e8d..b0fa5fca320a 100644 --- a/packages/nvmedit/src/lib/io/NVMMemoryIO.ts +++ b/packages/nvmedit/src/lib/io/NVMMemoryIO.ts @@ -1,5 +1,5 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; -import { NVMAccess, type NVMIO } from "../common/definitions"; +import { NVMAccess, type NVMIO } from "../common/definitions.js"; /** An im-memory implementation of NVMIO */ export class NVMMemoryIO implements NVMIO { diff --git a/packages/nvmedit/src/lib/nvm3/adapter.ts b/packages/nvmedit/src/lib/nvm3/adapter.ts index 531c88e96c57..faa60d5080b3 100644 --- a/packages/nvmedit/src/lib/nvm3/adapter.ts +++ b/packages/nvmedit/src/lib/nvm3/adapter.ts @@ -1,8 +1,8 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import { num2hex } from "@zwave-js/shared"; -import { assertNever } from "alcalzone-shared/helpers"; -import { SUC_MAX_UPDATES } from "../../consts"; -import { type NVM3 } from "../NVM3"; +import { assertNever } from "alcalzone-shared/helpers/index.js"; +import { SUC_MAX_UPDATES } from "../../consts.js"; +import { type NVM3 } from "../NVM3.js"; import { type ControllerNVMProperty, type LRNodeNVMProperty, @@ -10,8 +10,8 @@ import { type NVMProperty, type NVMPropertyToDataType, type NodeNVMProperty, -} from "../common/definitions"; -import { type RouteCache } from "../common/routeCache"; +} from "../common/definitions.js"; +import { type RouteCache } from "../common/routeCache.js"; import { type ApplicationCCsFile, ApplicationCCsFileID, @@ -68,7 +68,7 @@ import { nodeIdToRouteCacheFileIDV0, nodeIdToRouteCacheFileIDV1, sucUpdateIndexToSUCUpdateEntriesFileIDV5, -} from "./files"; +} from "./files/index.js"; const DEFAULT_FILE_VERSION = "7.0.0"; diff --git a/packages/nvmedit/src/lib/nvm3/files/ApplicationCCsFile.ts b/packages/nvmedit/src/lib/nvm3/files/ApplicationCCsFile.ts index c2cbfa05225f..fb7c8332c8ce 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ApplicationCCsFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ApplicationCCsFile.ts @@ -1,6 +1,6 @@ import { CommandClasses } from "@zwave-js/core/safe"; import { Bytes } from "@zwave-js/shared/safe"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -8,7 +8,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export interface ApplicationCCsFileOptions extends NVMFileCreationOptions { includedInsecurely: CommandClasses[]; diff --git a/packages/nvmedit/src/lib/nvm3/files/ApplicationDataFile.ts b/packages/nvmedit/src/lib/nvm3/files/ApplicationDataFile.ts index e16d6fc8b74b..74a0834a0ab9 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ApplicationDataFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ApplicationDataFile.ts @@ -6,7 +6,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export interface ApplicationDataFileOptions extends NVMFileCreationOptions { applicationData: Bytes; diff --git a/packages/nvmedit/src/lib/nvm3/files/ApplicationNameFile.ts b/packages/nvmedit/src/lib/nvm3/files/ApplicationNameFile.ts index 69074a7a4711..0fa0c3ad3c1e 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ApplicationNameFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ApplicationNameFile.ts @@ -1,5 +1,5 @@ import { Bytes, cpp2js } from "@zwave-js/shared"; -import { type NVM3Object } from "../object"; +import { type NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -7,7 +7,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export interface ApplicationNameFileOptions extends NVMFileCreationOptions { name: string; diff --git a/packages/nvmedit/src/lib/nvm3/files/ApplicationRFConfigFile.ts b/packages/nvmedit/src/lib/nvm3/files/ApplicationRFConfigFile.ts index a2f1b286a881..68d053a7c722 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ApplicationRFConfigFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ApplicationRFConfigFile.ts @@ -10,7 +10,7 @@ import { getEnumMemberName, } from "@zwave-js/shared/safe"; import semver from "semver"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -18,7 +18,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export type ApplicationRFConfigFileOptions = & NVMFileCreationOptions diff --git a/packages/nvmedit/src/lib/nvm3/files/ApplicationTypeFile.ts b/packages/nvmedit/src/lib/nvm3/files/ApplicationTypeFile.ts index e756cb626b34..2885b00618d2 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ApplicationTypeFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ApplicationTypeFile.ts @@ -1,5 +1,5 @@ import { Bytes } from "@zwave-js/shared/safe"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -7,7 +7,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export interface ApplicationTypeFileOptions extends NVMFileCreationOptions { isListening: boolean; diff --git a/packages/nvmedit/src/lib/nvm3/files/ControllerInfoFile.ts b/packages/nvmedit/src/lib/nvm3/files/ControllerInfoFile.ts index 63cb8ff743bb..f591c068e093 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ControllerInfoFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ControllerInfoFile.ts @@ -4,7 +4,7 @@ import { stripUndefined, } from "@zwave-js/core/safe"; import { Bytes, buffer2hex } from "@zwave-js/shared"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -12,7 +12,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export type ControllerInfoFileOptions = & NVMFileCreationOptions diff --git a/packages/nvmedit/src/lib/nvm3/files/NVMFile.ts b/packages/nvmedit/src/lib/nvm3/files/NVMFile.ts index 0102fcdd00a9..e13fa9b4387f 100644 --- a/packages/nvmedit/src/lib/nvm3/files/NVMFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/NVMFile.ts @@ -6,8 +6,12 @@ import { isUint8Array, num2hex, } from "@zwave-js/shared"; -import { FragmentType, NVM3_MAX_OBJ_SIZE_SMALL, ObjectType } from "../consts"; -import type { NVM3Object } from "../object"; +import { + FragmentType, + NVM3_MAX_OBJ_SIZE_SMALL, + ObjectType, +} from "../consts.js"; +import type { NVM3Object } from "../object.js"; export interface NVMFileBaseOptions { fileId?: number; diff --git a/packages/nvmedit/src/lib/nvm3/files/NodeInfoFiles.ts b/packages/nvmedit/src/lib/nvm3/files/NodeInfoFiles.ts index 5252eab97ea2..85261757c069 100644 --- a/packages/nvmedit/src/lib/nvm3/files/NodeInfoFiles.ts +++ b/packages/nvmedit/src/lib/nvm3/files/NodeInfoFiles.ts @@ -12,7 +12,7 @@ import { parseNodeProtocolInfo, } from "@zwave-js/core/safe"; import { Bytes, pick } from "@zwave-js/shared/safe"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -20,7 +20,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export const NODEINFOS_PER_FILE_V1 = 4; export const LR_NODEINFOS_PER_FILE_V5 = 50; diff --git a/packages/nvmedit/src/lib/nvm3/files/ProtocolNodeMaskFiles.ts b/packages/nvmedit/src/lib/nvm3/files/ProtocolNodeMaskFiles.ts index d0bf00d64986..dd84a1f90e4b 100644 --- a/packages/nvmedit/src/lib/nvm3/files/ProtocolNodeMaskFiles.ts +++ b/packages/nvmedit/src/lib/nvm3/files/ProtocolNodeMaskFiles.ts @@ -1,6 +1,6 @@ import { NODE_ID_MAX, encodeBitMask, parseBitMask } from "@zwave-js/core/safe"; import { type Bytes } from "@zwave-js/shared/safe"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -8,7 +8,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export interface ProtocolNodeMaskFileOptions extends NVMFileCreationOptions { nodeIds: number[]; diff --git a/packages/nvmedit/src/lib/nvm3/files/RouteCacheFiles.ts b/packages/nvmedit/src/lib/nvm3/files/RouteCacheFiles.ts index a54e42d48d1f..dc672674da74 100644 --- a/packages/nvmedit/src/lib/nvm3/files/RouteCacheFiles.ts +++ b/packages/nvmedit/src/lib/nvm3/files/RouteCacheFiles.ts @@ -7,8 +7,8 @@ import { emptyRouteCache, encodeRoute, parseRoute, -} from "../../common/routeCache"; -import type { NVM3Object } from "../object"; +} from "../../common/routeCache.js"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -16,7 +16,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export const ROUTECACHES_PER_FILE_V1 = 8; diff --git a/packages/nvmedit/src/lib/nvm3/files/SUCUpdateEntriesFile.ts b/packages/nvmedit/src/lib/nvm3/files/SUCUpdateEntriesFile.ts index ecb9203b02a0..171a878469f0 100644 --- a/packages/nvmedit/src/lib/nvm3/files/SUCUpdateEntriesFile.ts +++ b/packages/nvmedit/src/lib/nvm3/files/SUCUpdateEntriesFile.ts @@ -1,11 +1,11 @@ import { Bytes } from "@zwave-js/shared/safe"; -import { SUC_MAX_UPDATES, SUC_UPDATE_ENTRY_SIZE } from "../../../consts"; +import { SUC_MAX_UPDATES, SUC_UPDATE_ENTRY_SIZE } from "../../../consts.js"; import { type SUCUpdateEntry, encodeSUCUpdateEntry, parseSUCUpdateEntry, -} from "../../common/sucUpdateEntry"; -import type { NVM3Object } from "../object"; +} from "../../common/sucUpdateEntry.js"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -13,7 +13,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export const SUC_UPDATES_PER_FILE_V5 = 8; diff --git a/packages/nvmedit/src/lib/nvm3/files/VersionFiles.ts b/packages/nvmedit/src/lib/nvm3/files/VersionFiles.ts index f409f7deeef5..663759d5dfc2 100644 --- a/packages/nvmedit/src/lib/nvm3/files/VersionFiles.ts +++ b/packages/nvmedit/src/lib/nvm3/files/VersionFiles.ts @@ -1,5 +1,5 @@ import { Bytes } from "@zwave-js/shared"; -import type { NVM3Object } from "../object"; +import type { NVM3Object } from "../object.js"; import { NVMFile, type NVMFileCreationOptions, @@ -7,7 +7,7 @@ import { gotDeserializationOptions, nvmFileID, nvmSection, -} from "./NVMFile"; +} from "./NVMFile.js"; export interface VersionFileOptions extends NVMFileCreationOptions { format: number; diff --git a/packages/nvmedit/src/lib/nvm3/files/index.ts b/packages/nvmedit/src/lib/nvm3/files/index.ts index 5cc62c2c61a8..4f9974d0d70a 100644 --- a/packages/nvmedit/src/lib/nvm3/files/index.ts +++ b/packages/nvmedit/src/lib/nvm3/files/index.ts @@ -1,14 +1,14 @@ import "reflect-metadata"; -export * from "./ApplicationCCsFile"; -export * from "./ApplicationDataFile"; -export * from "./ApplicationNameFile"; -export * from "./ApplicationRFConfigFile"; -export * from "./ApplicationTypeFile"; -export * from "./ControllerInfoFile"; -export * from "./NVMFile"; -export * from "./NodeInfoFiles"; -export * from "./ProtocolNodeMaskFiles"; -export * from "./RouteCacheFiles"; -export * from "./SUCUpdateEntriesFile"; -export * from "./VersionFiles"; +export * from "./ApplicationCCsFile.js"; +export * from "./ApplicationDataFile.js"; +export * from "./ApplicationNameFile.js"; +export * from "./ApplicationRFConfigFile.js"; +export * from "./ApplicationTypeFile.js"; +export * from "./ControllerInfoFile.js"; +export * from "./NVMFile.js"; +export * from "./NodeInfoFiles.js"; +export * from "./ProtocolNodeMaskFiles.js"; +export * from "./RouteCacheFiles.js"; +export * from "./SUCUpdateEntriesFile.js"; +export * from "./VersionFiles.js"; diff --git a/packages/nvmedit/src/lib/nvm3/object.ts b/packages/nvmedit/src/lib/nvm3/object.ts index 4bf0b7fa3416..67a3c088e263 100644 --- a/packages/nvmedit/src/lib/nvm3/object.ts +++ b/packages/nvmedit/src/lib/nvm3/object.ts @@ -14,8 +14,8 @@ import { NVM3_OBJ_TYPE_MASK, NVM3_WORD_SIZE, ObjectType, -} from "./consts"; -import { computeBergerCode, computeBergerCodeMulti } from "./utils"; +} from "./consts.js"; +import { computeBergerCode, computeBergerCodeMulti } from "./utils.js"; export interface NVM3ObjectHeader { offset: number; diff --git a/packages/nvmedit/src/lib/nvm3/page.ts b/packages/nvmedit/src/lib/nvm3/page.ts index 513b8da25d55..04e0ef6b1bb6 100644 --- a/packages/nvmedit/src/lib/nvm3/page.ts +++ b/packages/nvmedit/src/lib/nvm3/page.ts @@ -7,9 +7,9 @@ import { NVM3_PAGE_MAGIC, type PageStatus, type PageWriteSize, -} from "./consts"; -import { type NVM3Object } from "./object"; -import { computeBergerCode } from "./utils"; +} from "./consts.js"; +import { type NVM3Object } from "./object.js"; +import { computeBergerCode } from "./utils.js"; export interface NVM3PageHeader { offset: number; diff --git a/packages/nvmedit/src/lib/nvm3/utils.test.ts b/packages/nvmedit/src/lib/nvm3/utils.test.ts index 8bdf766f153e..8044d362a383 100644 --- a/packages/nvmedit/src/lib/nvm3/utils.test.ts +++ b/packages/nvmedit/src/lib/nvm3/utils.test.ts @@ -1,5 +1,5 @@ -import test from "ava"; -import { computeBergerCode } from "./utils"; +import { test } from "vitest"; +import { computeBergerCode } from "./utils.js"; { const cases = [ @@ -27,7 +27,7 @@ import { computeBergerCode } from "./utils"; for (const { input, numBits, result } of cases) { test(`computeBergerCode() -> returns ${result} for input ${input} with ${numBits} bits`, (t) => { - t.is(computeBergerCode(input, numBits), result); + t.expect(computeBergerCode(input, numBits)).toBe(result); }); } } diff --git a/packages/nvmedit/src/lib/nvm3/utils.ts b/packages/nvmedit/src/lib/nvm3/utils.ts index bf2087893fa0..70b28ade35aa 100644 --- a/packages/nvmedit/src/lib/nvm3/utils.ts +++ b/packages/nvmedit/src/lib/nvm3/utils.ts @@ -1,9 +1,9 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core/safe"; import { buffer2hex, num2hex } from "@zwave-js/shared"; -import { type NVM3 } from "../NVM3"; -import { FragmentType, ObjectType, PageStatus } from "./consts"; -import { NVMFile } from "./files/NVMFile"; -import type { NVM3Object } from "./object"; +import { type NVM3 } from "../NVM3.js"; +import { FragmentType, ObjectType, PageStatus } from "./consts.js"; +import { NVMFile } from "./files/NVMFile.js"; +import type { NVM3Object } from "./object.js"; /** Counts the number of unset bits in the given word */ export function computeBergerCode(word: number, numBits: number = 32): number { diff --git a/packages/nvmedit/src/lib/nvm500/EntryParsers.ts b/packages/nvmedit/src/lib/nvm500/EntryParsers.ts index 909b4da48198..a0d3051a8746 100644 --- a/packages/nvmedit/src/lib/nvm500/EntryParsers.ts +++ b/packages/nvmedit/src/lib/nvm500/EntryParsers.ts @@ -4,8 +4,8 @@ import { parseNodeProtocolInfo, } from "@zwave-js/core/safe"; import { Bytes } from "@zwave-js/shared/safe"; -import { padStart } from "alcalzone-shared/strings"; -import type { NVMModuleType } from "./shared"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import type { NVMModuleType } from "./shared.js"; export interface NVMDescriptor { manufacturerID: number; diff --git a/packages/nvmedit/src/lib/nvm500/adapter.ts b/packages/nvmedit/src/lib/nvm500/adapter.ts index 12fba9ee195d..6bda4f4324e0 100644 --- a/packages/nvmedit/src/lib/nvm500/adapter.ts +++ b/packages/nvmedit/src/lib/nvm500/adapter.ts @@ -4,26 +4,26 @@ import { ZWaveErrorCodes, } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared"; -import { assertNever } from "alcalzone-shared/helpers"; -import { SUC_MAX_UPDATES } from "../../consts"; -import { type NVM500, type NVM500Info } from "../NVM500"; +import { assertNever } from "alcalzone-shared/helpers/index.js"; +import { SUC_MAX_UPDATES } from "../../consts.js"; +import { type NVM500, type NVM500Info } from "../NVM500.js"; import { type ControllerNVMProperty, type NVMAdapter, type NVMProperty, type NVMPropertyToDataType, type NodeNVMProperty, -} from "../common/definitions"; -import { type Route } from "../common/routeCache"; -import { type SUCUpdateEntry } from "../common/sucUpdateEntry"; -import { type NodeInfo } from "../nvm3/files"; -import { type NVM500NodeInfo } from "./EntryParsers"; +} from "../common/definitions.js"; +import { type Route } from "../common/routeCache.js"; +import { type SUCUpdateEntry } from "../common/sucUpdateEntry.js"; +import { type NodeInfo } from "../nvm3/files/index.js"; +import { type NVM500NodeInfo } from "./EntryParsers.js"; import { APPL_NODEPARM_MAX, type NVMData, type NVMEntryName, NVM_SERIALAPI_HOST_SIZE, -} from "./shared"; +} from "./shared.js"; export class NVM500Adapter implements NVMAdapter { public constructor(nvm: NVM500) { diff --git a/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_6x.ts b/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_6x.ts index 55a00de55c01..35331cc3a238 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_6x.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_6x.ts @@ -1,6 +1,6 @@ import { MAX_NODES, NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_MAX_UPDATES } from "../../../consts"; -import type { NVM500Impl } from "../shared"; +import { SUC_MAX_UPDATES } from "../../../consts.js"; +import type { NVM500Impl } from "../shared.js"; import { APPL_NODEPARM_MAX, NVMEntryType, @@ -9,7 +9,7 @@ import { RTC_TIMER_SIZE, SUC_CONTROLLER_LIST_SIZE, TOTAL_RTC_TIMER_MAX, -} from "../shared"; +} from "../shared.js"; const NVM_Layout_Bridge_6_6x: NVMLayout = [ { name: "nvmTotalEnd", type: NVMEntryType.Word, count: 1 }, diff --git a/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_7x.ts b/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_7x.ts index 669b01aaf3dc..d928e2160dfc 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_7x.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_7x.ts @@ -1,6 +1,6 @@ import { MAX_NODES, NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_MAX_UPDATES } from "../../../consts"; -import type { NVM500Impl } from "../shared"; +import { SUC_MAX_UPDATES } from "../../../consts.js"; +import type { NVM500Impl } from "../shared.js"; import { APPL_NODEPARM_MAX, NVMEntryType, @@ -10,7 +10,7 @@ import { RTC_TIMER_SIZE, SUC_CONTROLLER_LIST_SIZE, TOTAL_RTC_TIMER_MAX, -} from "../shared"; +} from "../shared.js"; const NVM_Layout_Bridge_6_7x: NVMLayout = [ { name: "nvmTotalEnd", type: NVMEntryType.Word, count: 1 }, diff --git a/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_8x.ts b/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_8x.ts index cd88be4698f7..1208c142f3f0 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_8x.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/Bridge_6_8x.ts @@ -1,6 +1,6 @@ import { MAX_NODES, NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_MAX_UPDATES } from "../../../consts"; -import type { NVM500Impl } from "../shared"; +import { SUC_MAX_UPDATES } from "../../../consts.js"; +import type { NVM500Impl } from "../shared.js"; import { APPL_NODEPARM_MAX, NVMEntryType, @@ -10,7 +10,7 @@ import { RTC_TIMER_SIZE, SUC_CONTROLLER_LIST_SIZE, TOTAL_RTC_TIMER_MAX, -} from "../shared"; +} from "../shared.js"; const NVM_Layout_Bridge_6_8x: NVMLayout = [ { name: "nvmTotalEnd", type: NVMEntryType.Word, count: 1 }, diff --git a/packages/nvmedit/src/lib/nvm500/impls/Static_6_6x.ts b/packages/nvmedit/src/lib/nvm500/impls/Static_6_6x.ts index 1ea466a9ad85..237d6a0f2989 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/Static_6_6x.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/Static_6_6x.ts @@ -1,6 +1,6 @@ import { MAX_NODES, NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_MAX_UPDATES } from "../../../consts"; -import type { NVM500Impl } from "../shared"; +import { SUC_MAX_UPDATES } from "../../../consts.js"; +import type { NVM500Impl } from "../shared.js"; import { APPL_NODEPARM_MAX, NVMEntryType, @@ -9,7 +9,7 @@ import { RTC_TIMER_SIZE, SUC_CONTROLLER_LIST_SIZE, TOTAL_RTC_TIMER_MAX, -} from "../shared"; +} from "../shared.js"; const NVM_Layout_Static_6_6x: NVMLayout = [ { name: "nvmTotalEnd", type: NVMEntryType.Word, count: 1 }, diff --git a/packages/nvmedit/src/lib/nvm500/impls/Static_6_7x.ts b/packages/nvmedit/src/lib/nvm500/impls/Static_6_7x.ts index a3343ee874c0..0d6df3a5cf56 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/Static_6_7x.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/Static_6_7x.ts @@ -1,6 +1,6 @@ import { MAX_NODES, NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_MAX_UPDATES } from "../../../consts"; -import type { NVM500Impl } from "../shared"; +import { SUC_MAX_UPDATES } from "../../../consts.js"; +import type { NVM500Impl } from "../shared.js"; import { APPL_NODEPARM_MAX, NVMEntryType, @@ -10,7 +10,7 @@ import { RTC_TIMER_SIZE, SUC_CONTROLLER_LIST_SIZE, TOTAL_RTC_TIMER_MAX, -} from "../shared"; +} from "../shared.js"; const NVM_Layout_Static_6_7x: NVMLayout = [ { name: "nvmTotalEnd", type: NVMEntryType.Word, count: 1 }, diff --git a/packages/nvmedit/src/lib/nvm500/impls/Static_6_8x.ts b/packages/nvmedit/src/lib/nvm500/impls/Static_6_8x.ts index c48db4068ed0..88b8228d61b6 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/Static_6_8x.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/Static_6_8x.ts @@ -1,6 +1,6 @@ import { MAX_NODES, NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_MAX_UPDATES } from "../../../consts"; -import type { NVM500Impl } from "../shared"; +import { SUC_MAX_UPDATES } from "../../../consts.js"; +import type { NVM500Impl } from "../shared.js"; import { APPL_NODEPARM_MAX, NVMEntryType, @@ -10,7 +10,7 @@ import { RTC_TIMER_SIZE, SUC_CONTROLLER_LIST_SIZE, TOTAL_RTC_TIMER_MAX, -} from "../shared"; +} from "../shared.js"; const NVM_Layout_Static_6_8x: NVMLayout = [ { name: "nvmTotalEnd", type: NVMEntryType.Word, count: 1 }, diff --git a/packages/nvmedit/src/lib/nvm500/impls/index.ts b/packages/nvmedit/src/lib/nvm500/impls/index.ts index f49192628c84..2a002664a32c 100644 --- a/packages/nvmedit/src/lib/nvm500/impls/index.ts +++ b/packages/nvmedit/src/lib/nvm500/impls/index.ts @@ -1,9 +1,9 @@ -import { Bridge_6_6x } from "./Bridge_6_6x"; -import { Bridge_6_7x } from "./Bridge_6_7x"; -import { Bridge_6_8x } from "./Bridge_6_8x"; -import { Static_6_6x } from "./Static_6_6x"; -import { Static_6_7x } from "./Static_6_7x"; -import { Static_6_8x } from "./Static_6_8x"; +import { Bridge_6_6x } from "./Bridge_6_6x.js"; +import { Bridge_6_7x } from "./Bridge_6_7x.js"; +import { Bridge_6_8x } from "./Bridge_6_8x.js"; +import { Static_6_6x } from "./Static_6_6x.js"; +import { Static_6_7x } from "./Static_6_7x.js"; +import { Static_6_8x } from "./Static_6_8x.js"; export const nvm500Impls = [ Bridge_6_6x, diff --git a/packages/nvmedit/src/lib/nvm500/shared.ts b/packages/nvmedit/src/lib/nvm500/shared.ts index 64c307237c8a..1b55f3eef977 100644 --- a/packages/nvmedit/src/lib/nvm500/shared.ts +++ b/packages/nvmedit/src/lib/nvm500/shared.ts @@ -1,12 +1,12 @@ import { NUM_NODEMASK_BYTES } from "@zwave-js/core/safe"; -import { SUC_UPDATE_ENTRY_SIZE } from "../../consts"; -import { type Route } from "../common/routeCache"; -import { type SUCUpdateEntry } from "../common/sucUpdateEntry"; +import { SUC_UPDATE_ENTRY_SIZE } from "../../consts.js"; +import { type Route } from "../common/routeCache.js"; +import { type SUCUpdateEntry } from "../common/sucUpdateEntry.js"; import type { NVM500NodeInfo, NVMDescriptor, NVMModuleDescriptor, -} from "./EntryParsers"; +} from "./EntryParsers.js"; export enum NVMEntryType { NVMModuleSize, diff --git a/packages/nvmedit/src/nvm500/NVMParser.ts b/packages/nvmedit/src/nvm500/NVMParser.ts index 1770a680c706..de026f27b063 100644 --- a/packages/nvmedit/src/nvm500/NVMParser.ts +++ b/packages/nvmedit/src/nvm500/NVMParser.ts @@ -1,8 +1,8 @@ import { type CommandClasses } from "@zwave-js/core/safe"; -import { type Route } from "../lib/common/routeCache"; -import { type SUCUpdateEntry } from "../lib/common/sucUpdateEntry"; -import { type NVM500NodeInfo } from "../lib/nvm500/EntryParsers"; -import { type NVM500Impl } from "../lib/nvm500/shared"; +import { type Route } from "../lib/common/routeCache.js"; +import { type SUCUpdateEntry } from "../lib/common/sucUpdateEntry.js"; +import { type NVM500NodeInfo } from "../lib/nvm500/EntryParsers.js"; +import { type NVM500Impl } from "../lib/nvm500/shared.js"; export interface NVM500JSON { // To distinguish between 700 and 500 series JSONs better diff --git a/packages/nvmedit/tsconfig.build.json b/packages/nvmedit/tsconfig.build.json index 0060030da691..1c12babeaa3a 100644 --- a/packages/nvmedit/tsconfig.build.json +++ b/packages/nvmedit/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/serial/ava.config.cjs b/packages/serial/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/serial/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/serial/package.json b/packages/serial/package.json index 80b9c7757c98..0351f40f6049 100644 --- a/packages/serial/package.json +++ b/packages/serial/package.json @@ -5,33 +5,34 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./serialapi": { "@@dev": "./src/index_serialapi.ts", - "types": "./build/index_serialapi.d.ts", - "default": "./build/index_serialapi.js" + "import": "./build/esm/index_serialapi.js", + "require": "./build/cjs/index_serialapi.js" }, "./mock": { "@@dev": "./src/index_mock.ts", - "types": "./build/index_mock.d.ts", - "default": "./build/index_mock.js" + "import": "./build/esm/index_mock.js", + "require": "./build/cjs/index_mock.js" }, "./package.json": "./package.json" }, "keywords": [], "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -53,13 +54,14 @@ "node": ">= 18" }, "scripts": { - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "dependencies": { "@serialport/stream": "^12.0.0", @@ -72,17 +74,17 @@ "winston": "^3.15.0" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@serialport/binding-mock": "^10.2.2", - "@serialport/bindings-interface": "*", + "@serialport/bindings-interface": "patch:@serialport/bindings-interface@npm%3A1.2.2#~/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch", "@types/node": "^18.19.63", "@types/sinon": "^17.0.3", "ansi-colors": "^4.1.3", - "ava": "^6.1.3", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", "sinon": "^19.0.2", - "typescript": "5.6.2" + "tsx": "^4.19.2", + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/serial/src/index.ts b/packages/serial/src/index.ts index 30ea53e36711..9721ee83f0e4 100644 --- a/packages/serial/src/index.ts +++ b/packages/serial/src/index.ts @@ -1,20 +1,20 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ -export { SerialLogger } from "./log/Logger"; -export type { SerialLogContext } from "./log/Logger_safe"; -export * from "./message/Constants"; -export * from "./message/Message"; -export * from "./message/MessageHeaders"; -export * from "./message/SuccessIndicator"; -export * from "./message/ZnifferMessages"; -export * from "./parsers/BootloaderParsers"; -export * from "./parsers/SerialAPIParser"; -export * from "./serialport/ZWaveSerialPort"; -export * from "./serialport/ZWaveSerialPortBase"; -export * from "./serialport/ZWaveSerialPortImplementation"; -export * from "./serialport/ZWaveSocket"; -export * from "./serialport/ZWaveSocketOptions"; -export * from "./zniffer/ZnifferSerialPort"; -export * from "./zniffer/ZnifferSerialPortBase"; -export * from "./zniffer/ZnifferSocket"; +export { SerialLogger } from "./log/Logger.js"; +export type { SerialLogContext } from "./log/Logger_safe.js"; +export * from "./message/Constants.js"; +export * from "./message/Message.js"; +export * from "./message/MessageHeaders.js"; +export * from "./message/SuccessIndicator.js"; +export * from "./message/ZnifferMessages.js"; +export * from "./parsers/BootloaderParsers.js"; +export * from "./parsers/SerialAPIParser.js"; +export * from "./serialport/ZWaveSerialPort.js"; +export * from "./serialport/ZWaveSerialPortBase.js"; +export * from "./serialport/ZWaveSerialPortImplementation.js"; +export * from "./serialport/ZWaveSocket.js"; +export * from "./serialport/ZWaveSocketOptions.js"; +export * from "./zniffer/ZnifferSerialPort.js"; +export * from "./zniffer/ZnifferSerialPortBase.js"; +export * from "./zniffer/ZnifferSocket.js"; -export * from "./index_serialapi"; +export * from "./index_serialapi.js"; diff --git a/packages/serial/src/index_mock.ts b/packages/serial/src/index_mock.ts index f8a96856b1d9..e077354e3e17 100644 --- a/packages/serial/src/index_mock.ts +++ b/packages/serial/src/index_mock.ts @@ -1,3 +1,3 @@ -export * from "./mock/MockSerialPort"; -export * from "./mock/SerialPortBindingMock"; -export * from "./mock/SerialPortMock"; +export * from "./mock/MockSerialPort.js"; +export * from "./mock/SerialPortBindingMock.js"; +export * from "./mock/SerialPortMock.js"; diff --git a/packages/serial/src/index_safe.ts b/packages/serial/src/index_safe.ts index 861445cd1ced..53faed97feb5 100644 --- a/packages/serial/src/index_safe.ts +++ b/packages/serial/src/index_safe.ts @@ -1,6 +1,6 @@ /* @forbiddenImports external */ -export type { SerialLogContext } from "./log/Logger_safe"; -export * from "./message/Constants"; -export * from "./message/MessageHeaders"; -export * from "./message/SuccessIndicator"; +export type { SerialLogContext } from "./log/Logger_safe.js"; +export * from "./message/Constants.js"; +export * from "./message/MessageHeaders.js"; +export * from "./message/SuccessIndicator.js"; diff --git a/packages/serial/src/index_serialapi.ts b/packages/serial/src/index_serialapi.ts index cde76496ee47..33b3630bc492 100644 --- a/packages/serial/src/index_serialapi.ts +++ b/packages/serial/src/index_serialapi.ts @@ -1,56 +1,56 @@ -export * from "./serialapi/application/ApplicationCommandRequest"; -export * from "./serialapi/application/ApplicationUpdateRequest"; -export * from "./serialapi/application/BridgeApplicationCommandRequest"; -export * from "./serialapi/application/SerialAPIStartedRequest"; -export * from "./serialapi/application/ShutdownMessages"; -export * from "./serialapi/capability/GetControllerCapabilitiesMessages"; -export * from "./serialapi/capability/GetControllerVersionMessages"; -export * from "./serialapi/capability/GetLongRangeNodesMessages"; -export * from "./serialapi/capability/GetProtocolVersionMessages"; -export * from "./serialapi/capability/GetSerialApiCapabilitiesMessages"; -export * from "./serialapi/capability/GetSerialApiInitDataMessages"; -export * from "./serialapi/capability/HardResetRequest"; -export * from "./serialapi/capability/LongRangeChannelMessages"; -export * from "./serialapi/capability/SerialAPISetupMessages"; -export * from "./serialapi/capability/SetApplicationNodeInformationRequest"; -export * from "./serialapi/capability/SetLongRangeShadowNodeIDsRequest"; -export * from "./serialapi/memory/GetControllerIdMessages"; -export * from "./serialapi/misc/GetBackgroundRSSIMessages"; -export * from "./serialapi/misc/SetRFReceiveModeMessages"; -export * from "./serialapi/misc/SetSerialApiTimeoutsMessages"; -export * from "./serialapi/misc/SoftResetRequest"; -export * from "./serialapi/misc/WatchdogMessages"; -export * from "./serialapi/network-mgmt/AddNodeToNetworkRequest"; -export * from "./serialapi/network-mgmt/AssignPriorityReturnRouteMessages"; -export * from "./serialapi/network-mgmt/AssignPrioritySUCReturnRouteMessages"; -export * from "./serialapi/network-mgmt/AssignReturnRouteMessages"; -export * from "./serialapi/network-mgmt/AssignSUCReturnRouteMessages"; -export * from "./serialapi/network-mgmt/DeleteReturnRouteMessages"; -export * from "./serialapi/network-mgmt/DeleteSUCReturnRouteMessages"; -export * from "./serialapi/network-mgmt/GetNodeProtocolInfoMessages"; -export * from "./serialapi/network-mgmt/GetPriorityRouteMessages"; -export * from "./serialapi/network-mgmt/GetRoutingInfoMessages"; -export * from "./serialapi/network-mgmt/GetSUCNodeIdMessages"; -export * from "./serialapi/network-mgmt/IsFailedNodeMessages"; -export * from "./serialapi/network-mgmt/RemoveFailedNodeMessages"; -export * from "./serialapi/network-mgmt/RemoveNodeFromNetworkRequest"; -export * from "./serialapi/network-mgmt/ReplaceFailedNodeRequest"; -export * from "./serialapi/network-mgmt/RequestNodeInfoMessages"; -export * from "./serialapi/network-mgmt/RequestNodeNeighborUpdateMessages"; -export * from "./serialapi/network-mgmt/SetLearnModeMessages"; -export * from "./serialapi/network-mgmt/SetPriorityRouteMessages"; -export * from "./serialapi/network-mgmt/SetSUCNodeIDMessages"; -export * from "./serialapi/nvm/ExtNVMReadLongBufferMessages"; -export * from "./serialapi/nvm/ExtNVMReadLongByteMessages"; -export * from "./serialapi/nvm/ExtNVMWriteLongBufferMessages"; -export * from "./serialapi/nvm/ExtNVMWriteLongByteMessages"; -export * from "./serialapi/nvm/ExtendedNVMOperationsMessages"; -export * from "./serialapi/nvm/FirmwareUpdateNVMMessages"; -export * from "./serialapi/nvm/GetNVMIdMessages"; -export * from "./serialapi/nvm/NVMOperationsMessages"; -export * from "./serialapi/transport/SendDataBridgeMessages"; -export * from "./serialapi/transport/SendDataMessages"; -export * from "./serialapi/transport/SendDataShared"; -export * from "./serialapi/transport/SendTestFrameMessages"; +export * from "./serialapi/application/ApplicationCommandRequest.js"; +export * from "./serialapi/application/ApplicationUpdateRequest.js"; +export * from "./serialapi/application/BridgeApplicationCommandRequest.js"; +export * from "./serialapi/application/SerialAPIStartedRequest.js"; +export * from "./serialapi/application/ShutdownMessages.js"; +export * from "./serialapi/capability/GetControllerCapabilitiesMessages.js"; +export * from "./serialapi/capability/GetControllerVersionMessages.js"; +export * from "./serialapi/capability/GetLongRangeNodesMessages.js"; +export * from "./serialapi/capability/GetProtocolVersionMessages.js"; +export * from "./serialapi/capability/GetSerialApiCapabilitiesMessages.js"; +export * from "./serialapi/capability/GetSerialApiInitDataMessages.js"; +export * from "./serialapi/capability/HardResetRequest.js"; +export * from "./serialapi/capability/LongRangeChannelMessages.js"; +export * from "./serialapi/capability/SerialAPISetupMessages.js"; +export * from "./serialapi/capability/SetApplicationNodeInformationRequest.js"; +export * from "./serialapi/capability/SetLongRangeShadowNodeIDsRequest.js"; +export * from "./serialapi/memory/GetControllerIdMessages.js"; +export * from "./serialapi/misc/GetBackgroundRSSIMessages.js"; +export * from "./serialapi/misc/SetRFReceiveModeMessages.js"; +export * from "./serialapi/misc/SetSerialApiTimeoutsMessages.js"; +export * from "./serialapi/misc/SoftResetRequest.js"; +export * from "./serialapi/misc/WatchdogMessages.js"; +export * from "./serialapi/network-mgmt/AddNodeToNetworkRequest.js"; +export * from "./serialapi/network-mgmt/AssignPriorityReturnRouteMessages.js"; +export * from "./serialapi/network-mgmt/AssignPrioritySUCReturnRouteMessages.js"; +export * from "./serialapi/network-mgmt/AssignReturnRouteMessages.js"; +export * from "./serialapi/network-mgmt/AssignSUCReturnRouteMessages.js"; +export * from "./serialapi/network-mgmt/DeleteReturnRouteMessages.js"; +export * from "./serialapi/network-mgmt/DeleteSUCReturnRouteMessages.js"; +export * from "./serialapi/network-mgmt/GetNodeProtocolInfoMessages.js"; +export * from "./serialapi/network-mgmt/GetPriorityRouteMessages.js"; +export * from "./serialapi/network-mgmt/GetRoutingInfoMessages.js"; +export * from "./serialapi/network-mgmt/GetSUCNodeIdMessages.js"; +export * from "./serialapi/network-mgmt/IsFailedNodeMessages.js"; +export * from "./serialapi/network-mgmt/RemoveFailedNodeMessages.js"; +export * from "./serialapi/network-mgmt/RemoveNodeFromNetworkRequest.js"; +export * from "./serialapi/network-mgmt/ReplaceFailedNodeRequest.js"; +export * from "./serialapi/network-mgmt/RequestNodeInfoMessages.js"; +export * from "./serialapi/network-mgmt/RequestNodeNeighborUpdateMessages.js"; +export * from "./serialapi/network-mgmt/SetLearnModeMessages.js"; +export * from "./serialapi/network-mgmt/SetPriorityRouteMessages.js"; +export * from "./serialapi/network-mgmt/SetSUCNodeIDMessages.js"; +export * from "./serialapi/nvm/ExtNVMReadLongBufferMessages.js"; +export * from "./serialapi/nvm/ExtNVMReadLongByteMessages.js"; +export * from "./serialapi/nvm/ExtNVMWriteLongBufferMessages.js"; +export * from "./serialapi/nvm/ExtNVMWriteLongByteMessages.js"; +export * from "./serialapi/nvm/ExtendedNVMOperationsMessages.js"; +export * from "./serialapi/nvm/FirmwareUpdateNVMMessages.js"; +export * from "./serialapi/nvm/GetNVMIdMessages.js"; +export * from "./serialapi/nvm/NVMOperationsMessages.js"; +export * from "./serialapi/transport/SendDataBridgeMessages.js"; +export * from "./serialapi/transport/SendDataMessages.js"; +export * from "./serialapi/transport/SendDataShared.js"; +export * from "./serialapi/transport/SendTestFrameMessages.js"; -export * from "./serialapi/utils"; +export * from "./serialapi/utils.js"; diff --git a/packages/serial/src/log/Logger.ts b/packages/serial/src/log/Logger.ts index cfffa8087d99..9a652381c2dd 100644 --- a/packages/serial/src/log/Logger.ts +++ b/packages/serial/src/log/Logger.ts @@ -5,12 +5,12 @@ import { getDirectionPrefix, } from "@zwave-js/core"; import { buffer2hex, getEnumMemberName, num2hex } from "@zwave-js/shared"; -import { MessageHeaders } from "../message/MessageHeaders"; +import { MessageHeaders } from "../message/MessageHeaders.js"; import { SERIAL_LABEL, SERIAL_LOGLEVEL, type SerialLogContext, -} from "./Logger_safe"; +} from "./Logger_safe.js"; export class SerialLogger extends ZWaveLoggerBase { constructor(loggers: ZWaveLogContainer) { diff --git a/packages/serial/src/message/Constants.ts b/packages/serial/src/message/Constants.ts index a156a492d5bc..1ba163913334 100644 --- a/packages/serial/src/message/Constants.ts +++ b/packages/serial/src/message/Constants.ts @@ -1,4 +1,4 @@ -import { ZnifferMessageHeaders } from "./MessageHeaders"; +import { ZnifferMessageHeaders } from "./MessageHeaders.js"; /** Indicates the type of a data message */ export enum MessageType { diff --git a/packages/serial/src/message/Message.test.ts b/packages/serial/src/message/Message.test.ts index 8bea7d0ef2e4..0af87b1f1a41 100644 --- a/packages/serial/src/message/Message.test.ts +++ b/packages/serial/src/message/Message.test.ts @@ -1,9 +1,9 @@ import { ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; import { createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared"; -import test from "ava"; -import { FunctionType, MessageType } from "./Constants"; -import { Message, messageTypes } from "./Message"; +import { test } from "vitest"; +import { FunctionType, MessageType } from "./Constants.js"; +import { Message, messageTypes } from "./Message.js"; test("should deserialize and serialize correctly", (t) => { // actual messages from OZW @@ -40,7 +40,7 @@ test("should deserialize and serialize correctly", (t) => { ]; for (const original of okayMessages) { const parsed = Message.parse(original, {} as any); - t.deepEqual(parsed.serialize({} as any), original); + t.expect(parsed.serialize({} as any)).toStrictEqual(original); } }); @@ -51,7 +51,7 @@ test("should serialize correctly when the payload is null", (t) => { type: MessageType.Request, functionType: 0xff as any, }); - t.deepEqual(message.serialize({} as any), expected); + t.expect(message.serialize({} as any)).toStrictEqual(expected); }); test("should throw the correct error when parsing a faulty message", (t) => { @@ -90,7 +90,7 @@ test("should throw the correct error when parsing a faulty message", (t) => { ]; for (const [message, msg, code] of brokenMessages) { assertZWaveError( - t, + t.expect, () => Message.parse(message, {} as any), { messageMatches: msg, @@ -148,23 +148,22 @@ test("toJSON() should return a semi-readable JSON representation", (t) => { payload: "aabbcc", }; - t.deepEqual(msg1.toJSON(), json1); - t.deepEqual(msg2.toJSON(), json2); - t.deepEqual(msg3.toJSON(), json3); - t.deepEqual(msg4.toJSON(), json4); + t.expect(msg1.toJSON()).toStrictEqual(json1); + t.expect(msg2.toJSON()).toStrictEqual(json2); + t.expect(msg3.toJSON()).toStrictEqual(json3); + t.expect(msg4.toJSON()).toStrictEqual(json4); }); test("Parsing a buffer with an unknown function type returns an unspecified `Message` instance", (t) => { const unknown = Bytes.from([0x01, 0x03, 0x00, 0x00, 0xfc]); - t.is( + t.expect( Message.parse(unknown, {} as any).constructor, - Message, - ); + ).toBe(Message); }); test(`the constructor should throw when no message type is specified`, (t) => { assertZWaveError( - t, + t.expect, () => new Message({ functionType: 0xff as any }), { errorCode: ZWaveErrorCodes.Argument_Invalid, @@ -175,7 +174,7 @@ test(`the constructor should throw when no message type is specified`, (t) => { @messageTypes(undefined as any, 0xff as any) class FakeMessageWithoutMessageType extends Message {} - assertZWaveError(t, () => new FakeMessageWithoutMessageType(), { + assertZWaveError(t.expect, () => new FakeMessageWithoutMessageType(), { errorCode: ZWaveErrorCodes.Argument_Invalid, messageMatches: /message type/i, }); @@ -183,7 +182,7 @@ test(`the constructor should throw when no message type is specified`, (t) => { test(`the constructor should throw when no function type is specified`, (t) => { assertZWaveError( - t, + t.expect, () => new Message({ type: MessageType.Request }), { errorCode: ZWaveErrorCodes.Argument_Invalid, @@ -194,7 +193,7 @@ test(`the constructor should throw when no function type is specified`, (t) => { @messageTypes(MessageType.Request, undefined as any) class FakeMessageWithoutFunctionType extends Message {} - assertZWaveError(t, () => new FakeMessageWithoutFunctionType(), { + assertZWaveError(t.expect, () => new FakeMessageWithoutFunctionType(), { errorCode: ZWaveErrorCodes.Argument_Invalid, messageMatches: /function type/i, }); @@ -206,7 +205,7 @@ test("tryGetNode() returns undefined when the controller is not initialized yet" type: MessageType.Request, functionType: 0xff as any, }); - t.is(msg.tryGetNode(host), undefined); + t.expect(msg.tryGetNode(host)).toBeUndefined(); }); test("tryGetNode() returns undefined when the message is no node query", (t) => { @@ -215,7 +214,7 @@ test("tryGetNode() returns undefined when the message is no node query", (t) => type: MessageType.Request, functionType: 0xff as any, }); - t.is(msg.tryGetNode(host), undefined); + t.expect(msg.tryGetNode(host)).toBeUndefined(); }); test("tryGetNode() returns the associated node otherwise", (t) => { @@ -229,9 +228,9 @@ test("tryGetNode() returns the associated node otherwise", (t) => { // This node exists (msg as any).nodeId = 1; - t.is(msg.tryGetNode(host), host.getNode(1)); + t.expect(msg.tryGetNode(host)).toBe(host.getNode(1)); // This one does (msg as any).nodeId = 2; - t.is(msg.tryGetNode(host), undefined); + t.expect(msg.tryGetNode(host)).toBeUndefined(); }); diff --git a/packages/serial/src/message/Message.ts b/packages/serial/src/message/Message.ts index 6d68bdebec7b..7946c5dcb94d 100644 --- a/packages/serial/src/message/Message.ts +++ b/packages/serial/src/message/Message.ts @@ -24,8 +24,8 @@ import { type TypedClassDecorator, } from "@zwave-js/shared/safe"; import { num2hex, staticExtends } from "@zwave-js/shared/safe"; -import { FunctionType, MessageType } from "./Constants"; -import { MessageHeaders } from "./MessageHeaders"; +import { FunctionType, MessageType } from "./Constants.js"; +import { MessageHeaders } from "./MessageHeaders.js"; export type MessageConstructor = typeof Message & { new (options: MessageBaseOptions): T; diff --git a/packages/serial/src/message/SuccessIndicator.ts b/packages/serial/src/message/SuccessIndicator.ts index 60064e9abdd3..7f91c24260f9 100644 --- a/packages/serial/src/message/SuccessIndicator.ts +++ b/packages/serial/src/message/SuccessIndicator.ts @@ -1,4 +1,4 @@ -import type { Message } from "./Message"; +import type { Message } from "./Message.js"; /** Should be implemented by Serial API responses and callbacks which indicate success of the operation */ export interface SuccessIndicator { diff --git a/packages/serial/src/message/ZnifferMessages.ts b/packages/serial/src/message/ZnifferMessages.ts index 7546d9933086..ce8edb15606c 100644 --- a/packages/serial/src/message/ZnifferMessages.ts +++ b/packages/serial/src/message/ZnifferMessages.ts @@ -13,7 +13,7 @@ import { ZnifferFrameType, ZnifferFunctionType, ZnifferMessageType, -} from "./Constants"; +} from "./Constants.js"; export type ZnifferMessageConstructor = & typeof ZnifferMessage diff --git a/packages/serial/src/mock/MockSerialPort.ts b/packages/serial/src/mock/MockSerialPort.ts index 4d10ceec8271..370272b8dd92 100644 --- a/packages/serial/src/mock/MockSerialPort.ts +++ b/packages/serial/src/mock/MockSerialPort.ts @@ -5,13 +5,13 @@ import { Mixin } from "@zwave-js/shared"; import { EventEmitter } from "node:events"; import { PassThrough } from "node:stream"; import sinon from "sinon"; -import { ZWaveSerialPort } from "../serialport/ZWaveSerialPort"; -import type { ZWaveSerialPortEventCallbacks } from "../serialport/ZWaveSerialPortBase"; +import { ZWaveSerialPort } from "../serialport/ZWaveSerialPort.js"; +import type { ZWaveSerialPortEventCallbacks } from "../serialport/ZWaveSerialPortBase.js"; import { MockBinding as SerialPortMockBinding, type MockPortBinding as SerialPortMockPortBinding, -} from "./SerialPortBindingMock"; -import { SerialPortMock } from "./SerialPortMock"; +} from "./SerialPortBindingMock.js"; +import { SerialPortMock } from "./SerialPortMock.js"; const instances = new Map(); diff --git a/packages/serial/src/mock/SerialPortMock.ts b/packages/serial/src/mock/SerialPortMock.ts index e03d10d0d741..b2144b78f3ad 100644 --- a/packages/serial/src/mock/SerialPortMock.ts +++ b/packages/serial/src/mock/SerialPortMock.ts @@ -9,7 +9,7 @@ import { import { MockBinding, type MockBindingInterface, -} from "./SerialPortBindingMock"; +} from "./SerialPortBindingMock.js"; export type SerialPortMockOpenOptions = Omit< OpenOptions, diff --git a/packages/serial/src/parsers/BootloaderParsers.ts b/packages/serial/src/parsers/BootloaderParsers.ts index 76c806d0ba88..e35a7d209584 100644 --- a/packages/serial/src/parsers/BootloaderParsers.ts +++ b/packages/serial/src/parsers/BootloaderParsers.ts @@ -1,6 +1,6 @@ import { Transform, type TransformCallback } from "node:stream"; -import type { SerialLogger } from "../log/Logger"; -import { XModemMessageHeaders } from "../message/MessageHeaders"; +import type { SerialLogger } from "../log/Logger.js"; +import { XModemMessageHeaders } from "../message/MessageHeaders.js"; export enum BootloaderChunkType { Error, diff --git a/packages/serial/src/parsers/SerialAPIParser.ts b/packages/serial/src/parsers/SerialAPIParser.ts index da3decdecd6e..c1afc92f08ac 100644 --- a/packages/serial/src/parsers/SerialAPIParser.ts +++ b/packages/serial/src/parsers/SerialAPIParser.ts @@ -1,7 +1,7 @@ import { Bytes, num2hex } from "@zwave-js/shared"; import { Transform, type TransformCallback } from "node:stream"; -import type { SerialLogger } from "../log/Logger"; -import { MessageHeaders } from "../message/MessageHeaders"; +import type { SerialLogger } from "../log/Logger.js"; +import { MessageHeaders } from "../message/MessageHeaders.js"; /** * Checks if there's enough data in the buffer to deserialize a complete message diff --git a/packages/serial/src/parsers/ZnifferParser.ts b/packages/serial/src/parsers/ZnifferParser.ts index c501ac0ac3a9..72d6171eee0c 100644 --- a/packages/serial/src/parsers/ZnifferParser.ts +++ b/packages/serial/src/parsers/ZnifferParser.ts @@ -1,8 +1,8 @@ import { Bytes } from "@zwave-js/shared"; import { Transform, type TransformCallback } from "node:stream"; -import type { SerialLogger } from "../log/Logger"; -import { ZnifferFrameType } from "../message/Constants"; -import { ZnifferMessageHeaders } from "../message/MessageHeaders"; +import type { SerialLogger } from "../log/Logger.js"; +import { ZnifferFrameType } from "../message/Constants.js"; +import { ZnifferMessageHeaders } from "../message/MessageHeaders.js"; /** Given a buffer that starts with SOF, this method returns the number of bytes the first message occupies in the buffer */ function getMessageLength(data: Uint8Array): number | undefined { diff --git a/packages/serial/src/serialapi/application/ApplicationCommandRequest.ts b/packages/serial/src/serialapi/application/ApplicationCommandRequest.ts index 2e8dda8176d5..ab932eb04229 100644 --- a/packages/serial/src/serialapi/application/ApplicationCommandRequest.ts +++ b/packages/serial/src/serialapi/application/ApplicationCommandRequest.ts @@ -22,7 +22,7 @@ import { priority, } from "@zwave-js/serial"; import { Bytes } from "@zwave-js/shared/safe"; -import { type MessageWithCC } from "../utils"; +import { type MessageWithCC } from "../utils.js"; export enum ApplicationCommandStatusFlags { RoutedBusy = 0b1, // A response route is locked by the application diff --git a/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.test.ts b/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.test.ts index 5da452cbf1c6..591b1fb3f1ed 100644 --- a/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.test.ts +++ b/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.test.ts @@ -1,11 +1,11 @@ // import "@zwave-js/cc"; import { Message } from "@zwave-js/serial"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; test("BridgeApplicationCommandRequest can be parsed without RSSI", async (t) => { // Repro for https://github.com/zwave-js/node-zwave-js/issues/4335 - t.notThrows(() => + t.expect(() => Message.parse( Bytes.from( "011200a80001020a320221340000000000000069", @@ -13,5 +13,5 @@ test("BridgeApplicationCommandRequest can be parsed without RSSI", async (t) => ), {} as any, ) - ); + ).not.toThrow(); }); diff --git a/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.ts b/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.ts index 5929319ded0a..ff959a65fd00 100644 --- a/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.ts +++ b/packages/serial/src/serialapi/application/BridgeApplicationCommandRequest.ts @@ -8,24 +8,29 @@ import { NODE_ID_BROADCAST_LR, type RSSI, RssiError, + ZWaveError, + ZWaveErrorCodes, + encodeNodeID, isLongRangeNodeId, parseNodeBitMask, parseNodeID, } from "@zwave-js/core"; +import { type CCEncodingContext } from "@zwave-js/host"; import { FunctionType, Message, type MessageBaseOptions, + type MessageEncodingContext, type MessageParsingContext, type MessageRaw, MessageType, messageTypes, priority, } from "@zwave-js/serial"; -import { getEnumMemberName } from "@zwave-js/shared"; -import { tryParseRSSI } from "../transport/SendDataShared"; -import { type MessageWithCC } from "../utils"; -import { ApplicationCommandStatusFlags } from "./ApplicationCommandRequest"; +import { Bytes, getEnumMemberName } from "@zwave-js/shared"; +import { tryParseRSSI } from "../transport/SendDataShared.js"; +import { type MessageWithCC } from "../utils.js"; +import { ApplicationCommandStatusFlags } from "./ApplicationCommandRequest.js"; export type BridgeApplicationCommandRequestOptions = & ( @@ -163,7 +168,19 @@ export class BridgeApplicationCommandRequest extends Message public readonly ownNodeId: number; - public readonly serializedCC: Uint8Array | undefined; + public serializedCC: Uint8Array | undefined; + public serializeCC(ctx: CCEncodingContext): Uint8Array { + if (!this.serializedCC) { + if (!this.command) { + throw new ZWaveError( + `Cannot serialize a ${this.constructor.name} without a command`, + ZWaveErrorCodes.Argument_Invalid, + ); + } + this.serializedCC = this.command.serialize(ctx); + } + return this.serializedCC; + } // This needs to be writable or unwrapping MultiChannelCCs crashes public command: CommandClass | undefined; @@ -176,6 +193,60 @@ export class BridgeApplicationCommandRequest extends Message return this._nodeId ?? super.getNodeId(); } + public serialize(ctx: MessageEncodingContext): Bytes { + let rxStatus = 0; + if (this.routedBusy) { + rxStatus |= ApplicationCommandStatusFlags.RoutedBusy; + } + switch (this.frameType) { + case "multicast": + rxStatus |= ApplicationCommandStatusFlags.TypeMulti; + break; + case "broadcast": + rxStatus |= ApplicationCommandStatusFlags.TypeBroad; + break; + default: + rxStatus |= ApplicationCommandStatusFlags.TypeSingle; + } + if (this.isExploreFrame) { + rxStatus |= ApplicationCommandStatusFlags.Explore; + } + if (this.isForeignFrame) { + rxStatus |= ApplicationCommandStatusFlags.ForeignFrame; + } + if (this.fromForeignHomeId) { + rxStatus |= ApplicationCommandStatusFlags.ForeignHomeId; + } + const destinationNodeId = encodeNodeID( + typeof this.targetNodeId === "number" ? this.targetNodeId : 0, + ctx.nodeIdType, + ); + const sourceNodeId = encodeNodeID( + this.getNodeId() ?? 0, + ctx.nodeIdType, + ); + const serializedCC = this.serializeCC(ctx); + const multicastNodeMask = typeof this.targetNodeId === "number" + ? Uint8Array.from([0]) + : Uint8Array.from([this.targetNodeId.length, ...this.targetNodeId]); + + this.payload = Bytes.concat([ + [rxStatus], + destinationNodeId, + sourceNodeId, + [serializedCC.length], + serializedCC, + multicastNodeMask, + [RssiError.NotAvailable], + ]); + + if (this.rssi != undefined) { + this.payload.writeInt8(this.rssi, this.payload.length - 1); + } + + return super.serialize(ctx); + } + public toLogEntry(): MessageOrCCLogEntry { const message: MessageRecord = {}; if (this.frameType !== "singlecast") { diff --git a/packages/serial/src/serialapi/capability/SerialAPISetupMessages.test.ts b/packages/serial/src/serialapi/capability/SerialAPISetupMessages.test.ts index 9a246765b065..0e05f58b4cb3 100644 --- a/packages/serial/src/serialapi/capability/SerialAPISetupMessages.test.ts +++ b/packages/serial/src/serialapi/capability/SerialAPISetupMessages.test.ts @@ -1,7 +1,7 @@ import { Message } from "@zwave-js/serial"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; -import { SerialAPISetup_GetSupportedCommandsResponse } from "./SerialAPISetupMessages"; +import { test } from "vitest"; +import { SerialAPISetup_GetSupportedCommandsResponse } from "./SerialAPISetupMessages.js"; test("GetSupportedCommandsResponse with extended bitmask parses correctly (pre-7.19.1 encoding)", (t) => { const data = Bytes.from( @@ -13,14 +13,15 @@ test("GetSupportedCommandsResponse with extended bitmask parses correctly (pre-7 data, { sdkVersion: "7.19.0" } as any, ); - t.true(msg instanceof SerialAPISetup_GetSupportedCommandsResponse); + t.expect(msg instanceof SerialAPISetup_GetSupportedCommandsResponse).toBe( + true, + ); const supported = (msg as SerialAPISetup_GetSupportedCommandsResponse) .supportedCommands; - t.deepEqual( + t.expect( supported, - [0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x20, 0x40, 0x80], - ); + ).toStrictEqual([0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x20, 0x40, 0x80]); }); test("GetSupportedCommandsResponse with extended bitmask parses correctly (post-7.19.1 encoding)", (t) => { @@ -33,12 +34,13 @@ test("GetSupportedCommandsResponse with extended bitmask parses correctly (post- data, { sdkVersion: "7.19.1" } as any, ); - t.true(msg instanceof SerialAPISetup_GetSupportedCommandsResponse); + t.expect(msg instanceof SerialAPISetup_GetSupportedCommandsResponse).toBe( + true, + ); const supported = (msg as SerialAPISetup_GetSupportedCommandsResponse) .supportedCommands; - t.deepEqual( + t.expect( supported, - [0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x20, 0x40, 0x80], - ); + ).toStrictEqual([0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x20, 0x40, 0x80]); }); diff --git a/packages/serial/src/serialapi/misc/GetBackgroundRSSIMessages.ts b/packages/serial/src/serialapi/misc/GetBackgroundRSSIMessages.ts index 5d7770fc06de..2f156cc98ef1 100644 --- a/packages/serial/src/serialapi/misc/GetBackgroundRSSIMessages.ts +++ b/packages/serial/src/serialapi/misc/GetBackgroundRSSIMessages.ts @@ -16,7 +16,7 @@ import { messageTypes, priority, } from "@zwave-js/serial"; -import { parseRSSI, tryParseRSSI } from "../transport/SendDataShared"; +import { parseRSSI, tryParseRSSI } from "../transport/SendDataShared.js"; @messageTypes(MessageType.Request, FunctionType.GetBackgroundRSSI) @priority(MessagePriority.Normal) diff --git a/packages/serial/src/serialapi/network-mgmt/GetNodeProtocolInfoMessages.ts b/packages/serial/src/serialapi/network-mgmt/GetNodeProtocolInfoMessages.ts index f65e023edb95..434692725659 100644 --- a/packages/serial/src/serialapi/network-mgmt/GetNodeProtocolInfoMessages.ts +++ b/packages/serial/src/serialapi/network-mgmt/GetNodeProtocolInfoMessages.ts @@ -25,7 +25,7 @@ import { priority, } from "@zwave-js/serial"; import { Bytes } from "@zwave-js/shared"; -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; export interface GetNodeProtocolInfoRequestOptions { requestedNodeId: number; diff --git a/packages/serial/src/serialapi/network-mgmt/RequestNodeInfoMessages.ts b/packages/serial/src/serialapi/network-mgmt/RequestNodeInfoMessages.ts index 03eb51eb8c8f..f477ae24c8f7 100644 --- a/packages/serial/src/serialapi/network-mgmt/RequestNodeInfoMessages.ts +++ b/packages/serial/src/serialapi/network-mgmt/RequestNodeInfoMessages.ts @@ -22,7 +22,7 @@ import { Bytes } from "@zwave-js/shared"; import { ApplicationUpdateRequestNodeInfoReceived, ApplicationUpdateRequestNodeInfoRequestFailed, -} from "../application/ApplicationUpdateRequest"; +} from "../application/ApplicationUpdateRequest.js"; export interface RequestNodeInfoResponseOptions { wasSent: boolean; diff --git a/packages/serial/src/serialapi/transport/SendDataBridgeMessages.ts b/packages/serial/src/serialapi/transport/SendDataBridgeMessages.ts index 71bf919bffb8..65c68ba0f9d8 100644 --- a/packages/serial/src/serialapi/transport/SendDataBridgeMessages.ts +++ b/packages/serial/src/serialapi/transport/SendDataBridgeMessages.ts @@ -12,6 +12,7 @@ import { ZWaveError, ZWaveErrorCodes, encodeNodeID, + parseNodeID, } from "@zwave-js/core"; import type { CCEncodingContext } from "@zwave-js/host"; import type { @@ -32,12 +33,16 @@ import { priority, } from "@zwave-js/serial"; import { Bytes, getEnumMemberName, num2hex } from "@zwave-js/shared"; -import { clamp } from "alcalzone-shared/math"; -import { ApplicationCommandRequest } from "../application/ApplicationCommandRequest"; -import { BridgeApplicationCommandRequest } from "../application/BridgeApplicationCommandRequest"; -import { type MessageWithCC, containsCC } from "../utils"; -import { MAX_SEND_ATTEMPTS } from "./SendDataMessages"; -import { parseTXReport, txReportToMessageRecord } from "./SendDataShared"; +import { clamp } from "alcalzone-shared/math/index.js"; +import { ApplicationCommandRequest } from "../application/ApplicationCommandRequest.js"; +import { BridgeApplicationCommandRequest } from "../application/BridgeApplicationCommandRequest.js"; +import { type MessageWithCC, containsCC } from "../utils.js"; +import { MAX_SEND_ATTEMPTS } from "./SendDataMessages.js"; +import { + encodeTXReport, + parseTXReport, + txReportToMessageRecord, +} from "./SendDataShared.js"; @messageTypes(MessageType.Request, FunctionType.SendDataBridge) @priority(MessagePriority.Normal) @@ -107,6 +112,39 @@ export class SendDataBridgeRequest } } + public static from( + raw: MessageRaw, + ctx: MessageParsingContext, + ): SendDataBridgeRequestBase { + let offset = 0; + let parseResult = parseNodeID(raw.payload, ctx.nodeIdType); + const sourceNodeId = parseResult.nodeId; + offset += parseResult.bytesRead; + + parseResult = parseNodeID(raw.payload, ctx.nodeIdType, offset); + const destinationNodeId = parseResult.nodeId; + offset += parseResult.bytesRead; + + const ccLength = raw.payload[offset++]; + const serializedCC = raw.payload.slice(offset, offset + ccLength); + offset += ccLength; + + const transmitOptions = raw.payload[offset++]; + + // The route field is unused + offset += 4; + + const callbackId = raw.payload[offset++]; + + return new this({ + sourceNodeId, + nodeId: destinationNodeId, + serializedCC, + transmitOptions, + callbackId, + }); + } + /** Which Node ID this command originates from */ public sourceNodeId: number; @@ -254,6 +292,19 @@ export class SendDataBridgeRequestTransmitReport return this.transmitStatus === TransmitStatus.OK; } + public serialize(ctx: MessageEncodingContext): Bytes { + this.assertCallbackId(); + this.payload = Bytes.from([this.callbackId, this.transmitStatus]); + if (this.txReport) { + this.payload = Bytes.concat([ + this.payload, + encodeTXReport(this.txReport), + ]); + } + + return super.serialize(ctx); + } + public toLogEntry(): MessageOrCCLogEntry { return { ...super.toLogEntry(), @@ -392,6 +443,44 @@ export class SendDataMulticastBridgeRequest< } } + public static from( + raw: MessageRaw, + ctx: MessageParsingContext, + ): SendDataMulticastBridgeRequest { + const { nodeId: sourceNodeId, bytesRead } = parseNodeID( + raw.payload, + ctx.nodeIdType, + ); + let offset = bytesRead; + + const destinationNodeIdCount = raw.payload[offset++]; + const nodeIds: number[] = []; + for (let i = 0; i < destinationNodeIdCount; i++) { + const { nodeId, bytesRead } = parseNodeID( + raw.payload, + ctx.nodeIdType, + offset, + ); + nodeIds.push(nodeId); + offset += bytesRead; + } + + const ccLength = raw.payload[offset++]; + const serializedCC = raw.payload.slice(offset, offset + ccLength); + offset += ccLength; + + const transmitOptions = raw.payload[offset++]; + const callbackId = raw.payload[offset++]; + + return new this({ + sourceNodeId, + nodeIds: nodeIds as MulticastDestination, + serializedCC, + transmitOptions, + callbackId, + }); + } + /** Which Node ID this command originates from */ public sourceNodeId: number; diff --git a/packages/serial/src/serialapi/transport/SendDataMessages.ts b/packages/serial/src/serialapi/transport/SendDataMessages.ts index ec90059df1f1..23c423182419 100644 --- a/packages/serial/src/serialapi/transport/SendDataMessages.ts +++ b/packages/serial/src/serialapi/transport/SendDataMessages.ts @@ -32,16 +32,16 @@ import { priority, } from "@zwave-js/serial"; import { Bytes, getEnumMemberName, num2hex } from "@zwave-js/shared"; -import { clamp } from "alcalzone-shared/math"; -import { ApplicationCommandRequest } from "../application/ApplicationCommandRequest"; -import { BridgeApplicationCommandRequest } from "../application/BridgeApplicationCommandRequest"; -import { type MessageWithCC, containsCC } from "../utils"; +import { clamp } from "alcalzone-shared/math/index.js"; +import { ApplicationCommandRequest } from "../application/ApplicationCommandRequest.js"; +import { BridgeApplicationCommandRequest } from "../application/BridgeApplicationCommandRequest.js"; +import { type MessageWithCC, containsCC } from "../utils.js"; import { encodeTXReport, parseTXReport, serializableTXReportToTXReport, txReportToMessageRecord, -} from "./SendDataShared"; +} from "./SendDataShared.js"; export const MAX_SEND_ATTEMPTS = 5; diff --git a/packages/serial/src/serialapi/transport/SendDataShared.ts b/packages/serial/src/serialapi/transport/SendDataShared.ts index eb63dba41ab6..0190e1072eeb 100644 --- a/packages/serial/src/serialapi/transport/SendDataShared.ts +++ b/packages/serial/src/serialapi/transport/SendDataShared.ts @@ -12,24 +12,24 @@ import { stripUndefined, } from "@zwave-js/core/safe"; import { Bytes } from "@zwave-js/shared/safe"; -import { AssignPriorityReturnRouteRequestTransmitReport } from "../network-mgmt/AssignPriorityReturnRouteMessages"; -import { AssignPrioritySUCReturnRouteRequestTransmitReport } from "../network-mgmt/AssignPrioritySUCReturnRouteMessages"; -import { AssignReturnRouteRequestTransmitReport } from "../network-mgmt/AssignReturnRouteMessages"; -import { AssignSUCReturnRouteRequestTransmitReport } from "../network-mgmt/AssignSUCReturnRouteMessages"; -import { DeleteReturnRouteRequestTransmitReport } from "../network-mgmt/DeleteReturnRouteMessages"; -import { DeleteSUCReturnRouteRequestTransmitReport } from "../network-mgmt/DeleteSUCReturnRouteMessages"; +import { AssignPriorityReturnRouteRequestTransmitReport } from "../network-mgmt/AssignPriorityReturnRouteMessages.js"; +import { AssignPrioritySUCReturnRouteRequestTransmitReport } from "../network-mgmt/AssignPrioritySUCReturnRouteMessages.js"; +import { AssignReturnRouteRequestTransmitReport } from "../network-mgmt/AssignReturnRouteMessages.js"; +import { AssignSUCReturnRouteRequestTransmitReport } from "../network-mgmt/AssignSUCReturnRouteMessages.js"; +import { DeleteReturnRouteRequestTransmitReport } from "../network-mgmt/DeleteReturnRouteMessages.js"; +import { DeleteSUCReturnRouteRequestTransmitReport } from "../network-mgmt/DeleteSUCReturnRouteMessages.js"; import { SendDataBridgeRequest, SendDataBridgeRequestTransmitReport, SendDataMulticastBridgeRequest, SendDataMulticastBridgeRequestTransmitReport, -} from "./SendDataBridgeMessages"; +} from "./SendDataBridgeMessages.js"; import { SendDataMulticastRequest, SendDataMulticastRequestTransmitReport, SendDataRequest, SendDataRequestTransmitReport, -} from "./SendDataMessages"; +} from "./SendDataMessages.js"; export type SendDataMessage = | SendDataRequest diff --git a/packages/serial/src/serialapi/utils.ts b/packages/serial/src/serialapi/utils.ts index 61f7be63ba43..0f7ccc9054fd 100644 --- a/packages/serial/src/serialapi/utils.ts +++ b/packages/serial/src/serialapi/utils.ts @@ -1,9 +1,12 @@ import { CommandClass } from "@zwave-js/cc"; import { type Message } from "@zwave-js/serial"; import { isUint8Array } from "@zwave-js/shared"; -import { ApplicationCommandRequest } from "./application/ApplicationCommandRequest"; -import { BridgeApplicationCommandRequest } from "./application/BridgeApplicationCommandRequest"; -import { type SendDataMessage, isSendData } from "./transport/SendDataShared"; +import { ApplicationCommandRequest } from "./application/ApplicationCommandRequest.js"; +import { BridgeApplicationCommandRequest } from "./application/BridgeApplicationCommandRequest.js"; +import { + type SendDataMessage, + isSendData, +} from "./transport/SendDataShared.js"; export type CommandRequest = | ApplicationCommandRequest diff --git a/packages/serial/src/serialport/ZWaveSerialPort.test.ts b/packages/serial/src/serialport/ZWaveSerialPort.test.ts index 698897b0cd55..1e7a1a0af814 100644 --- a/packages/serial/src/serialport/ZWaveSerialPort.test.ts +++ b/packages/serial/src/serialport/ZWaveSerialPort.test.ts @@ -1,20 +1,18 @@ import { Bytes } from "@zwave-js/shared/safe"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; +import { wait } from "alcalzone-shared/async/index.js"; import { PassThrough } from "node:stream"; import sinon from "sinon"; -import { MessageHeaders } from "../message/MessageHeaders"; -import { createAndOpenMockedZWaveSerialPort } from "../mock/MockSerialPort"; -import type { MockPortBinding } from "../mock/SerialPortBindingMock"; -import type { ZWaveSerialPort } from "./ZWaveSerialPort"; +import { afterEach, beforeEach, test } from "vitest"; +import { MessageHeaders } from "../message/MessageHeaders.js"; +import { createAndOpenMockedZWaveSerialPort } from "../mock/MockSerialPort.js"; +import type { MockPortBinding } from "../mock/SerialPortBindingMock.js"; +import type { ZWaveSerialPort } from "./ZWaveSerialPort.js"; interface TestContext { port: ZWaveSerialPort; binding: MockPortBinding; } -const test = ava as TestFn; - async function waitForData(port: { once: (event: "data", callback: (data: any) => void) => any; }): Promise< @@ -25,11 +23,11 @@ async function waitForData(port: { }); } -test.beforeEach(async (t) => { +beforeEach(async (t) => { t.context = await createAndOpenMockedZWaveSerialPort("/dev/zwavetest"); }); -test.afterEach.always(async (t) => { +afterEach(async (t) => { const port = t.context.port; port.removeAllListeners(); if (port.isOpen) await port.close(); @@ -37,13 +35,13 @@ test.afterEach.always(async (t) => { test("isOpen returns true after opening", async (t) => { const { port } = t.context; - t.true(port.isOpen); + t.expect(port.isOpen).toBe(true); }); test("isOpen returns false after closing", async (t) => { const { port } = t.context; await port.close(); - t.false(port.isOpen); + t.expect(port.isOpen).toBe(false); }); test("passes written data through unchanged", async (t) => { @@ -54,31 +52,30 @@ test("passes written data through unchanged", async (t) => { ]; for (const buffer of buffers) { await port.writeAsync(buffer); - t.deepEqual(binding.lastWrite, buffer); + t.expect(binding.lastWrite).toStrictEqual(buffer); } }); test("write rejects if the port is not open", async (t) => { const { port } = t.context; await port.close(); - await t.throwsAsync(() => - port.writeAsync(Bytes.from([MessageHeaders.ACK])) - ); + await t.expect(() => port.writeAsync(Bytes.from([MessageHeaders.ACK]))) + .rejects.toThrowError(); }); test("emit an event for each single-byte message that was read", async (t) => { const { port, binding } = t.context; binding.emitData(Bytes.from([MessageHeaders.ACK])); let data = await waitForData(port); - t.deepEqual(data, MessageHeaders.ACK); + t.expect(data).toStrictEqual(MessageHeaders.ACK); binding.emitData(Bytes.from([MessageHeaders.CAN])); data = await waitForData(port); - t.deepEqual(data, MessageHeaders.CAN); + t.expect(data).toStrictEqual(MessageHeaders.CAN); binding.emitData(Bytes.from([MessageHeaders.NAK])); data = await waitForData(port); - t.deepEqual(data, MessageHeaders.NAK); + t.expect(data).toStrictEqual(MessageHeaders.NAK); }); test("emits a series of events when multiple single-byte messages are received", async (t) => { @@ -95,9 +92,9 @@ test("emits a series of events when multiple single-byte messages are received", return new Promise((resolve) => { port.on("data", (data) => { count++; - if (count === 1) t.is(data, MessageHeaders.ACK); - if (count === 2) t.is(data, MessageHeaders.CAN); - if (count === 3) t.is(data, MessageHeaders.NAK); + if (count === 1) t.expect(data).toBe(MessageHeaders.ACK); + if (count === 2) t.expect(data).toBe(MessageHeaders.CAN); + if (count === 3) t.expect(data).toBe(MessageHeaders.NAK); if (count === 3) resolve(); }); @@ -122,9 +119,9 @@ test("skips all invalid/unexpected data", async (t) => { return new Promise((resolve) => { port.on("data", (data) => { count++; - if (count === 1) t.is(data, MessageHeaders.ACK); - if (count === 2) t.is(data, MessageHeaders.CAN); - if (count === 3) t.is(data, MessageHeaders.ACK); + if (count === 1) t.expect(data).toBe(MessageHeaders.ACK); + if (count === 2) t.expect(data).toBe(MessageHeaders.CAN); + if (count === 3) t.expect(data).toBe(MessageHeaders.ACK); if (count === 3) resolve(); }); @@ -151,9 +148,9 @@ test("skips all invalid/unexpected data (test 2)", async (t) => { return new Promise((resolve) => { port.on("data", (data) => { count++; - if (count === 1) t.is(data, MessageHeaders.ACK); - if (count === 2) t.is(data, MessageHeaders.CAN); - if (count === 3) t.is(data, MessageHeaders.NAK); + if (count === 1) t.expect(data).toBe(MessageHeaders.ACK); + if (count === 2) t.expect(data).toBe(MessageHeaders.CAN); + if (count === 3) t.expect(data).toBe(MessageHeaders.NAK); if (count === 3) resolve(); }); @@ -173,7 +170,7 @@ test("emits a buffer when a message is received", async (t) => { binding.emitData(data); const received = await waitForData(port); - t.deepEqual(received, data); + t.expect(received).toStrictEqual(data); }); test("may be consumed with an async iterator", async (t) => { @@ -192,9 +189,9 @@ test("may be consumed with an async iterator", async (t) => { let count = 0; for await (const msg of port) { count++; - if (count === 1) t.is(msg, MessageHeaders.ACK); - if (count === 2) t.is(msg, MessageHeaders.CAN); - if (count === 3) t.is(msg, MessageHeaders.ACK); + if (count === 1) t.expect(msg).toBe(MessageHeaders.ACK); + if (count === 2) t.expect(msg).toBe(MessageHeaders.CAN); + if (count === 3) t.expect(msg).toBe(MessageHeaders.ACK); if (count === 3) break; } }); @@ -207,10 +204,10 @@ test("can be piped into", async (t) => { return new Promise((resolve) => { const data = Bytes.from([1, 2, 3, 4, 5]); passThrough.write(data, (err) => { - t.falsy(err); + t.expect(err).toBeFalsy(); // I see no better way of forcing the write to bubble through the streams setTimeout(() => { - t.deepEqual(binding.lastWrite, data); + t.expect(binding.lastWrite).toStrictEqual(data); resolve(); }, 1); }); @@ -227,7 +224,7 @@ test("can be piped to a reader", async (t) => { binding.emitData(expected); const data = await waitForData(stream); - t.deepEqual(data, expected); + t.expect(data).toStrictEqual(expected); }); test("can be unpiped again", async (t) => { @@ -244,5 +241,5 @@ test("can be unpiped again", async (t) => { await wait(1); - t.is(spy.callCount, 0); + t.expect(spy.callCount).toBe(0); }); diff --git a/packages/serial/src/serialport/ZWaveSerialPort.ts b/packages/serial/src/serialport/ZWaveSerialPort.ts index 4c5fae05d962..0cb6feed590a 100644 --- a/packages/serial/src/serialport/ZWaveSerialPort.ts +++ b/packages/serial/src/serialport/ZWaveSerialPort.ts @@ -4,8 +4,8 @@ import { type ZWaveLogContainer, } from "@zwave-js/core"; import { SerialPort } from "serialport"; -import type { DisconnectError } from "./DisconnectError"; -import { ZWaveSerialPortBase } from "./ZWaveSerialPortBase"; +import type { DisconnectError } from "./DisconnectError.js"; +import { ZWaveSerialPortBase } from "./ZWaveSerialPortBase.js"; /** The default version of the Z-Wave serial binding that works using node-serialport */ export class ZWaveSerialPort extends ZWaveSerialPortBase { diff --git a/packages/serial/src/serialport/ZWaveSerialPortBase.ts b/packages/serial/src/serialport/ZWaveSerialPortBase.ts index a3884abd8c79..b587ce48072d 100644 --- a/packages/serial/src/serialport/ZWaveSerialPortBase.ts +++ b/packages/serial/src/serialport/ZWaveSerialPortBase.ts @@ -2,16 +2,16 @@ import type { ZWaveLogContainer } from "@zwave-js/core"; import { Bytes, Mixin } from "@zwave-js/shared"; import { EventEmitter } from "node:events"; import { PassThrough, type Readable, type Writable } from "node:stream"; -import { SerialLogger } from "../log/Logger"; -import { MessageHeaders } from "../message/MessageHeaders"; +import { SerialLogger } from "../log/Logger.js"; +import { MessageHeaders } from "../message/MessageHeaders.js"; import { type BootloaderChunk, BootloaderParser, BootloaderScreenParser, bootloaderMenuPreamble, -} from "../parsers/BootloaderParsers"; -import { SerialAPIParser } from "../parsers/SerialAPIParser"; -import { type ZWaveSerialPortImplementation } from "./ZWaveSerialPortImplementation"; +} from "../parsers/BootloaderParsers.js"; +import { SerialAPIParser } from "../parsers/SerialAPIParser.js"; +import { type ZWaveSerialPortImplementation } from "./ZWaveSerialPortImplementation.js"; export type ZWaveSerialChunk = | MessageHeaders.ACK diff --git a/packages/serial/src/serialport/ZWaveSerialPortImplementation.ts b/packages/serial/src/serialport/ZWaveSerialPortImplementation.ts index 4e185210f2ff..82a8267b598d 100644 --- a/packages/serial/src/serialport/ZWaveSerialPortImplementation.ts +++ b/packages/serial/src/serialport/ZWaveSerialPortImplementation.ts @@ -1,4 +1,4 @@ -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import { type EventEmitter } from "node:events"; import { type Duplex } from "node:stream"; diff --git a/packages/serial/src/serialport/ZWaveSocket.ts b/packages/serial/src/serialport/ZWaveSocket.ts index 4cb0ed07b688..6ab2e85f7e7e 100644 --- a/packages/serial/src/serialport/ZWaveSocket.ts +++ b/packages/serial/src/serialport/ZWaveSocket.ts @@ -4,8 +4,8 @@ import { type ZWaveLogContainer, } from "@zwave-js/core"; import * as net from "node:net"; -import { ZWaveSerialPortBase } from "./ZWaveSerialPortBase"; -import { type ZWaveSocketOptions } from "./ZWaveSocketOptions"; +import { ZWaveSerialPortBase } from "./ZWaveSerialPortBase.js"; +import { type ZWaveSocketOptions } from "./ZWaveSocketOptions.js"; /** A version of the Z-Wave serial binding that works using a socket (TCP or IPC) */ export class ZWaveSocket extends ZWaveSerialPortBase { diff --git a/packages/serial/src/zniffer/ZnifferSerialPort.ts b/packages/serial/src/zniffer/ZnifferSerialPort.ts index 08b4fd0c595a..8917d5abde59 100644 --- a/packages/serial/src/zniffer/ZnifferSerialPort.ts +++ b/packages/serial/src/zniffer/ZnifferSerialPort.ts @@ -4,8 +4,8 @@ import { type ZWaveLogContainer, } from "@zwave-js/core"; import { SerialPort } from "serialport"; -import type { DisconnectError } from "../serialport/DisconnectError"; -import { ZnifferSerialPortBase } from "./ZnifferSerialPortBase"; +import type { DisconnectError } from "../serialport/DisconnectError.js"; +import { ZnifferSerialPortBase } from "./ZnifferSerialPortBase.js"; // FIXME: This class is identical to ZWaveSerialPort, except for the class name and the base class diff --git a/packages/serial/src/zniffer/ZnifferSerialPortBase.ts b/packages/serial/src/zniffer/ZnifferSerialPortBase.ts index 946135ec8a68..2f3c6f500a88 100644 --- a/packages/serial/src/zniffer/ZnifferSerialPortBase.ts +++ b/packages/serial/src/zniffer/ZnifferSerialPortBase.ts @@ -2,9 +2,9 @@ import type { ZWaveLogContainer } from "@zwave-js/core"; import { Mixin } from "@zwave-js/shared"; import { EventEmitter } from "node:events"; import { PassThrough, type Readable, type Writable } from "node:stream"; -import { SerialLogger } from "../log/Logger"; -import { ZnifferParser } from "../parsers/ZnifferParser"; -import { type ZWaveSerialPortImplementation } from "../serialport/ZWaveSerialPortImplementation"; +import { SerialLogger } from "../log/Logger.js"; +import { ZnifferParser } from "../parsers/ZnifferParser.js"; +import { type ZWaveSerialPortImplementation } from "../serialport/ZWaveSerialPortImplementation.js"; export interface ZnifferSerialPortEventCallbacks { error: (e: Error) => void; diff --git a/packages/serial/src/zniffer/ZnifferSocket.ts b/packages/serial/src/zniffer/ZnifferSocket.ts index 15183bf4e1f6..0f6667745554 100644 --- a/packages/serial/src/zniffer/ZnifferSocket.ts +++ b/packages/serial/src/zniffer/ZnifferSocket.ts @@ -4,8 +4,8 @@ import { type ZWaveLogContainer, } from "@zwave-js/core"; import * as net from "node:net"; -import { type ZWaveSocketOptions } from "../serialport/ZWaveSocketOptions"; -import { ZnifferSerialPortBase } from "./ZnifferSerialPortBase"; +import { type ZWaveSocketOptions } from "../serialport/ZWaveSocketOptions.js"; +import { ZnifferSerialPortBase } from "./ZnifferSerialPortBase.js"; // FIXME: This class is identical to ZWaveSocket, except for the class name and the base class diff --git a/packages/serial/tsconfig.build.json b/packages/serial/tsconfig.build.json index a2fb52512b12..785bf0153188 100644 --- a/packages/serial/tsconfig.build.json +++ b/packages/serial/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/shared/ava.config.cjs b/packages/shared/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/shared/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/shared/package.json b/packages/shared/package.json index 08a7f7785558..9c6c7975b006 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -6,22 +6,23 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./package.json": "./package.json" }, "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -46,23 +47,24 @@ "alcalzone-shared": "^4.0.8" }, "scripts": { - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "@types/sinon": "^17.0.3", - "ava": "^6.1.3", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", "sinon": "^19.0.2", - "typescript": "5.6.2" + "tsx": "^4.19.2", + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/shared/src/AsyncQueue.test.ts b/packages/shared/src/AsyncQueue.test.ts index d153f9e6398a..f1ce517151fd 100644 --- a/packages/shared/src/AsyncQueue.test.ts +++ b/packages/shared/src/AsyncQueue.test.ts @@ -1,6 +1,6 @@ -import { wait } from "alcalzone-shared/async"; -import test from "ava"; -import { AsyncQueue } from "./AsyncQueue"; +import { wait } from "alcalzone-shared/async/index.js"; +import { test } from "vitest"; +import { AsyncQueue } from "./AsyncQueue.js"; test("can be iterated over after adding items", async (t) => { const queue = new AsyncQueue(); @@ -16,7 +16,7 @@ test("can be iterated over after adding items", async (t) => { resolve(seen); }); - t.deepEqual(await actual, [1, 2, 3]); + t.expect(await actual).toStrictEqual([1, 2, 3]); }); test("can be iterated over when adding items later", async (t) => { @@ -33,7 +33,7 @@ test("can be iterated over when adding items later", async (t) => { queue.add(1, 2, 3); queue.end(); - t.deepEqual(await actual, [1, 2, 3]); + t.expect(await actual).toStrictEqual([1, 2, 3]); }); test("can be iterated over when adding items asynchronously", async (t) => { @@ -52,7 +52,7 @@ test("can be iterated over when adding items asynchronously", async (t) => { queue.add(4, 5); queue.end(); - t.deepEqual(await actual, [1, 2, 3, 4, 5]); + t.expect(await actual).toStrictEqual([1, 2, 3, 4, 5]); }); test("aborting clears all pending items", async (t) => { @@ -73,7 +73,7 @@ test("aborting clears all pending items", async (t) => { await wait(50); queue.abort(); - t.deepEqual(await actual, [1, 2, 3]); + t.expect(await actual).toStrictEqual([1, 2, 3]); }); test("items can be removed before they are consumed", async (t) => { @@ -92,10 +92,10 @@ test("items can be removed before they are consumed", async (t) => { queue.add(1, 2, 3, 4, 5); await wait(50); - t.is(queue.remove(2), false); - t.is(queue.remove(3), true); - t.is(queue.remove(4), true); + t.expect(queue.remove(2)).toBe(false); + t.expect(queue.remove(3)).toBe(true); + t.expect(queue.remove(4)).toBe(true); queue.end(); - t.deepEqual(await actual, [1, 2, 5]); + t.expect(await actual).toStrictEqual([1, 2, 5]); }); diff --git a/packages/shared/src/AsyncQueue.ts b/packages/shared/src/AsyncQueue.ts index 1b612db3a0a2..e9ddcc3f7bf6 100644 --- a/packages/shared/src/AsyncQueue.ts +++ b/packages/shared/src/AsyncQueue.ts @@ -1,7 +1,7 @@ import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; +} from "alcalzone-shared/deferred-promise/index.js"; export class AsyncQueue implements AsyncIterable { /** Adds one or more items onto the queue */ diff --git a/packages/shared/src/Bytes.test.ts b/packages/shared/src/Bytes.test.ts index f1af7f9e3ba2..1b3c9781a003 100644 --- a/packages/shared/src/Bytes.test.ts +++ b/packages/shared/src/Bytes.test.ts @@ -1,6 +1,6 @@ -import test from "ava"; -import { Bytes } from "./Bytes"; -import { uint8ArrayToHex } from "./uint8array-extras"; +import { test } from "vitest"; +import { Bytes } from "./Bytes.js"; +import { uint8ArrayToHex } from "./uint8array-extras.js"; test("writeUIntLE works as expected", (t) => { const b = new Bytes(10); @@ -8,7 +8,7 @@ test("writeUIntLE works as expected", (t) => { b.writeUIntLE(0xdead, 1, 2); b.writeUIntLE(0xdeadbe, 3, 3); b.writeUIntLE(0xdeadbeef, 6, 4); - t.is(uint8ArrayToHex(b), "deaddebeaddeefbeadde"); + t.expect(uint8ArrayToHex(b)).toBe("deaddebeaddeefbeadde"); }); test("writeUIntBE works as expected", (t) => { @@ -17,7 +17,7 @@ test("writeUIntBE works as expected", (t) => { b.writeUIntBE(0xdead, 1, 2); b.writeUIntBE(0xdeadbe, 3, 3); b.writeUIntBE(0xdeadbeef, 6, 4); - t.is(uint8ArrayToHex(b), "dedeaddeadbedeadbeef"); + t.expect(uint8ArrayToHex(b)).toBe("dedeaddeadbedeadbeef"); }); test("readUIntLE works as expected", (t) => { @@ -26,10 +26,10 @@ test("readUIntLE works as expected", (t) => { const v2 = b.readUIntLE(1, 2); const v3 = b.readUIntLE(3, 3); const v4 = b.readUIntLE(6, 4); - t.is(v1, 0xde); - t.is(v2, 0xdead); - t.is(v3, 0xdeadbe); - t.is(v4, 0xdeadbeef); + t.expect(v1).toBe(0xde); + t.expect(v2).toBe(0xdead); + t.expect(v3).toBe(0xdeadbe); + t.expect(v4).toBe(0xdeadbeef); }); test("readUIntBE works as expected", (t) => { @@ -38,10 +38,10 @@ test("readUIntBE works as expected", (t) => { const v2 = b.readUIntBE(1, 2); const v3 = b.readUIntBE(3, 3); const v4 = b.readUIntBE(6, 4); - t.is(v1, 0xde); - t.is(v2, 0xdead); - t.is(v3, 0xdeadbe); - t.is(v4, 0xdeadbeef); + t.expect(v1).toBe(0xde); + t.expect(v2).toBe(0xdead); + t.expect(v3).toBe(0xdeadbe); + t.expect(v4).toBe(0xdeadbeef); }); test("writeIntLE works as expected", (t) => { @@ -50,7 +50,7 @@ test("writeIntLE works as expected", (t) => { b.writeIntLE(-31870, 1, 2); b.writeIntLE(-7961212, 3, 3); b.writeIntLE(-1870034809, 6, 4); - t.is(uint8ArrayToHex(b), "81828384858687888990"); + t.expect(uint8ArrayToHex(b)).toBe("81828384858687888990"); }); test("writeIntBE works as expected", (t) => { @@ -59,7 +59,7 @@ test("writeIntBE works as expected", (t) => { b.writeIntBE(-32125, 1, 2); b.writeIntBE(-8092282, 3, 3); b.writeIntBE(-2021095024, 6, 4); - t.is(uint8ArrayToHex(b), "81828384858687888990"); + t.expect(uint8ArrayToHex(b)).toBe("81828384858687888990"); }); test("readIntLE works as expected", (t) => { @@ -68,10 +68,10 @@ test("readIntLE works as expected", (t) => { const v2 = b.readIntLE(1, 2); const v3 = b.readIntLE(3, 3); const v4 = b.readIntLE(6, 4); - t.is(v1, -127); - t.is(v2, -31870); - t.is(v3, -7961212); - t.is(v4, -1870034809); + t.expect(v1).toBe(-127); + t.expect(v2).toBe(-31870); + t.expect(v3).toBe(-7961212); + t.expect(v4).toBe(-1870034809); }); test("readIntBE works as expected", (t) => { @@ -80,10 +80,10 @@ test("readIntBE works as expected", (t) => { const v2 = b.readIntBE(1, 2); const v3 = b.readIntBE(3, 3); const v4 = b.readIntBE(6, 4); - t.is(v1, -127); - t.is(v2, -32125); - t.is(v3, -8092282); - t.is(v4, -2021095024); + t.expect(v1).toBe(-127); + t.expect(v2).toBe(-32125); + t.expect(v3).toBe(-8092282); + t.expect(v4).toBe(-2021095024); }); test("Buffer.concat works as expected", (t) => { @@ -92,23 +92,23 @@ test("Buffer.concat works as expected", (t) => { const b2 = Bytes.from([4, 5, 6]); const b3 = Bytes.from([7, 8, 9]); const b4 = Bytes.concat([b1, b2, b3]); - t.is(uint8ArrayToHex(b4), "010203040506070809"); + t.expect(uint8ArrayToHex(b4)).toBe("010203040506070809"); // Higher total length const b5 = Bytes.concat([b1, b2, b3], 12); - t.is(uint8ArrayToHex(b5), "010203040506070809000000"); + t.expect(uint8ArrayToHex(b5)).toBe("010203040506070809000000"); // Shorter total length const b6 = Bytes.concat([b1, b2, b3], 8); - t.is(uint8ArrayToHex(b6), "0102030405060708"); + t.expect(uint8ArrayToHex(b6)).toBe("0102030405060708"); }); test("subarray works multiple times in a row", (t) => { const b = Bytes.from([1, 2, 3, 4, 5, 6, 7, 8, 9]); const b1 = b.subarray(1, 4); // 2, 3, 4 const b2 = b1.subarray(1, 2); // 3 - t.is(uint8ArrayToHex(b1), "020304"); - t.is(uint8ArrayToHex(b2), "03"); + t.expect(uint8ArrayToHex(b1)).toBe("020304"); + t.expect(uint8ArrayToHex(b2)).toBe("03"); - t.is(b2.readInt8(0), 3); + t.expect(b2.readInt8(0)).toBe(3); }); diff --git a/packages/shared/src/Bytes.ts b/packages/shared/src/Bytes.ts index 805ca6abd11a..716c06343ac4 100644 --- a/packages/shared/src/Bytes.ts +++ b/packages/shared/src/Bytes.ts @@ -11,7 +11,7 @@ import { uint8ArrayToBase64, uint8ArrayToHex, uint8ArrayToString, -} from "./uint8array-extras"; +} from "./uint8array-extras.js"; /** An almost drop-in replacement for the Node.js Buffer class that's compatible with the native Uint8Array */ // See https://sindresorhus.com/blog/goodbye-nodejs-buffer for background diff --git a/packages/shared/src/EventEmitter.test.ts b/packages/shared/src/EventEmitter.test.ts index 306bce593fa3..d645360ad55d 100644 --- a/packages/shared/src/EventEmitter.test.ts +++ b/packages/shared/src/EventEmitter.test.ts @@ -1,8 +1,8 @@ -import test from "ava"; import { EventEmitter } from "node:events"; -import { TypedEventEmitter } from "./EventEmitter"; -import { AllOf, Mixin } from "./inheritance"; -import type { Constructor } from "./types"; +import { test } from "vitest"; +import { TypedEventEmitter } from "./EventEmitter.js"; +import { AllOf, Mixin } from "./inheritance.js"; +import type { Constructor } from "./types.js"; interface TestEvents { test1: (arg1: number) => void; @@ -30,10 +30,10 @@ interface TestEvents { test("Type-Safe EventEmitter as Mixin works", (t) => { return new Promise((resolve) => { const testClass = new Test(); - t.is(testClass.baseProp, "base"); - t.is(testClass.baseProp2, "base"); + t.expect(testClass.baseProp).toBe("base"); + t.expect(testClass.baseProp2).toBe("base"); testClass.on("test1", (arg1) => { - t.is(arg1, 1); + t.expect(arg1).toBe(1); resolve(); }); testClass.emit1(); @@ -52,7 +52,7 @@ interface TestEvents { return new Promise((resolve) => { const testClass = new Test(); testClass.on("test1", (arg1) => { - t.is(arg1, 1); + t.expect(arg1).toBe(1); resolve(); }); testClass.emit1(); @@ -79,11 +79,11 @@ interface TestEvents { test("Type-Safe EventEmitter (with multi-inheritance) works", async (t) => { const testClass = new Test(); - t.is(testClass.baseProp, "base"); - t.is(testClass.baseProp2, "base"); + t.expect(testClass.baseProp).toBe("base"); + t.expect(testClass.baseProp2).toBe("base"); return new Promise((resolve) => { testClass.on("test1", (arg1) => { - t.is(arg1, 1); + t.expect(arg1).toBe(1); resolve(); }); testClass.emit1(); diff --git a/packages/shared/src/EventEmitter.ts b/packages/shared/src/EventEmitter.ts index c19189167fba..719135c134d2 100644 --- a/packages/shared/src/EventEmitter.ts +++ b/packages/shared/src/EventEmitter.ts @@ -1,5 +1,5 @@ import EventEmitter from "node:events"; -import { applyMixin } from "./inheritance"; +import { applyMixin } from "./inheritance.js"; export type EventHandler = // Add more overloads as necessary diff --git a/packages/shared/src/ObjectKeyMap.test.ts b/packages/shared/src/ObjectKeyMap.test.ts index 8ddcf3adbb18..4f17966fc5d1 100644 --- a/packages/shared/src/ObjectKeyMap.test.ts +++ b/packages/shared/src/ObjectKeyMap.test.ts @@ -1,5 +1,5 @@ -import test from "ava"; -import { ObjectKeyMap, type ReadonlyObjectKeyMap } from "./ObjectKeyMap"; +import { test } from "vitest"; +import { ObjectKeyMap, type ReadonlyObjectKeyMap } from "./ObjectKeyMap.js"; const fixtures = { entries: [ @@ -32,66 +32,62 @@ const fixtures = { test("get(): should treat different property keys as distinct values", (t) => { const map = fixtures.createMapWithEntries(); - t.is( + t.expect( map.get({ property: "prop", propertyKey: "foo", }), - 1, - ); - t.is( + ).toBe(1); + t.expect( map.get({ property: "prop", propertyKey: "bar", }), - 2, - ); + ).toBe(2); }); test("get(): should return undefined after a call to clear()", (t) => { const map = fixtures.createMapWithEntries(); map.clear(); - t.is( + t.expect( map.get({ property: "prop", propertyKey: "foo", }), - undefined, - ); - t.is( + ).toBeUndefined(); + t.expect( map.get({ property: "prop", propertyKey: "bar", }), - undefined, - ); + ).toBeUndefined(); }); test("has(): should treat different property keys as distinct values", (t) => { const map = fixtures.createMapWithEntries(); - t.true( + t.expect( map.has({ property: "prop", propertyKey: "foo", }), - ); - t.false( + ).toBe(true); + t.expect( map.has({ property: "prop", propertyKey: "baz", }), - ); + ).toBe(false); }); test("has(): should return false after a call to clear()", (t) => { const map = fixtures.createMapWithEntries(); map.clear(); - t.false( + t.expect( map.has({ property: "prop", propertyKey: "foo", }), - ); + ).toBe(false); }); test("set(): should overwrite previous values", (t) => { @@ -114,29 +110,26 @@ test("set(): should overwrite previous values", (t) => { 6, ); - t.is( + t.expect( map.get({ property: "prop", propertyKey: "foo", }), - 6, - ); + ).toBe(6); }); test("values(): works like on the original Map class", (t) => { const map = fixtures.createMapWithEntries(); - t.deepEqual( + t.expect( [...map.values()], - fixtures.entries.map(([, v]) => v), - ); + ).toStrictEqual(fixtures.entries.map(([, v]) => v)); }); test("keys(): works like on the original Map class", (t) => { const map = fixtures.createMapWithEntries(); - t.deepEqual( + t.expect( [...map.keys()], - fixtures.entries.map(([k]) => k), - ); + ).toStrictEqual(fixtures.entries.map(([k]) => k)); }); test("required key properties should automatically be filled in", (t) => { @@ -146,22 +139,21 @@ test("required key properties should automatically be filled in", (t) => { >(undefined, { propertyKey: "5" }); map.set({ property: "foo" }, 1); map.set({ property: "foo", propertyKey: "1" }, 2); - t.deepEqual( + t.expect( [...map.keys()], - [ - { property: "foo", propertyKey: "5" }, - { property: "foo", propertyKey: "1" }, - ], - ); + ).toStrictEqual([ + { property: "foo", propertyKey: "5" }, + { property: "foo", propertyKey: "1" }, + ]); }); test("should be iterable", (t) => { const map: ReadonlyObjectKeyMap<{ key: string }, number> = new ObjectKeyMap( [[{ key: "test" }, 1]], ); - t.deepEqual([...map], [[{ key: "test" }, 1]]); + t.expect([...map]).toStrictEqual([[{ key: "test" }, 1]]); const readonlyMap: ReadonlyObjectKeyMap<{ key: string }, number> = new ObjectKeyMap([[{ key: "test" }, 1]]); - t.deepEqual([...readonlyMap], [[{ key: "test" }, 1]]); + t.expect([...readonlyMap]).toStrictEqual([[{ key: "test" }, 1]]); }); diff --git a/packages/shared/src/ObjectKeyMap.ts b/packages/shared/src/ObjectKeyMap.ts index 5189fe31584d..de787b17b01a 100644 --- a/packages/shared/src/ObjectKeyMap.ts +++ b/packages/shared/src/ObjectKeyMap.ts @@ -1,4 +1,4 @@ -import { composeObject, entries } from "alcalzone-shared/objects"; +import { composeObject, entries } from "alcalzone-shared/objects/index.js"; export class ObjectKeyMap, TValue> { public constructor( diff --git a/packages/shared/src/TimedExpectation.test.ts b/packages/shared/src/TimedExpectation.test.ts index 6bf414aa4af8..68f9ab97b483 100644 --- a/packages/shared/src/TimedExpectation.test.ts +++ b/packages/shared/src/TimedExpectation.test.ts @@ -1,6 +1,6 @@ -import test from "ava"; import sinon from "sinon"; -import { TimedExpectation } from "./TimedExpectation"; +import { test } from "vitest"; +import { TimedExpectation } from "./TimedExpectation.js"; test("resolves to the given value", async (t) => { const exp = new TimedExpectation(100); @@ -8,7 +8,7 @@ test("resolves to the given value", async (t) => { exp.resolve("OK"); }); const result = await exp; - t.is(result, "OK"); + t.expect(result).toBe("OK"); }); test("only resolves once", async (t) => { @@ -18,7 +18,7 @@ test("only resolves once", async (t) => { exp.resolve("NOK"); }); const result = await exp; - t.is(result, "OK"); + t.expect(result).toBe("OK"); }); test("rejects when timed out and does not resolve afterwards", (t) => { @@ -32,8 +32,8 @@ test("rejects when timed out and does not resolve afterwards", (t) => { throw new Error("Should not resolve"); }, (e) => { - t.true(e instanceof Error); - t.is(Date.now() - start, 100); + t.expect(e instanceof Error).toBe(true); + t.expect(Date.now() - start).toBe(100); exp.resolve("NOK"); clock.restore(); resolve(); diff --git a/packages/shared/src/TimedExpectation.ts b/packages/shared/src/TimedExpectation.ts index e9c57e1cbfef..560fecb471ec 100644 --- a/packages/shared/src/TimedExpectation.ts +++ b/packages/shared/src/TimedExpectation.ts @@ -1,7 +1,7 @@ import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; +} from "alcalzone-shared/deferred-promise/index.js"; /** Allows waiting for something for a given amount of time, after which the expectation will automatically be rejected. */ export class TimedExpectation diff --git a/packages/shared/src/fs.ts b/packages/shared/src/fs.ts index a79738a5b9da..d45a3f48b16b 100644 --- a/packages/shared/src/fs.ts +++ b/packages/shared/src/fs.ts @@ -1,6 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { getErrorMessage } from "."; +import { getErrorMessage } from "./errors.js"; export async function enumFilesRecursive( rootDir: string, diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index ca7c63d06644..39939137dccf 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,17 +1,17 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ -export * from "./AsyncQueue"; -export { Bytes } from "./Bytes"; -export * from "./EventEmitter"; -export { ObjectKeyMap } from "./ObjectKeyMap"; -export type { ReadonlyObjectKeyMap } from "./ObjectKeyMap"; -export * from "./ThrowingMap"; -export * from "./TimedExpectation"; -export * from "./docker"; -export * from "./errors"; -export * from "./fs"; -export * from "./inheritance"; -export * from "./strings"; -export * from "./types"; +export * from "./AsyncQueue.js"; +export { Bytes } from "./Bytes.js"; +export * from "./EventEmitter.js"; +export { ObjectKeyMap } from "./ObjectKeyMap.js"; +export type { ReadonlyObjectKeyMap } from "./ObjectKeyMap.js"; +export * from "./ThrowingMap.js"; +export * from "./TimedExpectation.js"; +export * from "./docker.js"; +export * from "./errors.js"; +export * from "./fs.js"; +export * from "./inheritance.js"; +export * from "./strings.js"; +export * from "./types.js"; export { areUint8ArraysEqual, assertUint8Array, @@ -19,6 +19,6 @@ export { isUint8Array, uint8ArrayToHex, uint8ArrayToString, -} from "./uint8array-extras"; -export * from "./utils"; -export * from "./wrappingCounter"; +} from "./uint8array-extras.js"; +export * from "./utils.js"; +export * from "./wrappingCounter.js"; diff --git a/packages/shared/src/index_safe.ts b/packages/shared/src/index_safe.ts index 8a0cdcb25174..b2a2adf00ae7 100644 --- a/packages/shared/src/index_safe.ts +++ b/packages/shared/src/index_safe.ts @@ -1,15 +1,15 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ /* @forbiddenImports external */ -export { Bytes } from "./Bytes"; -export { ObjectKeyMap } from "./ObjectKeyMap"; -export type { ReadonlyObjectKeyMap } from "./ObjectKeyMap"; -export * from "./ThrowingMap"; -export * from "./TimedExpectation"; -export * from "./errors"; -export * from "./inheritance"; -export * from "./strings"; -export * from "./types"; +export { Bytes } from "./Bytes.js"; +export { ObjectKeyMap } from "./ObjectKeyMap.js"; +export type { ReadonlyObjectKeyMap } from "./ObjectKeyMap.js"; +export * from "./ThrowingMap.js"; +export * from "./TimedExpectation.js"; +export * from "./errors.js"; +export * from "./inheritance.js"; +export * from "./strings.js"; +export * from "./types.js"; export { areUint8ArraysEqual, assertUint8Array, @@ -17,6 +17,6 @@ export { isUint8Array, uint8ArrayToHex, uint8ArrayToString, -} from "./uint8array-extras"; -export * from "./utils"; -export * from "./wrappingCounter"; +} from "./uint8array-extras.js"; +export * from "./utils.js"; +export * from "./wrappingCounter.js"; diff --git a/packages/shared/src/inheritance.ts b/packages/shared/src/inheritance.ts index 50f9e43eb705..23ed3f6e4ee0 100644 --- a/packages/shared/src/inheritance.ts +++ b/packages/shared/src/inheritance.ts @@ -1,4 +1,4 @@ -import type { Constructor, UnionToIntersection } from "./types"; +import type { Constructor, UnionToIntersection } from "./types.js"; /** Decorator to support multi-inheritance using mixins */ export function Mixin(baseCtors: Constructor[]) { diff --git a/packages/shared/src/strings.test.ts b/packages/shared/src/strings.test.ts index 0ce6dc29dc2b..7d6d03391605 100644 --- a/packages/shared/src/strings.test.ts +++ b/packages/shared/src/strings.test.ts @@ -1,13 +1,13 @@ -import test from "ava"; +import { test } from "vitest"; -import { Bytes } from "./Bytes"; +import { Bytes } from "./Bytes.js"; import { cpp2js, isPrintableASCIIWithWhitespace, num2hex, stringToUint8ArrayUTF16BE, uint8ArrayToStringUTF16BE, -} from "./strings"; +} from "./strings.js"; test("cpp2js() -> should truncate null-terminated strings", (t) => { const testCases = [ @@ -16,20 +16,20 @@ test("cpp2js() -> should truncate null-terminated strings", (t) => { ["abcdef\0", "abcdef"], ]; for (const [inp, out] of testCases) { - t.is(cpp2js(inp), out); + t.expect(cpp2js(inp)).toBe(out); } }); test("cpp2js() -> should just return non-terminated strings", (t) => { const testCases = ["abc", "def", "abcdef"]; for (const tc of testCases) { - t.is(cpp2js(tc), tc); + t.expect(cpp2js(tc)).toBe(tc); } }); test(`num2hex() -> should return "undefined" when the input is null or undefined`, (t) => { - t.is(num2hex(null), "undefined"); - t.is(num2hex(undefined), "undefined"); + t.expect(num2hex(null)).toBe("undefined"); + t.expect(num2hex(undefined)).toBe("undefined"); }); test("num2hex() -> should return an even number lowercase hex digits prefixed with 0x", (t) => { @@ -38,12 +38,12 @@ test("num2hex() -> should return an even number lowercase hex digits prefixed wi [0xfed, "0x0fed"], ]; for (const [inp, out] of testCases) { - t.is(num2hex(inp), out); + t.expect(num2hex(inp)).toBe(out); } }); test("num2hex() -> when the uppercase parameter is true, the hex digits should be uppercase", (t) => { - t.is(num2hex(0xabc123, true), "0xABC123"); + t.expect(num2hex(0xabc123, true)).toBe("0xABC123"); }); test("isPrintableASCIIWithWhitespace() -> should return true for ASCII strings that start or end with newlines", (t) => { @@ -56,7 +56,7 @@ test("isPrintableASCIIWithWhitespace() -> should return true for ASCII strings t ["\r\nß\r\n", false], ] as const; for (const [inp, result] of testCases) { - t.is(isPrintableASCIIWithWhitespace(inp), result); + t.expect(isPrintableASCIIWithWhitespace(inp)).toBe(result); } }); @@ -68,8 +68,8 @@ test("stringToUint8ArrayUTF16BE / uint8ArrayToStringUTF16BE", (t) => { ] as const; for (const [inp, out] of testCases) { // One way - t.deepEqual(stringToUint8ArrayUTF16BE(inp), Bytes.from(out)); + t.expect(stringToUint8ArrayUTF16BE(inp)).toStrictEqual(Bytes.from(out)); // And back - t.is(uint8ArrayToStringUTF16BE(Bytes.from(out)), inp); + t.expect(uint8ArrayToStringUTF16BE(Bytes.from(out))).toBe(inp); } }); diff --git a/packages/shared/src/strings.ts b/packages/shared/src/strings.ts index fae3d75d3cf3..2e81b40e38e3 100644 --- a/packages/shared/src/strings.ts +++ b/packages/shared/src/strings.ts @@ -1,6 +1,6 @@ -import { padStart } from "alcalzone-shared/strings"; -import { Bytes } from "./Bytes"; -import { uint8ArrayToHex } from "./uint8array-extras"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import { Bytes } from "./Bytes.js"; +import { uint8ArrayToHex } from "./uint8array-extras.js"; /** Translates a null-terminated (C++) string to JS */ export function cpp2js(str: string): string { diff --git a/packages/shared/src/utils.test.ts b/packages/shared/src/utils.test.ts index 1527a0ab6258..dba6f13efb4e 100644 --- a/packages/shared/src/utils.test.ts +++ b/packages/shared/src/utils.test.ts @@ -1,172 +1,164 @@ -import test from "ava"; +import { test } from "vitest"; import { cloneDeep, discreteBinarySearch, discreteLinearSearch, mergeDeep, -} from "./utils"; +} from "./utils.js"; test("discreteBinarySearch -> test case 1", async (t) => { const [rangeMin, rangeMax] = [0, 9]; const values = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]; - t.is( + t.expect( await discreteBinarySearch(rangeMin, rangeMax, (i) => values[i] === 0), - 4, - ); + ).toBe(4); }); test("discreteBinarySearch -> test case 2", async (t) => { const [rangeMin, rangeMax] = [0, 9]; const values = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - t.is( + t.expect( await discreteBinarySearch(rangeMin, rangeMax, (i) => values[i] === 0), - 9, - ); + ).toBe(9); }); test("discreteBinarySearch -> test case 3", async (t) => { const [rangeMin, rangeMax] = [0, 6]; const values = [0, 1, 1, 1, 1, 1, 1]; - t.is( + t.expect( await discreteBinarySearch(rangeMin, rangeMax, (i) => values[i] === 0), - 0, - ); + ).toBe(0); }); test("discreteBinarySearch -> test case 4", async (t) => { const [rangeMin, rangeMax] = [0, 6]; const values = [1, 1, 1, 1, 1, 1, 1]; - t.is( + t.expect( await discreteBinarySearch(rangeMin, rangeMax, (i) => values[i] === 0), - undefined, - ); + ).toBeUndefined(); }); test("discreteBinarySearch -> test case 5", async (t) => { const [rangeMin, rangeMax] = [0, 0]; const values = [0]; - t.is( + t.expect( await discreteBinarySearch(rangeMin, rangeMax, (i) => values[i] === 0), - 0, - ); + ).toBe(0); }); test("discreteBinarySearch -> test case 6", async (t) => { const [rangeMin, rangeMax] = [1, -1]; const values: number[] = []; - t.is( + t.expect( await discreteBinarySearch(rangeMin, rangeMax, (i) => values[i] === 0), - undefined, - ); + ).toBeUndefined(); }); test("discreteLinearSearch -> test case 1", async (t) => { const [rangeMin, rangeMax] = [0, 9]; const values = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]; - t.is( + t.expect( await discreteLinearSearch(rangeMin, rangeMax, (i) => values[i] === 0), - 4, - ); + ).toBe(4); }); test("discreteLinearSearch -> test case 2", async (t) => { const [rangeMin, rangeMax] = [0, 9]; const values = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - t.is( + t.expect( await discreteLinearSearch(rangeMin, rangeMax, (i) => values[i] === 0), - 9, - ); + ).toBe(9); }); test("discreteLinearSearch -> test case 3", async (t) => { const [rangeMin, rangeMax] = [0, 6]; const values = [0, 1, 1, 1, 1, 1, 1]; - t.is( + t.expect( await discreteLinearSearch(rangeMin, rangeMax, (i) => values[i] === 0), - 0, - ); + ).toBe(0); }); test("discreteLinearSearch -> test case 4", async (t) => { const [rangeMin, rangeMax] = [0, 6]; const values = [1, 1, 1, 1, 1, 1, 1]; - t.is( + t.expect( await discreteLinearSearch(rangeMin, rangeMax, (i) => values[i] === 0), - undefined, - ); + ).toBeUndefined(); }); test("discreteLinearSearch -> test case 5", async (t) => { const [rangeMin, rangeMax] = [0, 0]; const values = [0]; - t.is( + t.expect( await discreteLinearSearch(rangeMin, rangeMax, (i) => values[i] === 0), - 0, - ); + ).toBe(0); }); test("discreteLinearSearch -> test case 6", async (t) => { const [rangeMin, rangeMax] = [1, -1]; const values: number[] = []; - t.is( + t.expect( await discreteLinearSearch(rangeMin, rangeMax, (i) => values[i] === 0), - undefined, - ); + ).toBeUndefined(); }); test("cloneDeep -> works with primitives", (t) => { - t.is(cloneDeep(1), 1); - t.is(cloneDeep("foo"), "foo"); - t.is(cloneDeep(true), true); + t.expect(cloneDeep(1)).toBe(1); + t.expect(cloneDeep("foo")).toBe("foo"); + t.expect(cloneDeep(true)).toBe(true); }); test("cloneDeep -> works with arrays", (t) => { - t.deepEqual(cloneDeep([1, 2, 3]), [1, 2, 3]); - t.not(cloneDeep([1, 2, 3]), [1, 2, 3]); + t.expect(cloneDeep([1, 2, 3])).toStrictEqual([1, 2, 3]); + t.expect(cloneDeep([1, 2, 3])).not.toBe([1, 2, 3]); }); test("cloneDeep -> works with objects", (t) => { - t.deepEqual(cloneDeep({ a: 1, b: 2, c: 3 }), { a: 1, b: 2, c: 3 }); - t.not(cloneDeep({ a: 1, b: 2, c: 3 }), { a: 1, b: 2, c: 3 }); + t.expect(cloneDeep({ a: 1, b: 2, c: 3 })).toStrictEqual({ + a: 1, + b: 2, + c: 3, + }); + t.expect(cloneDeep({ a: 1, b: 2, c: 3 })).not.toBe({ a: 1, b: 2, c: 3 }); }); test("cloneDeep -> works with nested objects", (t) => { const source = { a: 1, b: { c: 3, d: 4 }, e: [5, 6, 7] }; const target = cloneDeep(source); - t.deepEqual(target, source); - t.not(target, source); - t.not(target.b, source.b); - t.not(target.e, source.e); + t.expect(target).toStrictEqual(source); + t.expect(target).not.toBe(source); + t.expect(target.b).not.toBe(source.b); + t.expect(target.e).not.toBe(source.e); }); test("cloneDeep -> works with nested arrays", (t) => { const source = [1, [2, 3], 4]; const target = cloneDeep(source); - t.deepEqual(target, source); - t.not(target, source); - t.not(target[1], source[1]); + t.expect(target).toStrictEqual(source); + t.expect(target).not.toBe(source); + t.expect(target[1]).not.toBe(source[1]); }); test("cloneDeep -> works with objects nested in arrays", (t) => { const source = [{ a: 1 }, { b: 2 }, { c: 3 }]; const target = cloneDeep(source); - t.deepEqual(target, source); - t.not(target, source); - t.not(target[0], source[0]); - t.not(target[1], source[1]); - t.not(target[2], source[2]); + t.expect(target).toStrictEqual(source); + t.expect(target).not.toBe(source); + t.expect(target[0]).not.toBe(source[0]); + t.expect(target[1]).not.toBe(source[1]); + t.expect(target[2]).not.toBe(source[2]); }); test("cloneDeep -> works with arrays nested in objects", (t) => { const source = { a: [1, 2, 3] }; const target = cloneDeep(source); - t.deepEqual(target, source); - t.not(target, source); - t.not(target.a, source.a); + t.expect(target).toStrictEqual(source); + t.expect(target).not.toBe(source); + t.expect(target.a).not.toBe(source.a); }); test("cloneDeep -> creates new object instances", (t) => { @@ -174,27 +166,27 @@ test("cloneDeep -> creates new object instances", (t) => { const target = cloneDeep(source); target.a.b.c = 0; - t.not(source.a.b.c, 0); + t.expect(source.a.b.c).not.toBe(0); }); test("mergeDeep -> can delete keys when undefined is passed", (t) => { const target = { a: 1, b: 2, c: 3 }; const result = mergeDeep(target, { a: undefined }, true); - t.deepEqual(result, { b: 2, c: 3 }); + t.expect(result).toStrictEqual({ b: 2, c: 3 }); }); test("mergeDeep -> sanity check with overwrite: true", (t) => { const target = { a: 1, b: { c: 3, d: 4 }, e: [5, 6, 7] }; const source = { b: { c: undefined }, e: "foo" }; const result = mergeDeep(target, source, true); - t.deepEqual(result, { a: 1, b: { d: 4 }, e: "foo" }); + t.expect(result).toStrictEqual({ a: 1, b: { d: 4 }, e: "foo" }); }); test("mergeDeep -> sanity check with overwrite: false", (t) => { const target = { a: 1, b: { c: 3, d: 4 }, e: [5, 6, 7] }; const source = { b: { c: undefined }, e: "foo", f: "bar" }; const result = mergeDeep(target, source, false); - t.deepEqual(result, { + t.expect(result).toStrictEqual({ a: 1, b: { c: 3, d: 4 }, e: [5, 6, 7], diff --git a/packages/shared/src/utils.throttle.test.ts b/packages/shared/src/utils.throttle.test.ts index b1fd1dc111c1..79d05ee1014b 100644 --- a/packages/shared/src/utils.throttle.test.ts +++ b/packages/shared/src/utils.throttle.test.ts @@ -1,32 +1,13 @@ -import ava, { type TestFn } from "ava"; import sinon from "sinon"; -import { throttle } from "./utils"; +import { afterAll, beforeAll, test, vi } from "vitest"; +import { throttle } from "./utils.js"; -interface TestContext { - clock: sinon.SinonFakeTimers; - advanceTime(ms: number): void; -} - -const test = ava as TestFn; - -const originalDateNow = Date.now; -let now: number; - -test.before((t) => { - now = Date.now(); - Date.now = sinon.fake(() => { - return now; - }); - t.context.clock = sinon.useFakeTimers(now); - t.context.advanceTime = (ms) => { - now += ms; - t.context.clock.tick(ms); - }; +beforeAll((t) => { + vi.useFakeTimers(); }); -test.after.always((t) => { - t.context.clock.restore(); - Date.now = originalDateNow; +afterAll((t) => { + vi.useRealTimers(); }); test("calls the function immediately when called once", (t) => { @@ -34,7 +15,6 @@ test("calls the function immediately when called once", (t) => { const throttled = throttle(spy, 100); throttled(); sinon.assert.calledOnce(spy); - t.pass(); }); test("passes the given parameters along", (t) => { @@ -42,7 +22,6 @@ test("passes the given parameters along", (t) => { const throttled = throttle(spy, 100); throttled(5, 6, "7"); sinon.assert.calledWith(spy, 5, 6, "7"); - t.pass(); }); test("calls the function once when called twice quickly", (t) => { @@ -52,7 +31,6 @@ test("calls the function once when called twice quickly", (t) => { throttled(2); sinon.assert.calledOnce(spy); sinon.assert.calledWith(spy, 1); - t.pass(); }); test("only adds a delayed function call when trailing=true", (t) => { @@ -63,7 +41,7 @@ test("only adds a delayed function call when trailing=true", (t) => { throttled(1); throttled(2); sinon.assert.calledOnce(spy); - t.context.advanceTime(100); + vi.advanceTimersByTime(100); sinon.assert.calledOnce(spy); spy.resetHistory(); @@ -73,10 +51,9 @@ test("only adds a delayed function call when trailing=true", (t) => { throttled(2); sinon.assert.calledOnce(spy); sinon.assert.calledWith(spy, 1); - t.context.advanceTime(100); + vi.advanceTimersByTime(100); sinon.assert.calledTwice(spy); sinon.assert.calledWith(spy, 2); - t.pass(); }); test("when called during the wait time for the trailing call, the most recent arguments are used", (t) => { @@ -87,13 +64,12 @@ test("when called during the wait time for the trailing call, the most recent ar throttled(2); sinon.assert.calledOnce(spy); sinon.assert.calledWith(spy, 1); - t.context.advanceTime(50); + vi.advanceTimersByTime(50); throttled(3); - t.context.advanceTime(25); + vi.advanceTimersByTime(25); throttled(4); - t.context.advanceTime(25); + vi.advanceTimersByTime(25); sinon.assert.calledTwice(spy); sinon.assert.neverCalledWith(spy, 2); sinon.assert.calledWith(spy, 4); - t.pass(); }); diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index 640527a5966b..c4f44ac7d1dc 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -1,5 +1,5 @@ -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { num2hex } from "./strings"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { num2hex } from "./strings.js"; /** Object.keys, but with `(keyof T)[]` as the return type */ export function keysOf(obj: T): (keyof T)[] { diff --git a/packages/shared/src/wrappingCounter.test.ts b/packages/shared/src/wrappingCounter.test.ts index 7e94fd12b3b2..df4545fca7c5 100644 --- a/packages/shared/src/wrappingCounter.test.ts +++ b/packages/shared/src/wrappingCounter.test.ts @@ -1,24 +1,24 @@ -import test from "ava"; -import { createWrappingCounter } from "./wrappingCounter"; +import { test } from "vitest"; +import { createWrappingCounter } from "./wrappingCounter.js"; test("wrappingCounter -> should return 1 first", (t) => { const c1 = createWrappingCounter(1); const c2 = createWrappingCounter(0b1111); - t.is(c1(), 1); - t.is(c2(), 1); + t.expect(c1()).toBe(1); + t.expect(c2()).toBe(1); }); test("wrappingCounter -> should wrap back to 1 after surpassing the max value", (t) => { // Useless counter, but it's a good test to make sure that the wrapping works const c1 = createWrappingCounter(1); - t.is(c1(), 1); - t.is(c1(), 1); - t.is(c1(), 1); - t.is(c1(), 1); + t.expect(c1()).toBe(1); + t.expect(c1()).toBe(1); + t.expect(c1()).toBe(1); + t.expect(c1()).toBe(1); const c2 = createWrappingCounter(0b11); - t.is(c2(), 1); - t.is(c2(), 2); - t.is(c2(), 3); - t.is(c2(), 1); + t.expect(c2()).toBe(1); + t.expect(c2()).toBe(2); + t.expect(c2()).toBe(3); + t.expect(c2()).toBe(1); }); diff --git a/packages/shared/tsconfig.build.json b/packages/shared/tsconfig.build.json index 9a7a326cc6e3..7927e1dc8325 100644 --- a/packages/shared/tsconfig.build.json +++ b/packages/shared/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/testing/package.json b/packages/testing/package.json index 9f1f55a3ea0b..a191eeb5557b 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -6,17 +6,18 @@ "publishConfig": { "access": "public" }, - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./package.json": "./package.json" }, "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -38,7 +39,8 @@ "node": ">= 18" }, "scripts": { - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", @@ -53,14 +55,14 @@ "ansi-colors": "^4.1.3" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "@types/triple-beam": "^1.3.5", "@zwave-js/cc": "workspace:*", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", "triple-beam": "*", + "tsx": "^4.19.2", "typescript": "5.6.2", "winston-transport": "^4.8.0" } diff --git a/packages/testing/src/MockController.ts b/packages/testing/src/MockController.ts index 8dd06ad604ca..abb3ce700833 100644 --- a/packages/testing/src/MockController.ts +++ b/packages/testing/src/MockController.ts @@ -19,13 +19,13 @@ import { import type { MockPortBinding } from "@zwave-js/serial/mock"; import { AsyncQueue } from "@zwave-js/shared"; import { TimedExpectation } from "@zwave-js/shared/safe"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import { randomInt } from "node:crypto"; import { type MockControllerCapabilities, getDefaultMockControllerCapabilities, -} from "./MockControllerCapabilities"; -import type { MockNode } from "./MockNode"; +} from "./MockControllerCapabilities.js"; +import type { MockNode } from "./MockNode.js"; import { type LazyMockZWaveFrame, MOCK_FRAME_ACK_TIMEOUT, @@ -35,7 +35,7 @@ import { type MockZWaveRequestFrame, createMockZWaveAckFrame, unlazyMockZWaveFrame, -} from "./MockZWaveFrame"; +} from "./MockZWaveFrame.js"; export interface MockControllerOptions { serial: MockPortBinding; diff --git a/packages/testing/src/MockControllerCapabilities.ts b/packages/testing/src/MockControllerCapabilities.ts index fd448b55a571..67408da80564 100644 --- a/packages/testing/src/MockControllerCapabilities.ts +++ b/packages/testing/src/MockControllerCapabilities.ts @@ -38,6 +38,8 @@ export function getDefaultSupportedFunctionTypes(): FunctionType[] { FunctionType.GetControllerCapabilities, FunctionType.SendData, FunctionType.SendDataMulticast, + FunctionType.SendDataBridge, + FunctionType.SendDataMulticastBridge, FunctionType.GetControllerVersion, FunctionType.GetControllerId, FunctionType.GetNodeProtocolInfo, diff --git a/packages/testing/src/MockNode.ts b/packages/testing/src/MockNode.ts index 5b26aecf214a..0cd42563046c 100644 --- a/packages/testing/src/MockNode.ts +++ b/packages/testing/src/MockNode.ts @@ -11,15 +11,15 @@ import { import type { CCEncodingContext } from "@zwave-js/host"; import { TimedExpectation } from "@zwave-js/shared"; import { isDeepStrictEqual } from "node:util"; -import type { CCIdToCapabilities } from "./CCSpecificCapabilities"; -import type { MockController } from "./MockController"; +import type { CCIdToCapabilities } from "./CCSpecificCapabilities.js"; +import type { MockController } from "./MockController.js"; import { type MockEndpointCapabilities, type MockNodeCapabilities, type PartialCCCapabilities, getDefaultMockEndpointCapabilities, getDefaultMockNodeCapabilities, -} from "./MockNodeCapabilities"; +} from "./MockNodeCapabilities.js"; import { type LazyMockZWaveFrame, MOCK_FRAME_ACK_TIMEOUT, @@ -29,7 +29,7 @@ import { type MockZWaveRequestFrame, createMockZWaveAckFrame, createMockZWaveRequestFrame, -} from "./MockZWaveFrame"; +} from "./MockZWaveFrame.js"; const defaultCCInfo: CommandClassInfo = { isSupported: true, @@ -226,7 +226,7 @@ export class MockNode { /** Can be used by behaviors to store controller related state */ public readonly state = new Map(); - /** Controls whether the controller automatically ACKs node frames before handling them */ + /** Controls whether the node automatically ACKs CCs from the controller before handling them */ public autoAckControllerFrames: boolean = true; private expectedControllerFrames: TimedExpectation< diff --git a/packages/testing/src/MockNodeCapabilities.ts b/packages/testing/src/MockNodeCapabilities.ts index 47d677f2c3ec..9d6f97600a23 100644 --- a/packages/testing/src/MockNodeCapabilities.ts +++ b/packages/testing/src/MockNodeCapabilities.ts @@ -5,7 +5,7 @@ import { type NodeProtocolInfoAndDeviceClass, NodeType, } from "@zwave-js/core"; -import type { CCIdToCapabilities } from "./CCSpecificCapabilities"; +import type { CCIdToCapabilities } from "./CCSpecificCapabilities.js"; export type PartialCCCapabilities = | T diff --git a/packages/testing/src/index.ts b/packages/testing/src/index.ts index db131d8c61e4..0d294c4846ba 100644 --- a/packages/testing/src/index.ts +++ b/packages/testing/src/index.ts @@ -1,12 +1,18 @@ /* eslint-disable @typescript-eslint/consistent-type-exports */ -export * from "./CCSpecificCapabilities"; -export * from "./MockController"; -export { getDefaultSupportedFunctionTypes } from "./MockControllerCapabilities"; -export * from "./MockNode"; +export * from "./CCSpecificCapabilities.js"; +export * from "./MockController.js"; export { + type MockControllerCapabilities, + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "./MockControllerCapabilities.js"; +export * from "./MockNode.js"; +export { + type MockEndpointCapabilities, + type MockNodeCapabilities, ccCaps, getDefaultMockEndpointCapabilities, getDefaultMockNodeCapabilities, -} from "./MockNodeCapabilities"; -export type { PartialCCCapabilities } from "./MockNodeCapabilities"; -export * from "./MockZWaveFrame"; +} from "./MockNodeCapabilities.js"; +export type { PartialCCCapabilities } from "./MockNodeCapabilities.js"; +export * from "./MockZWaveFrame.js"; diff --git a/packages/testing/tsconfig.build.json b/packages/testing/tsconfig.build.json index 33c071766e8a..96eb59295154 100644 --- a/packages/testing/tsconfig.build.json +++ b/packages/testing/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", // Do not use the @@dev export for compiling "customConditions": [] }, diff --git a/packages/transformers/ava.config.cjs b/packages/transformers/ava.config.cjs deleted file mode 100644 index cbc51b93a9ea..000000000000 --- a/packages/transformers/ava.config.cjs +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), - files: ["src/**/*.test.ts"], - // We're running .js files, so do not use the custom conditions that are used - // to resolve to .ts exports - nodeArguments: [], -}; diff --git a/packages/transformers/package.json b/packages/transformers/package.json index 550641f8fe30..c2611bbab070 100644 --- a/packages/transformers/package.json +++ b/packages/transformers/package.json @@ -7,7 +7,8 @@ "main": "build/index.js", "types": "build/index.d.ts", "files": [ - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "author": { "name": "AlCalzone", @@ -35,15 +36,15 @@ "pretest": "del-cli \"test/fixtures/*.js\" && tsc -p tsconfig.test.json && cpy \"test/build/test/fixtures/*.js\" test/fixtures && del-cli test/build", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "devDependencies": { - "ava": "^6.1.3", "cpy-cli": "^5.0.0", "del-cli": "^6.0.0", "execa": "^5.1.1", "tsutils": "^3.21.0", - "typescript": "5.6.2" + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/transformers/src/index.test.ts b/packages/transformers/src/index.test.ts index 72653dd93ec6..6b9bc3a0fff1 100644 --- a/packages/transformers/src/index.test.ts +++ b/packages/transformers/src/index.test.ts @@ -1,19 +1,18 @@ -import test from "ava"; import execa from "execa"; import fs from "node:fs/promises"; import path from "node:path"; +import { beforeAll, test } from "vitest"; const fixturesDir = path.join(__dirname, "../test/fixtures"); const files: string[] = []; -test.before(async (t) => { - t.timeout(180000); +beforeAll(async (t) => { await execa("yarn", ["run", "pretest"], { cwd: __dirname }); const jsFiles = (await fs.readdir(fixturesDir)).filter( (f) => f.startsWith("test") && f.endsWith(".js"), ); files.push(...jsFiles); -}); +}, 180000); test("run fixtures", async (t) => { for (const file of files) { @@ -23,5 +22,4 @@ test("run fixtures", async (t) => { throw new Error(`${file} failed to run: ${e.stack}`); } } - t.pass(); }); diff --git a/packages/transformers/vitest.config.mjs b/packages/transformers/vitest.config.mjs new file mode 100644 index 000000000000..34069b2f91f5 --- /dev/null +++ b/packages/transformers/vitest.config.mjs @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: [ + "./src/**/*.test.ts", + ], + }, +}); diff --git a/packages/zwave-js/ava.config.cjs b/packages/zwave-js/ava.config.cjs deleted file mode 100644 index 75a10030a7a2..000000000000 --- a/packages/zwave-js/ava.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require("../../ava.config.cjs"), -}; diff --git a/packages/zwave-js/maintenance/codegen.ts b/packages/zwave-js/maintenance/codegen.ts index f258145614ed..a7ae7a43d68a 100644 --- a/packages/zwave-js/maintenance/codegen.ts +++ b/packages/zwave-js/maintenance/codegen.ts @@ -1,5 +1,8 @@ import fs from "node:fs"; import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); // // Generate PACKAGE_VERSION module diff --git a/packages/zwave-js/package.json b/packages/zwave-js/package.json index c2948c8a9ade..8eae5d8f65d3 100644 --- a/packages/zwave-js/package.json +++ b/packages/zwave-js/package.json @@ -3,63 +3,64 @@ "version": "14.0.0-beta.1", "description": "Z-Wave driver written entirely in JavaScript/TypeScript", "keywords": [], - "type": "commonjs", + "type": "module", "exports": { ".": { "@@dev": "./src/index.ts", - "types": "./build/index.d.ts", - "default": "./build/index.js" + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js" }, "./safe": { "@@dev": "./src/index_safe.ts", - "types": "./build/index_safe.d.ts", - "default": "./build/index_safe.js" + "import": "./build/esm/index_safe.js", + "require": "./build/cjs/index_safe.js" }, "./Controller": { "@@dev": "./src/Controller.ts", - "types": "./build/Controller.d.ts", - "default": "./build/Controller.js" + "import": "./build/esm/Controller.js", + "require": "./build/cjs/Controller.js" }, "./Driver": { "@@dev": "./src/Driver.ts", - "types": "./build/Driver.d.ts", - "default": "./build/Driver.js" + "import": "./build/esm/Driver.js", + "require": "./build/cjs/Driver.js" }, "./Error": { "@@dev": "./src/Error.ts", - "types": "./build/Error.d.ts", - "default": "./build/Error.js" + "import": "./build/esm/Error.js", + "require": "./build/cjs/Error.js" }, "./Node": { "@@dev": "./src/Node.ts", - "types": "./build/Node.d.ts", - "default": "./build/Node.js" + "import": "./build/esm/Node.js", + "require": "./build/cjs/Node.js" }, "./Testing": { "@@dev": "./src/Testing.ts", - "types": "./build/Testing.d.ts", - "default": "./build/Testing.js" + "import": "./build/esm/Testing.js", + "require": "./build/cjs/Testing.js" }, "./Utils": { "@@dev": "./src/Utils.ts", - "types": "./build/Utils.d.ts", - "default": "./build/Utils.js" + "import": "./build/esm/Utils.js", + "require": "./build/cjs/Utils.js" }, "./Values": { "@@dev": "./src/Values.ts", - "types": "./build/Values.d.ts", - "default": "./build/Values.js" + "import": "./build/esm/Values.js", + "require": "./build/cjs/Values.js" }, "./Zniffer": { "@@dev": "./src/Zniffer.ts", - "types": "./build/Zniffer.d.ts", - "default": "./build/Zniffer.js" + "import": "./build/esm/Zniffer.js", + "require": "./build/cjs/Zniffer.js" }, "./package.json": "./package.json" }, "files": [ "bin/", - "build/**/*.{js,d.ts,map}" + "build/**/*.{js,cjs,mjs,d.ts,d.cts,d.mts,map}", + "build/**/package.json" ], "bin": { "mock-server": "bin/mock-server.js" @@ -84,15 +85,16 @@ "node": ">= 18" }, "scripts": { - "ts": "node -r esbuild-register --conditions=@@dev", + "ts": "tsx --conditions=@@dev", "codegen": "yarn ts maintenance/codegen.ts", - "build": "tsc -b tsconfig.build.json --pretty", + "build": "tsc -b tsconfig.build.json --pretty && yarn postbuild", + "postbuild": "yarn esm2cjs --in build/esm --out build/cjs -l error -t node18", "clean": "del-cli build/ \"*.tsbuildinfo\"", "extract-api": "yarn api-extractor run", "lint:ts": "eslint --cache \"src/**/*.ts\"", "lint:ts:fix": "yarn run lint:ts --fix", - "test:ts": "ava", - "test:dirty": "node -r ../../maintenance/esbuild-register.js ../maintenance/src/resolveDirtyTests.ts --run" + "test:ts": "vitest", + "test:dirty": "tsx ../maintenance/src/resolveDirtyTests.ts --run" }, "dependencies": { "@alcalzone/jsonl-db": "^3.1.1", @@ -121,6 +123,7 @@ "xstate": "4.38.3" }, "devDependencies": { + "@alcalzone/esm2cjs": "^1.2.3", "@microsoft/api-extractor": "^7.47.9", "@types/node": "^18.19.63", "@types/proper-lockfile": "^4.1.4", @@ -131,13 +134,12 @@ "@xstate/test": "^0.5.1", "@zwave-js/maintenance": "workspace:*", "@zwave-js/transformers": "workspace:*", - "ava": "^6.1.3", "del-cli": "^6.0.0", - "esbuild": "0.24.0", - "esbuild-register": "^3.6.0", "mockdate": "^3.0.5", "proxyquire": "^2.1.3", "sinon": "^19.0.2", - "typescript": "5.6.2" + "tsx": "^4.19.2", + "typescript": "5.6.2", + "vitest": "^2.1.4" } } diff --git a/packages/zwave-js/src/Controller.ts b/packages/zwave-js/src/Controller.ts index 970e6c700640..b557dcd32681 100644 --- a/packages/zwave-js/src/Controller.ts +++ b/packages/zwave-js/src/Controller.ts @@ -13,12 +13,12 @@ export { export type { RSSI, TXReport } from "@zwave-js/core/safe"; export type { ZWaveApiVersion, ZWaveLibraryTypes } from "@zwave-js/core/safe"; export { SerialAPISetupCommand } from "@zwave-js/serial/serialapi"; -export { ZWaveController } from "./lib/controller/Controller"; -export type { ControllerEvents } from "./lib/controller/Controller"; -export type { ControllerStatistics } from "./lib/controller/ControllerStatistics"; -export { ZWaveFeature } from "./lib/controller/Features"; -export * from "./lib/controller/Inclusion"; -export { ControllerFirmwareUpdateStatus } from "./lib/controller/_Types"; +export { ZWaveController } from "./lib/controller/Controller.js"; +export type { ControllerEvents } from "./lib/controller/Controller.js"; +export type { ControllerStatistics } from "./lib/controller/ControllerStatistics.js"; +export { ZWaveFeature } from "./lib/controller/Features.js"; +export * from "./lib/controller/Inclusion.js"; +export { ControllerFirmwareUpdateStatus } from "./lib/controller/_Types.js"; export type { ControllerFirmwareUpdateProgress, ControllerFirmwareUpdateResult, @@ -29,4 +29,4 @@ export type { RebuildRoutesOptions, RebuildRoutesStatus, SDKVersion, -} from "./lib/controller/_Types"; +} from "./lib/controller/_Types.js"; diff --git a/packages/zwave-js/src/Controller_safe.ts b/packages/zwave-js/src/Controller_safe.ts index c5645007f296..ffd249dee401 100644 --- a/packages/zwave-js/src/Controller_safe.ts +++ b/packages/zwave-js/src/Controller_safe.ts @@ -6,10 +6,10 @@ export { } from "@zwave-js/core/safe"; export type { RSSI, TXReport } from "@zwave-js/core/safe"; export type { ZWaveLibraryTypes } from "@zwave-js/core/safe"; -export type { ControllerStatistics } from "./lib/controller/ControllerStatistics"; -export { ZWaveFeature } from "./lib/controller/Features"; -export * from "./lib/controller/Inclusion"; -export { ControllerFirmwareUpdateStatus } from "./lib/controller/_Types"; +export type { ControllerStatistics } from "./lib/controller/ControllerStatistics.js"; +export { ZWaveFeature } from "./lib/controller/Features.js"; +export * from "./lib/controller/Inclusion.js"; +export { ControllerFirmwareUpdateStatus } from "./lib/controller/_Types.js"; export type { ControllerFirmwareUpdateProgress, ControllerFirmwareUpdateResult, @@ -18,4 +18,4 @@ export type { RebuildRoutesOptions, RebuildRoutesStatus, SDKVersion, -} from "./lib/controller/_Types"; +} from "./lib/controller/_Types.js"; diff --git a/packages/zwave-js/src/Driver.ts b/packages/zwave-js/src/Driver.ts index b11f18d0307b..f09234bbd226 100644 --- a/packages/zwave-js/src/Driver.ts +++ b/packages/zwave-js/src/Driver.ts @@ -17,10 +17,10 @@ export { isCommandRequest, isMessageWithCC, } from "@zwave-js/serial/serialapi"; -export { Driver, libName, libVersion } from "./lib/driver/Driver"; +export { Driver, libName, libVersion } from "./lib/driver/Driver.js"; export type { EditableZWaveOptions, PartialZWaveOptions, ZWaveOptions, -} from "./lib/driver/ZWaveOptions"; -export type { DriverLogContext } from "./lib/log/Driver"; +} from "./lib/driver/ZWaveOptions.js"; +export type { DriverLogContext } from "./lib/log/Driver.js"; diff --git a/packages/zwave-js/src/Node.ts b/packages/zwave-js/src/Node.ts index 123a5a12fd8e..866e91a43837 100644 --- a/packages/zwave-js/src/Node.ts +++ b/packages/zwave-js/src/Node.ts @@ -7,15 +7,15 @@ export { ProtocolVersion, } from "@zwave-js/core/safe"; export type { DataRate, FLiRS } from "@zwave-js/core/safe"; -export { DeviceClass } from "./lib/node/DeviceClass"; -export type { NodeDump } from "./lib/node/Dump"; -export { Endpoint } from "./lib/node/Endpoint"; -export { ZWaveNode } from "./lib/node/Node"; +export { DeviceClass } from "./lib/node/DeviceClass.js"; +export type { NodeDump } from "./lib/node/Dump.js"; +export { Endpoint } from "./lib/node/Endpoint.js"; +export { ZWaveNode } from "./lib/node/Node.js"; export type { NodeStatistics, RouteStatistics, -} from "./lib/node/NodeStatistics"; -export { VirtualEndpoint } from "./lib/node/VirtualEndpoint"; -export { VirtualNode } from "./lib/node/VirtualNode"; -export type { VirtualValueID } from "./lib/node/VirtualNode"; -export * from "./lib/node/_Types"; +} from "./lib/node/NodeStatistics.js"; +export { VirtualEndpoint } from "./lib/node/VirtualEndpoint.js"; +export { VirtualNode } from "./lib/node/VirtualNode.js"; +export type { VirtualValueID } from "./lib/node/VirtualNode.js"; +export * from "./lib/node/_Types.js"; diff --git a/packages/zwave-js/src/Node_safe.ts b/packages/zwave-js/src/Node_safe.ts index 064feb2d8b2a..5d627fab8cae 100644 --- a/packages/zwave-js/src/Node_safe.ts +++ b/packages/zwave-js/src/Node_safe.ts @@ -7,10 +7,10 @@ export { ProtocolVersion, } from "@zwave-js/core/safe"; export type { DataRate, FLiRS } from "@zwave-js/core/safe"; -export { DeviceClass } from "./lib/node/DeviceClass"; +export { DeviceClass } from "./lib/node/DeviceClass.js"; export type { NodeStatistics, RouteStatistics, -} from "./lib/node/NodeStatistics"; -export type { VirtualValueID } from "./lib/node/VirtualNode"; -export * from "./lib/node/_Types"; +} from "./lib/node/NodeStatistics.js"; +export type { VirtualValueID } from "./lib/node/VirtualNode.js"; +export * from "./lib/node/_Types.js"; diff --git a/packages/zwave-js/src/Testing.ts b/packages/zwave-js/src/Testing.ts index 7c8ad297bd8b..cdbd8d65f23e 100644 --- a/packages/zwave-js/src/Testing.ts +++ b/packages/zwave-js/src/Testing.ts @@ -1,7 +1,7 @@ -export { createAndStartDriverWithMockPort } from "./lib/driver/DriverMock"; -export { MockServer, createMockNodeOptionsFromDump } from "./mockServer"; +export { createAndStartDriverWithMockPort } from "./lib/driver/DriverMock.js"; +export { MockServer, createMockNodeOptionsFromDump } from "./mockServer.js"; export type { MockServerControllerOptions, MockServerNodeOptions, MockServerOptions, -} from "./mockServer"; +} from "./mockServer.js"; diff --git a/packages/zwave-js/src/Utils.ts b/packages/zwave-js/src/Utils.ts index ebbb5a1b2afa..cff011388b91 100644 --- a/packages/zwave-js/src/Utils.ts +++ b/packages/zwave-js/src/Utils.ts @@ -22,13 +22,13 @@ export { getEnumMemberName, num2hex, } from "@zwave-js/shared/safe"; -export { createDefaultBehaviors as createDefaultMockControllerBehaviors } from "./lib/controller/MockControllerBehaviors"; -export { driverPresets } from "./lib/driver/ZWaveOptions"; +export { createDefaultBehaviors as createDefaultMockControllerBehaviors } from "./lib/controller/MockControllerBehaviors.js"; +export { driverPresets } from "./lib/driver/ZWaveOptions.js"; export { formatLifelineHealthCheckRound, formatLifelineHealthCheckSummary, formatRouteHealthCheckRound, formatRouteHealthCheckSummary, healthCheckRatingToWord, -} from "./lib/node/HealthCheck"; -export { createDefaultBehaviors as createDefaultMockNodeBehaviors } from "./lib/node/MockNodeBehaviors"; +} from "./lib/node/HealthCheck.js"; +export { createDefaultBehaviors as createDefaultMockNodeBehaviors } from "./lib/node/MockNodeBehaviors.js"; diff --git a/packages/zwave-js/src/Utils_safe.ts b/packages/zwave-js/src/Utils_safe.ts index af798f85d272..9b1141598872 100644 --- a/packages/zwave-js/src/Utils_safe.ts +++ b/packages/zwave-js/src/Utils_safe.ts @@ -14,11 +14,11 @@ export { getEnumMemberName, num2hex, } from "@zwave-js/shared/safe"; -export { driverPresets } from "./lib/driver/ZWaveOptions"; +export { driverPresets } from "./lib/driver/ZWaveOptions.js"; export { formatLifelineHealthCheckRound, formatLifelineHealthCheckSummary, formatRouteHealthCheckRound, formatRouteHealthCheckSummary, healthCheckRatingToWord, -} from "./lib/node/HealthCheck"; +} from "./lib/node/HealthCheck.js"; diff --git a/packages/zwave-js/src/Values.ts b/packages/zwave-js/src/Values.ts index d039e8f1d472..55a63e6e875d 100644 --- a/packages/zwave-js/src/Values.ts +++ b/packages/zwave-js/src/Values.ts @@ -19,4 +19,4 @@ export type { ZWaveNodeValueNotificationArgs, ZWaveNodeValueRemovedArgs, ZWaveNodeValueUpdatedArgs, -} from "./lib/node/_Types"; +} from "./lib/node/_Types.js"; diff --git a/packages/zwave-js/src/Zniffer.ts b/packages/zwave-js/src/Zniffer.ts index 85c656d605d0..0f1ac28cb91e 100644 --- a/packages/zwave-js/src/Zniffer.ts +++ b/packages/zwave-js/src/Zniffer.ts @@ -1,17 +1,17 @@ export { BeamingInfo, MPDUHeaderType } from "@zwave-js/core/safe"; -export type { MPDU } from "./lib/zniffer/MPDU"; +export type { MPDU } from "./lib/zniffer/MPDU.js"; export type { BeamFrame, CorruptedFrame, Frame, LongRangeFrame, ZWaveFrame, -} from "./lib/zniffer/MPDU"; -export { LongRangeMPDU, ZWaveMPDU, parseMPDU } from "./lib/zniffer/MPDU"; -export type { ZnifferOptions } from "./lib/zniffer/Zniffer"; -export { Zniffer } from "./lib/zniffer/Zniffer"; +} from "./lib/zniffer/MPDU.js"; +export { LongRangeMPDU, ZWaveMPDU, parseMPDU } from "./lib/zniffer/MPDU.js"; +export type { ZnifferOptions } from "./lib/zniffer/Zniffer.js"; +export { Zniffer } from "./lib/zniffer/Zniffer.js"; export { ExplorerFrameCommand, LongRangeFrameType, ZWaveFrameType, -} from "./lib/zniffer/_Types"; +} from "./lib/zniffer/_Types.js"; diff --git a/packages/zwave-js/src/Zniffer_safe.ts b/packages/zwave-js/src/Zniffer_safe.ts index fe9df8784945..944534f66c9b 100644 --- a/packages/zwave-js/src/Zniffer_safe.ts +++ b/packages/zwave-js/src/Zniffer_safe.ts @@ -1,7 +1,7 @@ export { BeamingInfo, MPDUHeaderType } from "@zwave-js/core/safe"; -export type { ZnifferOptions } from "./lib/zniffer/Zniffer"; +export type { ZnifferOptions } from "./lib/zniffer/Zniffer.js"; export { ExplorerFrameCommand, LongRangeFrameType, ZWaveFrameType, -} from "./lib/zniffer/_Types"; +} from "./lib/zniffer/_Types.js"; diff --git a/packages/zwave-js/src/index.ts b/packages/zwave-js/src/index.ts index 01461a34672a..7ca8c40ca442 100644 --- a/packages/zwave-js/src/index.ts +++ b/packages/zwave-js/src/index.ts @@ -12,10 +12,10 @@ installSourceMapSupport(); // Export some frequently-used things and types - this also loads all CC files including metadata export * from "@zwave-js/cc"; -export * from "./Controller"; -export * from "./Driver"; -export * from "./Error"; -export * from "./Node"; -export * from "./Utils"; -export * from "./Values"; -export * from "./Zniffer"; +export * from "./Controller.js"; +export * from "./Driver.js"; +export * from "./Error.js"; +export * from "./Node.js"; +export * from "./Utils.js"; +export * from "./Values.js"; +export * from "./Zniffer.js"; diff --git a/packages/zwave-js/src/index_safe.ts b/packages/zwave-js/src/index_safe.ts index 17b702db6647..ae8dfc648e80 100644 --- a/packages/zwave-js/src/index_safe.ts +++ b/packages/zwave-js/src/index_safe.ts @@ -1,9 +1,9 @@ /* @forbiddenImports external */ -export * from "./Controller_safe"; +export * from "./Controller_safe.js"; // export * from "./Driver"; -export * from "./Error"; -export * from "./Node_safe"; -export * from "./Utils_safe"; -export * from "./Values"; -export * from "./Zniffer_safe"; +export * from "./Error.js"; +export * from "./Node_safe.js"; +export * from "./Utils_safe.js"; +export * from "./Values.js"; +export * from "./Zniffer_safe.js"; diff --git a/packages/zwave-js/src/lib/_version.ts b/packages/zwave-js/src/lib/_version.ts index 1faddcbe66e9..942315b377e0 100644 --- a/packages/zwave-js/src/lib/_version.ts +++ b/packages/zwave-js/src/lib/_version.ts @@ -1,3 +1,3 @@ // This file is auto-generated by the codegen maintenance script -export const PACKAGE_VERSION = "14.0.0-beta.0"; +export const PACKAGE_VERSION = "14.0.0-beta.1"; export const PACKAGE_NAME = "zwave-js"; diff --git a/packages/zwave-js/src/lib/controller/Controller.getAssociationGroups.test.ts b/packages/zwave-js/src/lib/controller/Controller.getAssociationGroups.test.ts index 6ca4ed17ce40..6f4ff540c639 100644 --- a/packages/zwave-js/src/lib/controller/Controller.getAssociationGroups.test.ts +++ b/packages/zwave-js/src/lib/controller/Controller.getAssociationGroups.test.ts @@ -1,29 +1,37 @@ import { AssociationCCValues } from "@zwave-js/cc/AssociationCC"; import { CommandClasses } from "@zwave-js/core"; -import ava, { type TestFn } from "ava"; -import type { Driver } from "../driver/Driver"; -import { ZWaveNode } from "../node/Node"; -import { createEmptyMockDriver } from "../test/mocks"; -import { ZWaveController } from "./Controller"; +import { test as baseTest } from "vitest"; +import type { Driver } from "../driver/Driver.js"; +import { ZWaveNode } from "../node/Node.js"; +import { createEmptyMockDriver } from "../test/mocks.js"; +import { ZWaveController } from "./Controller.js"; -interface TestContext { - fakeDriver: Driver; +interface LocalTestContext { + context: { + fakeDriver: Driver; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup -test.before(async (t) => { - t.timeout(60000); + const fakeDriver = createEmptyMockDriver() as unknown as Driver; + fakeDriver.registerRequestHandler = () => {}; + await fakeDriver.configManager.loadAll(); - const fakeDriver = createEmptyMockDriver() as unknown as Driver; - fakeDriver.registerRequestHandler = () => {}; - await fakeDriver.configManager.loadAll(); + // Run tests + await use({ fakeDriver }); - t.context.fakeDriver = fakeDriver; + // Teardown + }, + { auto: true }, + ], }); -test("should respect the endpoint definition format when AGI is supported", async (t) => { - const { fakeDriver } = t.context; +test("should respect the endpoint definition format when AGI is supported", async ({ context, expect }) => { + const { fakeDriver } = context; const ctrl = new ZWaveController(fakeDriver); ctrl["_nodes"].set(1, new ZWaveNode(1, fakeDriver)); @@ -48,14 +56,13 @@ test("should respect the endpoint definition format when AGI is supported", asyn ); fakeDriver.getDeviceConfig = () => deviceConfig; - t.is( + expect( ctrl.getAssociationGroups({ nodeId: 1, endpoint: 0 }).get(4)?.label, - "Button 1 (Multilevel Set)", - ); + ).toBe("Button 1 (Multilevel Set)"); }); -test("should respect the endpoint definition format when AGI is not supported", async (t) => { - const { fakeDriver } = t.context; +test("should respect the endpoint definition format when AGI is not supported", async ({ context, expect }) => { + const { fakeDriver } = context; const ctrl = new ZWaveController(fakeDriver); ctrl["_nodes"].set(1, new ZWaveNode(1, fakeDriver)); @@ -76,8 +83,7 @@ test("should respect the endpoint definition format when AGI is not supported", ); fakeDriver.getDeviceConfig = () => deviceConfig; - t.is( + expect( ctrl.getAssociationGroups({ nodeId: 1, endpoint: 0 }).get(4)?.label, - "Button 1 (Multilevel Set)", - ); + ).toBe("Button 1 (Multilevel Set)"); }); diff --git a/packages/zwave-js/src/lib/controller/Controller.manageAssociations.test.ts b/packages/zwave-js/src/lib/controller/Controller.manageAssociations.test.ts index 27bb3d5d9d0a..662e1b511c1c 100644 --- a/packages/zwave-js/src/lib/controller/Controller.manageAssociations.test.ts +++ b/packages/zwave-js/src/lib/controller/Controller.manageAssociations.test.ts @@ -6,8 +6,8 @@ import { } from "@zwave-js/cc"; import { CommandClasses, SecurityClass } from "@zwave-js/core/safe"; import { createTestingHost } from "@zwave-js/host"; -import test from "ava"; -import { type CreateTestNodeOptions, createTestNode } from "../test/mocks"; +import { test } from "vitest"; +import { type CreateTestNodeOptions, createTestNode } from "../test/mocks.js"; test("associations between insecure nodes are allowed", (t) => { // This test simulates two Zooz ZEN76 switches, included insecurely @@ -63,10 +63,9 @@ test("associations between insecure nodes are allowed", (t) => { commands, ); - t.is( + t.expect( ccUtils.checkAssociation(host, node2, groupId, { nodeId: 3, }), - AssociationCheckResult.OK, - ); + ).toBe(AssociationCheckResult.OK); }); diff --git a/packages/zwave-js/src/lib/controller/Controller.nodes.getOrThrow.test.ts b/packages/zwave-js/src/lib/controller/Controller.nodes.getOrThrow.test.ts index fe49ca359423..02e5553c2b3c 100644 --- a/packages/zwave-js/src/lib/controller/Controller.nodes.getOrThrow.test.ts +++ b/packages/zwave-js/src/lib/controller/Controller.nodes.getOrThrow.test.ts @@ -1,51 +1,63 @@ import { ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../Utils"; -import type { Driver } from "../driver/Driver"; -import { createAndStartTestingDriver } from "../driver/DriverMock"; -import { ZWaveNode } from "../node/Node"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../Utils.js"; +import type { Driver } from "../driver/Driver.js"; +import { createAndStartTestingDriver } from "../driver/DriverMock.js"; +import { ZWaveNode } from "../node/Node.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.before(async (t) => { - t.timeout(30000); - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - skipNodeInterview: true, - beforeStartup(mockPort) { - t.context.controller = new MockController({ serial: mockPort }); - t.context.controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - }, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipNodeInterview: true, + beforeStartup(mockPort) { + context.controller = new MockController({ + serial: mockPort, + }); + context.controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + }, + }); + context.driver = driver; -test.after.always(async (t) => { - await t.context.driver.destroy(); + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test("should return a node if it was found", (t) => { - const { driver } = t.context; +test("should return a node if it was found", ({ context, expect }) => { + const { driver } = context; const node2 = new ZWaveNode(2, driver); (driver.controller.nodes as ThrowingMap).set( node2.id, node2, ); - t.notThrows(() => driver.controller.nodes.getOrThrow(2)); + expect(() => driver.controller.nodes.getOrThrow(2)).not.toThrow(); }); -test("should throw if the node was not found", (t) => { - const { driver } = t.context; - assertZWaveError(t, () => driver.controller.nodes.getOrThrow(3), { +test("should throw if the node was not found", ({ context, expect }) => { + const { driver } = context; + assertZWaveError(expect, () => driver.controller.nodes.getOrThrow(3), { errorCode: ZWaveErrorCodes.Controller_NodeNotFound, }); }); diff --git a/packages/zwave-js/src/lib/controller/Controller.ts b/packages/zwave-js/src/lib/controller/Controller.ts index 78db7005be82..099245bcffb2 100644 --- a/packages/zwave-js/src/lib/controller/Controller.ts +++ b/packages/zwave-js/src/lib/controller/Controller.ts @@ -371,36 +371,36 @@ import { num2hex, pick, } from "@zwave-js/shared"; -import { distinct } from "alcalzone-shared/arrays"; -import { wait } from "alcalzone-shared/async"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { wait } from "alcalzone-shared/async/index.js"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import { roundTo } from "alcalzone-shared/math"; -import { isObject } from "alcalzone-shared/typeguards"; +} from "alcalzone-shared/deferred-promise/index.js"; +import { roundTo } from "alcalzone-shared/math/index.js"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import crypto from "node:crypto"; -import type { Driver } from "../driver/Driver"; -import { cacheKeyUtils, cacheKeys } from "../driver/NetworkCache"; -import type { StatisticsEventCallbacks } from "../driver/Statistics"; -import { type TaskBuilder, TaskPriority } from "../driver/Task"; -import { DeviceClass } from "../node/DeviceClass"; -import { ZWaveNode } from "../node/Node"; -import { VirtualNode } from "../node/VirtualNode"; +import type { Driver } from "../driver/Driver.js"; +import { cacheKeyUtils, cacheKeys } from "../driver/NetworkCache.js"; +import type { StatisticsEventCallbacks } from "../driver/Statistics.js"; +import { type TaskBuilder, TaskPriority } from "../driver/Task.js"; +import { DeviceClass } from "../node/DeviceClass.js"; +import { ZWaveNode } from "../node/Node.js"; +import { VirtualNode } from "../node/VirtualNode.js"; import { InterviewStage, type LifelineRoutes, NodeStatus, -} from "../node/_Types"; +} from "../node/_Types.js"; import { type ControllerStatistics, ControllerStatisticsHost, -} from "./ControllerStatistics"; -import { ZWaveFeature, minFeatureVersions } from "./Features"; +} from "./ControllerStatistics.js"; +import { ZWaveFeature, minFeatureVersions } from "./Features.js"; import { downloadFirmwareUpdate, getAvailableFirmwareUpdates, -} from "./FirmwareUpdateService"; +} from "./FirmwareUpdateService.js"; import { type ExclusionOptions, ExclusionStrategy, @@ -423,10 +423,10 @@ import { type ReplaceNodeOptions, SecurityBootstrapFailure, type SmartStartProvisioningEntry, -} from "./Inclusion"; -import { SerialNVMIO500, SerialNVMIO700 } from "./NVMIO"; -import { determineNIF } from "./NodeInformationFrame"; -import { protocolVersionToSDKVersion } from "./ZWaveSDKVersions"; +} from "./Inclusion.js"; +import { SerialNVMIO500, SerialNVMIO700 } from "./NVMIO.js"; +import { determineNIF } from "./NodeInformationFrame.js"; +import { protocolVersionToSDKVersion } from "./ZWaveSDKVersions.js"; import { type ControllerFirmwareUpdateProgress, type ControllerFirmwareUpdateResult, @@ -437,8 +437,8 @@ import { type RebuildRoutesOptions, type RebuildRoutesStatus, type SDKVersion, -} from "./_Types"; -import { assertProvisioningEntry, isRebuildRoutesTask } from "./utils"; +} from "./_Types.js"; +import { assertProvisioningEntry, isRebuildRoutesTask } from "./utils.js"; // Strongly type the event emitter events interface ControllerEventCallbacks diff --git a/packages/zwave-js/src/lib/controller/ControllerStatistics.ts b/packages/zwave-js/src/lib/controller/ControllerStatistics.ts index 061a766bdb9c..109cab21a881 100644 --- a/packages/zwave-js/src/lib/controller/ControllerStatistics.ts +++ b/packages/zwave-js/src/lib/controller/ControllerStatistics.ts @@ -1,4 +1,4 @@ -import { StatisticsHost } from "../driver/Statistics"; +import { StatisticsHost } from "../driver/Statistics.js"; export class ControllerStatisticsHost extends StatisticsHost diff --git a/packages/zwave-js/src/lib/controller/Features.ts b/packages/zwave-js/src/lib/controller/Features.ts index 4a608603036b..e6f6537907d2 100644 --- a/packages/zwave-js/src/lib/controller/Features.ts +++ b/packages/zwave-js/src/lib/controller/Features.ts @@ -1,4 +1,4 @@ -import type { SDKVersion } from "./_Types"; +import type { SDKVersion } from "./_Types.js"; /** A named list of Z-Wave features */ export enum ZWaveFeature { diff --git a/packages/zwave-js/src/lib/controller/FirmwareUpdateService.ts b/packages/zwave-js/src/lib/controller/FirmwareUpdateService.ts index 9c5b2bd30228..bfb5dfb60fbd 100644 --- a/packages/zwave-js/src/lib/controller/FirmwareUpdateService.ts +++ b/packages/zwave-js/src/lib/controller/FirmwareUpdateService.ts @@ -7,19 +7,15 @@ import { guessFirmwareFileFormat, } from "@zwave-js/core"; import { formatId } from "@zwave-js/shared"; +import type { Headers, OptionsOfTextResponseBody } from "got"; import crypto from "node:crypto"; +import type PQueue from "p-queue"; import type { FirmwareUpdateDeviceID, FirmwareUpdateFileInfo, FirmwareUpdateInfo, FirmwareUpdateServiceResponse, -} from "./_Types"; - -// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529 -import type { Headers, OptionsOfTextResponseBody } from "got"; - -// @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529 -import type PQueue from "p-queue"; +} from "./_Types.js"; function serviceURL(): string { return process.env.ZWAVEJS_FW_SERVICE_URL || "https://firmware.zwave-js.io"; diff --git a/packages/zwave-js/src/lib/controller/Inclusion.ts b/packages/zwave-js/src/lib/controller/Inclusion.ts index f4334a0f56df..0e655fc16597 100644 --- a/packages/zwave-js/src/lib/controller/Inclusion.ts +++ b/packages/zwave-js/src/lib/controller/Inclusion.ts @@ -3,7 +3,7 @@ import type { Protocols, SecurityClass, } from "@zwave-js/core/safe"; -import type { DeviceClass } from "../node/DeviceClass"; +import type { DeviceClass } from "../node/DeviceClass.js"; /** Additional information about the outcome of a node inclusion */ export type InclusionResult = diff --git a/packages/zwave-js/src/lib/controller/MockControllerBehaviors.ts b/packages/zwave-js/src/lib/controller/MockControllerBehaviors.ts index d46ad7394fd1..c4d2c959344f 100644 --- a/packages/zwave-js/src/lib/controller/MockControllerBehaviors.ts +++ b/packages/zwave-js/src/lib/controller/MockControllerBehaviors.ts @@ -13,7 +13,16 @@ import { ZWaveErrorCodes, isZWaveError, } from "@zwave-js/core"; -import { ApplicationCommandRequest } from "@zwave-js/serial/serialapi"; +import { + ApplicationCommandRequest, + SendDataBridgeRequest, + SendDataBridgeRequestTransmitReport, + SendDataBridgeResponse, + type SendDataMessage, + SendDataMulticastBridgeRequest, + SendDataMulticastBridgeRequestTransmitReport, + SendDataMulticastBridgeResponse, +} from "@zwave-js/serial/serialapi"; import { type ApplicationUpdateRequest, ApplicationUpdateRequestNodeInfoReceived, @@ -93,13 +102,13 @@ import { MockControllerCommunicationState, MockControllerInclusionState, MockControllerStateKeys, -} from "./MockControllerState"; -import { determineNIF } from "./NodeInformationFrame"; +} from "./MockControllerState.js"; +import { determineNIF } from "./NodeInformationFrame.js"; function createLazySendDataPayload( controller: MockController, node: MockNode, - msg: SendDataRequest | SendDataMulticastRequest, + msg: SendDataMessage, ): () => CommandClass { return () => { try { @@ -474,6 +483,197 @@ const handleSendDataMulticast: MockControllerBehavior = { }, }; +const handleSendDataBridge: MockControllerBehavior = { + async onHostMessage(controller, msg) { + if (msg instanceof SendDataBridgeRequest) { + // Check if this command is legal right now + const state = controller.state.get( + MockControllerStateKeys.CommunicationState, + ) as MockControllerCommunicationState | undefined; + if ( + state != undefined + && state !== MockControllerCommunicationState.Idle + ) { + throw new Error( + "Received SendDataBridgeRequest while not idle", + ); + } + + // Put the controller into sending state + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.Sending, + ); + + // Notify the host that the message was sent + const res = new SendDataBridgeResponse({ + wasSent: true, + }); + await controller.sendMessageToHost(res); + + // We deferred parsing of the CC because it requires the node's host to do so. + // Now we can do that. Also set the CC node ID to the controller's own node ID, + // so CC knows it came from the controller's node ID. + const node = controller.nodes.get(msg.getNodeId()!)!; + // Create a lazy frame, so it can be deserialized on the node after a short delay to simulate radio transmission + const lazyPayload = createLazySendDataPayload( + controller, + node, + msg, + ); + const lazyFrame = createMockZWaveRequestFrame(lazyPayload, { + ackRequested: !!(msg.transmitOptions & TransmitOptions.ACK), + }); + const ackPromise = controller.sendToNode(node, lazyFrame); + + if (msg.callbackId !== 0) { + // Put the controller into waiting state + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.WaitingForNode, + ); + + // Wait for the ACK and notify the host + let ack = false; + try { + const ackResult = await ackPromise; + ack = !!ackResult?.ack; + } catch (e) { + // We want to know when we're using a command in tests that cannot be decoded yet + if ( + isZWaveError(e) + && e.code + === ZWaveErrorCodes.Deserialization_NotImplemented + ) { + console.error(e.message); + throw e; + } + + // Treat all other errors as no response + } + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.Idle, + ); + + const cb = new SendDataBridgeRequestTransmitReport({ + callbackId: msg.callbackId, + transmitStatus: ack + ? TransmitStatus.OK + : TransmitStatus.NoAck, + }); + + await controller.sendMessageToHost(cb); + } else { + // No callback was requested, we're done + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.Idle, + ); + } + return true; + } + }, +}; + +const handleSendDataMulticastBridge: MockControllerBehavior = { + async onHostMessage(controller, msg) { + if (msg instanceof SendDataMulticastBridgeRequest) { + // Check if this command is legal right now + const state = controller.state.get( + MockControllerStateKeys.CommunicationState, + ) as MockControllerCommunicationState | undefined; + if ( + state != undefined + && state !== MockControllerCommunicationState.Idle + ) { + throw new Error( + "Received SendDataMulticastBridgeRequest while not idle", + ); + } + + // Put the controller into sending state + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.Sending, + ); + + // Notify the host that the message was sent + const res = new SendDataMulticastBridgeResponse({ + wasSent: true, + }); + await controller.sendMessageToHost(res); + + // We deferred parsing of the CC because it requires the node's host to do so. + // Now we can do that. Also set the CC node ID to the controller's own node ID, + // so CC knows it came from the controller's node ID. + const nodeIds = msg.nodeIds; + + const ackPromises = nodeIds.map((nodeId) => { + const node = controller.nodes.get(nodeId)!; + // Create a lazy frame, so it can be deserialized on the node after a short delay to simulate radio transmission + const lazyPayload = createLazySendDataPayload( + controller, + node, + msg, + ); + const lazyFrame = createMockZWaveRequestFrame(lazyPayload, { + ackRequested: !!(msg.transmitOptions & TransmitOptions.ACK), + }); + const ackPromise = controller.sendToNode(node, lazyFrame); + return ackPromise; + }); + + if (msg.callbackId !== 0) { + // Put the controller into waiting state + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.WaitingForNode, + ); + + // Wait for the ACKs and notify the host + let ack = false; + try { + const ackResults = await Promise.all(ackPromises); + ack = ackResults.every((result) => !!result?.ack); + } catch (e) { + // We want to know when we're using a command in tests that cannot be decoded yet + if ( + isZWaveError(e) + && e.code + === ZWaveErrorCodes.Deserialization_NotImplemented + ) { + console.error(e.message); + throw e; + } + + // Treat all other errors as no response + } + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.Idle, + ); + + const cb = new SendDataMulticastBridgeRequestTransmitReport({ + callbackId: msg.callbackId, + transmitStatus: ack + ? TransmitStatus.OK + : TransmitStatus.NoAck, + }); + + await controller.sendMessageToHost(cb); + } else { + // No callback was requested, we're done + controller.state.set( + MockControllerStateKeys.CommunicationState, + MockControllerCommunicationState.Idle, + ); + } + return true; + } + }, +}; + const handleRequestNodeInfo: MockControllerBehavior = { async onHostMessage(controller, msg) { if (msg instanceof RequestNodeInfoRequest) { @@ -803,6 +1003,8 @@ export function createDefaultBehaviors(): MockControllerBehavior[] { respondToGetNodeProtocolInfo, handleSendData, handleSendDataMulticast, + handleSendDataBridge, + handleSendDataMulticastBridge, handleRequestNodeInfo, handleAssignSUCReturnRoute, handleAddNode, diff --git a/packages/zwave-js/src/lib/controller/NVMIO.ts b/packages/zwave-js/src/lib/controller/NVMIO.ts index 1a01c1dbf746..8ef224a86bf3 100644 --- a/packages/zwave-js/src/lib/controller/NVMIO.ts +++ b/packages/zwave-js/src/lib/controller/NVMIO.ts @@ -2,7 +2,7 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import { NVMAccess, type NVMIO } from "@zwave-js/nvmedit"; import { FunctionType } from "@zwave-js/serial"; import { nvmSizeToBufferSize } from "@zwave-js/serial/serialapi"; -import { type ZWaveController } from "./Controller"; +import { type ZWaveController } from "./Controller.js"; /** NVM IO over serial for 500 series controllers */ export class SerialNVMIO500 implements NVMIO { diff --git a/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.test.ts b/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.test.ts index f8200c5b57dc..54825fd98d9d 100644 --- a/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.test.ts +++ b/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.test.ts @@ -1,24 +1,24 @@ -import test from "ava"; -import { protocolVersionToSDKVersion } from "./ZWaveSDKVersions"; +import { test } from "vitest"; +import { protocolVersionToSDKVersion } from "./ZWaveSDKVersions.js"; test("protocolVersionToSDKVersion() looks up the correct SDK version for a given protocol version", (t) => { - t.is(protocolVersionToSDKVersion("2.97"), "4.51.0"); - t.is(protocolVersionToSDKVersion("4.12"), "6.60.0-beta"); + t.expect(protocolVersionToSDKVersion("2.97")).toBe("4.51.0"); + t.expect(protocolVersionToSDKVersion("4.12")).toBe("6.60.0-beta"); }); test("protocolVersionToSDKVersion() falls back to the protocol version if the SDK version is not found", (t) => { - t.is(protocolVersionToSDKVersion("8.99"), "8.99"); + t.expect(protocolVersionToSDKVersion("8.99")).toBe("8.99"); }); test("protocolVersionToSDKVersion() ensures a non-existent version is at least parsable with semver", (t) => { - t.is(protocolVersionToSDKVersion("99.01"), "99.1"); + t.expect(protocolVersionToSDKVersion("99.01")).toBe("99.1"); }); test("protocolVersionToSDKVersion() finds protocol version 6.02", (t) => { - t.is(protocolVersionToSDKVersion("6.02"), "6.81.1"); + t.expect(protocolVersionToSDKVersion("6.02")).toBe("6.81.1"); }); test("protocolVersionToSDKVersion() handles both the legacy x.0y and x.y.z versions", (t) => { - t.is(protocolVersionToSDKVersion("6.07"), "6.81.6"); - t.is(protocolVersionToSDKVersion("6.7.0"), "6.81.6"); + t.expect(protocolVersionToSDKVersion("6.07")).toBe("6.81.6"); + t.expect(protocolVersionToSDKVersion("6.7.0")).toBe("6.81.6"); }); diff --git a/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.ts b/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.ts index 0b8ad9f583d3..f9a0fc8962fd 100644 --- a/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.ts +++ b/packages/zwave-js/src/lib/controller/ZWaveSDKVersions.ts @@ -1,4 +1,4 @@ -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; // Based on INS13954-13, chapter 7 const versions = Object.freeze([ diff --git a/packages/zwave-js/src/lib/controller/utils.assertProvisioningEntry.test.ts b/packages/zwave-js/src/lib/controller/utils.assertProvisioningEntry.test.ts index 08bd7a2d5c78..9234833a893e 100644 --- a/packages/zwave-js/src/lib/controller/utils.assertProvisioningEntry.test.ts +++ b/packages/zwave-js/src/lib/controller/utils.assertProvisioningEntry.test.ts @@ -1,7 +1,7 @@ import { SecurityClass, assertZWaveError } from "@zwave-js/core"; -import test from "ava"; -import { ProvisioningEntryStatus } from "./Inclusion"; -import { assertProvisioningEntry } from "./utils"; +import { test } from "vitest"; +import { ProvisioningEntryStatus } from "./Inclusion.js"; +import { assertProvisioningEntry } from "./utils.js"; // A valid DSK const dsk = "11111-22222-12345-54321-65535-00001-11111-22222"; @@ -12,30 +12,30 @@ const securityClasses = [ ]; test("should throw if the argument is not an object", (t) => { - assertZWaveError(t, () => assertProvisioningEntry(undefined), { + assertZWaveError(t.expect, () => assertProvisioningEntry(undefined), { messageMatches: "not an object", }); - assertZWaveError(t, () => assertProvisioningEntry(1), { + assertZWaveError(t.expect, () => assertProvisioningEntry(1), { messageMatches: "not an object", }); }); test("should throw if the argument does not have a valid dsk", (t) => { - assertZWaveError(t, () => assertProvisioningEntry({}), { + assertZWaveError(t.expect, () => assertProvisioningEntry({}), { messageMatches: "dsk must be a string", }); - assertZWaveError(t, () => assertProvisioningEntry({ dsk: 1 }), { + assertZWaveError(t.expect, () => assertProvisioningEntry({ dsk: 1 }), { messageMatches: "dsk must be a string", }); - assertZWaveError(t, () => assertProvisioningEntry({ dsk: "abc" }), { + assertZWaveError(t.expect, () => assertProvisioningEntry({ dsk: "abc" }), { messageMatches: "dsk does not have the correct format", }); }); test("should throw if the status is invalid", (t) => { assertZWaveError( - t, + t.expect, () => assertProvisioningEntry({ dsk, @@ -44,7 +44,7 @@ test("should throw if the status is invalid", (t) => { { messageMatches: "not a ProvisioningEntryStatus" }, ); assertZWaveError( - t, + t.expect, () => assertProvisioningEntry({ dsk, @@ -56,7 +56,7 @@ test("should throw if the status is invalid", (t) => { test("should throw if the securityClasses are invalid", (t) => { assertZWaveError( - t, + t.expect, () => assertProvisioningEntry({ dsk, @@ -66,7 +66,7 @@ test("should throw if the securityClasses are invalid", (t) => { { messageMatches: "securityClasses must be an array" }, ); assertZWaveError( - t, + t.expect, () => assertProvisioningEntry({ dsk, @@ -79,7 +79,7 @@ test("should throw if the securityClasses are invalid", (t) => { test("should throw if the requestedSecurityClasses are invalid", (t) => { assertZWaveError( - t, + t.expect, () => assertProvisioningEntry({ dsk, @@ -90,7 +90,7 @@ test("should throw if the requestedSecurityClasses are invalid", (t) => { { messageMatches: "requestedSecurityClasses must be an array" }, ); assertZWaveError( - t, + t.expect, () => assertProvisioningEntry({ dsk, @@ -116,6 +116,4 @@ test("happy path", (t) => { status: ProvisioningEntryStatus.Active, requestedSecurityClasses: [SecurityClass.S0_Legacy], }); - - t.pass(); }); diff --git a/packages/zwave-js/src/lib/controller/utils.ts b/packages/zwave-js/src/lib/controller/utils.ts index 5d14963948db..e67009b8c326 100644 --- a/packages/zwave-js/src/lib/controller/utils.ts +++ b/packages/zwave-js/src/lib/controller/utils.ts @@ -5,12 +5,12 @@ import { ZWaveErrorCodes, isValidDSK, } from "@zwave-js/core/safe"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { type Task } from "../driver/Task"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { type Task } from "../driver/Task.js"; import { type PlannedProvisioningEntry, ProvisioningEntryStatus, -} from "./Inclusion"; +} from "./Inclusion.js"; export function assertProvisioningEntry( arg: any, diff --git a/packages/zwave-js/src/lib/driver/Driver.ts b/packages/zwave-js/src/lib/driver/Driver.ts index 577d9f3c5106..152bdc6eac7a 100644 --- a/packages/zwave-js/src/lib/driver/Driver.ts +++ b/packages/zwave-js/src/lib/driver/Driver.ts @@ -182,13 +182,13 @@ import { pathExists, pick, } from "@zwave-js/shared"; -import { distinct } from "alcalzone-shared/arrays"; -import { wait } from "alcalzone-shared/async"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { wait } from "alcalzone-shared/async/index.js"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +} from "alcalzone-shared/deferred-promise/index.js"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import { randomBytes } from "node:crypto"; import type { EventEmitter } from "node:events"; import fs from "node:fs/promises"; @@ -198,18 +198,18 @@ import { URL } from "node:url"; import * as util from "node:util"; import { SerialPort } from "serialport"; import { InterpreterStatus, interpret } from "xstate"; -import { ZWaveController } from "../controller/Controller"; -import { InclusionState, RemoveNodeReason } from "../controller/Inclusion"; -import { DriverLogger } from "../log/Driver"; -import type { Endpoint } from "../node/Endpoint"; -import type { ZWaveNode } from "../node/Node"; +import { ZWaveController } from "../controller/Controller.js"; +import { InclusionState, RemoveNodeReason } from "../controller/Inclusion.js"; +import { DriverLogger } from "../log/Driver.js"; +import type { Endpoint } from "../node/Endpoint.js"; +import type { ZWaveNode } from "../node/Node.js"; import { InterviewStage, NodeStatus, type ZWaveNodeEventCallbacks, type ZWaveNotificationCallback, zWaveNodeEvents, -} from "../node/_Types"; +} from "../node/_Types.js"; import { SendTestFrameRequest, @@ -222,56 +222,56 @@ import { containsSerializedCC, isCommandRequest, } from "@zwave-js/serial/serialapi"; -import { PACKAGE_NAME, PACKAGE_VERSION } from "../_version"; -import { type ZWaveNodeBase } from "../node/mixins/00_Base"; -import { type NodeWakeup } from "../node/mixins/30_Wakeup"; -import { type NodeValues } from "../node/mixins/40_Values"; -import { type SchedulePoll } from "../node/mixins/60_ScheduledPoll"; -import { reportMissingDeviceConfig } from "../telemetry/deviceConfig"; +import { PACKAGE_NAME, PACKAGE_VERSION } from "../_version.js"; +import { type ZWaveNodeBase } from "../node/mixins/00_Base.js"; +import { type NodeWakeup } from "../node/mixins/30_Wakeup.js"; +import { type NodeValues } from "../node/mixins/40_Values.js"; +import { type SchedulePoll } from "../node/mixins/60_ScheduledPoll.js"; +import { reportMissingDeviceConfig } from "../telemetry/deviceConfig.js"; import { type AppInfo, compileStatistics, sendStatistics, -} from "../telemetry/statistics"; -import { Bootloader } from "./Bootloader"; -import { createMessageGenerator } from "./MessageGenerators"; +} from "../telemetry/statistics.js"; +import { Bootloader } from "./Bootloader.js"; +import { createMessageGenerator } from "./MessageGenerators.js"; import { cacheKeys, deserializeNetworkCacheValue, migrateLegacyNetworkCache, serializeNetworkCacheValue, -} from "./NetworkCache"; -import { type SerialAPIQueueItem, TransactionQueue } from "./Queue"; +} from "./NetworkCache.js"; +import { type SerialAPIQueueItem, TransactionQueue } from "./Queue.js"; import { type SerialAPICommandDoneData, type SerialAPICommandInterpreter, createSerialAPICommandMachine, -} from "./SerialAPICommandMachine"; +} from "./SerialAPICommandMachine.js"; import { type TransactionReducer, type TransactionReducerResult, createMessageDroppedUnexpectedError, serialAPICommandErrorToZWaveError, -} from "./StateMachineShared"; -import { TaskScheduler } from "./Task"; -import { throttlePresets } from "./ThrottlePresets"; -import { Transaction } from "./Transaction"; +} from "./StateMachineShared.js"; +import { TaskScheduler } from "./Task.js"; +import { throttlePresets } from "./ThrottlePresets.js"; +import { Transaction } from "./Transaction.js"; import { type TransportServiceRXInterpreter, createTransportServiceRXMachine, -} from "./TransportServiceMachine"; +} from "./TransportServiceMachine.js"; import { checkForConfigUpdates, installConfigUpdate, installConfigUpdateInDocker, -} from "./UpdateConfig"; -import { mergeUserAgent, userAgentComponentsToString } from "./UserAgent"; +} from "./UpdateConfig.js"; +import { mergeUserAgent, userAgentComponentsToString } from "./UserAgent.js"; import type { EditableZWaveOptions, PartialZWaveOptions, ZWaveOptions, -} from "./ZWaveOptions"; -import { discoverRemoteSerialPorts } from "./mDNSDiscovery"; +} from "./ZWaveOptions.js"; +import { discoverRemoteSerialPorts } from "./mDNSDiscovery.js"; export const libVersion: string = PACKAGE_VERSION; export const libName: string = PACKAGE_NAME; diff --git a/packages/zwave-js/src/lib/driver/Driver.unit.test.ts b/packages/zwave-js/src/lib/driver/Driver.unit.test.ts.txt similarity index 85% rename from packages/zwave-js/src/lib/driver/Driver.unit.test.ts rename to packages/zwave-js/src/lib/driver/Driver.unit.test.ts.txt index 6a5019e55742..98dcf54f8388 100644 --- a/packages/zwave-js/src/lib/driver/Driver.unit.test.ts +++ b/packages/zwave-js/src/lib/driver/Driver.unit.test.ts.txt @@ -2,23 +2,14 @@ import { ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; // import { Message, MessageType, messageTypes } from "@zwave-js/serial"; import { MockSerialPort } from "@zwave-js/serial/mock"; import { Bytes, mergeDeep } from "@zwave-js/shared"; -import test from "ava"; -import proxyquire from "proxyquire"; import sinon from "sinon"; -import { PORT_ADDRESS, createAndStartDriver } from "../test/utils"; -import { type PartialZWaveOptions, driverPresets } from "./ZWaveOptions"; +import { test } from "vitest"; +import { type PartialZWaveOptions, driverPresets } from "./ZWaveOptions.js"; -// @messageTypes(MessageType.Request, 0xff) -// class TestMessage extends Message {} +// FIXME: Check if we need these tests. If so, migrate to createAndStartDriverWithMockPort() -// load the driver with stubbed out Serialport -const { Driver } = proxyquire("./Driver", { - "@zwave-js/serial": { - ZWaveSerialPort: MockSerialPort, - }, -}); - -test.serial("starting the driver should open a new serialport", async (t) => { +test.sequential("starting the driver should open a new serialport", async (t) => { + const driver = new Driver(PORT_ADDRESS, { testingHooks: { skipBootloaderCheck: true, @@ -33,11 +24,11 @@ test.serial("starting the driver should open a new serialport", async (t) => { await driver.start(); const portInstance = MockSerialPort.getInstance(PORT_ADDRESS)!; - t.is(portInstance.openStub.callCount, 1); + t.expect(portInstance.openStub.callCount).toBe(1); await driver.destroy(); }); -test.serial("starting the driver should only work once", async (t) => { +test.sequential("starting the driver should only work once", async (t) => { const driver = new Driver(PORT_ADDRESS, { testingHooks: { skipBootloaderCheck: true, @@ -53,11 +44,11 @@ test.serial("starting the driver should only work once", async (t) => { await driver.start(); const portInstance = MockSerialPort.getInstance(PORT_ADDRESS)!; - t.is(portInstance.openStub.callCount, 1); + t.expect(portInstance.openStub.callCount).toBe(1); await driver.destroy(); }); -test.serial( +test.sequential( "the driver start promise should only be fulfilled after the port was opened", async (t) => { const driver = new Driver(PORT_ADDRESS, { @@ -74,14 +65,14 @@ test.serial( // start the driver const fulfilledSpy = sinon.spy(); const startPromise = driver.start().then(fulfilledSpy); - t.true(fulfilledSpy.notCalled); + t.expect(fulfilledSpy.notCalled).toBe(true); // Opening the mock port succeeds by default await startPromise; await driver.destroy(); }, ); -test.serial( +test.sequential( "the driver start promise should be rejected if the port opening fails", async (t) => { const driver = new Driver(PORT_ADDRESS, { @@ -105,12 +96,12 @@ test.serial( Promise.reject(new Error("NOPE")) ); - await t.throwsAsync(startPromise, { message: /NOPE/ }); + await t.expect(() => startPromise).rejects.toThrowError("NOPE"); await driver.destroy(); }, ); -test.serial( +test.sequential( "after a failed driver start, starting again should not be possible", async (t) => { const driver = new Driver(PORT_ADDRESS, { @@ -131,10 +122,10 @@ test.serial( // fail opening of the serialport const portInstance = MockSerialPort.getInstance(PORT_ADDRESS)!; portInstance.openStub.rejects(new Error("NOPE")); - await t.throwsAsync(startPromise, { message: /NOPE/ }); + await t.expect(() => startPromise).rejects.toThrowError("NOPE"); // try to start again - await assertZWaveError(t, () => driver.start(), { + await assertZWaveError(t.expect, () => driver.start(), { errorCode: ZWaveErrorCodes.Driver_Destroyed, }); @@ -142,7 +133,7 @@ test.serial( }, ); -test.serial( +test.sequential( `starting the driver should throw if no "error" handler is attached`, async (t) => { const driver = new Driver(PORT_ADDRESS, { @@ -150,27 +141,27 @@ test.serial( logConfig: { enabled: false }, }); // start the driver - await assertZWaveError(t, () => driver.start(), { + await assertZWaveError(t.expect, () => driver.start(), { errorCode: ZWaveErrorCodes.Driver_NoErrorHandler, }); }, ); -test.serial( +test.sequential( "the driver passes errors from the serialport through", async (t) => { const { driver, serialport } = await createAndStartDriver(); const errorSpy = sinon.spy(); driver.on("error", errorSpy); serialport.emit("error", new Error("foo")); - t.is(errorSpy.callCount, 1); - t.true(errorSpy.firstCall.args[0].message.includes("foo")); + t.expect(errorSpy.callCount).toBe(1); + t.expect(errorSpy.firstCall.args[0].message.includes("foo")).toBe(true); }, ); -test.serial("the constructor should throw on duplicate security keys", (t) => { - let driver: import("./Driver").Driver; - t.teardown(async () => { +test.sequential("the constructor should throw on duplicate security keys", (t) => { + let driver: import("./Driver.js").Driver; + t.onTestFinished(async () => { if (driver) { await driver.destroy(); driver.removeAllListeners(); @@ -178,7 +169,7 @@ test.serial("the constructor should throw on duplicate security keys", (t) => { }); assertZWaveError( - t, + t.expect, () => { driver = new Driver("/dev/test", { securityKeys: { @@ -222,7 +213,7 @@ test("merging multiple sets of options should work", (t) => { const driver = new Driver("/dev/test", preset1, preset2); - t.like(driver.options, { + t.expect(driver.options).toMatchObject({ attempts: { sendDataJammed: 2, sendData: 3, @@ -259,10 +250,14 @@ test("The result of merging multiple sets of options is still checked", (t) => { }, }; - assertZWaveError(t, () => new Driver("/dev/test", preset1, preset2), { - errorCode: ZWaveErrorCodes.Driver_InvalidOptions, - messageMatches: /Abort/, - }); + assertZWaveError( + t.expect, + () => new Driver("/dev/test", preset1, preset2), + { + errorCode: ZWaveErrorCodes.Driver_InvalidOptions, + messageMatches: /Abort/, + }, + ); }); test("The exported driver presets work", (t) => { @@ -275,7 +270,7 @@ test("The exported driver presets work", (t) => { let expected = mergeDeep({}, driverPresets.SAFE_MODE, true); expected = mergeDeep(expected, driverPresets.AWAKE_LONGER, true); - t.like(driver.options, expected); + t.expect(driver.options).toMatchObject(expected); }); // describe.skip("sending messages", () => { @@ -292,7 +287,7 @@ test("The exported driver presets work", (t) => { // driver.on("error", () => {}); // const msg = new TestMessage(driver); -// await assertZWaveError(t, () => driver.sendMessage(msg), { +// await assertZWaveError(t.expect, () => driver.sendMessage(msg), { // errorCode: ZWaveErrorCodes.Driver_NotReady, // }); @@ -315,7 +310,7 @@ test("The exported driver presets work", (t) => { // driver.start(); // const msg = new TestMessage(driver); -// await assertZWaveError(t, () => driver.sendMessage(msg), { +// await assertZWaveError(t.expect, () => driver.sendMessage(msg), { // errorCode: ZWaveErrorCodes.Driver_NotReady, // }); @@ -343,7 +338,7 @@ test("The exported driver presets work", (t) => { // await expect(startPromise).rejects.toThrow("NOPE"); // const msg = new TestMessage(driver); -// await assertZWaveError(t, () => driver.sendMessage(msg), { +// await assertZWaveError(t.expect, () => driver.sendMessage(msg), { // errorCode: ZWaveErrorCodes.Driver_NotReady, // }); @@ -400,7 +395,7 @@ test("The exported driver presets work", (t) => { // // receive something that's not a message header // await serialport.receiveData(Buffer.from([0xff])); // t.is(errorSpy.callCount, 1); -// assertZWaveError(t, errorSpy.mock.calls[0][0] as unknown, { +// assertZWaveError(t.expect, errorSpy.mock.calls[0][0] as unknown, { // errorCode: ZWaveErrorCodes.Driver_InvalidDataReceived, // }); @@ -442,7 +437,7 @@ test("The exported driver presets work", (t) => { // // This is necessary or the test will finish too early and fail // await promise; // t.is(errorSpy.callCount, 1); -// assertZWaveError(t, errorSpy.mock.calls[0][0] as unknown, { +// assertZWaveError(t.expect, errorSpy.mock.calls[0][0] as unknown, { // errorCode: ZWaveErrorCodes.Driver_Reset, // }); // }); diff --git a/packages/zwave-js/src/lib/driver/DriverMock.ts b/packages/zwave-js/src/lib/driver/DriverMock.ts index c5c4c98ac614..a83d8e465185 100644 --- a/packages/zwave-js/src/lib/driver/DriverMock.ts +++ b/packages/zwave-js/src/lib/driver/DriverMock.ts @@ -4,13 +4,13 @@ import { type MockPortBinding, SerialPortMock, } from "@zwave-js/serial/mock"; -import { createDeferredPromise } from "alcalzone-shared/deferred-promise"; +import { createDeferredPromise } from "alcalzone-shared/deferred-promise/index.js"; import fs from "node:fs/promises"; import { tmpdir } from "node:os"; import path from "node:path"; import type { SerialPort } from "serialport"; -import { Driver } from "./Driver"; -import type { PartialZWaveOptions, ZWaveOptions } from "./ZWaveOptions"; +import { Driver } from "./Driver.js"; +import type { PartialZWaveOptions, ZWaveOptions } from "./ZWaveOptions.js"; export interface CreateAndStartDriverWithMockPortResult { driver: Driver; diff --git a/packages/zwave-js/src/lib/driver/MessageGenerators.ts b/packages/zwave-js/src/lib/driver/MessageGenerators.ts index c563a70381c9..109c1cf88715 100644 --- a/packages/zwave-js/src/lib/driver/MessageGenerators.ts +++ b/packages/zwave-js/src/lib/driver/MessageGenerators.ts @@ -50,13 +50,13 @@ import { } from "@zwave-js/serial/serialapi"; import { type ContainsCC, containsCC } from "@zwave-js/serial/serialapi"; import { getErrorMessage } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import type { Driver } from "./Driver"; -import type { MessageGenerator } from "./Transaction"; +} from "alcalzone-shared/deferred-promise/index.js"; +import type { Driver } from "./Driver.js"; +import type { MessageGenerator } from "./Transaction.js"; export type MessageGeneratorImplementation = ( /** A reference to the driver */ diff --git a/packages/zwave-js/src/lib/driver/NetworkCache.ts b/packages/zwave-js/src/lib/driver/NetworkCache.ts index 28eb8ef1b93c..baa4fbc1053c 100644 --- a/packages/zwave-js/src/lib/driver/NetworkCache.ts +++ b/packages/zwave-js/src/lib/driver/NetworkCache.ts @@ -13,14 +13,14 @@ import { } from "@zwave-js/core"; import type { FileSystem } from "@zwave-js/host"; import { Bytes, getEnumMemberName, num2hex, pickDeep } from "@zwave-js/shared"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import path from "node:path"; import { ProvisioningEntryStatus, type SmartStartProvisioningEntry, -} from "../controller/Inclusion"; -import { DeviceClass } from "../node/DeviceClass"; -import { InterviewStage } from "../node/_Types"; +} from "../controller/Inclusion.js"; +import { DeviceClass } from "../node/DeviceClass.js"; +import { InterviewStage } from "../node/_Types.js"; /** * Defines the keys that are used to store certain properties in the network cache. diff --git a/packages/zwave-js/src/lib/driver/Queue.ts b/packages/zwave-js/src/lib/driver/Queue.ts index 0f22e99d29ed..77d7d9e98237 100644 --- a/packages/zwave-js/src/lib/driver/Queue.ts +++ b/packages/zwave-js/src/lib/driver/Queue.ts @@ -2,9 +2,9 @@ import { type Message } from "@zwave-js/serial"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import { SortedList } from "alcalzone-shared/sorted-list"; -import { type Transaction } from "./Transaction"; +} from "alcalzone-shared/deferred-promise/index.js"; +import { SortedList } from "alcalzone-shared/sorted-list/index.js"; +import { type Transaction } from "./Transaction.js"; export interface TransactionQueueOptions { name: string; diff --git a/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.test.ts b/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.test.ts index bbb96eb3eabb..ac65f84309e9 100644 --- a/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.test.ts +++ b/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.test.ts @@ -3,9 +3,9 @@ import type { Message } from "@zwave-js/serial"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import ava, { type ExecutionContext, type TestFn } from "ava"; +} from "alcalzone-shared/deferred-promise/index.js"; import sinon from "sinon"; +import { type ExpectStatic, afterAll, beforeAll, test, vi } from "vitest"; import { Machine, type State, assign, interpret } from "xstate"; import { dummyCallbackNOK, @@ -18,20 +18,14 @@ import { dummyMessageWithResponseWithCallback, dummyResponseNOK, dummyResponseOK, -} from "../test/messages"; +} from "../test/messages.js"; import { type SerialAPICommandDoneData, type SerialAPICommandInterpreter, type SerialAPICommandMachineParams, type SerialAPICommandServiceImplementations, createSerialAPICommandMachine, -} from "./SerialAPICommandMachine"; - -interface AvaTestContext { - clock: sinon.SinonFakeTimers; -} - -const test = ava as TestFn; +} from "./SerialAPICommandMachine.js"; interface TestMachineStateSchema { states: { @@ -93,7 +87,7 @@ interface MockImplementations { } interface TestContext { - avaExecutionContext: ExecutionContext; + expect: ExpectStatic; interpreter: SerialAPICommandInterpreter; implementations: MockImplementations; sendDataPromise?: DeferredPromise | undefined; @@ -116,12 +110,12 @@ const machineParams: SerialAPICommandMachineParams = { }, }; -test.before((t) => { - t.context.clock = sinon.useFakeTimers(); +beforeAll((t) => { + vi.useFakeTimers(); }); -test.after.always((t) => { - t.context.clock.restore(); +afterAll((t) => { + vi.useRealTimers(); }); const testMachine = Machine< @@ -164,7 +158,7 @@ const testMachine = Machine< meta: { test: async ( { - avaExecutionContext: t, + expect, interpreter, implementations: { sendData }, }: TestContext, @@ -173,15 +167,17 @@ const testMachine = Machine< // Skip the wait time if there should be any const att = state.context.attempt; if (att > 1) { - t.is(interpreter.getSnapshot().value, "retryWait"); - t.context.clock.tick(100 + (att - 1) * 1000); + expect(interpreter.getSnapshot().value).toBe( + "retryWait", + ); + vi.advanceTimersByTime(100 + (att - 1) * 1000); } // Assert that sendData was called - t.is(interpreter.getSnapshot().value, "sending"); + expect(interpreter.getSnapshot().value).toBe("sending"); // but not more than 3 times - t.true(att <= 3); - t.is(sendData.callCount, att); + expect(att).toBeLessThanOrEqual(3); + expect(sendData.callCount).toBe(att); }, }, }, @@ -261,26 +257,26 @@ const testMachine = Machine< unsolicited: { meta: { test: ({ - avaExecutionContext: t, + expect, respondedUnsolicited, }: TestContext) => { - t.true(respondedUnsolicited); + expect(respondedUnsolicited).toBe(true); }, }, }, success: { meta: { test: ({ - avaExecutionContext: t, + expect, interpreter, expectedResult, machineResult, }: TestContext) => { // Ensure that the interpreter is in "success" state - t.is(interpreter.getSnapshot().value, "success"); + expect(interpreter.getSnapshot().value).toBe("success"); // with the correct reason // expect(machineResult).toBeObject(); - t.like(machineResult, { + expect(machineResult).toMatchObject({ type: "success", result: expectedResult, }); @@ -290,22 +286,22 @@ const testMachine = Machine< failure: { meta: { test: ({ - avaExecutionContext: t, + expect, interpreter, expectedFailureReason, machineResult, implementations: { sendData }, }: TestContext) => { // Ensure that the interpreter is in "failure" state - t.is(interpreter.getSnapshot().value, "failure"); + expect(interpreter.getSnapshot().value).toBe("failure"); // with the correct reason // expect(machineResult).toBeObject(); - t.like(machineResult, { + expect(machineResult).toMatchObject({ type: "failure", reason: expectedFailureReason, }); // and that at most three attempts were made - t.true(sendData.callCount <= 3); + expect(sendData.callCount).toBeLessThanOrEqual(3); }, }, }, @@ -375,14 +371,14 @@ const testModel = createModel( message: dummyMessageUnrelated, }); }, - ACK_TIMEOUT: ({ avaExecutionContext: t }) => { - t.context.clock.tick(machineParams.timeouts.ack); + ACK_TIMEOUT: ({ expect }) => { + vi.advanceTimersByTime(machineParams.timeouts.ack); }, - RESPONSE_TIMEOUT: ({ avaExecutionContext: t }) => { - t.context.clock.tick(machineParams.timeouts.response); + RESPONSE_TIMEOUT: ({ expect }) => { + vi.advanceTimersByTime(machineParams.timeouts.response); }, - CALLBACK_TIMEOUT: ({ avaExecutionContext: t }) => { - t.context.clock.tick(machineParams.timeouts.sendDataCallback); + CALLBACK_TIMEOUT: ({ expect }) => { + vi.advanceTimersByTime(machineParams.timeouts.sendDataCallback); }, }); @@ -405,7 +401,7 @@ testPlans.forEach((plan) => { // ) { // return; // } - test.serial(`${planDescription} ${path.description}`, async (t) => { + test.sequential(`${planDescription} ${path.description}`, async (t) => { // eslint-disable-next-line prefer-const let context: TestContext; const sendData = sinon.stub().callsFake(() => { @@ -435,7 +431,6 @@ testPlans.forEach((plan) => { const match = createMachineRegex.exec(path.description); if (!match?.groups?.json) { await path.test(undefined as any); - t.pass(); return; } @@ -451,7 +446,7 @@ testPlans.forEach((plan) => { ); context = { - avaExecutionContext: t, + expect: t.expect, interpreter: interpret(machine), implementations: implementations as any, }; @@ -501,7 +496,6 @@ testPlans.forEach((plan) => { } await path.test(context); - t.pass(); }); }); }); @@ -512,5 +506,4 @@ testPlans.forEach((plan) => { // return !!stateNode.meta; // }, // }); -// t.pass(); -// }); +// // }); diff --git a/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.ts b/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.ts index a5867330b147..1a83951f5ac9 100644 --- a/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.ts +++ b/packages/zwave-js/src/lib/driver/SerialAPICommandMachine.ts @@ -14,7 +14,7 @@ import { createMachine, raise, } from "xstate"; -import type { ZWaveOptions } from "./ZWaveOptions"; +import type { ZWaveOptions } from "./ZWaveOptions.js"; export interface SerialAPICommandStateSchema { states: { diff --git a/packages/zwave-js/src/lib/driver/StateMachineShared.ts b/packages/zwave-js/src/lib/driver/StateMachineShared.ts index e44b5544964a..88a86387130f 100644 --- a/packages/zwave-js/src/lib/driver/StateMachineShared.ts +++ b/packages/zwave-js/src/lib/driver/StateMachineShared.ts @@ -29,8 +29,8 @@ import { type InterpreterFrom, type InterpreterOptions, } from "xstate"; -import type { SerialAPICommandDoneData } from "./SerialAPICommandMachine"; -import type { Transaction } from "./Transaction"; +import type { SerialAPICommandDoneData } from "./SerialAPICommandMachine.js"; +import type { Transaction } from "./Transaction.js"; export function serialAPICommandErrorToZWaveError( reason: (SerialAPICommandDoneData & { type: "failure" })["reason"], diff --git a/packages/zwave-js/src/lib/driver/Statistics.test.ts b/packages/zwave-js/src/lib/driver/Statistics.test.ts index e2a1a62d9428..ef4c8d425887 100644 --- a/packages/zwave-js/src/lib/driver/Statistics.test.ts +++ b/packages/zwave-js/src/lib/driver/Statistics.test.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/no-empty-object-type */ import { Mixin } from "@zwave-js/shared"; -import test from "ava"; import EventEmitter from "node:events"; -import { StatisticsHost } from "./Statistics"; +import { test } from "vitest"; +import { StatisticsHost } from "./Statistics.js"; interface TestStatistics { one: number; @@ -25,7 +25,7 @@ class Test extends EventEmitter {} test("the statistics property is available and has the correct defaults", (t) => { const test = new Test(); - t.deepEqual(test.statistics, { + t.expect(test.statistics).toStrictEqual({ one: 1, two: 2, }); diff --git a/packages/zwave-js/src/lib/driver/Task.test.ts b/packages/zwave-js/src/lib/driver/Task.test.ts index a0fd0920a78e..35c2b19bce6d 100644 --- a/packages/zwave-js/src/lib/driver/Task.test.ts +++ b/packages/zwave-js/src/lib/driver/Task.test.ts @@ -1,21 +1,20 @@ import { ZWaveError, ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; import { noop } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import { createDeferredPromise } from "alcalzone-shared/deferred-promise"; -import test from "ava"; +import { wait } from "alcalzone-shared/async/index.js"; +import { createDeferredPromise } from "alcalzone-shared/deferred-promise/index.js"; +import { test } from "vitest"; import { type TaskBuilder, TaskInterruptBehavior, TaskPriority, type TaskReturnType, TaskScheduler, -} from "./Task"; +} from "./Task.js"; test("The scheduler can be started and stopped", async (t) => { const scheduler = new TaskScheduler(); scheduler.start(); await scheduler.stop(); - t.pass(); }); test("An empty task runs to completion", async (t) => { @@ -26,7 +25,6 @@ test("An empty task runs to completion", async (t) => { task: async function*() {}, }); await task; - t.pass(); }); test("The task promise resolves to the return value of the task function", async (t) => { @@ -38,7 +36,7 @@ test("The task promise resolves to the return value of the task function", async return 1; }, }); - t.is(await task, 1); + t.expect(await task).toBe(1); }); test("A task with multiple interrupt points runs to completion", async (t) => { @@ -52,7 +50,6 @@ test("A task with multiple interrupt points runs to completion", async (t) => { }, }); await task; - t.pass(); }); test("A task with multiple interrupt points has the correct result", async (t) => { @@ -66,7 +63,7 @@ test("A task with multiple interrupt points has the correct result", async (t) = return 2; }, }); - t.is(await task, 2); + t.expect(await task).toBe(2); }); test("Multiple tasks run to completion", async (t) => { @@ -89,7 +86,7 @@ test("Multiple tasks run to completion", async (t) => { }, }); const result = await Promise.all([task1, task2]); - t.deepEqual(result, [1, 2]); + t.expect(result).toStrictEqual([1, 2]); }); test("Higher priority tasks run before lower priority ones if the scheduler is started afterwards", async (t) => { @@ -115,7 +112,7 @@ test("Higher priority tasks run before lower priority ones if the scheduler is s scheduler.start(); await Promise.all([task1, task2]); - t.deepEqual(order, [2, 1]); + t.expect(order).toStrictEqual([2, 1]); }); test("Higher priority tasks run before lower priority ones when added at the same time", async (t) => { @@ -142,7 +139,7 @@ test("Higher priority tasks run before lower priority ones when added at the sam }); await Promise.all([task1, task2]); - t.deepEqual(order, [2, 1]); + t.expect(order).toStrictEqual([2, 1]); }); test("Higher priority tasks run before lower priority ones when added at the same time, part 2", async (t) => { @@ -177,7 +174,7 @@ test("Higher priority tasks run before lower priority ones when added at the sam }); await Promise.all([task1, task2, task3]); - t.deepEqual(order, [2, 1, 3]); + t.expect(order).toStrictEqual([2, 1, 3]); }); test("Higher priority tasks interrupt lower priority ones", async (t) => { @@ -185,9 +182,12 @@ test("Higher priority tasks interrupt lower priority ones", async (t) => { const order: string[] = []; scheduler.start(); + const t1WasStarted = createDeferredPromise(); + const task1 = scheduler.queueTask({ priority: TaskPriority.Normal, task: async function*() { + t1WasStarted.resolve(); order.push("1a"); await wait(1); yield; @@ -197,7 +197,8 @@ test("Higher priority tasks interrupt lower priority ones", async (t) => { order.push("1c"); }, }); - await wait(0); + // The test expects that task 1 has started executing before task 2 is queued + await t1WasStarted; const task2 = scheduler.queueTask({ priority: TaskPriority.High, task: async function*() { @@ -213,7 +214,7 @@ test("Higher priority tasks interrupt lower priority ones", async (t) => { await Promise.all([task1, task2]); - t.deepEqual(order, ["1a", "2a", "2b", "2c", "1b", "1c"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b", "2c", "1b", "1c"]); }); test("Higher priority tasks interrupt lower priority ones, part 2", async (t) => { @@ -262,7 +263,17 @@ test("Higher priority tasks interrupt lower priority ones, part 2", async (t) => await Promise.all([task1, task2, task3]); - t.deepEqual(order, ["1a", "2a", "2b", "2c", "3a", "3b", "3c", "1b", "1c"]); + t.expect(order).toStrictEqual([ + "1a", + "2a", + "2b", + "2c", + "3a", + "3b", + "3c", + "1b", + "1c", + ]); }); test("Higher priority tasks do not interrupt non-interruptible lower priority ones", async (t) => { @@ -299,7 +310,7 @@ test("Higher priority tasks do not interrupt non-interruptible lower priority on await Promise.all([task1, task2]); - t.deepEqual(order, ["1a", "1b", "1c", "2a", "2b", "2c"]); + t.expect(order).toStrictEqual(["1a", "1b", "1c", "2a", "2b", "2c"]); }); test("Interrupting a task with the Restart interrupt behavior restarts it completely", async (t) => { @@ -307,10 +318,13 @@ test("Interrupting a task with the Restart interrupt behavior restarts it comple const order: string[] = []; scheduler.start(); + const t1WasStarted = createDeferredPromise(); + const task1 = scheduler.queueTask({ priority: TaskPriority.Normal, interrupt: TaskInterruptBehavior.Restart, task: async function*() { + t1WasStarted.resolve(); order.push("1a"); await wait(1); yield; @@ -320,7 +334,8 @@ test("Interrupting a task with the Restart interrupt behavior restarts it comple order.push("1c"); }, }); - await wait(0); + // The test expects that task 1 has started executing before task 2 is queued + await t1WasStarted; const task2 = scheduler.queueTask({ priority: TaskPriority.High, task: async function*() { @@ -336,7 +351,7 @@ test("Interrupting a task with the Restart interrupt behavior restarts it comple await Promise.all([task1, task2]); - t.deepEqual(order, ["1a", "2a", "2b", "2c", "1a", "1b", "1c"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b", "2c", "1a", "1b", "1c"]); }); test("Completed Restart tasks are not restarted after completion", async (t) => { @@ -371,7 +386,7 @@ test("Completed Restart tasks are not restarted after completion", async (t) => await Promise.all([task1, task2]); - t.deepEqual(order, ["1a", "1b", "1c", "2a", "2b", "2c"]); + t.expect(order).toStrictEqual(["1a", "1b", "1c", "2a", "2b", "2c"]); }); test("Yielding a promise-returning function causes the scheduler to wait for that until resuming the task", async (t) => { @@ -393,13 +408,13 @@ test("Yielding a promise-returning function causes the scheduler to wait for tha // Wait long enough that the task is definitely waiting for the promise await wait(50); - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); // Run to completion yieldedPromise.resolve(); await task1; - t.deepEqual(order, ["1a", "1b"]); + t.expect(order).toStrictEqual(["1a", "1b"]); }); test("While a task is waiting, higher-priority tasks are still executed", async (t) => { @@ -437,13 +452,13 @@ test("While a task is waiting, higher-priority tasks are still executed", async // Task 1 should not have completed yet // Wait long enough that it would have if the scheduler didn't work correctly await wait(50); - t.deepEqual(order, ["1a", "2a", "2b"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b"]); // Run task 1 to completion yieldedPromise.resolve(); await task1; - t.deepEqual(order, ["1a", "2a", "2b", "1b"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b", "1b"]); }); test("Waiting tasks are deprioritized over tasks with the same priority", async (t) => { @@ -481,13 +496,13 @@ test("Waiting tasks are deprioritized over tasks with the same priority", async // Task 1 should not have completed yet // Wait long enough that it would have if the scheduler didn't work correctly await wait(50); - t.deepEqual(order, ["1a", "2a", "2b"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b"]); // Run task 1 to completion yieldedPromise.resolve(); await task1; - t.deepEqual(order, ["1a", "2a", "2b", "1b"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b", "1b"]); }); test("Waiting tasks are deprioritized over tasks with a higher priority", async (t) => { @@ -525,13 +540,13 @@ test("Waiting tasks are deprioritized over tasks with a higher priority", async // Task 1 should not have completed yet // Wait long enough that it would have if the scheduler didn't work correctly await wait(50); - t.deepEqual(order, ["1a", "2a", "2b"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b"]); // Run task 1 to completion yieldedPromise.resolve(); await task1; - t.deepEqual(order, ["1a", "2a", "2b", "1b"]); + t.expect(order).toStrictEqual(["1a", "2a", "2b", "1b"]); }); test("Waiting tasks are NOT deprioritized over tasks with a lower priority", async (t) => { @@ -565,13 +580,13 @@ test("Waiting tasks are NOT deprioritized over tasks with a lower priority", asy // Task 2 should not have started yet await wait(50); - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); // Run to completion yieldedPromise.resolve(); await Promise.all([task1, task2]); - t.deepEqual(order, ["1a", "1b", "2a", "2b"]); + t.expect(order).toStrictEqual(["1a", "1b", "2a", "2b"]); }); test("Two tasks of the same priority can wait at the same time", async (t) => { @@ -600,7 +615,7 @@ test("Two tasks of the same priority can wait at the same time", async (t) => { await Promise.all([task1, task2]); - t.deepEqual(order, ["1a", "2a", "1b", "2b"]); + t.expect(order).toStrictEqual(["1a", "2a", "1b", "2b"]); }); test("Stopping the scheduler mid-task works", async (t) => { @@ -634,14 +649,14 @@ test("Stopping the scheduler mid-task works", async (t) => { // Task 2 should not have started yet await wait(1); - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); await scheduler.stop(); // "Run" to completion, but nothing should happen yieldedPromise.resolve(); await wait(50); - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); }); test("Stopping the scheduler works after multiple tasks have run to completion", async (t) => { @@ -664,7 +679,7 @@ test("Stopping the scheduler works after multiple tasks have run to completion", }, }); const result = await Promise.all([task1, task2]); - t.deepEqual(result, [1, 2]); + t.expect(result).toStrictEqual([1, 2]); await scheduler.stop(); }); @@ -694,7 +709,7 @@ test("Tasks can yield-queue higher-priority tasks", async (t) => { await outer; - t.deepEqual(order, ["inner", "outer"]); + t.expect(order).toStrictEqual(["inner", "outer"]); }); test("Tasks can yield-queue same-priority tasks", async (t) => { @@ -722,10 +737,10 @@ test("Tasks can yield-queue same-priority tasks", async (t) => { await outer; - t.deepEqual(order, ["inner", "outer"]); + t.expect(order).toStrictEqual(["inner", "outer"]); }); -test.failing("Tasks cannot yield-queue lower-priority tasks", async (t) => { +test("Tasks cannot yield-queue lower-priority tasks", async (t) => { const scheduler = new TaskScheduler(); scheduler.start(); @@ -748,7 +763,7 @@ test.failing("Tasks cannot yield-queue lower-priority tasks", async (t) => { }, }); - await outer; + t.expect(() => outer).rejects.toThrowError("lower priority"); }); test("Yielding tasks multiple levels deep works", async (t) => { @@ -792,13 +807,13 @@ test("Yielding tasks multiple levels deep works", async (t) => { // Wait long enough that the task is definitely waiting for the promise await wait(10); - t.deepEqual(order, ["outer1", "inner1", "innerinner1"]); + t.expect(order).toStrictEqual(["outer1", "inner1", "innerinner1"]); // Run to completion yieldedPromise.resolve(); await outer; - t.deepEqual(order, [ + t.expect(order).toStrictEqual([ "outer1", "inner1", "innerinner1", @@ -831,7 +846,7 @@ test("Tasks receive the result of yielded tasks", async (t) => { }, }); - t.is(await outer, "foo"); + t.expect(await outer).toBe("foo"); }); test("Tasks receive the result of yielded tasks, part 2", async (t) => { @@ -870,7 +885,7 @@ test("Tasks receive the result of yielded tasks, part 2", async (t) => { }, }); - t.is(await outer, "foobar"); + t.expect(await outer).toBe("foobar"); }); test("Tasks receive the result of yielded tasks, part 3", async (t) => { @@ -898,8 +913,8 @@ test("Tasks receive the result of yielded tasks, part 3", async (t) => { }); const result = await outer; - t.true(result instanceof Error); - t.is(result.message, "foo"); + t.expect(result instanceof Error).toBe(true); + t.expect(result.message).toBe("foo"); }); test("Tasks can queue lower-priority tasks without waiting for them", async (t) => { @@ -929,7 +944,7 @@ test("Tasks can queue lower-priority tasks without waiting for them", async (t) await outer; await inner!; - t.deepEqual(order, ["outer", "inner"]); + t.expect(order).toStrictEqual(["outer", "inner"]); }); test("Failing tasks reject the corresponding Promise", async (t) => { @@ -952,8 +967,8 @@ test("Failing tasks reject the corresponding Promise", async (t) => { }, }); - await t.throwsAsync(task1, { message: "Task 1 failed" }); - t.is(await task2, 2); + await t.expect(() => task1).rejects.toThrowError("Task 1 failed"); + t.expect(await task2).toBe(2); }); test("Tasks can be removed if they haven't been started yet", async (t) => { @@ -989,18 +1004,18 @@ test("Tasks can be removed if they haven't been started yet", async (t) => { // Task 2 should not have started yet await wait(1); - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); await scheduler.removeTasks((t) => t.name === "task2"); - await assertZWaveError(t, () => task2, { + await assertZWaveError(t.expect, () => task2, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); // Run to completion longRunningThing.resolve(); await task1; - t.deepEqual(order, ["1a", "1b"]); + t.expect(order).toStrictEqual(["1a", "1b"]); }); test("Tasks can be removed while paused", async (t) => { @@ -1024,15 +1039,15 @@ test("Tasks can be removed while paused", async (t) => { await wait(1); // The task should have run to the first yield - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); await scheduler.removeTasks((t) => true); - await assertZWaveError(t, () => task1, { + await assertZWaveError(t.expect, () => task1, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); - t.deepEqual(order, ["1a", "1c"]); + t.expect(order).toStrictEqual(["1a", "1c"]); }); test("Tasks can be removed while paused, part 2", async (t) => { @@ -1071,19 +1086,19 @@ test("Tasks can be removed while paused, part 2", async (t) => { await wait(1); // The tasks should have run to the first yield - t.deepEqual(order, ["1a", "2a"]); + t.expect(order).toStrictEqual(["1a", "2a"]); await scheduler.removeTasks((t) => true); - await assertZWaveError(t, () => task1, { + await assertZWaveError(t.expect, () => task1, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); - await assertZWaveError(t, () => task2, { + await assertZWaveError(t.expect, () => task2, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); // Current task "1" gets cleaned up last - t.deepEqual(order, ["1a", "2a", "2c", "1c"]); + t.expect(order).toStrictEqual(["1a", "2a", "2c", "1c"]); }); test("Tasks can be removed while running", async (t) => { @@ -1122,19 +1137,19 @@ test("Tasks can be removed while running", async (t) => { await wait(1); // Task 1 should have run to the first yield, // Task 2 should not have started yet - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); await scheduler.removeTasks((t) => true); - await assertZWaveError(t, () => task1, { + await assertZWaveError(t.expect, () => task1, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); - await assertZWaveError(t, () => task2, { + await assertZWaveError(t.expect, () => task2, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); // Only task 1 should have been cleaned up, since task 2 was not started - t.deepEqual(order, ["1a", "1c"]); + t.expect(order).toStrictEqual(["1a", "1c"]); }); test("Tasks can be removed while running and paused", async (t) => { @@ -1172,20 +1187,20 @@ test("Tasks can be removed while running and paused", async (t) => { await wait(1); // Both tasks should have run to the first yield. - t.deepEqual(order, ["1a", "2a"]); + t.expect(order).toStrictEqual(["1a", "2a"]); await scheduler.removeTasks((t) => true); - await assertZWaveError(t, () => task1, { + await assertZWaveError(t.expect, () => task1, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); - await assertZWaveError(t, () => task2, { + await assertZWaveError(t.expect, () => task2, { errorCode: ZWaveErrorCodes.Driver_TaskRemoved, }); // Both tasks should be cleaned up, 1c before 2c, // since task 2 was the current task and should be cleaned up last - t.deepEqual(order, ["1a", "2a", "1c", "2c"]); + t.expect(order).toStrictEqual(["1a", "2a", "1c", "2c"]); }); test("The task rejection uses the given error, if any", async (t) => { @@ -1209,18 +1224,18 @@ test("The task rejection uses the given error, if any", async (t) => { await wait(1); // The task should have run to the first yield - t.deepEqual(order, ["1a"]); + t.expect(order).toStrictEqual(["1a"]); await scheduler.removeTasks( (t) => true, new ZWaveError("Test error", ZWaveErrorCodes.Driver_Reset), ); - await assertZWaveError(t, () => task1, { + await assertZWaveError(t.expect, () => task1, { errorCode: ZWaveErrorCodes.Driver_Reset, }); - t.deepEqual(order, ["1a", "1c"]); + t.expect(order).toStrictEqual(["1a", "1c"]); }); test("Canceling nested tasks works", async (t) => { @@ -1250,12 +1265,12 @@ test("Canceling nested tasks works", async (t) => { // Wait long enough that the task is definitely waiting for the promise await wait(50); - t.deepEqual(order, ["1a", "2a"]); + t.expect(order).toStrictEqual(["1a", "2a"]); // Cancel all tasks await scheduler.removeTasks(() => true); - t.deepEqual(order, ["1a", "2a"]); + t.expect(order).toStrictEqual(["1a", "2a"]); }); test("Canceling nested tasks works, part 2", async (t) => { @@ -1290,7 +1305,7 @@ test("Canceling nested tasks works, part 2", async (t) => { // FIXME: Restore parent tasks when removing nested tasks await scheduler.removeTasks((t) => t.name === "inner"); - t.is(await outer, "canceled"); + t.expect(await outer).toBe("canceled"); }); test("Splitting tasks into multiple generator functions works", async (t) => { @@ -1318,7 +1333,7 @@ test("Splitting tasks into multiple generator functions works", async (t) => { await task1; - t.deepEqual(order, ["1a", "1b", "1c", "1d"]); + t.expect(order).toStrictEqual(["1a", "1b", "1c", "1d"]); }); test("Split tasks can be canceled", async (t) => { @@ -1351,5 +1366,5 @@ test("Split tasks can be canceled", async (t) => { // Cancel all tasks await scheduler.removeTasks(() => true); - t.deepEqual(order, ["1a", "1b"]); + t.expect(order).toStrictEqual(["1a", "1b"]); }); diff --git a/packages/zwave-js/src/lib/driver/Task.ts b/packages/zwave-js/src/lib/driver/Task.ts index 5a95ccb469ef..bc838d1a9e5b 100644 --- a/packages/zwave-js/src/lib/driver/Task.ts +++ b/packages/zwave-js/src/lib/driver/Task.ts @@ -1,11 +1,11 @@ import { ZWaveError, ZWaveErrorCodes, highResTimestamp } from "@zwave-js/core"; import { createWrappingCounter, evalOrStatic, noop } from "@zwave-js/shared"; -import { type CompareResult } from "alcalzone-shared/comparable"; +import { type CompareResult } from "alcalzone-shared/comparable/index.js"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import { SortedList } from "alcalzone-shared/sorted-list"; +} from "alcalzone-shared/deferred-promise/index.js"; +import { SortedList } from "alcalzone-shared/sorted-list/index.js"; /** A high-level task that can be started and stepped through */ export interface Task { @@ -363,6 +363,11 @@ export class TaskScheduler { promise: waitForPromise, }; } else if (isTaskBuilder(waitFor)) { + if (waitFor.priority > builder.priority) { + throw new Error( + "Tasks cannot yield to tasks with lower priority than their own", + ); + } // Create a sub-task with a reference to this task state = TaskState.AwaitingTask; const subTask = self.createTask(waitFor, this); diff --git a/packages/zwave-js/src/lib/driver/ThrottlePresets.ts b/packages/zwave-js/src/lib/driver/ThrottlePresets.ts index f978ee4a9463..a4b1a2a436e2 100644 --- a/packages/zwave-js/src/lib/driver/ThrottlePresets.ts +++ b/packages/zwave-js/src/lib/driver/ThrottlePresets.ts @@ -1,5 +1,5 @@ import type { JsonlDBOptions } from "@alcalzone/jsonl-db"; -import type { ZWaveOptions } from "./ZWaveOptions"; +import type { ZWaveOptions } from "./ZWaveOptions.js"; export const throttlePresets: Record< ZWaveOptions["storage"]["throttle"], diff --git a/packages/zwave-js/src/lib/driver/Transaction.test.ts b/packages/zwave-js/src/lib/driver/Transaction.test.ts index abfe6ccaa000..5d94cb08c65c 100644 --- a/packages/zwave-js/src/lib/driver/Transaction.test.ts +++ b/packages/zwave-js/src/lib/driver/Transaction.test.ts @@ -4,15 +4,15 @@ import { type Message, getDefaultPriority } from "@zwave-js/serial"; import { GetControllerVersionRequest } from "@zwave-js/serial/serialapi"; import { RemoveFailedNodeRequest } from "@zwave-js/serial/serialapi"; import { SendDataRequest } from "@zwave-js/serial/serialapi"; -import test from "ava"; -import type { ZWaveNode } from "../node/Node"; -import { NodeStatus } from "../node/_Types"; -import type { Driver } from "./Driver"; +import { test } from "vitest"; +import type { ZWaveNode } from "../node/Node.js"; +import { NodeStatus } from "../node/_Types.js"; +import type { Driver } from "./Driver.js"; import { type MessageGenerator, Transaction, type TransactionOptions, -} from "./Transaction"; +} from "./Transaction.js"; function createDummyMessageGenerator(msg: Message): MessageGenerator { return { @@ -72,8 +72,8 @@ test("should compare priority, then the timestamp", (t) => { priority: MessagePriority.Controller, }); // equal priority, earlier timestamp wins - t.is(t1.compareTo(t2), -1); - t.is(t2.compareTo(t1), 1); + t.expect(t1.compareTo(t2)).toBe(-1); + t.expect(t2.compareTo(t1)).toBe(1); const t3 = createDummyTransaction(driverMock, { priority: MessagePriority.Poll, @@ -82,8 +82,8 @@ test("should compare priority, then the timestamp", (t) => { priority: MessagePriority.Controller, }); // lower priority loses - t.is(t3.compareTo(t4), 1); - t.is(t4.compareTo(t3), -1); + t.expect(t3.compareTo(t4)).toBe(1); + t.expect(t4.compareTo(t3)).toBe(-1); // this should not happen but we still need to test it const t5 = createDummyTransaction(driverMock, { @@ -93,8 +93,8 @@ test("should compare priority, then the timestamp", (t) => { priority: MessagePriority.Controller, }); t6.creationTimestamp = t5.creationTimestamp; - t.is(t5.compareTo(t6), 0); - t.is(t6.compareTo(t5), 0); + t.expect(t5.compareTo(t6)).toBe(0); + t.expect(t6.compareTo(t5)).toBe(0); }); test("NodeQuery comparisons should prioritize listening nodes", (t) => { @@ -193,44 +193,44 @@ test("NodeQuery comparisons should prioritize listening nodes", (t) => { const tNoneLowPrio = createTransactionForNode(1, MessagePriority.Poll); // t2/3/4 prioritized because it's listening and t1 is not - t.is(tNone.compareTo(tList), 1); - t.is(tNone.compareTo(tList), 1); - t.is(tNone.compareTo(tFreq), 1); + t.expect(tNone.compareTo(tList)).toBe(1); + t.expect(tNone.compareTo(tList)).toBe(1); + t.expect(tNone.compareTo(tFreq)).toBe(1); // sanity checks - t.is(tList.compareTo(tNone), -1); - t.is(tFreq.compareTo(tNone), -1); - t.is(tListFreq.compareTo(tNone), -1); + t.expect(tList.compareTo(tNone)).toBe(-1); + t.expect(tFreq.compareTo(tNone)).toBe(-1); + t.expect(tListFreq.compareTo(tNone)).toBe(-1); // equal priority because both are (frequent or not) listening - t.is(tList.compareTo(tFreq), 0); - t.is(tList.compareTo(tListFreq), 0); + t.expect(tList.compareTo(tFreq)).toBe(0); + t.expect(tList.compareTo(tListFreq)).toBe(0); // sanity checks - t.is(tFreq.compareTo(tListFreq), 0); - t.is(tFreq.compareTo(tList), 0); - t.is(tListFreq.compareTo(tList), 0); + t.expect(tFreq.compareTo(tListFreq)).toBe(0); + t.expect(tFreq.compareTo(tList)).toBe(0); + t.expect(tListFreq.compareTo(tList)).toBe(0); // NodeQuery (non listening) should be lower than other priorities (listening) - t.is(tNone.compareTo(tListLowPrio), 1); - t.is(tNone.compareTo(tListNormalPrio), 1); + t.expect(tNone.compareTo(tListLowPrio)).toBe(1); + t.expect(tNone.compareTo(tListNormalPrio)).toBe(1); // sanity checks - t.is(tListLowPrio.compareTo(tNone), -1); - t.is(tListNormalPrio.compareTo(tNone), -1); + t.expect(tListLowPrio.compareTo(tNone)).toBe(-1); + t.expect(tListNormalPrio.compareTo(tNone)).toBe(-1); // The default order should apply when both nodes are not listening - t.is(tNone.compareTo(tNoneNormalPrio), 1); - t.is(tNone.compareTo(tNoneLowPrio), -1); + t.expect(tNone.compareTo(tNoneNormalPrio)).toBe(1); + t.expect(tNone.compareTo(tNoneLowPrio)).toBe(-1); // sanity checks - t.is(tNoneNormalPrio.compareTo(tNone), -1); - t.is(tNoneLowPrio.compareTo(tNone), 1); + t.expect(tNoneNormalPrio.compareTo(tNone)).toBe(-1); + t.expect(tNoneLowPrio.compareTo(tNone)).toBe(1); // fallbacks for undefined nodes - t.is(tNoId.compareTo(tNone), 0); - t.is(tNoId.compareTo(tList), 0); - t.is(tFreq.compareTo(tNoId), 0); - t.is(tListFreq.compareTo(tNoId), 0); - t.is(tNoNode.compareTo(tNone), 0); - t.is(tNoNode.compareTo(tList), 0); - t.is(tFreq.compareTo(tNoNode), 0); - t.is(tListFreq.compareTo(tNoNode), 0); + t.expect(tNoId.compareTo(tNone)).toBe(0); + t.expect(tNoId.compareTo(tList)).toBe(0); + t.expect(tFreq.compareTo(tNoId)).toBe(0); + t.expect(tListFreq.compareTo(tNoId)).toBe(0); + t.expect(tNoNode.compareTo(tNone)).toBe(0); + t.expect(tNoNode.compareTo(tList)).toBe(0); + t.expect(tFreq.compareTo(tNoNode)).toBe(0); + t.expect(tListFreq.compareTo(tNoNode)).toBe(0); }); test("Messages in the wakeup queue should be preferred over lesser priorities only if the node is awake", (t) => { @@ -301,31 +301,31 @@ test("Messages in the wakeup queue should be preferred over lesser priorities on const tAsleepLow = createTransaction(2, MessagePriority.Poll); // For alive nodes, the conventional order should apply - t.is(tAwakeHigh.compareTo(tAwakeWU), -1); - t.is(tAwakeHigh.compareTo(tAwakeLow), -1); - t.is(tAwakeWU.compareTo(tAwakeLow), -1); + t.expect(tAwakeHigh.compareTo(tAwakeWU)).toBe(-1); + t.expect(tAwakeHigh.compareTo(tAwakeLow)).toBe(-1); + t.expect(tAwakeWU.compareTo(tAwakeLow)).toBe(-1); // Test the opposite direction aswell - t.is(tAwakeWU.compareTo(tAwakeHigh), 1); - t.is(tAwakeLow.compareTo(tAwakeHigh), 1); - t.is(tAwakeLow.compareTo(tAwakeWU), 1); + t.expect(tAwakeWU.compareTo(tAwakeHigh)).toBe(1); + t.expect(tAwakeLow.compareTo(tAwakeHigh)).toBe(1); + t.expect(tAwakeLow.compareTo(tAwakeWU)).toBe(1); // For asleep nodes, the conventional order should apply too - t.is(tAsleepHigh.compareTo(tAsleepWU), -1); - t.is(tAsleepHigh.compareTo(tAsleepLow), -1); - t.is(tAsleepWU.compareTo(tAsleepLow), -1); + t.expect(tAsleepHigh.compareTo(tAsleepWU)).toBe(-1); + t.expect(tAsleepHigh.compareTo(tAsleepLow)).toBe(-1); + t.expect(tAsleepWU.compareTo(tAsleepLow)).toBe(-1); // Test the opposite direction aswell - t.is(tAsleepWU.compareTo(tAsleepHigh), 1); - t.is(tAsleepLow.compareTo(tAsleepHigh), 1); - t.is(tAsleepLow.compareTo(tAsleepWU), 1); + t.expect(tAsleepWU.compareTo(tAsleepHigh)).toBe(1); + t.expect(tAsleepLow.compareTo(tAsleepHigh)).toBe(1); + t.expect(tAsleepLow.compareTo(tAsleepWU)).toBe(1); // The wake-up priority of sleeping nodes is lower than everything else of awake nodes - t.is(tAsleepWU.compareTo(tAwakeHigh), 1); - t.is(tAsleepWU.compareTo(tAwakeWU), 1); - t.is(tAsleepWU.compareTo(tAwakeLow), 1); + t.expect(tAsleepWU.compareTo(tAwakeHigh)).toBe(1); + t.expect(tAsleepWU.compareTo(tAwakeWU)).toBe(1); + t.expect(tAsleepWU.compareTo(tAwakeLow)).toBe(1); // Test the opposite direction aswell - t.is(tAwakeHigh.compareTo(tAsleepWU), -1); - t.is(tAwakeWU.compareTo(tAsleepWU), -1); - t.is(tAwakeLow.compareTo(tAsleepWU), -1); + t.expect(tAwakeHigh.compareTo(tAsleepWU)).toBe(-1); + t.expect(tAwakeWU.compareTo(tAsleepWU)).toBe(-1); + t.expect(tAwakeLow.compareTo(tAsleepWU)).toBe(-1); }); // Repro for #550 @@ -396,7 +396,7 @@ test("Controller message should be preferred over messages for sleeping nodes", const tController = createTransaction(msgForController); // The controller transaction should have a higher priority - t.is(tController.compareTo(tSleepingNode), -1); + t.expect(tController.compareTo(tSleepingNode)).toBe(-1); }); test("should capture a stack trace where it was created", (t) => { @@ -417,6 +417,6 @@ test("should capture a stack trace where it was created", (t) => { const test = createDummyTransaction(driverMock, { message: "FOOBAR" as any, }); - t.true(test.stack.includes(__filename)); - t.false(test.stack.includes("FOOBAR")); + t.expect(test.stack.includes(__filename)).toBe(true); + t.expect(test.stack.includes("FOOBAR")).toBe(false); }); diff --git a/packages/zwave-js/src/lib/driver/Transaction.ts b/packages/zwave-js/src/lib/driver/Transaction.ts index a2064e7ecc2d..83690e6bf358 100644 --- a/packages/zwave-js/src/lib/driver/Transaction.ts +++ b/packages/zwave-js/src/lib/driver/Transaction.ts @@ -12,10 +12,10 @@ import { type Comparable, type CompareResult, compareNumberOrString, -} from "alcalzone-shared/comparable"; -import type { DeferredPromise } from "alcalzone-shared/deferred-promise"; -import { NodeStatus } from "../node/_Types"; -import type { Driver } from "./Driver"; +} from "alcalzone-shared/comparable/index.js"; +import type { DeferredPromise } from "alcalzone-shared/deferred-promise/index.js"; +import { NodeStatus } from "../node/_Types.js"; +import type { Driver } from "./Driver.js"; export interface MessageGenerator { parent: Transaction; diff --git a/packages/zwave-js/src/lib/driver/UpdateConfig.ts b/packages/zwave-js/src/lib/driver/UpdateConfig.ts index d242da13b5bb..6982ac004d6a 100644 --- a/packages/zwave-js/src/lib/driver/UpdateConfig.ts +++ b/packages/zwave-js/src/lib/driver/UpdateConfig.ts @@ -5,14 +5,17 @@ import { getErrorMessage, readJSON, } from "@zwave-js/shared"; -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import execa from "execa"; import fs from "node:fs/promises"; +import { createRequire } from "node:module"; import os from "node:os"; import * as path from "node:path"; import * as lockfile from "proper-lockfile"; import * as semver from "semver"; +const require = createRequire(import.meta.url); + /** * Checks whether there is a compatible update for the currently installed config package. * Returns the new version if there is an update, `undefined` otherwise. diff --git a/packages/zwave-js/src/lib/driver/ZWaveOptions.ts b/packages/zwave-js/src/lib/driver/ZWaveOptions.ts index 0fc7ac7f8706..268e6acbc5f5 100644 --- a/packages/zwave-js/src/lib/driver/ZWaveOptions.ts +++ b/packages/zwave-js/src/lib/driver/ZWaveOptions.ts @@ -6,7 +6,7 @@ import type { SerialPort } from "serialport"; import type { InclusionUserCallbacks, JoinNetworkUserCallbacks, -} from "../controller/Inclusion"; +} from "../controller/Inclusion.js"; export interface ZWaveOptions extends ZWaveHostOptions { /** Specify timeouts in milliseconds */ diff --git a/packages/zwave-js/src/lib/driver/mDNSDiscovery.ts b/packages/zwave-js/src/lib/driver/mDNSDiscovery.ts index bd72bad2bebc..7ce761c7262f 100644 --- a/packages/zwave-js/src/lib/driver/mDNSDiscovery.ts +++ b/packages/zwave-js/src/lib/driver/mDNSDiscovery.ts @@ -1,5 +1,5 @@ import { Bytes, isUint8Array } from "@zwave-js/shared"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import createMDNSServer from "mdns-server"; export interface RemoteSerialPort { diff --git a/packages/zwave-js/src/lib/log/Driver.test.ts b/packages/zwave-js/src/lib/log/Driver.test.ts index 1d2a75f697e3..270d1fd821f2 100644 --- a/packages/zwave-js/src/lib/log/Driver.test.ts +++ b/packages/zwave-js/src/lib/log/Driver.test.ts @@ -10,63 +10,65 @@ import { assertMessage, } from "@zwave-js/core/test"; import { FunctionType, Message, MessageType } from "@zwave-js/serial"; -import { createDeferredPromise } from "alcalzone-shared/deferred-promise"; +import { createDeferredPromise } from "alcalzone-shared/deferred-promise/index.js"; import colors from "ansi-colors"; -import ava, { type TestFn } from "ava"; import MockDate from "mockdate"; -import type { Driver } from "../driver/Driver"; -import { createAndStartTestingDriver } from "../driver/DriverMock"; -import { TransactionQueue } from "../driver/Queue"; -import { Transaction } from "../driver/Transaction"; -import { DriverLogger } from "./Driver"; - -interface TestContext { - driver: Driver; - driverLogger: DriverLogger; - spyTransport: SpyTransport; +import { beforeEach, test as baseTest } from "vitest"; +import type { Driver } from "../driver/Driver.js"; +import { createAndStartTestingDriver } from "../driver/DriverMock.js"; +import { TransactionQueue } from "../driver/Queue.js"; +import { Transaction } from "../driver/Transaction.js"; +import { DriverLogger } from "./Driver.js"; + +interface LocalTestContext { + context: { + driver: Driver; + driverLogger: DriverLogger; + spyTransport: SpyTransport; + }; } -const test = ava as TestFn; - -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - skipNodeInterview: true, - skipControllerIdentification: true, - }); - t.context.driver = driver; - - // Replace all defined transports with a spy transport - const spyTransport = new SpyTransport(); - spyTransport.format = createDefaultTransportFormat(true, true); - const driverLogger = new DriverLogger( - driver, - new ZWaveLogContainer({ - transports: [spyTransport], - }), - ); - // Uncomment this to debug the log outputs manually - // wasSilenced = unsilence(driverLogger); - - t.context.driverLogger = driverLogger; - t.context.spyTransport = spyTransport; - - MockDate.set(new Date().setHours(0, 0, 0, 0)); -}); - -test.after.always(async (t) => { - const { driver, driverLogger } = t.context; - await driver.destroy(); - - // Don't spam the console when performing the other tests not related to logging - driverLogger.container.updateConfiguration({ enabled: false }); - MockDate.reset(); +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipNodeInterview: true, + skipControllerIdentification: true, + }); + + // Replace all defined transports with a spy transport + const spyTransport = new SpyTransport(); + spyTransport.format = createDefaultTransportFormat(true, true); + const driverLogger = new DriverLogger( + driver, + new ZWaveLogContainer({ + transports: [spyTransport], + }), + ); + // Uncomment this to debug the log outputs manually + // wasSilenced = unsilence(driverLogger); + + MockDate.set(new Date().setHours(0, 0, 0, 0)); + + // Run tests + await use({ driver, driverLogger, spyTransport }); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + + // Don't spam the console when performing the other tests not related to logging + driverLogger.container.updateConfiguration({ enabled: false }); + MockDate.reset(); + }, + { auto: true }, + ], }); -test.beforeEach((t) => { - t.context.spyTransport.spy.resetHistory(); +beforeEach(({ context, expect }) => { + context.spyTransport.spy.resetHistory(); }); interface CreateMessageOptions { @@ -102,44 +104,44 @@ function createTransaction( return trns; } -test.serial("print() logs short messages correctly", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("print() logs short messages correctly", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print("Test"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` Test`, }); }); -test.serial("print() logs long messages correctly", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("print() logs long messages correctly", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print( "This is a very long message that should be broken into multiple lines maybe sometimes...", ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` This is a very long message that should be broken into multiple lines maybe so metimes...`, }); }); -test.serial("print() logs with the given loglevel", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("print() logs with the given loglevel", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print("Test", "warn"); - assertLogInfo(t, spyTransport, { level: "warn" }); + assertLogInfo(expect, spyTransport, { level: "warn" }); }); -test.serial("print() has a default loglevel of verbose", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("print() has a default loglevel of verbose", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print("Test"); - assertLogInfo(t, spyTransport, { level: "verbose" }); + assertLogInfo(expect, spyTransport, { level: "verbose" }); }); -test.serial( +test.sequential( "print() prefixes the messages with the current timestamp and channel name", - (t) => { - const { driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print("Whatever"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `00:00:00.000 DRIVER Whatever`, ignoreTimestamp: false, ignoreChannel: false, @@ -147,10 +149,10 @@ test.serial( }, ); -test.serial("print() the timestamp is in a dim color", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("print() the timestamp is in a dim color", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print("Whatever"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.startsWith(colors.gray("00:00:00.000")), ignoreTimestamp: false, ignoreChannel: false, @@ -158,98 +160,98 @@ test.serial("print() the timestamp is in a dim color", (t) => { }); }); -test.serial("print() the channel name is in inverted gray color", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("print() the channel name is in inverted gray color", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print("Whatever"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.startsWith(colors.gray.inverse("DRIVER")), ignoreChannel: false, ignoreColor: false, }); }); -test.serial( +test.sequential( "transaction() (for outbound messages) contains the direction", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; driverLogger.transaction(createTransaction(driver, {})); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.startsWith(getDirectionPrefix("outbound")), }); }, ); -test.serial( +test.sequential( "transaction() (for outbound messages) contains the message type as a tag", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; driverLogger.transaction( createTransaction(driver, { type: MessageType.Request }), ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[REQ]"), }); driverLogger.transaction( createTransaction(driver, { type: MessageType.Response }), ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[RES]"), callNumber: 1, }); }, ); -test.serial( +test.sequential( "transaction() (for outbound messages) contains the function type as a tag", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; driverLogger.transaction( createTransaction(driver, { functionType: FunctionType.GetSerialApiInitData, }), ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[GetSerialApiInitData]"), }); }, ); -test.serial( +test.sequential( "transaction() (for outbound messages) contains the message priority", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; driverLogger.transaction( createTransaction(driver, { priority: MessagePriority.Controller, }), ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[P: Controller]"), }); }, ); -test.serial( +test.sequential( "transactionResponse() (for inbound messages) contains the direction", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const msg = createMessage(driver, {}); driverLogger.transactionResponse(msg, undefined, null as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.startsWith(getDirectionPrefix("inbound")), }); }, ); -test.serial( +test.sequential( "transactionResponse() (for inbound messages) contains the message type as a tag", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; let msg = createMessage(driver, { type: MessageType.Request, }); driverLogger.transactionResponse(msg, undefined, null as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[REQ]"), }); @@ -257,46 +259,46 @@ test.serial( type: MessageType.Response, }); driverLogger.transactionResponse(msg, undefined, null as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[RES]"), callNumber: 1, }); }, ); -test.serial( +test.sequential( "transactionResponse() (for inbound messages) contains the function type as a tag", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const msg = createMessage(driver, { functionType: FunctionType.HardReset, }); driverLogger.transactionResponse(msg, undefined, null as any); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[HardReset]"), }); }, ); -test.serial( +test.sequential( "transactionResponse() (for inbound messages) contains the role (regarding the transaction) of the received message as a tag", - (t) => { - const { driver, driverLogger, spyTransport } = t.context; + ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const msg = createMessage(driver, { functionType: FunctionType.HardReset, }); driverLogger.transactionResponse(msg, undefined, "fatal_controller"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("[fatal_controller]"), }); }, ); -test.serial("sendQueue() prints the send queue length", (t) => { - const { driver, driverLogger, spyTransport } = t.context; +test.sequential("sendQueue() prints the send queue length", ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const queue = new TransactionQueue(); driverLogger.sendQueue(queue); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("(0 messages)"), }); @@ -306,7 +308,7 @@ test.serial("sendQueue() prints the send queue length", (t) => { }), ); driverLogger.sendQueue(queue); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("(1 message)"), callNumber: 1, }); @@ -317,14 +319,14 @@ test.serial("sendQueue() prints the send queue length", (t) => { }), ); driverLogger.sendQueue(queue); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("(2 messages)"), callNumber: 2, }); }); -test.serial("sendQueue() prints the function type for each message", (t) => { - const { driver, driverLogger, spyTransport } = t.context; +test.sequential("sendQueue() prints the function type for each message", ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const queue = new TransactionQueue(); queue.add( createTransaction(driver, { @@ -336,16 +338,16 @@ test.serial("sendQueue() prints the function type for each message", (t) => { ); driverLogger.sendQueue(queue); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("GetSUCNodeId"), }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("HardReset"), }); }); -test.serial("sendQueue() prints the message type for each message", (t) => { - const { driver, driverLogger, spyTransport } = t.context; +test.sequential("sendQueue() prints the message type for each message", ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const queue = new TransactionQueue(); queue.add( createTransaction(driver, { @@ -361,16 +363,16 @@ test.serial("sendQueue() prints the message type for each message", (t) => { ); driverLogger.sendQueue(queue); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("· [REQ] GetSUCNodeId"), }); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes("· [RES] HardReset"), }); }); -test.serial("primary tags are printed in inverse colors", (t) => { - const { driver, driverLogger, spyTransport } = t.context; +test.sequential("primary tags are printed in inverse colors", ({ context, expect }) => { + const { driver, driverLogger, spyTransport } = context; const msg = createMessage(driver, { functionType: FunctionType.HardReset, type: MessageType.Response, @@ -387,14 +389,14 @@ test.serial("primary tags are printed in inverse colors", (t) => { + colors.bgCyan("]"), ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes(expected1), ignoreColor: false, }); }); -test.serial("inline tags are printed in inverse colors", (t) => { - const { driverLogger, spyTransport } = t.context; +test.sequential("inline tags are printed in inverse colors", ({ context, expect }) => { + const { driverLogger, spyTransport } = context; driverLogger.print(`This is a message [with] [inline] tags...`); const expected1 = colors.bgCyan("[") @@ -405,7 +407,7 @@ test.serial("inline tags are printed in inverse colors", (t) => { + colors.inverse("inline") + colors.bgCyan("]"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes(expected1), ignoreColor: false, }); diff --git a/packages/zwave-js/src/lib/log/Driver.ts b/packages/zwave-js/src/lib/log/Driver.ts index 3d4133413b90..be5335fee4ac 100644 --- a/packages/zwave-js/src/lib/log/Driver.ts +++ b/packages/zwave-js/src/lib/log/Driver.ts @@ -17,10 +17,10 @@ import type { Message, ResponseRole } from "@zwave-js/serial"; import { FunctionType, MessageType } from "@zwave-js/serial"; import { containsCC } from "@zwave-js/serial/serialapi"; import { getEnumMemberName } from "@zwave-js/shared"; -import type { Driver } from "../driver/Driver"; -import { type TransactionQueue } from "../driver/Queue"; -import type { Transaction } from "../driver/Transaction"; -import { NodeStatus } from "../node/_Types"; +import type { Driver } from "../driver/Driver.js"; +import { type TransactionQueue } from "../driver/Queue.js"; +import type { Transaction } from "../driver/Transaction.js"; +import { NodeStatus } from "../node/_Types.js"; export const DRIVER_LABEL = "DRIVER"; const DRIVER_LOGLEVEL = "verbose"; diff --git a/packages/zwave-js/src/lib/log/Zniffer.ts b/packages/zwave-js/src/lib/log/Zniffer.ts index 783c3825ad0c..4d42ed5796ec 100644 --- a/packages/zwave-js/src/lib/log/Zniffer.ts +++ b/packages/zwave-js/src/lib/log/Zniffer.ts @@ -18,15 +18,15 @@ import { } from "@zwave-js/core"; import { type ZnifferDataMessage } from "@zwave-js/serial"; import { buffer2hex, num2hex } from "@zwave-js/shared"; -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import { type BeamStop, type LongRangeBeamStart, type LongRangeMPDU, type ZWaveBeamStart, type ZWaveMPDU, -} from "../zniffer/MPDU"; -import { type Zniffer } from "../zniffer/Zniffer"; +} from "../zniffer/MPDU.js"; +import { type Zniffer } from "../zniffer/Zniffer.js"; export const ZNIFFER_LABEL = "ZNIFFR"; const ZNIFFER_LOGLEVEL = "info"; diff --git a/packages/zwave-js/src/lib/node/Endpoint.test.ts b/packages/zwave-js/src/lib/node/Endpoint.test.ts index e3fa82b249d9..f56ec27d7e71 100644 --- a/packages/zwave-js/src/lib/node/Endpoint.test.ts +++ b/packages/zwave-js/src/lib/node/Endpoint.test.ts @@ -7,65 +7,73 @@ import { assertZWaveError, } from "@zwave-js/core"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../Utils"; -import type { Driver } from "../driver/Driver"; -import { createAndStartTestingDriver } from "../driver/DriverMock"; -import { Endpoint } from "./Endpoint"; -import { ZWaveNode } from "./Node"; - -interface TestContext { - driver: Driver; - controller: MockController; +import { afterEach, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../Utils.js"; +import type { Driver } from "../driver/Driver.js"; +import { createAndStartTestingDriver } from "../driver/DriverMock.js"; +import { Endpoint } from "./Endpoint.js"; +import { ZWaveNode } from "./Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; - -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); }, - }); - t.context.driver = driver; -}); - -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + { auto: true }, + ], }); -test.afterEach((t) => { - const { driver } = t.context; +afterEach(({ context, expect }) => { + const { driver } = context; driver.networkCache.clear(); driver.valueDB?.clear(); }); -test.serial( +test.sequential( "createAPI() throws if a non-implemented API should be created", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); - assertZWaveError(t, () => endpoint.createAPI(0xbada55), { + assertZWaveError(expect, () => endpoint.createAPI(0xbada55), { errorCode: ZWaveErrorCodes.CC_NoAPI, messageMatches: "no associated API", }); }, ); -test.serial( +test.sequential( "The API returned from createAPI() throws when trying to access a non-supported CC", - async (t) => { - const { driver } = t.context; + async ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); // We must not use Basic CC here, because that is assumed to be always supported const api = endpoint.createAPI(CommandClasses["Binary Sensor"]); @@ -73,79 +81,90 @@ test.serial( // this does not throw api.isSupported(); // this does - await assertZWaveError(t, () => api.get(), { + await assertZWaveError(expect, () => api.get(), { errorCode: ZWaveErrorCodes.CC_NotSupported, messageMatches: /Node 1 \(endpoint 1\) does not support/, }); // It only includes the endpoint number for non-root endpoints (endpoint as any).index = 0; - await assertZWaveError(t, () => api.get(), { + await assertZWaveError(expect, () => api.get(), { errorCode: ZWaveErrorCodes.CC_NotSupported, messageMatches: "Node 1 does not support", }); }, ); -test.serial( +test.sequential( "The commandClasses dictionary throws when trying to access a non-implemented CC", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); - assertZWaveError(t, () => (endpoint.commandClasses as any).FOOBAR, { - errorCode: ZWaveErrorCodes.CC_NotImplemented, - messageMatches: "FOOBAR is not implemented", - }); + assertZWaveError( + expect, + () => (endpoint.commandClasses as any).FOOBAR, + { + errorCode: ZWaveErrorCodes.CC_NotImplemented, + messageMatches: "FOOBAR is not implemented", + }, + ); }, ); -test.serial( +test.sequential( "The commandClasses dictionary throws when trying to use a command of an unsupported CC", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); - assertZWaveError(t, () => endpoint.commandClasses.Battery.get(), { - errorCode: ZWaveErrorCodes.CC_NotSupported, - messageMatches: "does not support the Command Class Battery", - }); + assertZWaveError( + expect, + () => endpoint.commandClasses.Battery.get(), + { + errorCode: ZWaveErrorCodes.CC_NotSupported, + messageMatches: "does not support the Command Class Battery", + }, + ); }, ); -test.serial( +test.sequential( "The commandClasses dictionary does not throw when checking support of a CC", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); - t.false(endpoint.commandClasses.Battery.isSupported()); + expect(endpoint.commandClasses.Battery.isSupported()).toBe(false); }, ); -test.serial( +test.sequential( "The commandClasses dictionary does not throw when accessing the ID of a CC", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); - t.is(endpoint.commandClasses.Battery.ccId, CommandClasses.Battery); + expect(endpoint.commandClasses.Battery.ccId).toBe( + CommandClasses.Battery, + ); }, ); -test.serial( +test.sequential( "The commandClasses dictionary does not throw when scoping the API options", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); - t.notThrows(() => endpoint.commandClasses.Battery.withOptions({})); + expect(() => endpoint.commandClasses.Battery.withOptions({})).not + .toThrow(); }, ); -test.serial( +test.sequential( "The commandClasses dictionary returns all supported CCs when being enumerated", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; // No supported CCs, empty array let node = new ZWaveNode(2, driver, undefined, []); let actual = [...node.commandClasses]; - t.deepEqual(actual, []); + expect(actual).toStrictEqual([]); // Supported and controlled CCs node = new ZWaveNode( @@ -156,50 +175,49 @@ test.serial( [CommandClasses["Wake Up"]], ); actual = [...node.commandClasses]; - t.is(actual.length, 2); - t.deepEqual( + expect(actual.length).toBe(2); + expect( actual.map((api) => api.constructor), - [ - BatteryCCAPI, - VersionCCAPI, - // WakeUpCCAPI is not supported (only controlled), so no API! - ], - ); + ).toStrictEqual([ + BatteryCCAPI, + VersionCCAPI, + // WakeUpCCAPI is not supported (only controlled), so no API! + ]); node.destroy(); }, ); -test.serial( +test.sequential( "The commandClasses dictionary returns [object Object] when turned into a string", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver, undefined, []); - t.is( + expect( (node.commandClasses as any)[Symbol.toStringTag], - "[object Object]", - ); + ).toBe("[object Object]"); node.destroy(); }, ); -test.serial( +test.sequential( "The commandClasses dictionary returns undefined for other symbol properties", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver, undefined, []); - t.is((node.commandClasses as any)[Symbol.unscopables], undefined); + expect((node.commandClasses as any)[Symbol.unscopables]) + .toBeUndefined(); node.destroy(); }, ); -test.serial( +test.sequential( "createCCInstance() returns undefined if the node supports the CC but it is not yet implemented", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const endpoint = new Endpoint(1, driver, 1); const cc = 0xbada55; endpoint.addCC(cc, { isSupported: true }); const instance = endpoint.createCCInstance(cc); - t.is(instance, undefined); + expect(instance).toBeUndefined(); }, ); diff --git a/packages/zwave-js/src/lib/node/Endpoint.ts b/packages/zwave-js/src/lib/node/Endpoint.ts index 3c11901c3b47..e57f8d722db6 100644 --- a/packages/zwave-js/src/lib/node/Endpoint.ts +++ b/packages/zwave-js/src/lib/node/Endpoint.ts @@ -32,11 +32,11 @@ import { } from "@zwave-js/core"; import { getEnumMemberName, num2hex } from "@zwave-js/shared"; import { isDeepStrictEqual } from "node:util"; -import type { Driver } from "../driver/Driver"; -import { cacheKeys } from "../driver/NetworkCache"; -import type { DeviceClass } from "./DeviceClass"; -import type { EndpointDump } from "./Dump"; -import type { ZWaveNode } from "./Node"; +import type { Driver } from "../driver/Driver.js"; +import { cacheKeys } from "../driver/NetworkCache.js"; +import type { DeviceClass } from "./DeviceClass.js"; +import type { EndpointDump } from "./Dump.js"; +import type { ZWaveNode } from "./Node.js"; /** * Represents a physical endpoint of a Z-Wave node. This can either be the root diff --git a/packages/zwave-js/src/lib/node/HealthCheck.ts b/packages/zwave-js/src/lib/node/HealthCheck.ts index 69c3a2feaca3..41c72bbf3d9e 100644 --- a/packages/zwave-js/src/lib/node/HealthCheck.ts +++ b/packages/zwave-js/src/lib/node/HealthCheck.ts @@ -1,12 +1,12 @@ import { Powerlevel } from "@zwave-js/cc/safe"; import { getEnumMemberName } from "@zwave-js/shared/safe"; -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import type { LifelineHealthCheckResult, LifelineHealthCheckSummary, RouteHealthCheckResult, RouteHealthCheckSummary, -} from "./_Types"; +} from "./_Types.js"; export const healthCheckTestFrameCount = 10; diff --git a/packages/zwave-js/src/lib/node/MockNodeBehaviors.ts b/packages/zwave-js/src/lib/node/MockNodeBehaviors.ts index ad6875a565b2..aa1bafa6fb8e 100644 --- a/packages/zwave-js/src/lib/node/MockNodeBehaviors.ts +++ b/packages/zwave-js/src/lib/node/MockNodeBehaviors.ts @@ -17,28 +17,28 @@ import { import { CommandClasses } from "@zwave-js/core"; import { type MockNodeBehavior } from "@zwave-js/testing"; -import { BasicCCBehaviors } from "./mockCCBehaviors/Basic"; -import { BinarySensorCCBehaviors } from "./mockCCBehaviors/BinarySensor"; -import { BinarySwitchCCBehaviors } from "./mockCCBehaviors/BinarySwitch"; -import { ColorSwitchCCBehaviors } from "./mockCCBehaviors/ColorSwitch"; -import { ConfigurationCCBehaviors } from "./mockCCBehaviors/Configuration"; -import { EnergyProductionCCBehaviors } from "./mockCCBehaviors/EnergyProduction"; -import { ManufacturerSpecificCCBehaviors } from "./mockCCBehaviors/ManufacturerSpecific"; -import { MeterCCBehaviors } from "./mockCCBehaviors/Meter"; +import { BasicCCBehaviors } from "./mockCCBehaviors/Basic.js"; +import { BinarySensorCCBehaviors } from "./mockCCBehaviors/BinarySensor.js"; +import { BinarySwitchCCBehaviors } from "./mockCCBehaviors/BinarySwitch.js"; +import { ColorSwitchCCBehaviors } from "./mockCCBehaviors/ColorSwitch.js"; +import { ConfigurationCCBehaviors } from "./mockCCBehaviors/Configuration.js"; +import { EnergyProductionCCBehaviors } from "./mockCCBehaviors/EnergyProduction.js"; +import { ManufacturerSpecificCCBehaviors } from "./mockCCBehaviors/ManufacturerSpecific.js"; +import { MeterCCBehaviors } from "./mockCCBehaviors/Meter.js"; import { MultiChannelCCBehaviors, MultiChannelCCHooks, -} from "./mockCCBehaviors/MultiChannel"; -import { MultilevelSensorCCBehaviors } from "./mockCCBehaviors/MultilevelSensor"; -import { MultilevelSwitchCCBehaviors } from "./mockCCBehaviors/MultilevelSwitch"; -import { NotificationCCBehaviors } from "./mockCCBehaviors/Notification"; -import { ScheduleEntryLockCCBehaviors } from "./mockCCBehaviors/ScheduleEntryLock"; -import { SoundSwitchCCBehaviors } from "./mockCCBehaviors/SoundSwitch"; -import { ThermostatModeCCBehaviors } from "./mockCCBehaviors/ThermostatMode"; -import { ThermostatSetbackCCBehaviors } from "./mockCCBehaviors/ThermostatSetback"; -import { ThermostatSetpointCCBehaviors } from "./mockCCBehaviors/ThermostatSetpoint"; -import { UserCodeCCBehaviors } from "./mockCCBehaviors/UserCode"; -import { WindowCoveringCCBehaviors } from "./mockCCBehaviors/WindowCovering"; +} from "./mockCCBehaviors/MultiChannel.js"; +import { MultilevelSensorCCBehaviors } from "./mockCCBehaviors/MultilevelSensor.js"; +import { MultilevelSwitchCCBehaviors } from "./mockCCBehaviors/MultilevelSwitch.js"; +import { NotificationCCBehaviors } from "./mockCCBehaviors/Notification.js"; +import { ScheduleEntryLockCCBehaviors } from "./mockCCBehaviors/ScheduleEntryLock.js"; +import { SoundSwitchCCBehaviors } from "./mockCCBehaviors/SoundSwitch.js"; +import { ThermostatModeCCBehaviors } from "./mockCCBehaviors/ThermostatMode.js"; +import { ThermostatSetbackCCBehaviors } from "./mockCCBehaviors/ThermostatSetback.js"; +import { ThermostatSetpointCCBehaviors } from "./mockCCBehaviors/ThermostatSetpoint.js"; +import { UserCodeCCBehaviors } from "./mockCCBehaviors/UserCode.js"; +import { WindowCoveringCCBehaviors } from "./mockCCBehaviors/WindowCovering.js"; const respondToRequestNodeInfo: MockNodeBehavior = { handleCC(controller, self, receivedCC) { diff --git a/packages/zwave-js/src/lib/node/Node.ts b/packages/zwave-js/src/lib/node/Node.ts index 0280acae3a2d..7cc53b83f811 100644 --- a/packages/zwave-js/src/lib/node/Node.ts +++ b/packages/zwave-js/src/lib/node/Node.ts @@ -226,37 +226,37 @@ import { pick, stringify, } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import { roundTo } from "alcalzone-shared/math"; -import { padStart } from "alcalzone-shared/strings"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; +} from "alcalzone-shared/deferred-promise/index.js"; +import { roundTo } from "alcalzone-shared/math/index.js"; +import { padStart } from "alcalzone-shared/strings/index.js"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; import { EventEmitter } from "node:events"; import path from "node:path"; import semver from "semver"; -import { RemoveNodeReason } from "../controller/Inclusion"; -import { determineNIF } from "../controller/NodeInformationFrame"; -import { type Driver, libVersion } from "../driver/Driver"; -import { cacheKeys } from "../driver/NetworkCache"; -import type { StatisticsEventCallbacksWithSelf } from "../driver/Statistics"; -import type { Transaction } from "../driver/Transaction"; -import { DeviceClass } from "./DeviceClass"; -import { type NodeDump, type ValueDump } from "./Dump"; -import { type Endpoint } from "./Endpoint"; +import { RemoveNodeReason } from "../controller/Inclusion.js"; +import { determineNIF } from "../controller/NodeInformationFrame.js"; +import { type Driver, libVersion } from "../driver/Driver.js"; +import { cacheKeys } from "../driver/NetworkCache.js"; +import type { StatisticsEventCallbacksWithSelf } from "../driver/Statistics.js"; +import type { Transaction } from "../driver/Transaction.js"; +import { DeviceClass } from "./DeviceClass.js"; +import { type NodeDump, type ValueDump } from "./Dump.js"; +import { type Endpoint } from "./Endpoint.js"; import { formatLifelineHealthCheckSummary, formatRouteHealthCheckSummary, healthCheckTestFrameCount, -} from "./HealthCheck"; +} from "./HealthCheck.js"; import { type NodeStatistics, NodeStatisticsHost, type RouteStatistics, routeStatisticsEquals, -} from "./NodeStatistics"; +} from "./NodeStatistics.js"; import { type DateAndTime, type LifelineHealthCheckResult, @@ -268,10 +268,10 @@ import { type RouteHealthCheckResult, type RouteHealthCheckSummary, type ZWaveNodeEventCallbacks, -} from "./_Types"; -import { InterviewStage, NodeStatus } from "./_Types"; -import { ZWaveNodeMixins } from "./mixins"; -import * as nodeUtils from "./utils"; +} from "./_Types.js"; +import { InterviewStage, NodeStatus } from "./_Types.js"; +import { ZWaveNodeMixins } from "./mixins/index.js"; +import * as nodeUtils from "./utils.js"; const MAX_ASSOCIATIONS = 1; diff --git a/packages/zwave-js/src/lib/node/NodeReadyMachine.test.ts b/packages/zwave-js/src/lib/node/NodeReadyMachine.test.ts index 6bc0ee19faa7..def13ea53e9d 100644 --- a/packages/zwave-js/src/lib/node/NodeReadyMachine.test.ts +++ b/packages/zwave-js/src/lib/node/NodeReadyMachine.test.ts @@ -1,20 +1,22 @@ import { type Interpreter, interpret } from "xstate"; // import { SimulatedClock } from "xstate/lib/SimulatedClock"; -import test, { type ExecutionContext } from "ava"; +import { type TaskContext, type TestContext, test } from "vitest"; import { type NodeReadyContext, type NodeReadyEvent, type NodeReadyMachine, type NodeReadyStateSchema, createNodeReadyMachine, -} from "./NodeReadyMachine"; +} from "./NodeReadyMachine.js"; function startMachine( - t: ExecutionContext, + t: TaskContext & TestContext, machine: NodeReadyMachine, ): Interpreter { const service = interpret(machine).start(); - t.teardown(() => service.stop()); + t.onTestFinished(() => { + service.stop(); + }); return service; } @@ -22,16 +24,16 @@ test(`The node should start in the notReady state`, (t) => { const testMachine = createNodeReadyMachine(undefined as any); const service = startMachine(t, testMachine); - t.is(service.getSnapshot().value, "notReady"); + t.expect(service.getSnapshot().value).toBe("notReady"); }); test("when the driver is restarted from cache, the node should be ready as soon as it is known NOT to be dead", (t) => { const testMachine = createNodeReadyMachine(); const service = startMachine(t, testMachine); service.send("RESTART_FROM_CACHE"); - t.is(service.getSnapshot().value, "readyIfNotDead"); + t.expect(service.getSnapshot().value).toBe("readyIfNotDead"); service.send("NOT_DEAD"); - t.is(service.getSnapshot().value, "ready"); + t.expect(service.getSnapshot().value).toBe("ready"); }); test("when the driver is restarted from cache and the node is known to be not dead, it should be ready immediately", (t) => { @@ -39,12 +41,12 @@ test("when the driver is restarted from cache and the node is known to be not de const service = startMachine(t, testMachine); service.send("NOT_DEAD"); service.send("RESTART_FROM_CACHE"); - t.is(service.getSnapshot().value, "ready"); + t.expect(service.getSnapshot().value).toBe("ready"); }); test("when the interview is done, the node should be marked as ready", (t) => { const testMachine = createNodeReadyMachine(); const service = startMachine(t, testMachine); service.send("INTERVIEW_DONE"); - t.is(service.getSnapshot().value, "ready"); + t.expect(service.getSnapshot().value).toBe("ready"); }); diff --git a/packages/zwave-js/src/lib/node/NodeStatistics.ts b/packages/zwave-js/src/lib/node/NodeStatistics.ts index b379ebec0ea2..23496f0d9cdf 100644 --- a/packages/zwave-js/src/lib/node/NodeStatistics.ts +++ b/packages/zwave-js/src/lib/node/NodeStatistics.ts @@ -1,5 +1,5 @@ import type { ProtocolDataRate, RSSI } from "@zwave-js/core"; -import { StatisticsHost } from "../driver/Statistics"; +import { StatisticsHost } from "../driver/Statistics.js"; export class NodeStatisticsHost extends StatisticsHost { getAdditionalEventArgs(): any[] { diff --git a/packages/zwave-js/src/lib/node/NodeStatusMachine.test.ts b/packages/zwave-js/src/lib/node/NodeStatusMachine.test.ts index ef1f946fa623..099353f6f3c9 100644 --- a/packages/zwave-js/src/lib/node/NodeStatusMachine.test.ts +++ b/packages/zwave-js/src/lib/node/NodeStatusMachine.test.ts @@ -1,22 +1,24 @@ import { type Interpreter, interpret } from "xstate"; // import { SimulatedClock } from "xstate/lib/SimulatedClock"; -import test, { type ExecutionContext } from "ava"; +import { type TaskContext, type TestContext, test } from "vitest"; import { type NodeStatusEvent, type NodeStatusMachine, type NodeStatusStateSchema, createNodeStatusMachine, -} from "./NodeStatusMachine"; +} from "./NodeStatusMachine.js"; const testNodeNonSleeping = { canSleep: false } as any; const testNodeSleeping = { canSleep: true } as any; function startMachine( - t: ExecutionContext, + t: TaskContext & TestContext, machine: NodeStatusMachine, ): Interpreter { const service = interpret(machine).start(); - t.teardown(() => service.stop()); + t.onTestFinished(() => { + service.stop(); + }); return service; } @@ -26,7 +28,7 @@ test(`The node should start in the unknown state if it maybe cannot sleep`, (t) } as any); const service = startMachine(t, testMachine); - t.is(service.getSnapshot().value, "unknown"); + t.expect(service.getSnapshot().value).toBe("unknown"); }); test(`The node should start in the unknown state if it can definitely sleep`, (t) => { @@ -35,7 +37,7 @@ test(`The node should start in the unknown state if it can definitely sleep`, (t } as any); const service = startMachine(t, testMachine); - t.is(service.getSnapshot().value, "unknown"); + t.expect(service.getSnapshot().value).toBe("unknown"); }); const transitions: { @@ -184,7 +186,7 @@ for (const testCase of transitions) { const service = startMachine(t, testMachine); service.send(testCase.event); - t.is(service.getSnapshot().value, testCase.target); + t.expect(service.getSnapshot().value).toBe(testCase.target); }); } @@ -193,7 +195,7 @@ test("A transition from unknown to awake should not happen if the node cannot sl const service = startMachine(t, testMachine); service.send("AWAKE"); - t.is(service.getSnapshot().value, "unknown"); + t.expect(service.getSnapshot().value).toBe("unknown"); }); test("A transition from unknown to asleep should not happen if the node cannot sleep", (t) => { @@ -201,5 +203,5 @@ test("A transition from unknown to asleep should not happen if the node cannot s const service = startMachine(t, testMachine); service.send("ASLEEP"); - t.is(service.getSnapshot().value, "unknown"); + t.expect(service.getSnapshot().value).toBe("unknown"); }); diff --git a/packages/zwave-js/src/lib/node/NodeStatusMachine.ts b/packages/zwave-js/src/lib/node/NodeStatusMachine.ts index 6823866e1295..22cb31fb17e3 100644 --- a/packages/zwave-js/src/lib/node/NodeStatusMachine.ts +++ b/packages/zwave-js/src/lib/node/NodeStatusMachine.ts @@ -1,6 +1,6 @@ import { type InterpreterFrom, Machine, type StateMachine } from "xstate"; -import { NodeStatus } from "./_Types"; -import { type NodeNetworkRole } from "./mixins/01_NetworkRole"; +import { NodeStatus } from "./_Types.js"; +import { type NodeNetworkRole } from "./mixins/01_NetworkRole.js"; export interface NodeStatusStateSchema { states: { diff --git a/packages/zwave-js/src/lib/node/VirtualEndpoint.test.ts b/packages/zwave-js/src/lib/node/VirtualEndpoint.test.ts index 059d8c9964e4..f68b4c422b7a 100644 --- a/packages/zwave-js/src/lib/node/VirtualEndpoint.test.ts +++ b/packages/zwave-js/src/lib/node/VirtualEndpoint.test.ts @@ -1,3 +1,4 @@ +import { BasicCommand } from "@zwave-js/cc"; import type { BinarySensorCCAPI } from "@zwave-js/cc/BinarySensorCC"; import { BinarySwitchCCAPI } from "@zwave-js/cc/BinarySwitchCC"; import { @@ -5,73 +6,129 @@ import { ZWaveErrorCodes, assertZWaveError, } from "@zwave-js/core"; -import { FunctionType } from "@zwave-js/serial"; -import type { MockSerialPort } from "@zwave-js/serial/mock"; -import { Bytes, type ThrowingMap } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import ava, { type ExecutionContext, type TestFn } from "ava"; -import { ZWaveController } from "../controller/Controller"; -import type { Driver } from "../driver/Driver"; -import { createAndStartDriver } from "../test/utils"; -import { ZWaveNode } from "./Node"; - -interface TestContext { - driver: Driver; - serialport: MockSerialPort; - makePhysicalNode(nodeId: number): ZWaveNode; -} - -const test = ava as TestFn; - -test.beforeEach(async (t) => { - const { driver, serialport } = await createAndStartDriver(); - driver["_controller"] = new ZWaveController(driver); - driver["_controller"].isFunctionSupported = isFunctionSupported; - - t.context.driver = driver; - t.context.serialport = serialport; - t.context.makePhysicalNode = (nodeId: number) => { - const node = new ZWaveNode(nodeId, driver); - (driver.controller.nodes as ThrowingMap).set( - nodeId, - node, - ); - return node; +import { + FunctionType, + SendDataMulticastRequest, + SendDataRequest, +} from "@zwave-js/serial"; +import type { MockPortBinding } from "@zwave-js/serial/mock"; +import { type ThrowingMap, noop } from "@zwave-js/shared"; +import { + MockController, + type MockControllerBehavior, + MockNode, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; +import { test as baseTest } from "vitest"; +import { + createDefaultMockControllerBehaviors, + createDefaultMockNodeBehaviors, +} from "../../Utils.js"; +import type { Driver } from "../driver/Driver.js"; +import { createAndStartTestingDriver } from "../driver/DriverMock.js"; +import { ZWaveNode } from "./Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + serialport: MockPortBinding; + makePhysicalNode(nodeId: number): ZWaveNode; }; -}); +} -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver, mockPort } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipNodeInterview: true, + beforeStartup(mockPort) { + context.controller = new MockController({ + serial: mockPort, + capabilities: { + supportedFunctionTypes: + getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft + !== FunctionType + .SendDataMulticastBridge, + ), + }, + }); + context.controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + + const ignoreBroadcast: MockControllerBehavior = { + onHostMessage(controller, msg) { + if ( + msg instanceof SendDataRequest + && msg.getNodeId() === 255 + ) { + return true; + } + }, + }; + context.controller.defineBehavior(ignoreBroadcast); + }, + }); + context.driver = driver; + context.serialport = mockPort; + + context.makePhysicalNode = (nodeId: number) => { + // Make the driver know about the node + const node = new ZWaveNode(nodeId, driver); + (driver.controller.nodes as ThrowingMap).set( + nodeId, + node, + ); + + // Make the mock controller know about the node + const mockNode = new MockNode({ + id: nodeId, + controller: context.controller, + }); + context.controller.addNode(mockNode); + + // Apply default behaviors that are required for interacting with the driver correctly + mockNode.defineBehavior(...createDefaultMockNodeBehaviors()); + + return node; + }; + + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -// Test mock for isFunctionSupported to control which commands are getting used -function isFunctionSupported(fn: FunctionType): boolean { - switch (fn) { - case FunctionType.SendDataBridge: - case FunctionType.SendDataMulticastBridge: - return false; - } - return true; -} - -test.serial( +test.sequential( "createAPI() throws if a non-implemented API should be created", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const broadcast = driver.controller.getBroadcastNode(); - assertZWaveError(t, () => broadcast.createAPI(0xbada55 as any), { + assertZWaveError(expect, () => broadcast.createAPI(0xbada55 as any), { errorCode: ZWaveErrorCodes.CC_NoAPI, messageMatches: "no associated API", }); }, ); -test.serial( +test.sequential( "the broadcast API throws when trying to access a non-supported CC", - async (t) => { - const { driver, makePhysicalNode } = t.context; + async ({ context, expect }) => { + const { driver, makePhysicalNode } = context; makePhysicalNode(2); makePhysicalNode(3); const broadcast = driver.controller.getBroadcastNode(); @@ -84,58 +141,61 @@ test.serial( // this does not throw api.isSupported(); // this does - await assertZWaveError(t, () => api.get(), { + await assertZWaveError(expect, () => api.get(), { errorCode: ZWaveErrorCodes.CC_NotSupported, }); }, ); -test.serial( +test.sequential( "the broadcast API should know it is a broadcast API", - async (t) => { - const { driver, makePhysicalNode } = t.context; + async ({ context, expect }) => { + const { driver, makePhysicalNode } = context; makePhysicalNode(2); makePhysicalNode(3); const broadcast = driver.controller.getBroadcastNode(); - t.true(broadcast.createAPI(CommandClasses.Basic)["isBroadcast"]()); + expect(broadcast.createAPI(CommandClasses.Basic)["isBroadcast"]()) + .toBe(true); }, ); -test.serial( +test.sequential( "the multicast API should know it is a multicast API", - async (t) => { - const { driver, makePhysicalNode } = t.context; + async ({ context, expect }) => { + const { driver, makePhysicalNode } = context; makePhysicalNode(2); makePhysicalNode(3); const multicast = driver.controller.getMulticastGroup([2, 3]); - t.true(multicast.createAPI(CommandClasses.Basic)["isMulticast"]()); + expect(multicast.createAPI(CommandClasses.Basic)["isMulticast"]()) + .toBe(true); }, ); { - function prepareTest(t: ExecutionContext): { + function prepareTest(context: LocalTestContext["context"]): { node2: ZWaveNode; node3: ZWaveNode; } { return { - node2: t.context.makePhysicalNode(2), - node3: t.context.makePhysicalNode(3), + node2: context.makePhysicalNode(2), + node3: context.makePhysicalNode(3), }; } - test.serial( + test.sequential( "the commandClasses dictionary throws when trying to access a non-implemented CC", - (t) => { - const { driver } = t.context; - prepareTest(t); + ({ context, expect }) => { + const { driver } = context; + prepareTest(context); const broadcast = driver.controller.getBroadcastNode(); assertZWaveError( - t, - () => (broadcast.commandClasses as any).FOOBAR, + expect, + // @ts-expect-error + () => broadcast.commandClasses.FOOBAR, { errorCode: ZWaveErrorCodes.CC_NotImplemented, messageMatches: "FOOBAR is not implemented", @@ -147,9 +207,9 @@ test.serial( // This test never worked: // test.serial.only( // "the commandClasses dictionary throws when trying to use a command of an unsupported CC", - // (t) => { - // const { driver } = t.context; - // prepareTest(t); + // ({ context, expect }) => { + // const { driver } = context; + // prepareTest(context); // const broadcast = driver.controller.getBroadcastNode(); // assertZWaveError( @@ -164,54 +224,54 @@ test.serial( // }, // ); - test.serial( + test.sequential( "the commandClasses dictionary does not throw when checking support of a CC", - (t) => { - const { driver } = t.context; - prepareTest(t); + ({ context, expect }) => { + const { driver } = context; + prepareTest(context); const broadcast = driver.controller.getBroadcastNode(); - t.false(broadcast.commandClasses["Binary Switch"].isSupported()); + expect(broadcast.commandClasses["Binary Switch"].isSupported()) + .toBe(false); }, ); - test.serial( - "the commandClasses dictionary does not throw when accessing the ID of a CC", - (t) => { - const { driver } = t.context; - prepareTest(t); + test.sequential( + "the commandClasses dictionary does not throw when accessing the ID of a CC", + ({ context, expect }) => { + const { driver } = context; + prepareTest(context); const broadcast = driver.controller.getBroadcastNode(); - t.is( + expect( broadcast.commandClasses["Binary Switch"].ccId, - CommandClasses["Binary Switch"], - ); + ).toBe(CommandClasses["Binary Switch"]); }, ); - test.serial( - "the commandClasses dictionary does not throw when scoping the API options", - (t) => { - const { driver } = t.context; - prepareTest(t); + test.sequential( + "the commandClasses dictionary does not throw when scoping the API options", + ({ context, expect }) => { + const { driver } = context; + prepareTest(context); const broadcast = driver.controller.getBroadcastNode(); - t.notThrows(() => + expect(() => broadcast.commandClasses["Binary Switch"].withOptions({}) - ); + ).not.toThrow(); }, ); - test.serial( + test.sequential( "the commandClasses dictionary returns all supported CCs when being enumerated", - (t) => { - const { driver } = t.context; - const { node2, node3 } = prepareTest(t); + ({ context, expect }) => { + const { driver } = context; + const { node2, node3 } = prepareTest(context); // No supported CCs, empty array let broadcast = driver.controller.getBroadcastNode(); let actual = [...broadcast.commandClasses]; - t.deepEqual(actual, []); + expect(actual).toStrictEqual([]); // Supported and controlled CCs node2.addCC(CommandClasses["Binary Switch"], { isSupported: true }); @@ -221,83 +281,88 @@ test.serial( broadcast = driver.controller.getBroadcastNode(); actual = [...broadcast.commandClasses]; - t.is(actual.length, 1); - t.deepEqual( + expect(actual.length).toBe(1); + expect( actual.map((api) => api.constructor), - [ - BinarySwitchCCAPI, - // VersionCCAPI cannot be used in broadcast - // WakeUpCCAPI is not supported (only controlled), so no API! - ], - ); + ).toStrictEqual([ + BinarySwitchCCAPI, + // VersionCCAPI cannot be used in broadcast + // WakeUpCCAPI is not supported (only controlled), so no API! + ]); }, ); - test.serial( + test.sequential( "the commandClasses dictionary returns [object Object] when turned into a string", - (t) => { - const { driver } = t.context; - prepareTest(t); + ({ context, expect }) => { + const { driver } = context; + prepareTest(context); const broadcast = driver.controller.getBroadcastNode(); - t.is( - (broadcast.commandClasses as any)[Symbol.toStringTag], - "[object Object]", - ); + expect( + // @ts-expect-error + broadcast.commandClasses[Symbol.toStringTag], + ).toBe("[object Object]"); }, ); - test.serial( + test.sequential( "the commandClasses dictionary returns undefined for other symbol properties", - (t) => { - const { driver } = t.context; - prepareTest(t); + ({ context, expect }) => { + const { driver } = context; + prepareTest(context); const broadcast = driver.controller.getBroadcastNode(); - t.is( - (broadcast.commandClasses as any)[Symbol.unscopables], - undefined, - ); + expect( + // @ts-expect-error + broadcast.commandClasses[Symbol.unscopables], + ).toBeUndefined(); }, ); } -test.serial( +test.sequential( "broadcast uses the correct commands behind the scenes", - async (t) => { - const { driver, serialport, makePhysicalNode } = t.context; + async ({ context, expect }) => { + const { driver, serialport, controller, makePhysicalNode } = context; makePhysicalNode(2); makePhysicalNode(3); const broadcast = driver.controller.getBroadcastNode(); - broadcast.commandClasses.Basic.set(99); + broadcast.commandClasses.Basic.set(99).catch(noop); await wait(1); // » [Node 255] [REQ] [SendData] // │ transmit options: 0x25 // │ callback id: 1 // └─[BasicCCSet] - t.deepEqual( - serialport.lastWrite, - Bytes.from("010a0013ff0320016325017c", "hex"), + controller.assertReceivedHostMessage((msg) => + msg instanceof SendDataRequest + && msg.getNodeId() === 255 + && msg.serializedCC?.[0] === CommandClasses.Basic + && msg.serializedCC?.[1] === BasicCommand.Set ); }, ); -test.serial( +test.sequential( "multicast uses the correct commands behind the scenes", - async (t) => { - const { driver, serialport, makePhysicalNode } = t.context; + async ({ context, expect }) => { + const { driver, serialport, controller, makePhysicalNode } = context; makePhysicalNode(2); makePhysicalNode(3); const multicast = driver.controller.getMulticastGroup([2, 3]); - multicast.commandClasses.Basic.set(99); + multicast.commandClasses.Basic.set(99).catch(noop); await wait(1); // » [Node 2, 3] [REQ] [SendData] // │ transmit options: 0x25 // │ callback id: 1 // └─[BasicCCSet] - t.deepEqual( - serialport.lastWrite, - Bytes.from("010c001402020303200163250181", "hex"), + controller.assertReceivedHostMessage((msg) => + msg instanceof SendDataMulticastRequest + && msg.nodeIds.length === 2 + && msg.nodeIds.includes(2) + && msg.nodeIds.includes(3) + && msg.serializedCC?.[0] === CommandClasses.Basic + && msg.serializedCC?.[1] === BasicCommand.Set ); }, ); diff --git a/packages/zwave-js/src/lib/node/VirtualEndpoint.ts b/packages/zwave-js/src/lib/node/VirtualEndpoint.ts index b965df0d6571..89f27b4d25b2 100644 --- a/packages/zwave-js/src/lib/node/VirtualEndpoint.ts +++ b/packages/zwave-js/src/lib/node/VirtualEndpoint.ts @@ -20,10 +20,10 @@ import { securityClassIsS2, } from "@zwave-js/core/safe"; import { staticExtends } from "@zwave-js/shared/safe"; -import { distinct } from "alcalzone-shared/arrays"; -import type { Driver } from "../driver/Driver"; -import { createMultiCCAPIWrapper } from "./MultiCCAPIWrapper"; -import { VirtualNode } from "./VirtualNode"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import type { Driver } from "../driver/Driver.js"; +import { createMultiCCAPIWrapper } from "./MultiCCAPIWrapper.js"; +import { VirtualNode } from "./VirtualNode.js"; /** * Represents an endpoint of a virtual (broadcast, multicast) Z-Wave node. diff --git a/packages/zwave-js/src/lib/node/VirtualNode.ts b/packages/zwave-js/src/lib/node/VirtualNode.ts index 0a26c4590ae2..61a53b8baeb6 100644 --- a/packages/zwave-js/src/lib/node/VirtualNode.ts +++ b/packages/zwave-js/src/lib/node/VirtualNode.ts @@ -26,10 +26,10 @@ import { supervisedCommandSucceeded, valueIdToString, } from "@zwave-js/core"; -import { distinct } from "alcalzone-shared/arrays"; -import type { Driver } from "../driver/Driver"; -import type { ZWaveNode } from "./Node"; -import { VirtualEndpoint } from "./VirtualEndpoint"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import type { Driver } from "../driver/Driver.js"; +import type { ZWaveNode } from "./Node.js"; +import { VirtualEndpoint } from "./VirtualEndpoint.js"; export interface VirtualValueID extends TranslatedValueID { /** The metadata that belongs to this virtual value ID */ diff --git a/packages/zwave-js/src/lib/node/_Types.ts b/packages/zwave-js/src/lib/node/_Types.ts index 7e217441e0a0..a56572c7beb6 100644 --- a/packages/zwave-js/src/lib/node/_Types.ts +++ b/packages/zwave-js/src/lib/node/_Types.ts @@ -20,9 +20,9 @@ import type { ValueUpdatedArgs, } from "@zwave-js/core/safe"; import { type AllOrNone } from "@zwave-js/shared"; -import { type Endpoint } from "./Endpoint"; -import type { ZWaveNode } from "./Node"; -import type { RouteStatistics } from "./NodeStatistics"; +import { type Endpoint } from "./Endpoint.js"; +import type { ZWaveNode } from "./Node.js"; +import type { RouteStatistics } from "./NodeStatistics.js"; export { EntryControlDataTypes, diff --git a/packages/zwave-js/src/lib/node/mixins/00_Base.ts b/packages/zwave-js/src/lib/node/mixins/00_Base.ts index fd114f1fd1c2..cd2b9ca0b1e3 100644 --- a/packages/zwave-js/src/lib/node/mixins/00_Base.ts +++ b/packages/zwave-js/src/lib/node/mixins/00_Base.ts @@ -1,5 +1,5 @@ import { type NodeId } from "@zwave-js/core/safe"; -import { Endpoint } from "../Endpoint"; +import { Endpoint } from "../Endpoint.js"; export abstract class ZWaveNodeBase extends Endpoint implements NodeId { /** diff --git a/packages/zwave-js/src/lib/node/mixins/01_NetworkRole.ts b/packages/zwave-js/src/lib/node/mixins/01_NetworkRole.ts index f43478ad7dba..46eb3d117774 100644 --- a/packages/zwave-js/src/lib/node/mixins/01_NetworkRole.ts +++ b/packages/zwave-js/src/lib/node/mixins/01_NetworkRole.ts @@ -8,8 +8,8 @@ import { Protocols, isLongRangeNodeId, } from "@zwave-js/core"; -import { cacheKeys } from "../../driver/NetworkCache"; -import { ZWaveNodeBase } from "./00_Base"; +import { cacheKeys } from "../../driver/NetworkCache.js"; +import { ZWaveNodeBase } from "./00_Base.js"; export interface NodeNetworkRole { /** Whether this node is always listening or not */ diff --git a/packages/zwave-js/src/lib/node/mixins/05_Security.ts b/packages/zwave-js/src/lib/node/mixins/05_Security.ts index 326dc757449d..629804aa7b21 100644 --- a/packages/zwave-js/src/lib/node/mixins/05_Security.ts +++ b/packages/zwave-js/src/lib/node/mixins/05_Security.ts @@ -9,10 +9,10 @@ import { securityClassOrder, } from "@zwave-js/core"; import { getEnumMemberName } from "@zwave-js/shared"; -import { type Driver } from "../../driver/Driver"; -import { cacheKeys } from "../../driver/NetworkCache"; -import { type DeviceClass } from "../DeviceClass"; -import { NetworkRoleMixin } from "./01_NetworkRole"; +import { type Driver } from "../../driver/Driver.js"; +import { cacheKeys } from "../../driver/NetworkCache.js"; +import { type DeviceClass } from "../DeviceClass.js"; +import { NetworkRoleMixin } from "./01_NetworkRole.js"; export abstract class NodeSecurityMixin extends NetworkRoleMixin implements QuerySecurityClasses, SetSecurityClass diff --git a/packages/zwave-js/src/lib/node/mixins/10_Events.ts b/packages/zwave-js/src/lib/node/mixins/10_Events.ts index 92909e3713e9..3d390d4ae377 100644 --- a/packages/zwave-js/src/lib/node/mixins/10_Events.ts +++ b/packages/zwave-js/src/lib/node/mixins/10_Events.ts @@ -1,9 +1,9 @@ import { type EventHandler } from "@zwave-js/shared"; -import { type StatisticsEventCallbacksWithSelf } from "../../driver/Statistics"; -import { type ZWaveNode } from "../Node"; -import { type NodeStatistics } from "../NodeStatistics"; -import { type ZWaveNodeEventCallbacks } from "../_Types"; -import { NodeSecurityMixin } from "./05_Security"; +import { type StatisticsEventCallbacksWithSelf } from "../../driver/Statistics.js"; +import { type ZWaveNode } from "../Node.js"; +import { type NodeStatistics } from "../NodeStatistics.js"; +import { type ZWaveNodeEventCallbacks } from "../_Types.js"; +import { NodeSecurityMixin } from "./05_Security.js"; // This mixin is a slightly ugly workaround to allow other mixins to // interact with events which would normally take an instance of ZWaveNode diff --git a/packages/zwave-js/src/lib/node/mixins/20_Status.ts b/packages/zwave-js/src/lib/node/mixins/20_Status.ts index 7a4e08693af9..638d88c79d87 100644 --- a/packages/zwave-js/src/lib/node/mixins/20_Status.ts +++ b/packages/zwave-js/src/lib/node/mixins/20_Status.ts @@ -1,19 +1,19 @@ import { type CommandClasses, InterviewStage } from "@zwave-js/core"; -import { type Driver } from "../../driver/Driver"; -import { cacheKeys } from "../../driver/NetworkCache"; -import { type Extended, interpretEx } from "../../driver/StateMachineShared"; -import { type DeviceClass } from "../DeviceClass"; +import { type Driver } from "../../driver/Driver.js"; +import { cacheKeys } from "../../driver/NetworkCache.js"; +import { type Extended, interpretEx } from "../../driver/StateMachineShared.js"; +import { type DeviceClass } from "../DeviceClass.js"; import { type NodeReadyInterpreter, createNodeReadyMachine, -} from "../NodeReadyMachine"; +} from "../NodeReadyMachine.js"; import { type NodeStatusInterpreter, createNodeStatusMachine, nodeStatusMachineStateToNodeStatus, -} from "../NodeStatusMachine"; -import { NodeStatus } from "../_Types"; -import { NodeEventsMixin } from "./10_Events"; +} from "../NodeStatusMachine.js"; +import { NodeStatus } from "../_Types.js"; +import { NodeEventsMixin } from "./10_Events.js"; export interface NodeWithStatus { /** diff --git a/packages/zwave-js/src/lib/node/mixins/30_Wakeup.ts b/packages/zwave-js/src/lib/node/mixins/30_Wakeup.ts index 1c2df3059705..7d7ff39120b4 100644 --- a/packages/zwave-js/src/lib/node/mixins/30_Wakeup.ts +++ b/packages/zwave-js/src/lib/node/mixins/30_Wakeup.ts @@ -5,7 +5,7 @@ import { ZWaveError, ZWaveErrorCodes, } from "@zwave-js/core"; -import { NodeStatusMixin } from "./20_Status"; +import { NodeStatusMixin } from "./20_Status.js"; /** * Interface for NodeWakeupMixin diff --git a/packages/zwave-js/src/lib/node/mixins/40_Values.ts b/packages/zwave-js/src/lib/node/mixins/40_Values.ts index 0171d8525aca..325226c76499 100644 --- a/packages/zwave-js/src/lib/node/mixins/40_Values.ts +++ b/packages/zwave-js/src/lib/node/mixins/40_Values.ts @@ -16,11 +16,11 @@ import { getCCName, } from "@zwave-js/core"; import { pick } from "@zwave-js/shared"; -import { type Driver } from "../../driver/Driver"; -import { type DeviceClass } from "../DeviceClass"; -import { type ZWaveNodeValueEventCallbacks } from "../_Types"; -import * as nodeUtils from "../utils"; -import { NodeWakeupMixin } from "./30_Wakeup"; +import { type Driver } from "../../driver/Driver.js"; +import { type DeviceClass } from "../DeviceClass.js"; +import { type ZWaveNodeValueEventCallbacks } from "../_Types.js"; +import * as nodeUtils from "../utils.js"; +import { NodeWakeupMixin } from "./30_Wakeup.js"; /** Defines functionality of Z-Wave nodes related to the value DB */ export interface NodeValues { diff --git a/packages/zwave-js/src/lib/node/mixins/50_Endpoints.ts b/packages/zwave-js/src/lib/node/mixins/50_Endpoints.ts index 6993355b6910..21c93d25da53 100644 --- a/packages/zwave-js/src/lib/node/mixins/50_Endpoints.ts +++ b/packages/zwave-js/src/lib/node/mixins/50_Endpoints.ts @@ -7,11 +7,11 @@ import { ZWaveError, ZWaveErrorCodes, } from "@zwave-js/core"; -import { isArray, isObject } from "alcalzone-shared/typeguards"; -import { DeviceClass } from "../DeviceClass"; -import { Endpoint } from "../Endpoint"; -import * as nodeUtils from "../utils"; -import { NodeValuesMixin } from "./40_Values"; +import { isArray, isObject } from "alcalzone-shared/typeguards/index.js"; +import { DeviceClass } from "../DeviceClass.js"; +import { Endpoint } from "../Endpoint.js"; +import * as nodeUtils from "../utils.js"; +import { NodeValuesMixin } from "./40_Values.js"; /** Defines functionality of Z-Wave nodes related to accessing endpoints and their capabilities */ export interface Endpoints { diff --git a/packages/zwave-js/src/lib/node/mixins/60_ScheduledPoll.ts b/packages/zwave-js/src/lib/node/mixins/60_ScheduledPoll.ts index 32166745a973..8e11f7151db5 100644 --- a/packages/zwave-js/src/lib/node/mixins/60_ScheduledPoll.ts +++ b/packages/zwave-js/src/lib/node/mixins/60_ScheduledPoll.ts @@ -10,9 +10,9 @@ import { import { type NodeSchedulePollOptions } from "@zwave-js/host"; import { ObjectKeyMap } from "@zwave-js/shared"; import { isDeepStrictEqual } from "node:util"; -import { type Driver } from "../../driver/Driver"; -import { type DeviceClass } from "../DeviceClass"; -import { EndpointsMixin } from "./50_Endpoints"; +import { type Driver } from "../../driver/Driver.js"; +import { type DeviceClass } from "../DeviceClass.js"; +import { EndpointsMixin } from "./50_Endpoints.js"; export interface ScheduledPoll { timeout: NodeJS.Timeout; diff --git a/packages/zwave-js/src/lib/node/mixins/70_FirmwareUpdate.ts b/packages/zwave-js/src/lib/node/mixins/70_FirmwareUpdate.ts index bfbeb28a2028..345b4b80f813 100644 --- a/packages/zwave-js/src/lib/node/mixins/70_FirmwareUpdate.ts +++ b/packages/zwave-js/src/lib/node/mixins/70_FirmwareUpdate.ts @@ -26,17 +26,21 @@ import { } from "@zwave-js/core"; import { containsCC } from "@zwave-js/serial/serialapi"; import { getEnumMemberName, throttle } from "@zwave-js/shared"; -import { distinct } from "alcalzone-shared/arrays"; -import { wait } from "alcalzone-shared/async"; +import { distinct } from "alcalzone-shared/arrays/index.js"; +import { wait } from "alcalzone-shared/async/index.js"; import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; -import { roundTo } from "alcalzone-shared/math"; +} from "alcalzone-shared/deferred-promise/index.js"; +import { roundTo } from "alcalzone-shared/math/index.js"; import { randomBytes } from "node:crypto"; -import { type Task, type TaskBuilder, TaskPriority } from "../../driver/Task"; -import { type Transaction } from "../../driver/Transaction"; -import { SchedulePollMixin } from "./60_ScheduledPoll"; +import { + type Task, + type TaskBuilder, + TaskPriority, +} from "../../driver/Task.js"; +import { type Transaction } from "../../driver/Transaction.js"; +import { SchedulePollMixin } from "./60_ScheduledPoll.js"; interface AbortFirmwareUpdateContext { abort: boolean; diff --git a/packages/zwave-js/src/lib/node/mixins/index.ts b/packages/zwave-js/src/lib/node/mixins/index.ts index 0843bf7efb64..810cf68021f4 100644 --- a/packages/zwave-js/src/lib/node/mixins/index.ts +++ b/packages/zwave-js/src/lib/node/mixins/index.ts @@ -1,3 +1,3 @@ -import { FirmwareUpdateMixin } from "./70_FirmwareUpdate"; +import { FirmwareUpdateMixin } from "./70_FirmwareUpdate.js"; export abstract class ZWaveNodeMixins extends FirmwareUpdateMixin {} diff --git a/packages/zwave-js/src/lib/node/mockCCBehaviors/ScheduleEntryLock.ts b/packages/zwave-js/src/lib/node/mockCCBehaviors/ScheduleEntryLock.ts index d539f2a3e2ac..10132ca78cb6 100644 --- a/packages/zwave-js/src/lib/node/mockCCBehaviors/ScheduleEntryLock.ts +++ b/packages/zwave-js/src/lib/node/mockCCBehaviors/ScheduleEntryLock.ts @@ -29,7 +29,7 @@ import { type MockNodeBehavior, type ScheduleEntryLockCCCapabilities, } from "@zwave-js/testing"; -import { defaultCapabilities as defaultUserCodeCapabilities } from "./UserCode"; +import { defaultCapabilities as defaultUserCodeCapabilities } from "./UserCode.js"; const defaultCapabilities: ScheduleEntryLockCCCapabilities = { numWeekDaySlots: 1, diff --git a/packages/zwave-js/src/lib/telemetry/deviceConfig.ts b/packages/zwave-js/src/lib/telemetry/deviceConfig.ts index bb501b3be2f2..a25740c91c08 100644 --- a/packages/zwave-js/src/lib/telemetry/deviceConfig.ts +++ b/packages/zwave-js/src/lib/telemetry/deviceConfig.ts @@ -2,8 +2,8 @@ // import { AssociationGroupInfoCC, ConfigurationCC } from "@zwave-js/cc"; // import { CommandClasses } from "@zwave-js/core"; // import { formatId } from "@zwave-js/shared"; -// import { isObject } from "alcalzone-shared/typeguards"; -import type { ZWaveNode } from "../node/Node"; +// import { isObject } from "alcalzone-shared/typeguards/index.js"; +import type { ZWaveNode } from "../node/Node.js"; // const missingDeviceConfigCache = new Set(); diff --git a/packages/zwave-js/src/lib/telemetry/statistics.ts b/packages/zwave-js/src/lib/telemetry/statistics.ts index df0af48d555a..0034e63fa634 100644 --- a/packages/zwave-js/src/lib/telemetry/statistics.ts +++ b/packages/zwave-js/src/lib/telemetry/statistics.ts @@ -1,7 +1,7 @@ import { formatId } from "@zwave-js/shared"; -import { isObject } from "alcalzone-shared/typeguards"; +import { isObject } from "alcalzone-shared/typeguards/index.js"; import * as crypto from "node:crypto"; -import type { Driver } from "../driver/Driver"; +import type { Driver } from "../driver/Driver.js"; const apiToken = "ef58278d935ccb26307800279458484d"; const statisticsUrl = `https://stats.zwave-js.io/statistics`; diff --git a/packages/zwave-js/src/lib/test/assertCC.ts b/packages/zwave-js/src/lib/test/assertCC.ts index 69f02f92d264..9e48ecd35aef 100644 --- a/packages/zwave-js/src/lib/test/assertCC.ts +++ b/packages/zwave-js/src/lib/test/assertCC.ts @@ -1,12 +1,12 @@ import type { CCConstructor, CommandClass } from "@zwave-js/cc"; import { SendDataBridgeRequest } from "@zwave-js/serial/serialapi"; import { SendDataRequest } from "@zwave-js/serial/serialapi"; -import type { ExecutionContext } from "ava"; +import { type ExpectStatic } from "vitest"; export function assertCC< TConst extends CCConstructor = CCConstructor, >( - t: ExecutionContext, + expect: ExpectStatic, callArg: any, options: { nodeId?: number; @@ -16,17 +16,17 @@ export function assertCC< ): void { const request: SendDataRequest | SendDataBridgeRequest = callArg; try { - t.true(request instanceof SendDataRequest); + expect(request).toBeInstanceOf(SendDataRequest); } catch { - t.true(request instanceof SendDataBridgeRequest); + expect(request).toBeInstanceOf(SendDataBridgeRequest); } - if (options.nodeId) t.is(request.getNodeId(), options.nodeId); + if (options.nodeId) expect(request.getNodeId()).toBe(options.nodeId); const command = request.command; - t.true(command instanceof options.cc); + expect(command).toBeInstanceOf(options.cc); if (options.ccValues) { for (const [prop, val] of Object.entries(options.ccValues)) { - t.is((command as any)[prop], val); + expect((command as any)[prop]).toBe(val); } } } diff --git a/packages/zwave-js/src/lib/test/cc-specific/configurationSetThrow.test.ts b/packages/zwave-js/src/lib/test/cc-specific/configurationSetThrow.test.ts index c9b8dd20cb05..6f3a602abe6c 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/configurationSetThrow.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/configurationSetThrow.test.ts @@ -1,6 +1,6 @@ import path from "node:path"; import sinon from "sinon"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; // repro from https://github.com/zwave-js/zwave-js-ui/issues/101#issuecomment-749007701 @@ -21,8 +21,8 @@ integrationTest( "not-a-number", ); - await t.throwsAsync(promise); - t.is(spy.callCount, 0); + await t.expect(() => promise).rejects.toThrowError(); + t.expect(spy.callCount).toBe(0); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/discardUnsupportedReports.test.ts b/packages/zwave-js/src/lib/test/cc-specific/discardUnsupportedReports.test.ts index 5acfc308b636..8274c560fccd 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/discardUnsupportedReports.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/discardUnsupportedReports.test.ts @@ -8,9 +8,9 @@ import { RateType, } from "@zwave-js/cc"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Discard Multilevel Sensor and Meter CC Reports on nodes and/or endpoints that do not support them", @@ -95,10 +95,10 @@ integrationTest( const temperature0 = node.getValue( sensorValue.id, ); - t.is(temperature0, undefined); + t.expect(temperature0).toBeUndefined(); const temperature1 = node.getValue(sensorValue.endpoint(1)); - t.is(temperature1, 25.12); + t.expect(temperature1).toBe(25.12); const meterValue = MeterCCValues.value( 0x01, @@ -106,10 +106,10 @@ integrationTest( 0x00, ); const meter0 = node.getValue(meterValue.id); - t.is(meter0, 2.34); + t.expect(meter0).toBe(2.34); const meter1 = node.getValue(meterValue.endpoint(1)); - t.is(meter1, undefined); + t.expect(meter1).toBeUndefined(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/mapNotificationDoorLock.test.ts b/packages/zwave-js/src/lib/test/cc-specific/mapNotificationDoorLock.test.ts index b99c1977ba42..77a64a30a320 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/mapNotificationDoorLock.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/mapNotificationDoorLock.test.ts @@ -2,9 +2,9 @@ import { DoorLockMode } from "@zwave-js/cc"; import { DoorLockCCValues } from "@zwave-js/cc/DoorLockCC"; import { NotificationCCReport } from "@zwave-js/cc/NotificationCC"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When receiving a NotificationCC::Report with a lock operation, the current value for Door Lock CC should be updated accordingly", @@ -31,7 +31,7 @@ integrationTest( // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(valueId), DoorLockMode.Secured); + t.expect(node.getValue(valueId)).toBe(DoorLockMode.Secured); cc = new NotificationCCReport({ nodeId: mockController.ownNodeId, @@ -46,7 +46,7 @@ integrationTest( // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(valueId), DoorLockMode.Unsecured); + t.expect(node.getValue(valueId)).toBe(DoorLockMode.Unsecured); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/meterReportPropertyKeyName.test.ts b/packages/zwave-js/src/lib/test/cc-specific/meterReportPropertyKeyName.test.ts index 76f043bc7608..29b16cb895fa 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/meterReportPropertyKeyName.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/meterReportPropertyKeyName.test.ts @@ -2,7 +2,7 @@ import { Bytes } from "@zwave-js/shared"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When receiving a MeterCC::Report, the value event should contain the meter name in propertyKeyName", @@ -13,7 +13,9 @@ integrationTest( testBody: async (t, driver, node, mockController, _mockNode) => { const valueAddedPromise = new Promise((resolve) => { node.on("value added", (_node, args) => { - t.is(args.propertyKeyName, "Electric_kWh_Consumed"); + t.expect(args.propertyKeyName).toBe( + "Electric_kWh_Consumed", + ); resolve(); }); }); diff --git a/packages/zwave-js/src/lib/test/cc-specific/notificationEnums.test.ts b/packages/zwave-js/src/lib/test/cc-specific/notificationEnums.test.ts index 17e70365ae34..1de85ecbd712 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/notificationEnums.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/notificationEnums.test.ts @@ -4,8 +4,8 @@ import { } from "@zwave-js/cc/NotificationCC"; import { CommandClasses, type ValueMetadataNumeric } from "@zwave-js/core"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Notifications with enum event parameters are evaluated correctly", @@ -40,7 +40,7 @@ integrationTest( valveOperationStatusId, ) as ValueMetadataNumeric ).states; - t.deepEqual(states, { + t.expect(states).toStrictEqual({ // For the valve operation status variable, the embedded enum replaces its possible states // since there is only one meaningless state, so it doesn't make sense to preserve it // This is different from the "Door state" value which has multiple states AND enums @@ -64,7 +64,7 @@ integrationTest( await wait(100); let value = node.getValue(valveOperationStatusId); - t.is(value, 0x00); + t.expect(value).toBe(0x00); cc = new NotificationCCReport({ nodeId: mockController.ownNodeId, @@ -80,7 +80,7 @@ integrationTest( await wait(100); value = node.getValue(valveOperationStatusId); - t.is(value, 0x01); + t.expect(value).toBe(0x01); }, }, ); @@ -114,7 +114,7 @@ integrationTest( const states = ( node.getValueMetadata(doorStateValueId) as ValueMetadataNumeric ).states; - t.deepEqual(states, { + t.expect(states).toStrictEqual({ [0x16]: "Window/door is open", [0x17]: "Window/door is closed", // The Door state notification type has an enum for the "open" state @@ -139,7 +139,7 @@ integrationTest( await wait(100); let value = node.getValue(doorStateValueId); - t.is(value, 0x1600); + t.expect(value).toBe(0x1600); cc = new NotificationCCReport({ nodeId: mockController.ownNodeId, @@ -155,7 +155,7 @@ integrationTest( await wait(100); value = node.getValue(doorStateValueId); - t.is(value, 0x1601); + t.expect(value).toBe(0x1601); cc = new NotificationCCReport({ nodeId: mockController.ownNodeId, @@ -170,7 +170,7 @@ integrationTest( await wait(100); value = node.getValue(doorStateValueId); - t.is(value, 0x16); + t.expect(value).toBe(0x16); cc = new NotificationCCReport({ nodeId: mockController.ownNodeId, @@ -185,7 +185,7 @@ integrationTest( await wait(100); value = node.getValue(doorStateValueId); - t.is(value, 0x17); + t.expect(value).toBe(0x17); }, }, ); @@ -218,10 +218,10 @@ integrationTest("The 'simple' Door state value works correctly", { vid.commandClass === CommandClasses.Notification && vid.propertyKey === "Door state (simple)", ); - t.truthy(simpleVID); + t.expect(simpleVID).toBeTruthy(); const meta = node.getValueMetadata(simpleVID!); - t.like(meta, { + t.expect(meta).toMatchObject({ ccSpecific: { notificationType: 6 }, label: "Door state (simple)", readable: true, @@ -254,8 +254,8 @@ integrationTest("The 'simple' Door state value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(valueWithEnum.id), 0x1601); - t.is(node.getValue(valueSimple.id), 0x16); + t.expect(node.getValue(valueWithEnum.id)).toBe(0x1601); + t.expect(node.getValue(valueSimple.id)).toBe(0x16); // === @@ -273,8 +273,8 @@ integrationTest("The 'simple' Door state value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(valueWithEnum.id), 0x1600); - t.is(node.getValue(valueSimple.id), 0x16); + t.expect(node.getValue(valueWithEnum.id)).toBe(0x1600); + t.expect(node.getValue(valueSimple.id)).toBe(0x16); // === @@ -291,8 +291,8 @@ integrationTest("The 'simple' Door state value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(valueWithEnum.id), 0x16); - t.is(node.getValue(valueSimple.id), 0x16); + t.expect(node.getValue(valueWithEnum.id)).toBe(0x16); + t.expect(node.getValue(valueSimple.id)).toBe(0x16); // === @@ -309,8 +309,8 @@ integrationTest("The 'simple' Door state value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(valueWithEnum.id), 0x17); - t.is(node.getValue(valueSimple.id), 0x17); + t.expect(node.getValue(valueWithEnum.id)).toBe(0x17); + t.expect(node.getValue(valueSimple.id)).toBe(0x17); }, }); @@ -343,7 +343,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { (vid) => NotificationCCValues.doorTiltState.is(vid), ); // Before receiving any notifications with the tilt enum, the synthetic value should not exist - t.false(hasTiltVID()); + t.expect(hasTiltVID()).toBe(false); // Send a notification to the node where the window is not tilted let cc = new NotificationCCReport({ @@ -361,7 +361,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { await wait(100); // The value should still not exist - t.false(hasTiltVID()); + t.expect(hasTiltVID()).toBe(false); // === @@ -381,8 +381,8 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { await wait(100); // The value should now exist - t.true(hasTiltVID()); - t.is(node.getValue(tiltVID), 0x01); + t.expect(hasTiltVID()).toBe(true); + t.expect(node.getValue(tiltVID)).toBe(0x01); // === @@ -401,7 +401,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(tiltVID), 0x00); + t.expect(node.getValue(tiltVID)).toBe(0x00); // === @@ -420,7 +420,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(tiltVID), 0x01); + t.expect(node.getValue(tiltVID)).toBe(0x01); // === @@ -438,7 +438,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(tiltVID), 0x00); + t.expect(node.getValue(tiltVID)).toBe(0x00); // === @@ -457,7 +457,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(tiltVID), 0x01); + t.expect(node.getValue(tiltVID)).toBe(0x01); // === @@ -475,7 +475,7 @@ integrationTest("The synthetic 'Door tilt state' value works correctly", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(tiltVID), 0x00); + t.expect(node.getValue(tiltVID)).toBe(0x00); }, }); @@ -511,7 +511,7 @@ integrationTest( waterPressureAlarmValueId, ) as ValueMetadataNumeric ).states; - t.deepEqual(states, { + t.expect(states).toStrictEqual({ [0x00]: "idle", [0x01]: "No data", [0x02]: "Below low threshold", @@ -535,7 +535,7 @@ integrationTest( await wait(100); let value = node.getValue(waterPressureAlarmValueId); - t.is(value, 0x02); + t.expect(value).toBe(0x02); // Now send one without an event parameter cc = new NotificationCCReport({ @@ -551,7 +551,7 @@ integrationTest( await wait(100); value = node.getValue(waterPressureAlarmValueId); - t.is(value, 0x01); + t.expect(value).toBe(0x01); // cc = new NotificationCCReport({ // nodeId: mockController.ownNodeId, diff --git a/packages/zwave-js/src/lib/test/cc-specific/notificationIdleManually.test.ts b/packages/zwave-js/src/lib/test/cc-specific/notificationIdleManually.test.ts index 736216c9a9c3..cb7799de692d 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/notificationIdleManually.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/notificationIdleManually.test.ts @@ -3,9 +3,9 @@ import { NotificationCCValues, } from "@zwave-js/cc/NotificationCC"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("Notification values can get idled manually", { // debug: true, @@ -29,15 +29,19 @@ integrationTest("Notification values can get idled manually", { ); // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(alarmStatusValueId), 0x03 /* Smoke alarm test */); + t.expect(node.getValue(alarmStatusValueId) /* Smoke alarm test */).toBe( + 0x03, + ); // Trying to idle a different value does not work node.manuallyIdleNotificationValue(0x01, 0x06 /* Alarm silenced */); - t.is(node.getValue(alarmStatusValueId), 0x03 /* Smoke alarm test */); + t.expect(node.getValue(alarmStatusValueId) /* Smoke alarm test */).toBe( + 0x03, + ); // Idling the correct value does work node.manuallyIdleNotificationValue(0x01, 0x03); - t.is(node.getValue(alarmStatusValueId), 0x00 /* Idle */); + t.expect(node.getValue(alarmStatusValueId) /* Idle */).toBe(0x00); // Now try one that cannot be idled @@ -59,11 +63,11 @@ integrationTest("Notification values can get idled manually", { // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(doorStateValueId), 0x16 /* Door state */); + t.expect(node.getValue(doorStateValueId) /* Door state */).toBe(0x16); node.manuallyIdleNotificationValue(0x06, 0x16); // Unchanged - t.is(node.getValue(doorStateValueId), 0x16 /* Door state */); + t.expect(node.getValue(doorStateValueId) /* Door state */).toBe(0x16); }, }); @@ -92,14 +96,13 @@ integrationTest( ); // wait a bit for the value to be updated await wait(100); - t.is( - node.getValue(alarmStatusValueId), - 0x03, /* Smoke alarm test */ - ); + t.expect( + node.getValue(alarmStatusValueId), /* Smoke alarm test */ + ).toBe(0x03); // Idling with a valueId does work node.manuallyIdleNotificationValue(alarmStatusValueId); - t.is(node.getValue(alarmStatusValueId), 0x00 /* Idle */); + t.expect(node.getValue(alarmStatusValueId) /* Idle */).toBe(0x00); // Now try one that cannot be idled @@ -121,11 +124,15 @@ integrationTest( // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(doorStateValueId), 0x16 /* Door state */); + t.expect(node.getValue(doorStateValueId) /* Door state */).toBe( + 0x16, + ); node.manuallyIdleNotificationValue(doorStateValueId); // Unchanged - t.is(node.getValue(doorStateValueId), 0x16 /* Door state */); + t.expect(node.getValue(doorStateValueId) /* Door state */).toBe( + 0x16, + ); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/notificationIdleRelated.test.ts b/packages/zwave-js/src/lib/test/cc-specific/notificationIdleRelated.test.ts index ddc52c574833..65fec1299389 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/notificationIdleRelated.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/notificationIdleRelated.test.ts @@ -3,9 +3,9 @@ import { NotificationCCValues, } from "@zwave-js/cc/NotificationCC"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When receiving a NotificationCC::Report with an event that has idleVariables configured, the referenced variables get idled", @@ -35,7 +35,9 @@ integrationTest( // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(lockStateValueId), 0x0b /* Lock jammed */); + t.expect(node.getValue(lockStateValueId) /* Lock jammed */).toBe( + 0x0b, + ); cc = new NotificationCCReport({ nodeId: mockController.ownNodeId, @@ -50,7 +52,7 @@ integrationTest( // wait a bit for the value to be updated await wait(100); - t.is(node.getValue(lockStateValueId), 0x00 /* Idle */); + t.expect(node.getValue(lockStateValueId) /* Idle */).toBe(0x00); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/notificationMultipleEventsMetadata.test.ts b/packages/zwave-js/src/lib/test/cc-specific/notificationMultipleEventsMetadata.test.ts index 6163ab83a62a..f0d199dcbb44 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/notificationMultipleEventsMetadata.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/notificationMultipleEventsMetadata.test.ts @@ -1,6 +1,6 @@ import { NotificationCCValues } from "@zwave-js/cc/NotificationCC"; import { CommandClasses, type ValueMetadataNumeric } from "@zwave-js/core"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Notification types with multiple supported events preserve states for all of them", @@ -33,7 +33,7 @@ integrationTest( ).id, ) as ValueMetadataNumeric ).states; - t.deepEqual(states, { + t.expect(states).toStrictEqual({ [0x00]: "idle", [0x03]: "Smoke alarm test", [0x06]: "Alarm silenced", diff --git a/packages/zwave-js/src/lib/test/cc-specific/sceneActivationValueID.test.ts b/packages/zwave-js/src/lib/test/cc-specific/sceneActivationValueID.test.ts index 14facbafb734..74b473bdf31f 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/sceneActivationValueID.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/sceneActivationValueID.test.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "a node that controls the Scene Activation CC should include the scene ID in getDefinedValueIDs()", @@ -12,7 +12,7 @@ integrationTest( testBody: async (t, driver, node, _mockController, _mockNode) => { const valueIDs = node.getDefinedValueIDs(); - t.true(valueIDs.some((v) => v.property === "sceneId")); + t.expect(valueIDs.some((v) => v.property === "sceneId")).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/soundSwitchInterviewValueChangeOptions.test.ts b/packages/zwave-js/src/lib/test/cc-specific/soundSwitchInterviewValueChangeOptions.test.ts index 488673e2bf83..925ffd8c5b74 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/soundSwitchInterviewValueChangeOptions.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/soundSwitchInterviewValueChangeOptions.test.ts @@ -1,7 +1,7 @@ import { SoundSwitchCCValues } from "@zwave-js/cc/SoundSwitchCC"; import { CommandClasses } from "@zwave-js/core"; import { ccCaps } from "@zwave-js/testing"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "The toneId value should have value change options after SoundSwitchCC interview", @@ -28,7 +28,7 @@ integrationTest( testBody: async (t, driver, node, _mockController, _mockNode) => { const toneIdValue = SoundSwitchCCValues.toneId; const meta = node.getValueMetadata(toneIdValue.id); - t.deepEqual(meta.valueChangeOptions, ["volume"]); + t.expect(meta.valueChangeOptions).toStrictEqual(["volume"]); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/undefinedTargetValue.test.ts b/packages/zwave-js/src/lib/test/cc-specific/undefinedTargetValue.test.ts index e1ed5ddb699f..f6ced6193485 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/undefinedTargetValue.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/undefinedTargetValue.test.ts @@ -4,9 +4,9 @@ import { } from "@zwave-js/cc/BinarySwitchCC"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "receiving a BinarySwitchCC::Report with undefined targetValue should not delete the actual targetValue", @@ -31,7 +31,7 @@ integrationTest( await wait(100); // The value in the DB should not be changed because we have no new info - t.is(node.getValue(targetValueValueID), false); + t.expect(node.getValue(targetValueValueID)).toBe(false); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc-specific/unknownNotifications.test.ts b/packages/zwave-js/src/lib/test/cc-specific/unknownNotifications.test.ts index 0cc050765dc9..9f6db9d652c3 100644 --- a/packages/zwave-js/src/lib/test/cc-specific/unknownNotifications.test.ts +++ b/packages/zwave-js/src/lib/test/cc-specific/unknownNotifications.test.ts @@ -4,9 +4,9 @@ import { } from "@zwave-js/cc/NotificationCC"; import { ValueMetadata } from "@zwave-js/core"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When receiving an NotificationCC::Report with known typa but an unknown event, the resulting value metadata should contain the ccSpecific field", @@ -31,21 +31,20 @@ integrationTest( // wait a bit for the value to be updated await wait(100); - t.like( + t.expect( node.getValueMetadata( NotificationCCValues.unknownNotificationVariable( 0x06, "Access Control", ).id, ), - { - ...ValueMetadata.ReadOnlyUInt8, - label: "Access Control: Unknown value", - ccSpecific: { - notificationType: 0x06, - }, + ).toMatchObject({ + ...ValueMetadata.ReadOnlyUInt8, + label: "Access Control: Unknown value", + ccSpecific: { + notificationType: 0x06, }, - ); + }); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc/API.test.ts b/packages/zwave-js/src/lib/test/cc/API.test.ts index 97762861ac6e..cf57f3847bc1 100644 --- a/packages/zwave-js/src/lib/test/cc/API.test.ts +++ b/packages/zwave-js/src/lib/test/cc/API.test.ts @@ -2,55 +2,62 @@ import { API, CCAPI } from "@zwave-js/cc"; import { NOT_KNOWN } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; - -interface TestContext { - driver: Driver; - node2: ZWaveNode; - controller: MockController; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + node2: ZWaveNode; + controller: MockController; + }; } -const test = ava as TestFn; - @API(0xff as any) export class DummyCCAPI extends CCAPI {} -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + const node2 = new ZWaveNode(2, driver); + (driver.controller.nodes as ThrowingMap).set( + node2.id, + node2, ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; - - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - node2.id, - node2, - ); - t.context.node2 = node2; -}); + context.node2 = node2; + + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test.serial(`supportsCommand() returns NOT_KNOWN by default`, (t) => { - const { node2, driver } = t.context; +test.sequential(`supportsCommand() returns NOT_KNOWN by default`, ({ context, expect }) => { + const { node2, driver } = context; const API = new DummyCCAPI(driver, node2); - t.is(API.supportsCommand(null as any), NOT_KNOWN); + expect(API.supportsCommand(null as any)).toBe(NOT_KNOWN); }); diff --git a/packages/zwave-js/src/lib/test/cc/AssociationCC.test.ts b/packages/zwave-js/src/lib/test/cc/AssociationCC.test.ts index 5419f60855f0..100c29d4d0af 100644 --- a/packages/zwave-js/src/lib/test/cc/AssociationCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/AssociationCC.test.ts @@ -10,7 +10,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -30,7 +30,7 @@ test("the SupportedGroupingsGet command should serialize correctly", (t) => { AssociationCommand.SupportedGroupingsGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedGroupingsReport command should be deserialized correctly", (t) => { @@ -44,9 +44,9 @@ test("the SupportedGroupingsReport command should be deserialized correctly", (t ccData, { sourceNodeId: 2 } as any, ) as AssociationCCSupportedGroupingsReport; - t.is(cc.constructor, AssociationCCSupportedGroupingsReport); + t.expect(cc.constructor).toBe(AssociationCCSupportedGroupingsReport); - t.is(cc.groupCount, 7); + t.expect(cc.groupCount).toBe(7); }); test("the Set command should serialize correctly", (t) => { @@ -65,7 +65,7 @@ test("the Set command should serialize correctly", (t) => { 5, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Get command should serialize correctly", (t) => { const cc = new AssociationCCGet({ @@ -78,7 +78,7 @@ test("the Get command should serialize correctly", (t) => { 9, // group ID ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly", (t) => { @@ -98,12 +98,12 @@ test("the Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as AssociationCCReport; - t.is(cc.constructor, AssociationCCReport); + t.expect(cc.constructor).toBe(AssociationCCReport); - t.is(cc.groupId, 5); - t.is(cc.maxNodes, 9); - t.is(cc.reportsToFollow, 0); - t.deepEqual(cc.nodeIds, [1, 2, 5]); + t.expect(cc.groupId).toBe(5); + t.expect(cc.maxNodes).toBe(9); + t.expect(cc.reportsToFollow).toBe(0); + t.expect(cc.nodeIds).toStrictEqual([1, 2, 5]); }); test("the Remove command should serialize correctly", (t) => { @@ -122,7 +122,7 @@ test("the Remove command should serialize correctly", (t) => { 5, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Remove command should serialize correctly (empty node list)", (t) => { @@ -136,7 +136,7 @@ test("the Remove command should serialize correctly (empty node list)", (t) => { 5, // group id ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); // test("deserializing an unsupported command should return an unspecified version of AssociationCC", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/AssociationGroupInfoCC.test.ts b/packages/zwave-js/src/lib/test/cc/AssociationGroupInfoCC.test.ts index 35b1c004af67..9fe7a281ca07 100644 --- a/packages/zwave-js/src/lib/test/cc/AssociationGroupInfoCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/AssociationGroupInfoCC.test.ts @@ -13,7 +13,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -35,7 +35,7 @@ test("the NameGet command should serialize correctly", (t) => { 7, // group id ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the NameReport command should be deserialized correctly", (t) => { @@ -57,10 +57,10 @@ test("the NameReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as AssociationGroupInfoCCNameReport; - t.is(cc.constructor, AssociationGroupInfoCCNameReport); + t.expect(cc.constructor).toBe(AssociationGroupInfoCCNameReport); - t.is(cc.groupId, 7); - t.is(cc.name, "foobar"); + t.expect(cc.groupId).toBe(7); + t.expect(cc.name).toBe("foobar"); }); test("the InfoGet command should serialize correctly (no flag set)", (t) => { @@ -77,7 +77,7 @@ test("the InfoGet command should serialize correctly (no flag set)", (t) => { 7, // group id ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the InfoGet command should serialize correctly (refresh cache flag set)", (t) => { @@ -94,7 +94,7 @@ test("the InfoGet command should serialize correctly (refresh cache flag set)", 7, // group id ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the InfoGet command should serialize correctly (list mode flag set)", (t) => { @@ -111,7 +111,7 @@ test("the InfoGet command should serialize correctly (list mode flag set)", (t) 0, // group id is ignored ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Info Report command should be deserialized correctly", (t) => { @@ -144,16 +144,17 @@ test("the Info Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as AssociationGroupInfoCCInfoReport; - t.is(cc.constructor, AssociationGroupInfoCCInfoReport); + t.expect(cc.constructor).toBe(AssociationGroupInfoCCInfoReport); - t.is(cc.groups.length, 2); - t.is(cc.groups[0].groupId, 1); - t.is( + t.expect(cc.groups.length).toBe(2); + t.expect(cc.groups[0].groupId).toBe(1); + t.expect( cc.groups[0].profile, - AssociationGroupInfoProfile["General: Lifeline"], + ).toBe(AssociationGroupInfoProfile["General: Lifeline"]); + t.expect(cc.groups[1].groupId).toBe(2); + t.expect(cc.groups[1].profile).toBe( + AssociationGroupInfoProfile["Control: Key 01"], ); - t.is(cc.groups[1].groupId, 2); - t.is(cc.groups[1].profile, AssociationGroupInfoProfile["Control: Key 01"]); }); test("the CommandListGet command should serialize correctly", (t) => { @@ -169,7 +170,7 @@ test("the CommandListGet command should serialize correctly", (t) => { 6, // group id ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CommandListReport command should be deserialized correctly", (t) => { @@ -190,15 +191,16 @@ test("the CommandListReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as AssociationGroupInfoCCCommandListReport; - t.is(cc.constructor, AssociationGroupInfoCCCommandListReport); + t.expect(cc.constructor).toBe(AssociationGroupInfoCCCommandListReport); - t.is(cc.groupId, 7); - t.is(cc.commands.size, 2); - t.deepEqual( + t.expect(cc.groupId).toBe(7); + t.expect(cc.commands.size).toBe(2); + t.expect( [...cc.commands.keys()], - [CommandClasses.Basic, CommandClasses["Security Mark"]], - ); - t.deepEqual([...cc.commands.values()], [[BasicCommand.Set], [0x05]]); + ).toStrictEqual([CommandClasses.Basic, CommandClasses["Security Mark"]]); + t.expect([...cc.commands.values()]).toStrictEqual([[BasicCommand.Set], [ + 0x05, + ]]); }); test("deserializing an unsupported command should return an unspecified version of AssociationGroupInfoCC", (t) => { @@ -209,7 +211,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as AssociationGroupInfoCC; - t.is(cc.constructor, AssociationGroupInfoCC); + t.expect(cc.constructor).toBe(AssociationGroupInfoCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/BasicCC.test.ts b/packages/zwave-js/src/lib/test/cc/BasicCC.test.ts index 24d0e2a9c210..134dd4229145 100644 --- a/packages/zwave-js/src/lib/test/cc/BasicCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/BasicCC.test.ts @@ -11,9 +11,9 @@ import { import { CommandClasses } from "@zwave-js/core"; import { createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; -import * as nodeUtils from "../../node/utils"; -import { type CreateTestNodeOptions, createTestNode } from "../mocks"; +import { test } from "vitest"; +import * as nodeUtils from "../../node/utils.js"; +import { type CreateTestNodeOptions, createTestNode } from "../mocks.js"; const host = createTestingHost(); @@ -33,7 +33,7 @@ test("the Get command should serialize correctly", (t) => { BasicCommand.Get, // CC Command ]), ); - t.deepEqual(basicCC.serialize({} as any), expected); + t.expect(basicCC.serialize({} as any)).toStrictEqual(expected); }); test("the Get command should be deserialized correctly", (t) => { @@ -46,8 +46,8 @@ test("the Get command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as BasicCCGet; - t.is(basicCC.constructor, BasicCCGet); - t.is(basicCC.nodeId, 2); + t.expect(basicCC.constructor).toBe(BasicCCGet); + t.expect(basicCC.nodeId).toBe(2); }); test("the Set command should serialize correctly", (t) => { @@ -61,7 +61,7 @@ test("the Set command should serialize correctly", (t) => { 55, // target value ]), ); - t.deepEqual(basicCC.serialize({} as any), expected); + t.expect(basicCC.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -75,11 +75,11 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as BasicCCReport; - t.is(basicCC.constructor, BasicCCReport); + t.expect(basicCC.constructor).toBe(BasicCCReport); - t.is(basicCC.currentValue, 55); - t.is(basicCC.targetValue, undefined); - t.is(basicCC.duration, undefined); + t.expect(basicCC.currentValue).toBe(55); + t.expect(basicCC.targetValue).toBeUndefined(); + t.expect(basicCC.duration).toBeUndefined(); }); test("the Report command (v2) should be deserialized correctly", (t) => { @@ -95,12 +95,12 @@ test("the Report command (v2) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as BasicCCReport; - t.is(basicCC.constructor, BasicCCReport); + t.expect(basicCC.constructor).toBe(BasicCCReport); - t.is(basicCC.currentValue, 55); - t.is(basicCC.targetValue, 66); - t.is(basicCC.duration!.unit, "seconds"); - t.is(basicCC.duration!.value, 1); + t.expect(basicCC.currentValue).toBe(55); + t.expect(basicCC.targetValue).toBe(66); + t.expect(basicCC.duration!.unit).toBe("seconds"); + t.expect(basicCC.duration!.value).toBe(1); }); test("deserializing an unsupported command should return an unspecified version of BasicCC", (t) => { @@ -111,7 +111,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 2 } as any, ) as BasicCCReport; - t.is(basicCC.constructor, BasicCC); + t.expect(basicCC.constructor).toBe(BasicCC); }); test("getDefinedValueIDs() should include the target value for all endpoints except the node itself", (t) => { @@ -142,7 +142,7 @@ test("getDefinedValueIDs() should include the target value for all endpoints exc && property === "targetValue", ); const endpointIndizes = valueIDs.map(({ endpoint }) => endpoint); - t.deepEqual(endpointIndizes, [1, 2]); + t.expect(endpointIndizes).toStrictEqual([1, 2]); }); test("BasicCCSet should expect no response", (t) => { @@ -151,7 +151,7 @@ test("BasicCCSet should expect no response", (t) => { endpointIndex: 2, targetValue: 7, }); - t.false(cc.expectsCCResponse()); + t.expect(cc.expectsCCResponse()).toBe(false); }); test("BasicCCSet => BasicCCReport = unexpected", (t) => { @@ -165,14 +165,14 @@ test("BasicCCSet => BasicCCReport = unexpected", (t) => { currentValue: 7, }); - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); test("BasicCCGet should expect a response", (t) => { const cc = new BasicCCGet({ nodeId: 2, }); - t.true(cc.expectsCCResponse()); + t.expect(cc.expectsCCResponse()).toBe(true); }); test("BasicCCGet => BasicCCReport = expected", (t) => { @@ -184,7 +184,7 @@ test("BasicCCGet => BasicCCReport = expected", (t) => { currentValue: 7, }); - t.true(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(true); }); test("BasicCCGet => BasicCCReport (wrong node) = unexpected", (t) => { @@ -196,7 +196,7 @@ test("BasicCCGet => BasicCCReport (wrong node) = unexpected", (t) => { currentValue: 7, }); - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); test("BasicCCGet => BasicCCSet = unexpected", (t) => { @@ -208,7 +208,7 @@ test("BasicCCGet => BasicCCSet = unexpected", (t) => { targetValue: 7, }); - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); test("Looking up CC values for a CC instance should work", (t) => { @@ -216,7 +216,7 @@ test("Looking up CC values for a CC instance should work", (t) => { nodeId: 2, }); const values = getCCValues(cc) as typeof BasicCCValues; - t.like(values.currentValue.id, { + t.expect(values.currentValue.id).toMatchObject({ commandClass: CommandClasses.Basic, property: "currentValue", }); diff --git a/packages/zwave-js/src/lib/test/cc/BatteryCC.test.ts b/packages/zwave-js/src/lib/test/cc/BatteryCC.test.ts index 9ead114b25eb..e3057048ebee 100644 --- a/packages/zwave-js/src/lib/test/cc/BatteryCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/BatteryCC.test.ts @@ -9,7 +9,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared"; -import test from "ava"; +import { test } from "vitest"; test("the Get command should serialize correctly", (t) => { const batteryCC = new BatteryCCGet({ nodeId: 1 }); @@ -17,7 +17,7 @@ test("the Get command should serialize correctly", (t) => { CommandClasses.Battery, // CC BatteryCommand.Get, // CC Command ]); - t.deepEqual(batteryCC.serialize({} as any), expected); + t.expect(batteryCC.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly: when the battery is not low", (t) => { @@ -30,10 +30,10 @@ test("the Report command (v1) should be deserialized correctly: when the battery ccData, { sourceNodeId: 7 } as any, ) as BatteryCCReport; - t.is(batteryCC.constructor, BatteryCCReport); + t.expect(batteryCC.constructor).toBe(BatteryCCReport); - t.is(batteryCC.level, 55); - t.false(batteryCC.isLow); + t.expect(batteryCC.level).toBe(55); + t.expect(batteryCC.isLow).toBe(false); }); test("the Report command (v1) should be deserialized correctly: when the battery is low", (t) => { @@ -46,10 +46,10 @@ test("the Report command (v1) should be deserialized correctly: when the battery ccData, { sourceNodeId: 7 } as any, ) as BatteryCCReport; - t.is(batteryCC.constructor, BatteryCCReport); + t.expect(batteryCC.constructor).toBe(BatteryCCReport); - t.is(batteryCC.level, 0); - t.true(batteryCC.isLow); + t.expect(batteryCC.level).toBe(0); + t.expect(batteryCC.isLow).toBe(true); }); test("the Report command (v2) should be deserialized correctly: all flags set", (t) => { @@ -64,13 +64,13 @@ test("the Report command (v2) should be deserialized correctly: all flags set", ccData, { sourceNodeId: 7 } as any, ) as BatteryCCReport; - t.is(batteryCC.constructor, BatteryCCReport); + t.expect(batteryCC.constructor).toBe(BatteryCCReport); - t.true(batteryCC.rechargeable); - t.true(batteryCC.backup); - t.true(batteryCC.overheating); - t.true(batteryCC.lowFluid); - t.true(batteryCC.disconnected); + t.expect(batteryCC.rechargeable).toBe(true); + t.expect(batteryCC.backup).toBe(true); + t.expect(batteryCC.overheating).toBe(true); + t.expect(batteryCC.lowFluid).toBe(true); + t.expect(batteryCC.disconnected).toBe(true); }); test("the Report command (v2) should be deserialized correctly: charging status", (t) => { @@ -85,9 +85,9 @@ test("the Report command (v2) should be deserialized correctly: charging status" ccData, { sourceNodeId: 7 } as any, ) as BatteryCCReport; - t.is(batteryCC.constructor, BatteryCCReport); + t.expect(batteryCC.constructor).toBe(BatteryCCReport); - t.is(batteryCC.chargingStatus, BatteryChargingStatus.Maintaining); + t.expect(batteryCC.chargingStatus).toBe(BatteryChargingStatus.Maintaining); }); test("the Report command (v2) should be deserialized correctly: recharge or replace", (t) => { @@ -102,9 +102,9 @@ test("the Report command (v2) should be deserialized correctly: recharge or repl ccData, { sourceNodeId: 7 } as any, ) as BatteryCCReport; - t.is(batteryCC.constructor, BatteryCCReport); + t.expect(batteryCC.constructor).toBe(BatteryCCReport); - t.is(batteryCC.rechargeOrReplace, BatteryReplacementStatus.Now); + t.expect(batteryCC.rechargeOrReplace).toBe(BatteryReplacementStatus.Now); }); test("deserializing an unsupported command should return an unspecified version of BatteryCC", (t) => { @@ -116,7 +116,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 7 } as any, ) as BatteryCCReport; - t.is(batteryCC.constructor, BatteryCC); + t.expect(batteryCC.constructor).toBe(BatteryCC); }); // describe.skip(`interview()`, () => { diff --git a/packages/zwave-js/src/lib/test/cc/BinarySensorCC.test.ts b/packages/zwave-js/src/lib/test/cc/BinarySensorCC.test.ts index 24f23b34fd7f..17c4bd3d0433 100644 --- a/packages/zwave-js/src/lib/test/cc/BinarySensorCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/BinarySensorCC.test.ts @@ -10,7 +10,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -29,7 +29,7 @@ test("the Get command should serialize correctly (no sensor type)", (t) => { BinarySensorType.Any, // sensor type ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Get command should serialize correctly", (t) => { @@ -40,7 +40,7 @@ test("the Get command should serialize correctly", (t) => { const expected = buildCCBuffer( Uint8Array.from([BinarySensorCommand.Get, BinarySensorType.CO]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -54,9 +54,9 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as BinarySensorCCReport; - t.is(cc.constructor, BinarySensorCCReport); + t.expect(cc.constructor).toBe(BinarySensorCCReport); - t.is(cc.value, true); + t.expect(cc.value).toBe(true); }); test("the Report command (v2) should be deserialized correctly", (t) => { @@ -71,10 +71,10 @@ test("the Report command (v2) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as BinarySensorCCReport; - t.is(cc.constructor, BinarySensorCCReport); + t.expect(cc.constructor).toBe(BinarySensorCCReport); - t.is(cc.value, false); - t.is(cc.type, BinarySensorType.CO2); + t.expect(cc.value).toBe(false); + t.expect(cc.type).toBe(BinarySensorType.CO2); }); test("the SupportedGet command should serialize correctly", (t) => { @@ -84,7 +84,7 @@ test("the SupportedGet command should serialize correctly", (t) => { BinarySensorCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedReport command should be deserialized correctly", (t) => { @@ -99,9 +99,9 @@ test("the SupportedReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as BinarySensorCCSupportedReport; - t.is(cc.constructor, BinarySensorCCSupportedReport); + t.expect(cc.constructor).toBe(BinarySensorCCSupportedReport); - t.deepEqual(cc.supportedSensorTypes, [ + t.expect(cc.supportedSensorTypes).toStrictEqual([ BinarySensorType["General Purpose"], BinarySensorType.CO, BinarySensorType.Heat, @@ -118,7 +118,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as BinarySensorCC; - t.is(cc.constructor, BinarySensorCC); + t.expect(cc.constructor).toBe(BinarySensorCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/BinarySwitchCC.test.ts b/packages/zwave-js/src/lib/test/cc/BinarySwitchCC.test.ts index 880a9f615b8b..3433b571c6e7 100644 --- a/packages/zwave-js/src/lib/test/cc/BinarySwitchCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/BinarySwitchCC.test.ts @@ -9,7 +9,7 @@ import { import { CommandClasses, Duration } from "@zwave-js/core"; import { type GetSupportedCCVersion } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -27,7 +27,7 @@ test("the Get command should serialize correctly", (t) => { BinarySwitchCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (no duration)", (t) => { @@ -48,7 +48,7 @@ test("the Set command should serialize correctly (no duration)", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Set command should serialize correctly", (t) => { @@ -71,7 +71,7 @@ test("the Set command should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -85,11 +85,11 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as BinarySwitchCCReport; - t.is(cc.constructor, BinarySwitchCCReport); + t.expect(cc.constructor).toBe(BinarySwitchCCReport); - t.is(cc.currentValue, true); - t.is(cc.targetValue, undefined); - t.is(cc.duration, undefined); + t.expect(cc.currentValue).toBe(true); + t.expect(cc.targetValue).toBeUndefined(); + t.expect(cc.duration).toBeUndefined(); }); test("the Report command (v2) should be deserialized correctly", (t) => { @@ -105,12 +105,12 @@ test("the Report command (v2) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as BinarySwitchCCReport; - t.is(cc.constructor, BinarySwitchCCReport); + t.expect(cc.constructor).toBe(BinarySwitchCCReport); - t.is(cc.currentValue, true); - t.is(cc.targetValue, false); - t.is(cc.duration!.unit, "seconds"); - t.is(cc.duration!.value, 1); + t.expect(cc.currentValue).toBe(true); + t.expect(cc.targetValue).toBe(false); + t.expect(cc.duration!.unit).toBe("seconds"); + t.expect(cc.duration!.value).toBe(1); }); test("deserializing an unsupported command should return an unspecified version of BinarySwitchCC", (t) => { @@ -121,7 +121,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 2 } as any, ) as BinarySwitchCC; - t.is(cc.constructor, BinarySwitchCC); + t.expect(cc.constructor).toBe(BinarySwitchCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/CRC16CC.test.ts b/packages/zwave-js/src/lib/test/cc/CRC16CC.test.ts index d0bde449dd31..e1ff6ff12c06 100644 --- a/packages/zwave-js/src/lib/test/cc/CRC16CC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/CRC16CC.test.ts @@ -8,7 +8,7 @@ import { isEncapsulatingCommandClass, } from "@zwave-js/cc"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; test("should be detected as an encapsulating CC", (t) => { const basicCCSet = new BasicCCSet({ @@ -16,7 +16,7 @@ test("should be detected as an encapsulating CC", (t) => { targetValue: 89, }); const crc16 = CRC16CC.encapsulate(basicCCSet); - t.true(isEncapsulatingCommandClass(crc16)); + t.expect(isEncapsulatingCommandClass(crc16)).toBe(true); }); test("should match the specs", (t) => { @@ -25,7 +25,7 @@ test("should match the specs", (t) => { const crc16 = CRC16CC.encapsulate(basicCCGet); const serialized = crc16.serialize({} as any); const expected = Bytes.from("560120024d26", "hex"); - t.deepEqual(serialized, expected); + t.expect(serialized).toStrictEqual(expected); }); test("serialization and deserialization should be compatible", (t) => { @@ -34,20 +34,20 @@ test("serialization and deserialization should be compatible", (t) => { targetValue: 89, }); const crc16 = CRC16CC.encapsulate(basicCCSet); - t.is(crc16.nodeId, basicCCSet.nodeId); - t.is(crc16.encapsulated, basicCCSet); + t.expect(crc16.nodeId).toBe(basicCCSet.nodeId); + t.expect(crc16.encapsulated).toBe(basicCCSet); const serialized = crc16.serialize({} as any); const deserialized = CommandClass.parse( serialized, { sourceNodeId: basicCCSet.nodeId as number } as any, ); - t.is(deserialized.nodeId, basicCCSet.nodeId); + t.expect(deserialized.nodeId).toBe(basicCCSet.nodeId); const deserializedPayload = (deserialized as CRC16CCCommandEncapsulation) .encapsulated as BasicCCSet; - t.true(deserializedPayload instanceof BasicCCSet); - t.is(deserializedPayload.nodeId, basicCCSet.nodeId); - t.is(deserializedPayload.targetValue, basicCCSet.targetValue); + t.expect(deserializedPayload instanceof BasicCCSet).toBe(true); + t.expect(deserializedPayload.nodeId).toBe(basicCCSet.nodeId); + t.expect(deserializedPayload.targetValue).toBe(basicCCSet.targetValue); }); test("deserializing a CC with a wrong checksum should result in an invalid CC", (t) => { @@ -56,8 +56,8 @@ test("deserializing a CC with a wrong checksum should result in an invalid CC", targetValue: 89, }); const crc16 = CRC16CC.encapsulate(basicCCSet); - t.is(crc16.nodeId, basicCCSet.nodeId); - t.is(crc16.encapsulated, basicCCSet); + t.expect(crc16.nodeId).toBe(basicCCSet.nodeId); + t.expect(crc16.encapsulated).toBe(basicCCSet); const serialized = crc16.serialize({} as any); serialized[serialized.length - 1] ^= 0xff; @@ -65,5 +65,5 @@ test("deserializing a CC with a wrong checksum should result in an invalid CC", serialized, { sourceNodeId: basicCCSet.nodeId as number } as any, ); - t.true(deserialized instanceof InvalidCC); + t.expect(deserialized instanceof InvalidCC).toBe(true); }); diff --git a/packages/zwave-js/src/lib/test/cc/CentralSceneCC.test.ts b/packages/zwave-js/src/lib/test/cc/CentralSceneCC.test.ts index f8bf1c69ab14..6e3bb411edf2 100644 --- a/packages/zwave-js/src/lib/test/cc/CentralSceneCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/CentralSceneCC.test.ts @@ -12,7 +12,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -32,7 +32,7 @@ test("the ConfigurationGet command should serialize correctly", (t) => { CentralSceneCommand.ConfigurationGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ConfigurationSet command should serialize correctly (flags set)", (t) => { @@ -46,7 +46,7 @@ test("the ConfigurationSet command should serialize correctly (flags set)", (t) 0b1000_0000, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ConfigurationSet command should serialize correctly (flags not set)", (t) => { @@ -60,7 +60,7 @@ test("the ConfigurationSet command should serialize correctly (flags not set)", 0, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ConfigurationReport command should be deserialized correctly", (t) => { @@ -74,9 +74,9 @@ test("the ConfigurationReport command should be deserialized correctly", (t) => ccData, { sourceNodeId: 1 } as any, ) as CentralSceneCCConfigurationReport; - t.is(cc.constructor, CentralSceneCCConfigurationReport); + t.expect(cc.constructor).toBe(CentralSceneCCConfigurationReport); - t.is(cc.slowRefresh, true); + t.expect(cc.slowRefresh).toBe(true); }); test("the SupportedGet command should serialize correctly", (t) => { @@ -88,7 +88,7 @@ test("the SupportedGet command should serialize correctly", (t) => { CentralSceneCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedReport command should be deserialized correctly", (t) => { @@ -107,14 +107,14 @@ test("the SupportedReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as CentralSceneCCSupportedReport; - t.is(cc.constructor, CentralSceneCCSupportedReport); + t.expect(cc.constructor).toBe(CentralSceneCCSupportedReport); - t.is(cc.sceneCount, 2); - t.true(cc.supportsSlowRefresh); - t.is(cc.supportedKeyAttributes.size, 2); + t.expect(cc.sceneCount).toBe(2); + t.expect(cc.supportsSlowRefresh).toBe(true); + t.expect(cc.supportedKeyAttributes.size).toBe(2); // Key attributes start counting at 0 - t.deepEqual(cc.supportedKeyAttributes.get(1), [0, 8, 9]); - t.deepEqual(cc.supportedKeyAttributes.get(2), [0, 2, 4]); + t.expect(cc.supportedKeyAttributes.get(1)).toStrictEqual([0, 8, 9]); + t.expect(cc.supportedKeyAttributes.get(2)).toStrictEqual([0, 2, 4]); }); test("the Notification command should be deserialized correctly", (t) => { @@ -130,13 +130,13 @@ test("the Notification command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as CentralSceneCCNotification; - t.is(cc.constructor, CentralSceneCCNotification); + t.expect(cc.constructor).toBe(CentralSceneCCNotification); - t.is(cc.sequenceNumber, 7); + t.expect(cc.sequenceNumber).toBe(7); // slow refresh is only evaluated if the attribute is KeyHeldDown - t.falsy(cc.slowRefresh); - t.is(cc.keyAttribute, CentralSceneKeys.KeyPressed4x); - t.is(cc.sceneNumber, 8); + t.expect(cc.slowRefresh).toBeFalsy(); + t.expect(cc.keyAttribute).toBe(CentralSceneKeys.KeyPressed4x); + t.expect(cc.sceneNumber).toBe(8); }); test("the Notification command should be deserialized correctly (KeyHeldDown)", (t) => { @@ -152,12 +152,12 @@ test("the Notification command should be deserialized correctly (KeyHeldDown)", ccData, { sourceNodeId: 1 } as any, ) as CentralSceneCCNotification; - t.is(cc.constructor, CentralSceneCCNotification); + t.expect(cc.constructor).toBe(CentralSceneCCNotification); - t.is(cc.sequenceNumber, 7); - t.true(cc.slowRefresh); - t.is(cc.keyAttribute, CentralSceneKeys.KeyHeldDown); - t.is(cc.sceneNumber, 8); + t.expect(cc.sequenceNumber).toBe(7); + t.expect(cc.slowRefresh).toBe(true); + t.expect(cc.keyAttribute).toBe(CentralSceneKeys.KeyHeldDown); + t.expect(cc.sceneNumber).toBe(8); }); test("deserializing an unsupported command should return an unspecified version of CentralSceneCC", (t) => { @@ -168,7 +168,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as CentralSceneCC; - t.is(cc.constructor, CentralSceneCC); + t.expect(cc.constructor).toBe(CentralSceneCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/ColorSwitchCC.test.ts b/packages/zwave-js/src/lib/test/cc/ColorSwitchCC.test.ts index dad7c467392d..7a05ae72fc43 100644 --- a/packages/zwave-js/src/lib/test/cc/ColorSwitchCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/ColorSwitchCC.test.ts @@ -19,7 +19,7 @@ import { } from "@zwave-js/core"; import { type GetSupportedCCVersion } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -39,7 +39,7 @@ test("the SupportedGet command should serialize correctly", (t) => { ColorSwitchCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedReport command should deserialize correctly", (t) => { @@ -54,9 +54,9 @@ test("the SupportedReport command should deserialize correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as ColorSwitchCCSupportedReport; - t.is(cc.constructor, ColorSwitchCCSupportedReport); + t.expect(cc.constructor).toBe(ColorSwitchCCSupportedReport); - t.deepEqual(cc.supportedColorComponents, [ + t.expect(cc.supportedColorComponents).toStrictEqual([ ColorComponent["Warm White"], ColorComponent["Cold White"], ColorComponent.Red, @@ -82,7 +82,7 @@ test("the Get command should serialize correctly", (t) => { 2, // Color Component ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should deserialize correctly (version 1)", (t) => { @@ -97,12 +97,12 @@ test("the Report command should deserialize correctly (version 1)", (t) => { ccData, { sourceNodeId: 1 } as any, ) as ColorSwitchCCReport; - t.is(cc.constructor, ColorSwitchCCReport); + t.expect(cc.constructor).toBe(ColorSwitchCCReport); - t.is(cc.colorComponent, ColorComponent.Red); - t.is(cc.currentValue, 255); - t.is(cc.targetValue, undefined); - t.is(cc.duration, undefined); + t.expect(cc.colorComponent).toBe(ColorComponent.Red); + t.expect(cc.currentValue).toBe(255); + t.expect(cc.targetValue).toBeUndefined(); + t.expect(cc.duration).toBeUndefined(); }); test("the Report command should deserialize correctly (version 3)", (t) => { @@ -119,13 +119,13 @@ test("the Report command should deserialize correctly (version 3)", (t) => { ccData, { sourceNodeId: 1 } as any, ) as ColorSwitchCCReport; - t.is(cc.constructor, ColorSwitchCCReport); + t.expect(cc.constructor).toBe(ColorSwitchCCReport); - t.is(cc.colorComponent, ColorComponent.Red); - t.is(cc.currentValue, 128); - t.is(cc.targetValue, 255); - t.is(cc.duration!.value, 1); - t.is(cc.duration!.unit, "seconds"); + t.expect(cc.colorComponent).toBe(ColorComponent.Red); + t.expect(cc.currentValue).toBe(128); + t.expect(cc.targetValue).toBe(255); + t.expect(cc.duration!.value).toBe(1); + t.expect(cc.duration!.unit).toBe("seconds"); }); test("the Set command should serialize correctly (without duration)", (t) => { @@ -154,7 +154,7 @@ test("the Set command should serialize correctly (without duration)", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Set command should serialize correctly (version 2)", (t) => { @@ -183,7 +183,7 @@ test("the Set command should serialize correctly (version 2)", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the StartLevelChange command should serialize correctly", (t) => { @@ -210,7 +210,7 @@ test("the StartLevelChange command should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the StopLevelChange command should serialize correctly", (t) => { @@ -225,7 +225,7 @@ test("the StopLevelChange command should serialize correctly", (t) => { 0b0000_0010, // color: red ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the setValue API verifies that targetColor isn't set with non-numeric keys", async (t) => { @@ -237,7 +237,7 @@ test("the setValue API verifies that targetColor isn't set with non-numeric keys false, ); await assertZWaveError( - t, + t.expect, () => API.setValue!( { property: "targetColor" }, diff --git a/packages/zwave-js/src/lib/test/cc/CommandClass.nonImplemented.test.ts b/packages/zwave-js/src/lib/test/cc/CommandClass.nonImplemented.test.ts index 40ba6a78e7fc..124c1b43aea1 100644 --- a/packages/zwave-js/src/lib/test/cc/CommandClass.nonImplemented.test.ts +++ b/packages/zwave-js/src/lib/test/cc/CommandClass.nonImplemented.test.ts @@ -1,6 +1,6 @@ import { CommandClass } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "the CC constructor does not throw when creating a raw instance of a non-implemented CC", @@ -15,8 +15,6 @@ integrationTest( ccCommand: 0x02, }); await driver.sendCommand(cc); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/cc/CommandClass.persistValues.test.ts b/packages/zwave-js/src/lib/test/cc/CommandClass.persistValues.test.ts index 81ed93adca18..3d8ff4579fe4 100644 --- a/packages/zwave-js/src/lib/test/cc/CommandClass.persistValues.test.ts +++ b/packages/zwave-js/src/lib/test/cc/CommandClass.persistValues.test.ts @@ -4,71 +4,78 @@ import { CentralSceneCCNotification } from "@zwave-js/cc/CentralSceneCC"; import { CommandClasses } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; import sinon from "sinon"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; - -interface TestContext { - driver: Driver; - node2: ZWaveNode; - controller: MockController; +import { afterEach, beforeEach, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + node2: ZWaveNode; + controller: MockController; + }; } -const test = ava as TestFn; - -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + const node2 = new ZWaveNode(2, driver); + (driver.controller.nodes as ThrowingMap).set( + node2.id, + node2, ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; + context.node2 = node2; - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - node2.id, - node2, - ); - t.context.node2 = node2; -}); + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test.beforeEach((t) => { - const { driver } = t.context; +beforeEach(({ context, expect }) => { + const { driver } = context; const node2 = new ZWaveNode(2, driver); (driver.controller.nodes as ThrowingMap).set( node2.id, node2, ); - t.context.node2 = node2; + context.node2 = node2; }); -test.afterEach((t) => { - const { node2, driver } = t.context; +afterEach(({ context, expect }) => { + const { node2, driver } = context; node2.destroy(); (driver.controller.nodes as ThrowingMap).delete( node2.id, ); }); -test(`persistValues() should not update "interviewComplete" in the value DB`, (t) => { - const { node2, driver } = t.context; +test(`persistValues() should not update "interviewComplete" in the value DB`, ({ context, expect }) => { + const { node2, driver } = context; // Repro for #383 const cc = new BasicCCSet({ @@ -85,11 +92,11 @@ test(`persistValues() should not update "interviewComplete" in the value DB`, (t .getCalls() .map((call) => call.args[0]) .map(({ property }) => property); - t.false(properties.includes("interviewComplete")); + expect(properties.includes("interviewComplete")).toBe(false); }); -test(`persistValues() should not store values marked as "events" (non-stateful)`, async (t) => { - const { node2, driver } = t.context; +test(`persistValues() should not store values marked as "events" (non-stateful)`, async ({ context, expect }) => { + const { node2, driver } = context; const cc = new CentralSceneCCNotification({ nodeId: node2.id, @@ -108,8 +115,9 @@ test(`persistValues() should not store values marked as "events" (non-stateful)` sinon.assert.notCalled(spyA); sinon.assert.called(spyN); - t.is(spyN.getCall(0).args[1].value, CentralSceneKeys.KeyPressed); + expect(spyN.getCall(0).args[1].value).toBe(CentralSceneKeys.KeyPressed); // and not persist the value in the DB - t.is(node2.valueDB.getValues(CommandClasses["Central Scene"]).length, 0); + expect(node2.valueDB.getValues(CommandClasses["Central Scene"]).length) + .toBe(0); }); diff --git a/packages/zwave-js/src/lib/test/cc/CommandClass.test.ts b/packages/zwave-js/src/lib/test/cc/CommandClass.test.ts index bd961eeb39f8..ee15f630607c 100644 --- a/packages/zwave-js/src/lib/test/cc/CommandClass.test.ts +++ b/packages/zwave-js/src/lib/test/cc/CommandClass.test.ts @@ -12,7 +12,7 @@ import { import { CommandClasses } from "@zwave-js/core"; import { SendDataRequest } from "@zwave-js/serial/serialapi"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; @implementedVersion(7) @commandClass(0xffff as any) @@ -37,10 +37,9 @@ test(`creating and serializing should work for unspecified commands`, (t) => { command: cc, callbackId: 0xfe, }); - t.deepEqual( + t.expect( msg.serialize({} as any), - Bytes.from("010c001302055d0201020325fe63", "hex"), - ); + ).toStrictEqual(Bytes.from("010c001302055d0201020325fe63", "hex")); }); test("parse() returns an un-specialized instance when receiving a non-implemented CC", (t) => { @@ -49,58 +48,58 @@ test("parse() returns an un-specialized instance when receiving a non-implemente Bytes.from("78030100", "hex"), { sourceNodeId: 5 } as any, ); - t.is(cc.constructor, CommandClass); - t.is(cc.nodeId, 5); - t.is(cc.ccId, 0x78); - t.is(cc.ccCommand, 0x03); - t.deepEqual(cc.payload, Bytes.from([0x01, 0x00])); + t.expect(cc.constructor).toBe(CommandClass); + t.expect(cc.nodeId).toBe(5); + t.expect(cc.ccId).toBe(0x78); + t.expect(cc.ccCommand).toBe(0x03); + t.expect(cc.payload).toStrictEqual(Bytes.from([0x01, 0x00])); }); test("parse() does not throw when the CC is implemented", (t) => { - t.notThrows(() => + t.expect(() => // CRC-16 with BasicCC CommandClass.parse( Bytes.from("560120024d26", "hex"), { sourceNodeId: 5 } as any, ) - ); + ).not.toThrow(); }); test("getImplementedVersion() should return the implemented version for a CommandClass instance", (t) => { const cc = new BasicCC({ nodeId: 1 }); - t.is(getImplementedVersion(cc), 2); + t.expect(getImplementedVersion(cc)).toBe(2); }); test("getImplementedVersion() should return the implemented version for a numeric CommandClass key", (t) => { const cc = CommandClasses.Basic; - t.is(getImplementedVersion(cc), 2); + t.expect(getImplementedVersion(cc)).toBe(2); }); test("getImplementedVersion() should return 0 for a non-existing CC", (t) => { const cc = -1; - t.is(getImplementedVersion(cc as any), 0); + t.expect(getImplementedVersion(cc as any)).toBe(0); }); test("getImplementedVersion() should work with inheritance", (t) => { const cc = new BasicCCGet({ nodeId: 1 }); - t.is(getImplementedVersion(cc), 2); + t.expect(getImplementedVersion(cc)).toBe(2); }); test("getImplementedVersionStatic() should return the implemented version for a CommandClass constructor", (t) => { - t.is(getImplementedVersionStatic(BasicCC), 2); + t.expect(getImplementedVersionStatic(BasicCC)).toBe(2); }); test("getImplementedVersionStatic() should work on inherited classes", (t) => { - t.is(getImplementedVersionStatic(DummyCCSubClass1), 7); + t.expect(getImplementedVersionStatic(DummyCCSubClass1)).toBe(7); }); test("expectMoreMessages() returns false by default", (t) => { const cc = new DummyCC({ nodeId: 1 }); - t.false(cc.expectMoreMessages([])); + t.expect(cc.expectMoreMessages([])).toBe(false); }); test("getExpectedCCResponse() returns the expected CC response like it was defined", (t) => { const cc = new DummyCCSubClass2({ nodeId: 1 }); const actual = getExpectedCCResponse(cc); - t.is(actual, DummyCCSubClass1); + t.expect(actual).toBe(DummyCCSubClass1); }); diff --git a/packages/zwave-js/src/lib/test/cc/DoorLockCC.test.ts b/packages/zwave-js/src/lib/test/cc/DoorLockCC.test.ts index 9f6dab243801..67efa062242a 100644 --- a/packages/zwave-js/src/lib/test/cc/DoorLockCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/DoorLockCC.test.ts @@ -16,7 +16,7 @@ import { DoorLockCCValues } from "@zwave-js/cc/DoorLockCC"; import { CommandClasses, Duration } from "@zwave-js/core"; import { createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -48,7 +48,7 @@ test("the OperationGet command should serialize correctly", (t) => { DoorLockCommand.OperationGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the OperationSet command should serialize correctly", (t) => { @@ -62,7 +62,7 @@ test("the OperationSet command should serialize correctly", (t) => { 0x20, // target value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the OperationReport command (v1-v3) should be deserialized correctly", (t) => { @@ -80,17 +80,27 @@ test("the OperationReport command (v1-v3) should be deserialized correctly", (t) ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCOperationReport; - t.is(cc.constructor, DoorLockCCOperationReport); - - t.is(cc.currentMode, DoorLockMode.InsideUnsecuredWithTimeout); - t.deepEqual(cc.outsideHandlesCanOpenDoor, [false, false, false, true]); - t.deepEqual(cc.insideHandlesCanOpenDoor, [false, true, false, false]); - t.is(cc.lockTimeout, 50 * 60 + 20); - t.is(cc.latchStatus, "open"); - t.is(cc.boltStatus, "unlocked"); - t.is(cc.doorStatus, "open"); - t.is(cc.targetMode, undefined); - t.is(cc.duration, undefined); + t.expect(cc.constructor).toBe(DoorLockCCOperationReport); + + t.expect(cc.currentMode).toBe(DoorLockMode.InsideUnsecuredWithTimeout); + t.expect(cc.outsideHandlesCanOpenDoor).toStrictEqual([ + false, + false, + false, + true, + ]); + t.expect(cc.insideHandlesCanOpenDoor).toStrictEqual([ + false, + true, + false, + false, + ]); + t.expect(cc.lockTimeout).toBe(50 * 60 + 20); + t.expect(cc.latchStatus).toBe("open"); + t.expect(cc.boltStatus).toBe("unlocked"); + t.expect(cc.doorStatus).toBe("open"); + t.expect(cc.targetMode).toBeUndefined(); + t.expect(cc.duration).toBeUndefined(); }); test("the OperationReport command (v4) should be deserialized correctly", (t) => { @@ -110,25 +120,34 @@ test("the OperationReport command (v4) should be deserialized correctly", (t) => ccData, { sourceNodeId: 2 } as any, ) as DoorLockCCOperationReport; - t.is(cc.constructor, DoorLockCCOperationReport); + t.expect(cc.constructor).toBe(DoorLockCCOperationReport); cc.persistValues(host); - t.is(cc.currentMode, DoorLockMode.OutsideUnsecured); - t.deepEqual(cc.outsideHandlesCanOpenDoor, [false, false, true, false]); - t.deepEqual(cc.insideHandlesCanOpenDoor, [true, true, true, true]); - t.is(cc.lockTimeout, undefined); - t.is(cc.latchStatus, "closed"); - t.is(cc.boltStatus, "locked"); + t.expect(cc.currentMode).toBe(DoorLockMode.OutsideUnsecured); + t.expect(cc.outsideHandlesCanOpenDoor).toStrictEqual([ + false, + false, + true, + false, + ]); + t.expect(cc.insideHandlesCanOpenDoor).toStrictEqual([ + true, + true, + true, + true, + ]); + t.expect(cc.lockTimeout).toBeUndefined(); + t.expect(cc.latchStatus).toBe("closed"); + t.expect(cc.boltStatus).toBe("locked"); // The CC itself contains the door status, but it does not get persisted (unsupported) - t.is(cc.doorStatus, "closed"); - t.is( + t.expect(cc.doorStatus).toBe("closed"); + t.expect( host .getValueDB(cc.nodeId as number) .getValue(DoorLockCCValues.doorStatus.endpoint(cc.endpointIndex)), - undefined, - ); - t.is(cc.targetMode, DoorLockMode.Secured); - t.deepEqual(cc.duration, new Duration(1, "seconds")); + ).toBeUndefined(); + t.expect(cc.targetMode).toBe(DoorLockMode.Secured); + t.expect(cc.duration).toStrictEqual(new Duration(1, "seconds")); }); test("the ConfigurationGet command should serialize correctly", (t) => { @@ -138,7 +157,7 @@ test("the ConfigurationGet command should serialize correctly", (t) => { DoorLockCommand.ConfigurationGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ConfigurationReport command (v1-v3) should be deserialized correctly", (t) => { @@ -155,26 +174,26 @@ test("the ConfigurationReport command (v1-v3) should be deserialized correctly", ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCConfigurationReport; - t.is(cc.constructor, DoorLockCCConfigurationReport); + t.expect(cc.constructor).toBe(DoorLockCCConfigurationReport); - t.is(cc.operationType, DoorLockOperationType.Timed); - t.deepEqual(cc.outsideHandlesCanOpenDoorConfiguration, [ + t.expect(cc.operationType).toBe(DoorLockOperationType.Timed); + t.expect(cc.outsideHandlesCanOpenDoorConfiguration).toStrictEqual([ false, false, false, true, ]); - t.deepEqual(cc.insideHandlesCanOpenDoorConfiguration, [ + t.expect(cc.insideHandlesCanOpenDoorConfiguration).toStrictEqual([ false, true, false, false, ]); - t.is(cc.lockTimeoutConfiguration, 50 * 60 + 20); - t.is(cc.autoRelockTime, undefined); - t.is(cc.holdAndReleaseTime, undefined); - t.is(cc.twistAssist, undefined); - t.is(cc.blockToBlock, undefined); + t.expect(cc.lockTimeoutConfiguration).toBe(50 * 60 + 20); + t.expect(cc.autoRelockTime).toBeUndefined(); + t.expect(cc.holdAndReleaseTime).toBeUndefined(); + t.expect(cc.twistAssist).toBeUndefined(); + t.expect(cc.blockToBlock).toBeUndefined(); }); test("the ConfigurationReport command must ignore invalid timeouts (constant)", (t) => { @@ -191,9 +210,9 @@ test("the ConfigurationReport command must ignore invalid timeouts (constant)", ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCConfigurationReport; - t.is(cc.constructor, DoorLockCCConfigurationReport); + t.expect(cc.constructor).toBe(DoorLockCCConfigurationReport); - t.is(cc.lockTimeoutConfiguration, undefined); + t.expect(cc.lockTimeoutConfiguration).toBeUndefined(); }); test("the ConfigurationReport command must ignore invalid timeouts (invalid minutes)", (t) => { @@ -210,9 +229,9 @@ test("the ConfigurationReport command must ignore invalid timeouts (invalid minu ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCConfigurationReport; - t.is(cc.constructor, DoorLockCCConfigurationReport); + t.expect(cc.constructor).toBe(DoorLockCCConfigurationReport); - t.is(cc.lockTimeoutConfiguration, undefined); + t.expect(cc.lockTimeoutConfiguration).toBeUndefined(); }); test("the ConfigurationReport command must ignore invalid timeouts (invalid seconds)", (t) => { @@ -229,9 +248,9 @@ test("the ConfigurationReport command must ignore invalid timeouts (invalid seco ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCConfigurationReport; - t.is(cc.constructor, DoorLockCCConfigurationReport); + t.expect(cc.constructor).toBe(DoorLockCCConfigurationReport); - t.is(cc.lockTimeoutConfiguration, undefined); + t.expect(cc.lockTimeoutConfiguration).toBeUndefined(); }); test("the ConfigurationReport command (v4) should be deserialized correctly", (t) => { @@ -254,12 +273,12 @@ test("the ConfigurationReport command (v4) should be deserialized correctly", (t ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCConfigurationReport; - t.is(cc.constructor, DoorLockCCConfigurationReport); + t.expect(cc.constructor).toBe(DoorLockCCConfigurationReport); - t.is(cc.autoRelockTime, 0xff01); - t.is(cc.holdAndReleaseTime, 0x0203); - t.true(cc.twistAssist); - t.false(cc.blockToBlock); + t.expect(cc.autoRelockTime).toBe(0xff01); + t.expect(cc.holdAndReleaseTime).toBe(0x0203); + t.expect(cc.twistAssist).toBe(true); + t.expect(cc.blockToBlock).toBe(false); }); test("the ConfigurationSet command (v4) should serialize correctly", (t) => { @@ -288,7 +307,7 @@ test("the ConfigurationSet command (v4) should serialize correctly", (t) => { 0b1, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CapabilitiesGet command should serialize correctly", (t) => { @@ -298,7 +317,7 @@ test("the CapabilitiesGet command should serialize correctly", (t) => { DoorLockCommand.CapabilitiesGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CapabilitiesReport command should be deserialized correctly", (t) => { @@ -320,25 +339,25 @@ test("the CapabilitiesReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as DoorLockCCCapabilitiesReport; - t.is(cc.constructor, DoorLockCCCapabilitiesReport); + t.expect(cc.constructor).toBe(DoorLockCCCapabilitiesReport); - t.deepEqual(cc.supportedOperationTypes, [ + t.expect(cc.supportedOperationTypes).toStrictEqual([ DoorLockOperationType.Constant, DoorLockOperationType.Timed, ]); - t.deepEqual(cc.supportedDoorLockModes, [ + t.expect(cc.supportedDoorLockModes).toStrictEqual([ DoorLockMode.Unsecured, DoorLockMode.InsideUnsecured, DoorLockMode.Secured, ]); - t.true(cc.latchSupported); - t.true(cc.boltSupported); - t.true(cc.doorSupported); - - t.true(cc.autoRelockSupported); - t.false(cc.holdAndReleaseSupported); - t.true(cc.twistAssistSupported); - t.false(cc.blockToBlockSupported); + t.expect(cc.latchSupported).toBe(true); + t.expect(cc.boltSupported).toBe(true); + t.expect(cc.doorSupported).toBe(true); + + t.expect(cc.autoRelockSupported).toBe(true); + t.expect(cc.holdAndReleaseSupported).toBe(false); + t.expect(cc.twistAssistSupported).toBe(true); + t.expect(cc.blockToBlockSupported).toBe(false); }); // test("the Report command (v2) should be deserialized correctly", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/DoorLockLoggingCC.test.ts b/packages/zwave-js/src/lib/test/cc/DoorLockLoggingCC.test.ts index 5b3f3eabfe0c..b8d30e06434a 100644 --- a/packages/zwave-js/src/lib/test/cc/DoorLockLoggingCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/DoorLockLoggingCC.test.ts @@ -9,7 +9,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -29,7 +29,7 @@ test("the RecordsCountGet command should serialize correctly", (t) => { DoorLockLoggingCommand.RecordsSupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the RecordsCountReport command should be deserialized correctly", (t) => { @@ -43,9 +43,9 @@ test("the RecordsCountReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as DoorLockLoggingCCRecordsSupportedReport; - t.is(cc.constructor, DoorLockLoggingCCRecordsSupportedReport); + t.expect(cc.constructor).toBe(DoorLockLoggingCCRecordsSupportedReport); - t.is(cc.recordsCount, 20); + t.expect(cc.recordsCount).toBe(20); }); test("the RecordGet command should serialize correctly", (t) => { @@ -59,7 +59,7 @@ test("the RecordGet command should serialize correctly", (t) => { 1, // Record Number ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the RecordReport command should be deserialized correctly", (t) => { @@ -85,17 +85,16 @@ test("the RecordReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as DoorLockLoggingCCRecordReport; - t.is(cc.constructor, DoorLockLoggingCCRecordReport); + t.expect(cc.constructor).toBe(DoorLockLoggingCCRecordReport); - t.is(cc.recordNumber, 7); + t.expect(cc.recordNumber).toBe(7); - t.is(cc.record!.eventType, 1); - t.is(cc.record!.label, "Locked via Access Code"); - t.is( + t.expect(cc.record!.eventType).toBe(1); + t.expect(cc.record!.label).toBe("Locked via Access Code"); + t.expect( cc.record!.timestamp, - new Date(1989, 12 - 1, 27, 10, 40, 30).toISOString(), - ); - t.is(cc.record!.userId, 1); + ).toBe(new Date(1989, 12 - 1, 27, 10, 40, 30).toISOString()); + t.expect(cc.record!.userId).toBe(1); }); // describe.skip(`interview()`, () => { diff --git a/packages/zwave-js/src/lib/test/cc/EntryControlCC.test.ts b/packages/zwave-js/src/lib/test/cc/EntryControlCC.test.ts index ffae8d2f79d1..65ce22fe786b 100644 --- a/packages/zwave-js/src/lib/test/cc/EntryControlCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/EntryControlCC.test.ts @@ -14,7 +14,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -48,12 +48,12 @@ test("the Notification command should deserialize correctly", (t) => { data, { sourceNodeId: 1 } as any, ) as EntryControlCCNotification; - t.is(cc.constructor, EntryControlCCNotification); + t.expect(cc.constructor).toBe(EntryControlCCNotification); - t.deepEqual(cc.sequenceNumber, 1); - t.deepEqual(cc.dataType, EntryControlDataTypes.ASCII); - t.deepEqual(cc.eventType, EntryControlEventTypes.DisarmAll); - t.deepEqual(cc.eventData, "1234"); + t.expect(cc.sequenceNumber).toStrictEqual(1); + t.expect(cc.dataType).toStrictEqual(EntryControlDataTypes.ASCII); + t.expect(cc.eventType).toStrictEqual(EntryControlEventTypes.DisarmAll); + t.expect(cc.eventData).toStrictEqual("1234"); }); test("the ConfigurationGet command should serialize correctly", (t) => { @@ -65,7 +65,7 @@ test("the ConfigurationGet command should serialize correctly", (t) => { EntryControlCommand.ConfigurationGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ConfigurationSet command should serialize correctly", (t) => { @@ -81,7 +81,7 @@ test("the ConfigurationSet command should serialize correctly", (t) => { 0x2, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ConfigurationReport command should be deserialize correctly", (t) => { @@ -97,10 +97,10 @@ test("the ConfigurationReport command should be deserialize correctly", (t) => { data, { sourceNodeId: 1 } as any, ) as EntryControlCCConfigurationReport; - t.is(cc.constructor, EntryControlCCConfigurationReport); + t.expect(cc.constructor).toBe(EntryControlCCConfigurationReport); - t.deepEqual(cc.keyCacheSize, 1); - t.deepEqual(cc.keyCacheTimeout, 2); + t.expect(cc.keyCacheSize).toStrictEqual(1); + t.expect(cc.keyCacheTimeout).toStrictEqual(2); }); test("the EventSupportedGet command should serialize correctly", (t) => { @@ -112,7 +112,7 @@ test("the EventSupportedGet command should serialize correctly", (t) => { EntryControlCommand.EventSupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the EventSupportedReport command should be deserialize correctly", (t) => { @@ -137,19 +137,21 @@ test("the EventSupportedReport command should be deserialize correctly", (t) => data, { sourceNodeId: 1 } as any, ) as EntryControlCCEventSupportedReport; - t.is(cc.constructor, EntryControlCCEventSupportedReport); + t.expect(cc.constructor).toBe(EntryControlCCEventSupportedReport); - t.deepEqual(cc.supportedDataTypes, [EntryControlDataTypes.ASCII]); - t.deepEqual(cc.supportedEventTypes, [ + t.expect(cc.supportedDataTypes).toStrictEqual([ + EntryControlDataTypes.ASCII, + ]); + t.expect(cc.supportedEventTypes).toStrictEqual([ EntryControlEventTypes.DisarmAll, EntryControlEventTypes.ArmAway, EntryControlEventTypes.ArmHome, EntryControlEventTypes.Cancel, ]); - t.deepEqual(cc.minKeyCacheSize, 1); - t.deepEqual(cc.maxKeyCacheSize, 20); - t.deepEqual(cc.minKeyCacheTimeout, 2); - t.deepEqual(cc.maxKeyCacheTimeout, 9); + t.expect(cc.minKeyCacheSize).toStrictEqual(1); + t.expect(cc.maxKeyCacheSize).toStrictEqual(20); + t.expect(cc.minKeyCacheTimeout).toStrictEqual(2); + t.expect(cc.maxKeyCacheTimeout).toStrictEqual(9); }); test("the KeySupportedGet command should serialize correctly", (t) => { @@ -159,7 +161,7 @@ test("the KeySupportedGet command should serialize correctly", (t) => { EntryControlCommand.KeySupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the KeySupportedReport command should be deserialize correctly", (t) => { @@ -175,7 +177,7 @@ test("the KeySupportedReport command should be deserialize correctly", (t) => { data, { sourceNodeId: 1 } as any, ) as EntryControlCCKeySupportedReport; - t.is(cc.constructor, EntryControlCCKeySupportedReport); + t.expect(cc.constructor).toBe(EntryControlCCKeySupportedReport); - t.deepEqual(cc.supportedKeys, [1, 3, 4, 6]); + t.expect(cc.supportedKeys).toStrictEqual([1, 3, 4, 6]); }); diff --git a/packages/zwave-js/src/lib/test/cc/FibaroCC.FGR222.test.ts b/packages/zwave-js/src/lib/test/cc/FibaroCC.FGR222.test.ts index f3739af9084c..9f062dd34d72 100644 --- a/packages/zwave-js/src/lib/test/cc/FibaroCC.FGR222.test.ts +++ b/packages/zwave-js/src/lib/test/cc/FibaroCC.FGR222.test.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("Fibaro FGR222 should support the Fibaro CC", { // debug: true, @@ -8,6 +8,6 @@ integrationTest("Fibaro FGR222 should support the Fibaro CC", { testBody: async (t, driver, node, _mockController, _mockNode) => { const CCs = (node.deviceConfig?.proprietary?.fibaroCCs ?? []) as number[]; - t.true(CCs.includes(0x26)); + t.expect(CCs.includes(0x26)).toBe(true); }, }); diff --git a/packages/zwave-js/src/lib/test/cc/FibaroCC.test.ts b/packages/zwave-js/src/lib/test/cc/FibaroCC.test.ts index 7828406cd8b5..41af48a358ba 100644 --- a/packages/zwave-js/src/lib/test/cc/FibaroCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/FibaroCC.test.ts @@ -7,7 +7,7 @@ import { } from "@zwave-js/cc/manufacturerProprietary/FibaroCC"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -36,7 +36,7 @@ test("the Set Tilt command should serialize correctly", (t) => { 0x63, // Tilt ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly", (t) => { @@ -52,9 +52,9 @@ test("the Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as FibaroVenetianBlindCCReport; - t.is(cc.constructor, FibaroVenetianBlindCCReport); - t.is(cc.position, 0); - t.is(cc.tilt, 0); + t.expect(cc.constructor).toBe(FibaroVenetianBlindCCReport); + t.expect(cc.position).toBe(0); + t.expect(cc.tilt).toBe(0); }); test("FibaroVenetianBlindCCSet should expect no response", (t) => { @@ -62,14 +62,14 @@ test("FibaroVenetianBlindCCSet should expect no response", (t) => { nodeId: 2, tilt: 7, }); - t.false(cc.expectsCCResponse()); + t.expect(cc.expectsCCResponse()).toBe(false); }); test("FibaroVenetianBlindCCGet should expect a response", (t) => { const cc = new FibaroVenetianBlindCCGet({ nodeId: 2, }); - t.true(cc.expectsCCResponse()); + t.expect(cc.expectsCCResponse()).toBe(true); }); test("FibaroVenetianBlindCCSet => FibaroVenetianBlindCCReport = unexpected", (t) => { @@ -89,7 +89,7 @@ test("FibaroVenetianBlindCCSet => FibaroVenetianBlindCCReport = unexpected", (t) { sourceNodeId: 2 } as any, ) as FibaroVenetianBlindCCReport; - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); test("FibaroVenetianBlindCCGet => FibaroVenetianBlindCCReport = expected", (t) => { @@ -108,5 +108,5 @@ test("FibaroVenetianBlindCCGet => FibaroVenetianBlindCCReport = expected", (t) = { sourceNodeId: 2 } as any, ) as FibaroVenetianBlindCCReport; - t.true(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(true); }); diff --git a/packages/zwave-js/src/lib/test/cc/HumidityControlModeCC.test.ts b/packages/zwave-js/src/lib/test/cc/HumidityControlModeCC.test.ts index bbb1efec50cd..6368d6388667 100644 --- a/packages/zwave-js/src/lib/test/cc/HumidityControlModeCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/HumidityControlModeCC.test.ts @@ -12,7 +12,7 @@ import { HumidityControlModeCCValues } from "@zwave-js/cc/HumidityControlModeCC" import { CommandClasses, enumValuesToMetadataStates } from "@zwave-js/core"; import { createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; const host = createTestingHost(); const nodeId = 2; @@ -35,7 +35,7 @@ test("the Get command should serialize correctly", (t) => { HumidityControlModeCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly", (t) => { @@ -49,7 +49,7 @@ test("the Set command should serialize correctly", (t) => { 0x03, // target value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly", (t) => { @@ -63,9 +63,9 @@ test("the Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: nodeId } as any, ) as HumidityControlModeCCReport; - t.is(cc.constructor, HumidityControlModeCCReport); + t.expect(cc.constructor).toBe(HumidityControlModeCCReport); - t.is(cc.mode, HumidityControlMode.Auto); + t.expect(cc.mode).toBe(HumidityControlMode.Auto); }); test("the Report command should set the correct value", (t) => { @@ -85,7 +85,7 @@ test("the Report command should set the correct value", (t) => { commandClass: CommandClasses["Humidity Control Mode"], property: "mode", }); - t.deepEqual(currentValue, HumidityControlMode.Auto); + t.expect(currentValue).toStrictEqual(HumidityControlMode.Auto); }); test("the Report command should set the correct metadata", (t) => { @@ -105,7 +105,7 @@ test("the Report command should set the correct metadata", (t) => { .getValueDB(nodeId) .getMetadata(HumidityControlModeCCValues.mode.id); - t.like(currentValueMeta, { + t.expect(currentValueMeta).toMatchObject({ states: enumValuesToMetadataStates(HumidityControlMode), label: "Humidity control mode", }); @@ -120,7 +120,7 @@ test("the SupportedGet command should serialize correctly", (t) => { HumidityControlModeCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedReport command should be deserialized correctly", (t) => { @@ -134,9 +134,9 @@ test("the SupportedReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: nodeId } as any, ) as HumidityControlModeCCSupportedReport; - t.is(cc.constructor, HumidityControlModeCCSupportedReport); + t.expect(cc.constructor).toBe(HumidityControlModeCCSupportedReport); - t.deepEqual(cc.supportedModes, [ + t.expect(cc.supportedModes).toStrictEqual([ HumidityControlMode.Off, HumidityControlMode.Auto, ]); @@ -159,7 +159,7 @@ test("the SupportedReport command should set the correct metadata", (t) => { .getValueDB(nodeId) .getMetadata(HumidityControlModeCCValues.mode.id); - t.like(currentValueMeta, { + t.expect(currentValueMeta).toMatchObject({ states: { 0: "Off", 3: "Auto", diff --git a/packages/zwave-js/src/lib/test/cc/HumidityControlOperatingStateCC.test.ts b/packages/zwave-js/src/lib/test/cc/HumidityControlOperatingStateCC.test.ts index 5ebddf7440ff..06e141e16d6b 100644 --- a/packages/zwave-js/src/lib/test/cc/HumidityControlOperatingStateCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/HumidityControlOperatingStateCC.test.ts @@ -7,7 +7,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -27,7 +27,7 @@ test("the Get command should serialize correctly", (t) => { HumidityControlOperatingStateCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly", (t) => { @@ -41,9 +41,9 @@ test("the Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as HumidityControlOperatingStateCCReport; - t.is(cc.constructor, HumidityControlOperatingStateCCReport); + t.expect(cc.constructor).toBe(HumidityControlOperatingStateCCReport); - t.is(cc.state, HumidityControlOperatingState.Humidifying); + t.expect(cc.state).toBe(HumidityControlOperatingState.Humidifying); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/HumidityControlSetpointCC.test.ts b/packages/zwave-js/src/lib/test/cc/HumidityControlSetpointCC.test.ts index 519e5efb3052..25838a14ecee 100644 --- a/packages/zwave-js/src/lib/test/cc/HumidityControlSetpointCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/HumidityControlSetpointCC.test.ts @@ -15,7 +15,7 @@ import { import { CommandClasses, encodeFloatWithScale } from "@zwave-js/core"; import { createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -40,7 +40,7 @@ test("the Get command should serialize correctly", (t) => { HumidityControlSetpointType.Humidifier, // type ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly", (t) => { @@ -59,7 +59,7 @@ test("the Set command should serialize correctly", (t) => { encodeFloatWithScale(57, 1), ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly", (t) => { @@ -76,16 +76,16 @@ test("the Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: nodeId } as any, ) as HumidityControlSetpointCCReport; - t.is(cc.constructor, HumidityControlSetpointCCReport); + t.expect(cc.constructor).toBe(HumidityControlSetpointCCReport); - t.deepEqual(cc.type, HumidityControlSetpointType.Humidifier); - t.is(cc.scale, 1); + t.expect(cc.type).toStrictEqual(HumidityControlSetpointType.Humidifier); + t.expect(cc.scale).toBe(1); // t.like(cc.scale, { // key: 1, // label: "Absolute humidity", // unit: "g/m³", // }); - t.is(cc.value, 12); + t.expect(cc.value).toBe(12); }); test("the Report command should set the correct value", (t) => { @@ -109,14 +109,14 @@ test("the Report command should set the correct value", (t) => { property: "setpoint", propertyKey: HumidityControlSetpointType.Humidifier, }); - t.deepEqual(currentValue, 12); + t.expect(currentValue).toStrictEqual(12); const scaleValue = host.getValueDB(nodeId).getValue({ commandClass: CommandClasses["Humidity Control Setpoint"], property: "setpointScale", propertyKey: HumidityControlSetpointType.Humidifier, }); - t.deepEqual(scaleValue, 1); + t.expect(scaleValue).toStrictEqual(1); }); test("the Report command should set the correct metadata", (t) => { @@ -140,7 +140,7 @@ test("the Report command should set the correct metadata", (t) => { property: "setpoint", propertyKey: HumidityControlSetpointType.Humidifier, }); - t.like(setpointMeta, { + t.expect(setpointMeta).toMatchObject({ unit: "g/m³", ccSpecific: { setpointType: HumidityControlSetpointType.Humidifier, @@ -157,7 +157,7 @@ test("the SupportedGet command should serialize correctly", (t) => { HumidityControlSetpointCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedReport command should be deserialized correctly", (t) => { @@ -172,9 +172,9 @@ test("the SupportedReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: nodeId } as any, ) as HumidityControlSetpointCCSupportedReport; - t.is(cc.constructor, HumidityControlSetpointCCSupportedReport); + t.expect(cc.constructor).toBe(HumidityControlSetpointCCSupportedReport); - t.deepEqual(cc.supportedSetpointTypes, [ + t.expect(cc.supportedSetpointTypes).toStrictEqual([ HumidityControlSetpointType.Humidifier, HumidityControlSetpointType.Auto, ]); @@ -198,7 +198,7 @@ test("the SupportedReport command should set the correct value", (t) => { commandClass: CommandClasses["Humidity Control Setpoint"], property: "supportedSetpointTypes", }); - t.deepEqual(currentValue, [ + t.expect(currentValue).toStrictEqual([ HumidityControlSetpointType.Humidifier, HumidityControlSetpointType.Auto, ]); @@ -215,7 +215,7 @@ test("the ScaleSupportedGet command should serialize correctly", (t) => { HumidityControlSetpointType.Auto, // type ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the ScaleSupportedReport command should be deserialized correctly", (t) => { @@ -229,9 +229,11 @@ test("the ScaleSupportedReport command should be deserialized correctly", (t) => ccData, { sourceNodeId: nodeId } as any, ) as HumidityControlSetpointCCScaleSupportedReport; - t.is(cc.constructor, HumidityControlSetpointCCScaleSupportedReport); + t.expect(cc.constructor).toBe( + HumidityControlSetpointCCScaleSupportedReport, + ); - t.deepEqual(cc.supportedScales, [0, 1]); + t.expect(cc.supportedScales).toStrictEqual([0, 1]); // new Scale(0, { // label: "Percentage value", // unit: "%", @@ -254,7 +256,7 @@ test("the CapabilitiesGet command should serialize correctly", (t) => { HumidityControlSetpointType.Auto, // type ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CapabilitiesReport command should be deserialized correctly", (t) => { @@ -272,13 +274,13 @@ test("the CapabilitiesReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: nodeId } as any, ) as HumidityControlSetpointCCCapabilitiesReport; - t.is(cc.constructor, HumidityControlSetpointCCCapabilitiesReport); + t.expect(cc.constructor).toBe(HumidityControlSetpointCCCapabilitiesReport); - t.deepEqual(cc.type, HumidityControlSetpointType.Humidifier); - t.deepEqual(cc.minValue, 10); - t.deepEqual(cc.minValueScale, 1); - t.deepEqual(cc.maxValue, 90); - t.deepEqual(cc.maxValueScale, 1); + t.expect(cc.type).toStrictEqual(HumidityControlSetpointType.Humidifier); + t.expect(cc.minValue).toStrictEqual(10); + t.expect(cc.minValueScale).toStrictEqual(1); + t.expect(cc.maxValue).toStrictEqual(90); + t.expect(cc.maxValueScale).toStrictEqual(1); }); test("the CapabilitiesReport command should set the correct metadata", (t) => { @@ -303,7 +305,7 @@ test("the CapabilitiesReport command should set the correct metadata", (t) => { property: "setpoint", propertyKey: HumidityControlSetpointType.Humidifier, }); - t.like(setpointMeta, { + t.expect(setpointMeta).toMatchObject({ min: 10, max: 90, unit: "g/m³", diff --git a/packages/zwave-js/src/lib/test/cc/IndicatorCC.test.ts b/packages/zwave-js/src/lib/test/cc/IndicatorCC.test.ts index ed3f54e1b240..e90415b5194f 100644 --- a/packages/zwave-js/src/lib/test/cc/IndicatorCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/IndicatorCC.test.ts @@ -10,8 +10,8 @@ import { IndicatorCCValues } from "@zwave-js/cc/IndicatorCC"; import { CommandClasses } from "@zwave-js/core"; import { createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; -import { createTestNode } from "../mocks"; +import { test } from "vitest"; +import { createTestNode } from "../mocks.js"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -31,7 +31,7 @@ test("the Get command (V1) should serialize correctly", (t) => { IndicatorCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Get command (V2) should serialize correctly", (t) => { @@ -45,7 +45,7 @@ test("the Get command (V2) should serialize correctly", (t) => { 5, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command (v1) should serialize correctly", (t) => { @@ -59,7 +59,7 @@ test("the Set command (v1) should serialize correctly", (t) => { 23, // value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command (v2) should serialize correctly", (t) => { @@ -91,7 +91,7 @@ test("the Set command (v2) should serialize correctly", (t) => { 1, // value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -105,10 +105,10 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as IndicatorCCReport; - t.is(cc.constructor, IndicatorCCReport); + t.expect(cc.constructor).toBe(IndicatorCCReport); - t.is(cc.indicator0Value, 55); - t.is(cc.values, undefined); + t.expect(cc.indicator0Value).toBe(55); + t.expect(cc.values).toBeUndefined(); }); test("the Report command (v2) should be deserialized correctly", (t) => { @@ -129,12 +129,12 @@ test("the Report command (v2) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as IndicatorCCReport; - t.is(cc.constructor, IndicatorCCReport); + t.expect(cc.constructor).toBe(IndicatorCCReport); // Boolean indicators are only interpreted during persistValues cc.persistValues(host); - t.is(cc.indicator0Value, undefined); - t.deepEqual(cc.values, [ + t.expect(cc.indicator0Value).toBeUndefined(); + t.expect(cc.values).toStrictEqual([ { indicatorId: 1, propertyId: 2, @@ -156,7 +156,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as IndicatorCC; - t.is(cc.constructor, IndicatorCC); + t.expect(cc.constructor).toBe(IndicatorCC); }); test("the value IDs should be translated properly", (t) => { @@ -176,8 +176,8 @@ test("the value IDs should be translated properly", (t) => { valueId.property, valueId.propertyKey, ); - t.is(translatedProperty, "Button 1 indication"); - t.is(translatedPropertyKey, "Binary"); + t.expect(translatedProperty).toBe("Button 1 indication"); + t.expect(translatedPropertyKey).toBe("Binary"); }); // describe.skip("interviewing the node", () => { diff --git a/packages/zwave-js/src/lib/test/cc/LanguageCC.test.ts b/packages/zwave-js/src/lib/test/cc/LanguageCC.test.ts index 08d1ba312896..effcb9867ff7 100644 --- a/packages/zwave-js/src/lib/test/cc/LanguageCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/LanguageCC.test.ts @@ -8,7 +8,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -26,7 +26,7 @@ test("the Get command should serialize correctly", (t) => { LanguageCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (w/o country code)", (t) => { @@ -43,7 +43,7 @@ test("the Set command should serialize correctly (w/o country code)", (t) => { 0x75, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (w/ country code)", (t) => { @@ -64,7 +64,7 @@ test("the Set command should serialize correctly (w/ country code)", (t) => { 0x45, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly (w/o country code)", (t) => { @@ -81,10 +81,10 @@ test("the Report command should be deserialized correctly (w/o country code)", ( ccData, { sourceNodeId: 4 } as any, ) as LanguageCCReport; - t.is(cc.constructor, LanguageCCReport); + t.expect(cc.constructor).toBe(LanguageCCReport); - t.is(cc.language, "deu"); - t.is(cc.country, undefined); + t.expect(cc.language).toBe("deu"); + t.expect(cc.country).toBeUndefined(); }); test("the Report command should be deserialized correctly (w/ country code)", (t) => { @@ -104,10 +104,10 @@ test("the Report command should be deserialized correctly (w/ country code)", (t ccData, { sourceNodeId: 4 } as any, ) as LanguageCCReport; - t.is(cc.constructor, LanguageCCReport); + t.expect(cc.constructor).toBe(LanguageCCReport); - t.is(cc.language, "deu"); - t.is(cc.country, "DE"); + t.expect(cc.language).toBe("deu"); + t.expect(cc.country).toBe("DE"); }); test("deserializing an unsupported command should return an unspecified version of LanguageCC", (t) => { @@ -118,7 +118,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 4 } as any, ) as LanguageCC; - t.is(cc.constructor, LanguageCC); + t.expect(cc.constructor).toBe(LanguageCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/ManufacturerSpecificCC.test.ts b/packages/zwave-js/src/lib/test/cc/ManufacturerSpecificCC.test.ts index 6759ea9b8ecc..43ad94017eb4 100644 --- a/packages/zwave-js/src/lib/test/cc/ManufacturerSpecificCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/ManufacturerSpecificCC.test.ts @@ -6,7 +6,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -24,7 +24,7 @@ test("the Get command should serialize correctly", (t) => { ManufacturerSpecificCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -43,9 +43,9 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as ManufacturerSpecificCCReport; - t.is(cc.constructor, ManufacturerSpecificCCReport); + t.expect(cc.constructor).toBe(ManufacturerSpecificCCReport); - t.is(cc.manufacturerId, 0x0102); - t.is(cc.productType, 0x0304); - t.is(cc.productId, 0x0506); + t.expect(cc.manufacturerId).toBe(0x0102); + t.expect(cc.productType).toBe(0x0304); + t.expect(cc.productId).toBe(0x0506); }); diff --git a/packages/zwave-js/src/lib/test/cc/MeterCC.test.ts b/packages/zwave-js/src/lib/test/cc/MeterCC.test.ts index 7e7d515b6006..adc587d4d56d 100644 --- a/packages/zwave-js/src/lib/test/cc/MeterCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/MeterCC.test.ts @@ -16,9 +16,9 @@ import { } from "@zwave-js/core"; import { type GetSupportedCCVersion, createTestingHost } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; -import * as nodeUtils from "../../node/utils"; -import { createTestNode } from "../mocks"; +import { test } from "vitest"; +import * as nodeUtils from "../../node/utils.js"; +import { createTestNode } from "../mocks.js"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -45,7 +45,7 @@ test("the Get command (V1) should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Get command (V2) should serialize correctly", (t) => { @@ -62,7 +62,7 @@ test("the Get command (V2) should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Get command (V3) should serialize correctly", (t) => { @@ -79,7 +79,7 @@ test("the Get command (V3) should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Get command (V4) should serialize correctly", (t) => { @@ -97,7 +97,7 @@ test("the Get command (V4) should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the SupportedGet command should serialize correctly", (t) => { @@ -107,7 +107,7 @@ test("the SupportedGet command should serialize correctly", (t) => { MeterCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Reset command (V2) should serialize correctly", (t) => { @@ -117,7 +117,7 @@ test("the Reset command (V2) should serialize correctly", (t) => { MeterCommand.Reset, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Reset command (V6) should serialize correctly", (t) => { @@ -136,7 +136,7 @@ test("the Reset command (V6) should serialize correctly", (t) => { 123, // 12.3 ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (V1) should be deserialized correctly", (t) => { @@ -152,14 +152,14 @@ test("the Report command (V1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(cc.constructor, MeterCCReport); - - t.is(cc.type, 3); - t.is(cc.scale, 2); - t.is(cc.value, 5.5); - t.is(cc.rateType, RateType.Unspecified); - t.is(cc.deltaTime, 0); - t.is(cc.previousValue, undefined); + t.expect(cc.constructor).toBe(MeterCCReport); + + t.expect(cc.type).toBe(3); + t.expect(cc.scale).toBe(2); + t.expect(cc.value).toBe(5.5); + t.expect(cc.rateType).toBe(RateType.Unspecified); + t.expect(cc.deltaTime).toBe(0); + t.expect(cc.previousValue).toBeUndefined(); }); test("the Report command (V2) should be deserialized correctly (no time delta)", (t) => { @@ -177,14 +177,14 @@ test("the Report command (V2) should be deserialized correctly (no time delta)", ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(cc.constructor, MeterCCReport); - - t.is(cc.type, 3); - t.is(cc.scale, 2); - t.is(cc.value, 5.5); - t.is(cc.rateType, RateType.Produced); - t.is(cc.deltaTime, 0); - t.is(cc.previousValue, undefined); + t.expect(cc.constructor).toBe(MeterCCReport); + + t.expect(cc.type).toBe(3); + t.expect(cc.scale).toBe(2); + t.expect(cc.value).toBe(5.5); + t.expect(cc.rateType).toBe(RateType.Produced); + t.expect(cc.deltaTime).toBe(0); + t.expect(cc.previousValue).toBeUndefined(); }); test("the Report command (V2) should be deserialized correctly (with time delta)", (t) => { @@ -203,14 +203,14 @@ test("the Report command (V2) should be deserialized correctly (with time delta) ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(cc.constructor, MeterCCReport); - - t.is(cc.type, 3); - t.is(cc.scale, 2); - t.is(cc.value, 5.5); - t.is(cc.rateType, RateType.Produced); - t.is(cc.deltaTime, 5); - t.is(cc.previousValue, 5.4); + t.expect(cc.constructor).toBe(MeterCCReport); + + t.expect(cc.type).toBe(3); + t.expect(cc.scale).toBe(2); + t.expect(cc.value).toBe(5.5); + t.expect(cc.rateType).toBe(RateType.Produced); + t.expect(cc.deltaTime).toBe(5); + t.expect(cc.previousValue).toBe(5.4); }); test("the Report command (V3) should be deserialized correctly", (t) => { @@ -229,9 +229,9 @@ test("the Report command (V3) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(cc.constructor, MeterCCReport); + t.expect(cc.constructor).toBe(MeterCCReport); - t.is(cc.scale, 6); + t.expect(cc.scale).toBe(6); }); test("the Report command (V4) should be deserialized correctly", (t) => { @@ -251,9 +251,9 @@ test("the Report command (V4) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(cc.constructor, MeterCCReport); + t.expect(cc.constructor).toBe(MeterCCReport); - t.is(cc.scale, 8); + t.expect(cc.scale).toBe(8); }); test("the Report command should validate that a known meter type is given", (t) => { @@ -274,10 +274,10 @@ test("the Report command should validate that a known meter type is given", (t) ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(report.constructor, MeterCCReport); + t.expect(report.constructor).toBe(MeterCCReport); // Meter type 31 (does not exist) - assertZWaveError(t, () => report.persistValues(host), { + assertZWaveError(t.expect, () => report.persistValues(host), { errorCode: ZWaveErrorCodes.PacketFormat_InvalidPayload, }); }); @@ -300,25 +300,24 @@ test("the Report command should validate that a known meter scale is given", (t) ccData, { sourceNodeId: 1 } as any, ) as MeterCCReport; - t.is(report.constructor, MeterCCReport); + t.expect(report.constructor).toBe(MeterCCReport); // Meter type 4, Scale 8 (does not exist) - assertZWaveError(t, () => report.persistValues(host), { + assertZWaveError(t.expect, () => report.persistValues(host), { errorCode: ZWaveErrorCodes.PacketFormat_InvalidPayload, }); }); test("the value IDs should be translated correctly", (t) => { - t.like( + t.expect( nodeUtils.translateValueID(host, node2, { commandClass: CommandClasses.Meter, property: "value", propertyKey: 329986, }), - { - propertyKeyName: "Cooling_Unknown (0x09)_Produced", - }, - ); + ).toMatchObject({ + propertyKeyName: "Cooling_Unknown (0x09)_Produced", + }); }); test("the SupportedReport command (V2/V3) should be deserialized correctly", (t) => { @@ -333,12 +332,12 @@ test("the SupportedReport command (V2/V3) should be deserialized correctly", (t) ccData, { sourceNodeId: 1 } as any, ) as MeterCCSupportedReport; - t.is(cc.constructor, MeterCCSupportedReport); + t.expect(cc.constructor).toBe(MeterCCSupportedReport); - t.is(cc.type, 21); - t.true(cc.supportsReset); - t.deepEqual(cc.supportedRateTypes, []); - t.deepEqual(cc.supportedScales, [1, 2, 3, 5, 6]); + t.expect(cc.type).toBe(21); + t.expect(cc.supportsReset).toBe(true); + t.expect(cc.supportedRateTypes).toStrictEqual([]); + t.expect(cc.supportedScales).toStrictEqual([1, 2, 3, 5, 6]); }); test("the SupportedReport command (V4/V5) should be deserialized correctly", (t) => { @@ -356,12 +355,12 @@ test("the SupportedReport command (V4/V5) should be deserialized correctly", (t) ccData, { sourceNodeId: 1 } as any, ) as MeterCCSupportedReport; - t.is(cc.constructor, MeterCCSupportedReport); + t.expect(cc.constructor).toBe(MeterCCSupportedReport); - t.is(cc.type, 21); - t.true(cc.supportsReset); - t.deepEqual(cc.supportedRateTypes, [RateType.Produced]); - t.deepEqual(cc.supportedScales, [0, 7, 15]); + t.expect(cc.type).toBe(21); + t.expect(cc.supportsReset).toBe(true); + t.expect(cc.supportedRateTypes).toStrictEqual([RateType.Produced]); + t.expect(cc.supportedScales).toStrictEqual([0, 7, 15]); }); // test("the SupportedReport command (V4/V5) should be deserialized correctly", (t) => { @@ -394,7 +393,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as MeterCC; - t.is(cc.constructor, MeterCC); + t.expect(cc.constructor).toBe(MeterCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/MultiChannelAssociationCC.test.ts b/packages/zwave-js/src/lib/test/cc/MultiChannelAssociationCC.test.ts index accb9dce7ff7..7478d867b128 100644 --- a/packages/zwave-js/src/lib/test/cc/MultiChannelAssociationCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/MultiChannelAssociationCC.test.ts @@ -10,7 +10,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -30,7 +30,7 @@ test("the SupportedGroupingsGet command should serialize correctly", (t) => { MultiChannelAssociationCommand.SupportedGroupingsGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the SupportedGroupingsReport command should be deserialized correctly", (t) => { @@ -44,9 +44,11 @@ test("the SupportedGroupingsReport command should be deserialized correctly", (t ccData, { sourceNodeId: 4 } as any, ) as MultiChannelAssociationCCSupportedGroupingsReport; - t.is(cc.constructor, MultiChannelAssociationCCSupportedGroupingsReport); + t.expect(cc.constructor).toBe( + MultiChannelAssociationCCSupportedGroupingsReport, + ); - t.is(cc.groupCount, 7); + t.expect(cc.groupCount).toBe(7); }); test("the Set command should serialize correctly (node IDs only)", (t) => { @@ -65,7 +67,7 @@ test("the Set command should serialize correctly (node IDs only)", (t) => { 5, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (endpoint addresses only)", (t) => { @@ -96,7 +98,7 @@ test("the Set command should serialize correctly (endpoint addresses only)", (t) 0b11010111, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (both options)", (t) => { @@ -132,7 +134,7 @@ test("the Set command should serialize correctly (both options)", (t) => { 0b11010111, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Get command should serialize correctly", (t) => { @@ -146,7 +148,7 @@ test("the Get command should serialize correctly", (t) => { 9, // group ID ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly (node IDs only)", (t) => { @@ -166,13 +168,13 @@ test("the Report command should be deserialized correctly (node IDs only)", (t) ccData, { sourceNodeId: 4 } as any, ) as MultiChannelAssociationCCReport; - t.is(cc.constructor, MultiChannelAssociationCCReport); + t.expect(cc.constructor).toBe(MultiChannelAssociationCCReport); - t.is(cc.groupId, 5); - t.is(cc.maxNodes, 9); - t.is(cc.reportsToFollow, 0); - t.deepEqual(cc.nodeIds, [1, 2, 5]); - t.deepEqual(cc.endpoints, []); + t.expect(cc.groupId).toBe(5); + t.expect(cc.maxNodes).toBe(9); + t.expect(cc.reportsToFollow).toBe(0); + t.expect(cc.nodeIds).toStrictEqual([1, 2, 5]); + t.expect(cc.endpoints).toStrictEqual([]); }); test("the Report command should be deserialized correctly (endpoint addresses only)", (t) => { @@ -195,10 +197,10 @@ test("the Report command should be deserialized correctly (endpoint addresses on ccData, { sourceNodeId: 4 } as any, ) as MultiChannelAssociationCCReport; - t.is(cc.constructor, MultiChannelAssociationCCReport); + t.expect(cc.constructor).toBe(MultiChannelAssociationCCReport); - t.deepEqual(cc.nodeIds, []); - t.deepEqual(cc.endpoints, [ + t.expect(cc.nodeIds).toStrictEqual([]); + t.expect(cc.endpoints).toStrictEqual([ { nodeId: 5, endpoint: 1, @@ -233,10 +235,10 @@ test("the Report command should be deserialized correctly (both options)", (t) = ccData, { sourceNodeId: 4 } as any, ) as MultiChannelAssociationCCReport; - t.is(cc.constructor, MultiChannelAssociationCCReport); + t.expect(cc.constructor).toBe(MultiChannelAssociationCCReport); - t.deepEqual(cc.nodeIds, [1, 5, 9]); - t.deepEqual(cc.endpoints, [ + t.expect(cc.nodeIds).toStrictEqual([1, 5, 9]); + t.expect(cc.endpoints).toStrictEqual([ { nodeId: 5, endpoint: 1, @@ -264,7 +266,7 @@ test("the Remove command should serialize correctly (node IDs only)", (t) => { 5, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Remove command should serialize correctly (endpoint addresses only)", (t) => { @@ -295,7 +297,7 @@ test("the Remove command should serialize correctly (endpoint addresses only)", 0b11010111, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Remove command should serialize correctly (both options)", (t) => { @@ -331,7 +333,7 @@ test("the Remove command should serialize correctly (both options)", (t) => { 0b11010111, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Remove command should serialize correctly (both empty)", (t) => { @@ -345,7 +347,7 @@ test("the Remove command should serialize correctly (both empty)", (t) => { 5, // group id ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); // test("deserializing an unsupported command should return an unspecified version of MultiChannelAssociationCC", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/MultiChannelCC.test.ts b/packages/zwave-js/src/lib/test/cc/MultiChannelCC.test.ts index 18953361e37c..936ceb7a90a3 100644 --- a/packages/zwave-js/src/lib/test/cc/MultiChannelCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/MultiChannelCC.test.ts @@ -17,7 +17,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -34,7 +34,7 @@ test("is an encapsulating CommandClass", (t) => { targetValue: 50, }); cc = MultiChannelCC.encapsulate(cc); - t.true(isEncapsulatingCommandClass(cc)); + t.expect(isEncapsulatingCommandClass(cc)).toBe(true); }); test("the EndPointGet command should serialize correctly", (t) => { @@ -44,7 +44,7 @@ test("the EndPointGet command should serialize correctly", (t) => { MultiChannelCommand.EndPointGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CapabilityGet command should serialize correctly", (t) => { @@ -58,7 +58,7 @@ test("the CapabilityGet command should serialize correctly", (t) => { 7, // EndPoint ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the EndPointFind command should serialize correctly", (t) => { @@ -74,7 +74,7 @@ test("the EndPointFind command should serialize correctly", (t) => { 0x02, // specificClass ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CommandEncapsulation command should serialize correctly", (t) => { @@ -94,7 +94,7 @@ test("the CommandEncapsulation command should serialize correctly", (t) => { 5, // target value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the AggregatedMembersGet command should serialize correctly", (t) => { @@ -108,7 +108,7 @@ test("the AggregatedMembersGet command should serialize correctly", (t) => { 6, // EndPoint ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CommandEncapsulation command should also accept V1CommandEncapsulation as a response", (t) => { @@ -126,7 +126,7 @@ test("the CommandEncapsulation command should also accept V1CommandEncapsulation }), }); received.endpointIndex = sent.destination as any; - t.true(sent.isExpectedCCResponse(received)); + t.expect(sent.isExpectedCCResponse(received)).toBe(true); }); // test("the Report command (v2) should be deserialized correctly", (t) => { @@ -155,7 +155,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as MultiChannelCC; - t.is(cc.constructor, MultiChannelCC); + t.expect(cc.constructor).toBe(MultiChannelCC); }); // test("the CC values should have the correct metadata", (t) => { @@ -191,7 +191,7 @@ test("MultiChannelCC/BasicCCGet should expect a response", (t) => { endpointIndex: 2, }), ); - t.true(ccRequest.expectsCCResponse()); + t.expect(ccRequest.expectsCCResponse()).toBe(true); }); test("MultiChannelCC/BasicCCGet (multicast) should expect NO response", (t) => { @@ -203,7 +203,7 @@ test("MultiChannelCC/BasicCCGet (multicast) should expect NO response", (t) => { ); // A multicast request never expects a response ccRequest.destination = [1, 2, 3]; - t.false(ccRequest.expectsCCResponse()); + t.expect(ccRequest.expectsCCResponse()).toBe(false); }); test("MultiChannelCC/BasicCCSet should expect NO response", (t) => { @@ -214,7 +214,7 @@ test("MultiChannelCC/BasicCCSet should expect NO response", (t) => { targetValue: 7, }), ); - t.false(ccRequest.expectsCCResponse()); + t.expect(ccRequest.expectsCCResponse()).toBe(false); }); test("MultiChannelCC/BasicCCGet => MultiChannelCC/BasicCCReport = expected", (t) => { @@ -232,7 +232,7 @@ test("MultiChannelCC/BasicCCGet => MultiChannelCC/BasicCCReport = expected", (t) ); ccResponse.endpointIndex = 2; - t.true(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(true); }); test("MultiChannelCC/BasicCCGet => MultiChannelCC/BasicCCGet = unexpected", (t) => { @@ -250,7 +250,7 @@ test("MultiChannelCC/BasicCCGet => MultiChannelCC/BasicCCGet = unexpected", (t) ); ccResponse.endpointIndex = 2; - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); test("MultiChannelCC/BasicCCGet => MultiCommandCC/BasicCCReport = unexpected", (t) => { @@ -268,5 +268,5 @@ test("MultiChannelCC/BasicCCGet => MultiCommandCC/BasicCCReport = unexpected", ( ]); ccResponse.endpointIndex = 2; - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); diff --git a/packages/zwave-js/src/lib/test/cc/MultiCommandCC.test.ts b/packages/zwave-js/src/lib/test/cc/MultiCommandCC.test.ts index 90aed18f813c..3fa970208c7a 100644 --- a/packages/zwave-js/src/lib/test/cc/MultiCommandCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/MultiCommandCC.test.ts @@ -4,7 +4,7 @@ import { MultiCommandCC, isMultiEncapsulatingCommandClass, } from "@zwave-js/cc"; -import test from "ava"; +import { test } from "vitest"; test("is a multi-encapsulating CommandClass", (t) => { let cc: CommandClass = new BasicCCSet({ @@ -12,5 +12,5 @@ test("is a multi-encapsulating CommandClass", (t) => { targetValue: 50, }); cc = MultiCommandCC.encapsulate([cc]); - t.true(isMultiEncapsulatingCommandClass(cc)); + t.expect(isMultiEncapsulatingCommandClass(cc)).toBe(true); }); diff --git a/packages/zwave-js/src/lib/test/cc/MultilevelSwitchCC.test.ts b/packages/zwave-js/src/lib/test/cc/MultilevelSwitchCC.test.ts index 32704955ace6..f18de651eb28 100644 --- a/packages/zwave-js/src/lib/test/cc/MultilevelSwitchCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/MultilevelSwitchCC.test.ts @@ -12,7 +12,7 @@ import { import { CommandClasses, Duration } from "@zwave-js/core"; import { type GetSupportedCCVersion } from "@zwave-js/host"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -30,7 +30,7 @@ test("the Get command should serialize correctly", (t) => { MultilevelSwitchCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (no duration)", (t) => { @@ -51,7 +51,7 @@ test("the Set command should serialize correctly (no duration)", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Set command (V2) should serialize correctly", (t) => { @@ -73,7 +73,7 @@ test("the Set command (V2) should serialize correctly", (t) => { }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the Report command (V1) should be deserialized correctly", (t) => { @@ -87,11 +87,11 @@ test("the Report command (V1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as MultilevelSwitchCCReport; - t.is(cc.constructor, MultilevelSwitchCCReport); + t.expect(cc.constructor).toBe(MultilevelSwitchCCReport); - t.is(cc.currentValue, 55); - t.is(cc.targetValue, undefined); - t.is(cc.duration, undefined); + t.expect(cc.currentValue).toBe(55); + t.expect(cc.targetValue).toBeUndefined(); + t.expect(cc.duration).toBeUndefined(); }); test("the Report command (v4) should be deserialized correctly", (t) => { @@ -107,12 +107,12 @@ test("the Report command (v4) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as MultilevelSwitchCCReport; - t.is(cc.constructor, MultilevelSwitchCCReport); + t.expect(cc.constructor).toBe(MultilevelSwitchCCReport); - t.is(cc.currentValue, 55); - t.is(cc.targetValue, 66); - t.is(cc.duration!.unit, "seconds"); - t.is(cc.duration!.value, 1); + t.expect(cc.currentValue).toBe(55); + t.expect(cc.targetValue).toBe(66); + t.expect(cc.duration!.unit).toBe("seconds"); + t.expect(cc.duration!.value).toBe(1); }); test("the StopLevelChange command should serialize correctly", (t) => { @@ -124,7 +124,7 @@ test("the StopLevelChange command should serialize correctly", (t) => { MultilevelSwitchCommand.StopLevelChange, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the StartLevelChange command (V2) should serialize correctly (down, ignore start level, with duration)", (t) => { @@ -149,7 +149,7 @@ test("the StartLevelChange command (V2) should serialize correctly (down, ignore }, } satisfies GetSupportedCCVersion as any; - t.deepEqual(cc.serialize(ctx), expected); + t.expect(cc.serialize(ctx)).toStrictEqual(expected); }); test("the SupportedGet command should serialize correctly", (t) => { @@ -161,7 +161,7 @@ test("the SupportedGet command should serialize correctly", (t) => { MultilevelSwitchCommand.SupportedGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("deserializing an unsupported command should return an unspecified version of MultilevelSwitchCC", (t) => { @@ -172,7 +172,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 2 } as any, ) as MultilevelSwitchCC; - t.is(cc.constructor, MultilevelSwitchCC); + t.expect(cc.constructor).toBe(MultilevelSwitchCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/NoOperationCC.test.ts b/packages/zwave-js/src/lib/test/cc/NoOperationCC.test.ts index 49b9162678c4..b3d986d5eb4b 100644 --- a/packages/zwave-js/src/lib/test/cc/NoOperationCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/NoOperationCC.test.ts @@ -1,7 +1,7 @@ import { NoOperationCC } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -17,14 +17,14 @@ test("the CC should serialize correctly", (t) => { const expected = buildCCBuffer( Uint8Array.from([]), // No command! ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the CC should be deserialized correctly", (t) => { const ccData = buildCCBuffer( Uint8Array.from([]), // No command! ); - t.notThrows(() => + t.expect(() => new NoOperationCC({ nodeId: 2, data: ccData, context: {} as any }) - ); + ).not.toThrow(); }); diff --git a/packages/zwave-js/src/lib/test/cc/PowerlevelCC.test.ts b/packages/zwave-js/src/lib/test/cc/PowerlevelCC.test.ts index d4ee905113b5..ff26fa647ef9 100644 --- a/packages/zwave-js/src/lib/test/cc/PowerlevelCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/PowerlevelCC.test.ts @@ -9,7 +9,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -27,7 +27,7 @@ test("the Get command should serialize correctly", (t) => { PowerlevelCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set NormalPower command should serialize correctly", (t) => { @@ -42,7 +42,7 @@ test("the Set NormalPower command should serialize correctly", (t) => { 0, // timeout (ignored) ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set NormalPower command with timeout should serialize correctly", (t) => { @@ -58,7 +58,7 @@ test("the Set NormalPower command with timeout should serialize correctly", (t) 0x00, // timeout ignored ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set Custom power command should serialize correctly", (t) => { @@ -74,7 +74,7 @@ test("the Set Custom power command should serialize correctly", (t) => { 50, // timeout ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly (NormalPower)", (t) => { @@ -89,10 +89,10 @@ test("the Report command should be deserialized correctly (NormalPower)", (t) => ccData, { sourceNodeId: 5 } as any, ) as PowerlevelCCReport; - t.is(cc.constructor, PowerlevelCCReport); + t.expect(cc.constructor).toBe(PowerlevelCCReport); - t.is(cc.powerlevel, Powerlevel["Normal Power"]); - t.is(cc.timeout, undefined); // timeout does not apply to NormalPower + t.expect(cc.powerlevel).toBe(Powerlevel["Normal Power"]); + t.expect(cc.timeout).toBeUndefined(); // timeout does not apply to NormalPower }); test("the Report command should be deserialized correctly (custom power)", (t) => { @@ -107,10 +107,10 @@ test("the Report command should be deserialized correctly (custom power)", (t) = ccData, { sourceNodeId: 5 } as any, ) as PowerlevelCCReport; - t.is(cc.constructor, PowerlevelCCReport); + t.expect(cc.constructor).toBe(PowerlevelCCReport); - t.is(cc.powerlevel, Powerlevel["-3 dBm"]); - t.is(cc.timeout, 50); // timeout does not apply to NormalPower + t.expect(cc.powerlevel).toBe(Powerlevel["-3 dBm"]); + t.expect(cc.timeout).toBe(50); // timeout does not apply to NormalPower }); test("deserializing an unsupported command should return an unspecified version of PowerlevelCC", (t) => { @@ -121,5 +121,5 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as PowerlevelCC; - t.is(cc.constructor, PowerlevelCC); + t.expect(cc.constructor).toBe(PowerlevelCC); }); diff --git a/packages/zwave-js/src/lib/test/cc/SceneActivationCC.test.ts b/packages/zwave-js/src/lib/test/cc/SceneActivationCC.test.ts index 5788db123906..bfae440edde1 100644 --- a/packages/zwave-js/src/lib/test/cc/SceneActivationCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/SceneActivationCC.test.ts @@ -6,7 +6,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses, Duration } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -29,7 +29,7 @@ test("the Set command (without Duration) should serialize correctly", (t) => { 0xff, // default duration ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command (with Duration) should serialize correctly", (t) => { @@ -45,7 +45,7 @@ test("the Set command (with Duration) should serialize correctly", (t) => { 0x80, // 1 minute ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should be deserialized correctly", (t) => { @@ -60,10 +60,10 @@ test("the Set command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as SceneActivationCCSet; - t.is(cc.constructor, SceneActivationCCSet); + t.expect(cc.constructor).toBe(SceneActivationCCSet); - t.is(cc.sceneId, 15); - t.deepEqual(cc.dimmingDuration, new Duration(0, "seconds")); + t.expect(cc.sceneId).toBe(15); + t.expect(cc.dimmingDuration).toStrictEqual(new Duration(0, "seconds")); }); test("deserializing an unsupported command should return an unspecified version of SceneActivationCC", (t) => { @@ -74,7 +74,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 2 } as any, ) as SceneActivationCC; - t.is(cc.constructor, SceneActivationCC); + t.expect(cc.constructor).toBe(SceneActivationCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/SceneActuatorConfigurationCC.test.ts b/packages/zwave-js/src/lib/test/cc/SceneActuatorConfigurationCC.test.ts index 49e431cb378d..bae1769b3e82 100644 --- a/packages/zwave-js/src/lib/test/cc/SceneActuatorConfigurationCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/SceneActuatorConfigurationCC.test.ts @@ -8,7 +8,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses, Duration } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -30,7 +30,7 @@ test("the Get command should serialize correctly", (t) => { 1, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly with level", (t) => { @@ -49,7 +49,7 @@ test("the Set command should serialize correctly with level", (t) => { 0x00, // level ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly with undefined level", (t) => { @@ -68,7 +68,7 @@ test("the Set command should serialize correctly with undefined level", (t) => { 0xff, // level ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -84,11 +84,11 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as SceneActuatorConfigurationCCReport; - t.is(cc.constructor, SceneActuatorConfigurationCCReport); + t.expect(cc.constructor).toBe(SceneActuatorConfigurationCCReport); - t.is(cc.sceneId, 55); - t.is(cc.level, 0x50); - t.deepEqual(cc.dimmingDuration, Duration.parseReport(0x05)!); + t.expect(cc.sceneId).toBe(55); + t.expect(cc.level).toBe(0x50); + t.expect(cc.dimmingDuration).toStrictEqual(Duration.parseReport(0x05)!); }); test("deserializing an unsupported command should return an unspecified version of SceneActuatorConfigurationCC", (t) => { @@ -99,5 +99,5 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 2 } as any, ) as SceneActuatorConfigurationCC; - t.is(cc.constructor, SceneActuatorConfigurationCC); + t.expect(cc.constructor).toBe(SceneActuatorConfigurationCC); }); diff --git a/packages/zwave-js/src/lib/test/cc/SceneControllerConfigurationCC.test.ts b/packages/zwave-js/src/lib/test/cc/SceneControllerConfigurationCC.test.ts index a713161c7d77..35c98f50a9da 100644 --- a/packages/zwave-js/src/lib/test/cc/SceneControllerConfigurationCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/SceneControllerConfigurationCC.test.ts @@ -8,7 +8,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses, Duration } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -30,7 +30,7 @@ test("the Get command should serialize correctly", (t) => { 0b0000_0001, ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly", (t) => { @@ -48,7 +48,7 @@ test("the Set command should serialize correctly", (t) => { 0x05, // dimming duration ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly with undefined duration", (t) => { @@ -66,7 +66,7 @@ test("the Set command should serialize correctly with undefined duration", (t) = 0xff, // dimming duration ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1) should be deserialized correctly", (t) => { @@ -82,11 +82,11 @@ test("the Report command (v1) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 2 } as any, ) as SceneControllerConfigurationCCReport; - t.is(cc.constructor, SceneControllerConfigurationCCReport); + t.expect(cc.constructor).toBe(SceneControllerConfigurationCCReport); - t.is(cc.groupId, 3); - t.is(cc.sceneId, 240); - t.deepEqual(cc.dimmingDuration, Duration.parseReport(0x05)!); + t.expect(cc.groupId).toBe(3); + t.expect(cc.sceneId).toBe(240); + t.expect(cc.dimmingDuration).toStrictEqual(Duration.parseReport(0x05)!); }); test("deserializing an unsupported command should return an unspecified version of SceneControllerConfigurationCC", (t) => { @@ -97,5 +97,5 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as SceneControllerConfigurationCC; - t.is(cc.constructor, SceneControllerConfigurationCC); + t.expect(cc.constructor).toBe(SceneControllerConfigurationCC); }); diff --git a/packages/zwave-js/src/lib/test/cc/SupervisionCC.test.ts b/packages/zwave-js/src/lib/test/cc/SupervisionCC.test.ts index 155f7bc9025a..81d2888059fa 100644 --- a/packages/zwave-js/src/lib/test/cc/SupervisionCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/SupervisionCC.test.ts @@ -1,6 +1,6 @@ import { BasicCCSet, SupervisionCC, SupervisionCCReport } from "@zwave-js/cc"; import { SupervisionStatus } from "@zwave-js/core"; -import test from "ava"; +import { test } from "vitest"; test("SupervisionCCGet should expect a response", (t) => { const ccRequest = SupervisionCC.encapsulate( @@ -10,7 +10,7 @@ test("SupervisionCCGet should expect a response", (t) => { }), 1, ); - t.true(ccRequest.expectsCCResponse()); + t.expect(ccRequest.expectsCCResponse()).toBe(true); }); test("SupervisionCC/BasicCCSet => SupervisionCCReport (correct session ID) = expected", (t) => { @@ -28,7 +28,7 @@ test("SupervisionCC/BasicCCSet => SupervisionCCReport (correct session ID) = exp status: SupervisionStatus.Success, }); - t.true(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(true); }); test("SupervisionCC/BasicCCSet => SupervisionCCReport (wrong session ID) = unexpected", (t) => { @@ -46,5 +46,5 @@ test("SupervisionCC/BasicCCSet => SupervisionCCReport (wrong session ID) = unexp status: SupervisionStatus.Success, }); - t.false(ccRequest.isExpectedCCResponse(ccResponse)); + t.expect(ccRequest.isExpectedCCResponse(ccResponse)).toBe(false); }); diff --git a/packages/zwave-js/src/lib/test/cc/ThermostatFanModeCC.test.ts b/packages/zwave-js/src/lib/test/cc/ThermostatFanModeCC.test.ts index 991b5c82c882..0ca02e23b037 100644 --- a/packages/zwave-js/src/lib/test/cc/ThermostatFanModeCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/ThermostatFanModeCC.test.ts @@ -8,7 +8,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -26,7 +26,7 @@ test("the Get command should serialize correctly", (t) => { ThermostatFanModeCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (off = false)", (t) => { @@ -41,7 +41,7 @@ test("the Set command should serialize correctly (off = false)", (t) => { 0x04, // target value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Set command should serialize correctly (off = true)", (t) => { @@ -56,7 +56,7 @@ test("the Set command should serialize correctly (off = true)", (t) => { 0b1000_0100, // target value ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command should be deserialized correctly", (t) => { @@ -70,10 +70,10 @@ test("the Report command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 5 } as any, ) as ThermostatFanModeCCReport; - t.is(cc.constructor, ThermostatFanModeCCReport); + t.expect(cc.constructor).toBe(ThermostatFanModeCCReport); - t.is(cc.mode, ThermostatFanMode["Auto high"]); - t.is(cc.off, true); + t.expect(cc.mode).toBe(ThermostatFanMode["Auto high"]); + t.expect(cc.off).toBe(true); }); // TODO: add tests for getting supported features, interview, etc diff --git a/packages/zwave-js/src/lib/test/cc/ThermostatFanStateCC.test.ts b/packages/zwave-js/src/lib/test/cc/ThermostatFanStateCC.test.ts index 3b328c2bbc8d..28c90d80fc62 100644 --- a/packages/zwave-js/src/lib/test/cc/ThermostatFanStateCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/ThermostatFanStateCC.test.ts @@ -8,7 +8,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -26,7 +26,7 @@ test("the Get command should serialize correctly", (t) => { ThermostatFanStateCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the Report command (v1 - v2) should be deserialized correctly", (t) => { @@ -40,9 +40,9 @@ test("the Report command (v1 - v2) should be deserialized correctly", (t) => { ccData, { sourceNodeId: 1 } as any, ) as ThermostatFanStateCCReport; - t.is(cc.constructor, ThermostatFanStateCCReport); + t.expect(cc.constructor).toBe(ThermostatFanStateCCReport); - t.is(cc.state, ThermostatFanState["Idle / off"]); + t.expect(cc.state).toBe(ThermostatFanState["Idle / off"]); }); test("deserializing an unsupported command should return an unspecified version of ThermostatFanStateCC", (t) => { @@ -53,7 +53,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 1 } as any, ) as ThermostatFanStateCC; - t.is(cc.constructor, ThermostatFanStateCC); + t.expect(cc.constructor).toBe(ThermostatFanStateCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/TimeCC.test.ts b/packages/zwave-js/src/lib/test/cc/TimeCC.test.ts index bcb08ef280ca..b4221a942639 100644 --- a/packages/zwave-js/src/lib/test/cc/TimeCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/TimeCC.test.ts @@ -9,7 +9,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -27,7 +27,7 @@ test("the TimeGet command should serialize correctly", (t) => { TimeCommand.TimeGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the TimeReport command should be deserialized correctly", (t) => { @@ -43,11 +43,11 @@ test("the TimeReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 8 } as any, ) as TimeCCTimeReport; - t.is(cc.constructor, TimeCCTimeReport); + t.expect(cc.constructor).toBe(TimeCCTimeReport); - t.is(cc.hour, 14); - t.is(cc.minute, 23); - t.is(cc.second, 59); + t.expect(cc.hour).toBe(14); + t.expect(cc.minute).toBe(23); + t.expect(cc.second).toBe(59); }); test("the DateGet command should serialize correctly", (t) => { @@ -57,7 +57,7 @@ test("the DateGet command should serialize correctly", (t) => { TimeCommand.DateGet, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); test("the DateReport command should be deserialized correctly", (t) => { @@ -74,11 +74,11 @@ test("the DateReport command should be deserialized correctly", (t) => { ccData, { sourceNodeId: 8 } as any, ) as TimeCCDateReport; - t.is(cc.constructor, TimeCCDateReport); + t.expect(cc.constructor).toBe(TimeCCDateReport); - t.is(cc.year, 1989); - t.is(cc.month, 10); - t.is(cc.day, 17); + t.expect(cc.year).toBe(1989); + t.expect(cc.month).toBe(10); + t.expect(cc.day).toBe(17); }); test("deserializing an unsupported command should return an unspecified version of TimeCC", (t) => { @@ -89,7 +89,7 @@ test("deserializing an unsupported command should return an unspecified version serializedCC, { sourceNodeId: 8 } as any, ) as TimeCC; - t.is(cc.constructor, TimeCC); + t.expect(cc.constructor).toBe(TimeCC); }); // test("the CC values should have the correct metadata", (t) => { diff --git a/packages/zwave-js/src/lib/test/cc/WakeUpCC.test.ts b/packages/zwave-js/src/lib/test/cc/WakeUpCC.test.ts index fe0513c63f52..40b6a4e908bc 100644 --- a/packages/zwave-js/src/lib/test/cc/WakeUpCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/WakeUpCC.test.ts @@ -5,15 +5,15 @@ import { } from "@zwave-js/cc"; import { generateAuthKey, generateEncryptionKey } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; import { randomBytes } from "node:crypto"; +import { test } from "vitest"; test("WakeUpCCNoMoreInformation should expect no response", (t) => { const cc = new WakeUpCCNoMoreInformation({ nodeId: 2, endpointIndex: 2, }); - t.false(cc.expectsCCResponse()); + t.expect(cc.expectsCCResponse()).toBe(false); }); test("MultiChannelCC/WakeUpCCNoMoreInformation should expect NO response", (t) => { @@ -23,7 +23,7 @@ test("MultiChannelCC/WakeUpCCNoMoreInformation should expect NO response", (t) = endpointIndex: 2, }), ); - t.false(ccRequest.expectsCCResponse()); + t.expect(ccRequest.expectsCCResponse()).toBe(false); }); test("SecurityCC/WakeUpCCNoMoreInformation should expect NO response", (t) => { @@ -46,5 +46,5 @@ test("SecurityCC/WakeUpCCNoMoreInformation should expect NO response", (t) => { endpointIndex: 2, }), ); - t.false(ccRequest.expectsCCResponse()); + t.expect(ccRequest.expectsCCResponse()).toBe(false); }); diff --git a/packages/zwave-js/src/lib/test/cc/ZWavePlusCC.test.ts b/packages/zwave-js/src/lib/test/cc/ZWavePlusCC.test.ts index 63850a0eaae3..02191fd73813 100644 --- a/packages/zwave-js/src/lib/test/cc/ZWavePlusCC.test.ts +++ b/packages/zwave-js/src/lib/test/cc/ZWavePlusCC.test.ts @@ -1,7 +1,7 @@ import { ZWavePlusCCGet, ZWavePlusCommand } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared/safe"; -import test from "ava"; +import { test } from "vitest"; function buildCCBuffer(payload: Uint8Array): Uint8Array { return Bytes.concat([ @@ -21,7 +21,7 @@ test("The Get command should serialize correctly", (t) => { ZWavePlusCommand.Get, // CC Command ]), ); - t.deepEqual(cc.serialize({} as any), expected); + t.expect(cc.serialize({} as any)).toStrictEqual(expected); }); // describe.skip(`interview()`, () => { diff --git a/packages/zwave-js/src/lib/test/compat/basicCCReportForThermostat.test.ts b/packages/zwave-js/src/lib/test/compat/basicCCReportForThermostat.test.ts index 5b52652675e0..89b733b8add5 100644 --- a/packages/zwave-js/src/lib/test/compat/basicCCReportForThermostat.test.ts +++ b/packages/zwave-js/src/lib/test/compat/basicCCReportForThermostat.test.ts @@ -1,7 +1,7 @@ import { BasicCCValues } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "A Thermostat with compat flag mapBasicReport=false exposes currentValue", @@ -48,18 +48,18 @@ integrationTest( async testBody(t, driver, node, mockController, mockNode) { // Despite the compat flag, Basic CC should not be considered supported - t.false(node.supportsCC(CommandClasses.Basic)); + t.expect(node.supportsCC(CommandClasses.Basic)).toBe(false); // But currentValue should be exposed - otherwise it makes no sense to not map it const valueIDs = node.getDefinedValueIDs(); - t.true( + t.expect( valueIDs.some((v) => BasicCCValues.currentValue.is(v)), "Did not find Basic CC currentValue although it should be exposed", - ); - t.false( + ).toBe(true); + t.expect( valueIDs.some((v) => BasicCCValues.targetValue.is(v)), "Found Basic CC targetValue although it shouldn't be exposed", - ); + ).toBe(false); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compat/basicCCSupportWhenForbidden.test.ts b/packages/zwave-js/src/lib/test/compat/basicCCSupportWhenForbidden.test.ts index 9fd20e33017b..7eb610a1467a 100644 --- a/packages/zwave-js/src/lib/test/compat/basicCCSupportWhenForbidden.test.ts +++ b/packages/zwave-js/src/lib/test/compat/basicCCSupportWhenForbidden.test.ts @@ -1,7 +1,7 @@ import { BasicCCValues } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "On devices that MUST not support Basic CC, and treat Basic Set as a report, ONLY currentValue should be exposed", @@ -35,27 +35,27 @@ integrationTest( async testBody(t, driver, node, mockController, mockNode) { const valueIDs = node.getDefinedValueIDs(); - t.true( + t.expect( valueIDs.some((v) => BasicCCValues.currentValue.is(v)), "Did not find Basic CC currentValue although it should be exposed", - ); - t.false( + ).toBe(true); + t.expect( valueIDs.some((v) => BasicCCValues.targetValue.is(v)), "Found Basic CC targetValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.duration.is(v)), "Found Basic CC duration although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.restorePrevious.is(v)), "Found Basic CC restorePrevious although it shouldn't be exposed", - ); + ).toBe(false); - t.false( + t.expect( valueIDs.some((v) => BasicCCValues.compatEvent.is(v)), "Found Basic CC compatEvent although it shouldn't be exposed", - ); + ).toBe(false); }, }, ); @@ -92,27 +92,27 @@ integrationTest( async testBody(t, driver, node, mockController, mockNode) { const valueIDs = node.getDefinedValueIDs(); - t.false( + t.expect( valueIDs.some((v) => BasicCCValues.currentValue.is(v)), "Found Basic CC currentValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.targetValue.is(v)), "Found Basic CC targetValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.duration.is(v)), "Found Basic CC duration although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.restorePrevious.is(v)), "Found Basic CC restorePrevious although it shouldn't be exposed", - ); + ).toBe(false); - t.false( + t.expect( valueIDs.some((v) => BasicCCValues.compatEvent.is(v)), "Found Basic CC compatEvent although it shouldn't be exposed", - ); + ).toBe(false); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compat/binarySensorReportAnyUseFirstSupported.test.ts b/packages/zwave-js/src/lib/test/compat/binarySensorReportAnyUseFirstSupported.test.ts index 456fbdbe0297..efe848ba067e 100644 --- a/packages/zwave-js/src/lib/test/compat/binarySensorReportAnyUseFirstSupported.test.ts +++ b/packages/zwave-js/src/lib/test/compat/binarySensorReportAnyUseFirstSupported.test.ts @@ -6,8 +6,8 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { type MockNodeBehavior, ccCaps } from "@zwave-js/testing"; -import { defaultCapabilities } from "../../node/mockCCBehaviors/UserCode"; -import { integrationTest } from "../integrationTestSuite"; +import { defaultCapabilities } from "../../node/mockCCBehaviors/UserCode.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When a node sends a Binary Sensor Report with type 0xFF (Any), use the first supported sensor instead", @@ -57,12 +57,12 @@ integrationTest( const anyValue = node.getValue( BinarySensorCCValues.state(BinarySensorType.Any).id, ); - t.is(anyValue, undefined); + t.expect(anyValue).toBeUndefined(); const motionValue = node.getValue( BinarySensorCCValues.state(BinarySensorType.Motion).id, ); - t.is(motionValue, true); + t.expect(motionValue).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compat/corruptACKAfterSoftReset.test.ts b/packages/zwave-js/src/lib/test/compat/corruptACKAfterSoftReset.test.ts index a2ad8692b8d0..56318b550c37 100644 --- a/packages/zwave-js/src/lib/test/compat/corruptACKAfterSoftReset.test.ts +++ b/packages/zwave-js/src/lib/test/compat/corruptACKAfterSoftReset.test.ts @@ -1,4 +1,4 @@ -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro for https://github.com/zwave-js/node-zwave-js/issues/6399 @@ -15,7 +15,7 @@ integrationTest( mockController.clearReceivedHostMessages(); mockController.corruptACK = true; - await t.notThrowsAsync(driver.softReset()); + await driver.softReset(); mockController.corruptACK = false; }, }, diff --git a/packages/zwave-js/src/lib/test/compat/invalidCallbackFunctionTypes.test.ts b/packages/zwave-js/src/lib/test/compat/invalidCallbackFunctionTypes.test.ts index 29684b2a7741..01a2b388a3f9 100644 --- a/packages/zwave-js/src/lib/test/compat/invalidCallbackFunctionTypes.test.ts +++ b/packages/zwave-js/src/lib/test/compat/invalidCallbackFunctionTypes.test.ts @@ -18,8 +18,8 @@ import { import { MockControllerCommunicationState, MockControllerStateKeys, -} from "../../controller/MockControllerState"; -import { integrationTest } from "../integrationTestSuite"; +} from "../../controller/MockControllerState.js"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro for https://github.com/zwave-js/node-zwave-js/issues/6363 @@ -222,12 +222,12 @@ integrationTest( let result = await driver.controller.assignSUCReturnRoutes( node.id, ); - t.false(result); + t.expect(result).toBe(false); result = await driver.controller.deleteSUCReturnRoutes( node.id, ); - t.false(result); + t.expect(result).toBe(false); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compat/notificationAlarmMapping.test.ts b/packages/zwave-js/src/lib/test/compat/notificationAlarmMapping.test.ts index e0b90d97733b..a8c4c52a7168 100644 --- a/packages/zwave-js/src/lib/test/compat/notificationAlarmMapping.test.ts +++ b/packages/zwave-js/src/lib/test/compat/notificationAlarmMapping.test.ts @@ -4,9 +4,9 @@ import { } from "@zwave-js/cc/NotificationCC"; import { CommandClasses } from "@zwave-js/core"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import sinon from "sinon"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "the alarmMapping compat flag works correctly (using the example Kwikset 910)", @@ -51,22 +51,22 @@ integrationTest( sinon.assert.calledOnce(nodeNotification); const event = nodeNotification.getCall(0).args[2]; - t.is(event.type, 0x06); - t.is(event.event, 0x05); - t.deepEqual(event.parameters, { + t.expect(event.type).toBe(0x06); + t.expect(event.event).toBe(0x05); + t.expect(event.parameters).toStrictEqual({ userId: 2, }); // And they should be known to be supported const supportedNotificationTypes: number[] | undefined = node .getValue(NotificationCCValues.supportedNotificationTypes.id); - t.true(supportedNotificationTypes?.includes(0x06)); + t.expect(supportedNotificationTypes?.includes(0x06)).toBe(true); const supportedAccessControlEvents: number[] | undefined = node .getValue( NotificationCCValues.supportedNotificationEvents(0x06).id, ); - t.true(supportedAccessControlEvents?.includes(0x05)); + t.expect(supportedAccessControlEvents?.includes(0x05)).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compat/reInterviewWakeUpNIF.test.ts b/packages/zwave-js/src/lib/test/compat/reInterviewWakeUpNIF.test.ts index f124ca57ec5e..a7030e7dbf1d 100644 --- a/packages/zwave-js/src/lib/test/compat/reInterviewWakeUpNIF.test.ts +++ b/packages/zwave-js/src/lib/test/compat/reInterviewWakeUpNIF.test.ts @@ -1,9 +1,9 @@ import { ZWaveProtocolCCNodeInformationFrame } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Re-interviews that wait for a wake-up start when receiving a NIF", @@ -48,7 +48,6 @@ integrationTest( await promise; await wait(500); - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compat/treatBasicSetAsEvent.test.ts b/packages/zwave-js/src/lib/test/compat/treatBasicSetAsEvent.test.ts index 3bcfb85021e1..bd16ff90f5e4 100644 --- a/packages/zwave-js/src/lib/test/compat/treatBasicSetAsEvent.test.ts +++ b/packages/zwave-js/src/lib/test/compat/treatBasicSetAsEvent.test.ts @@ -1,7 +1,7 @@ import { BasicCCValues } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Basic CC values should only include the compatEvent value if Basic CC is not supported, but the compat flag is set", @@ -39,30 +39,30 @@ integrationTest( // Make sure the custom config is loaded const mapBasicSet = node.deviceConfig?.compat ?.mapBasicSet; - t.is(mapBasicSet, "event"); + t.expect(mapBasicSet).toBe("event"); const valueIDs = node.getDefinedValueIDs(); - t.false( + t.expect( valueIDs.some((v) => BasicCCValues.currentValue.is(v)), "Found Basic CC currentValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.targetValue.is(v)), "Found Basic CC targetValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.duration.is(v)), "Found Basic CC duration although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.restorePrevious.is(v)), "Found Basic CC restorePrevious although it shouldn't be exposed", - ); + ).toBe(false); - t.true( + t.expect( valueIDs.some((v) => BasicCCValues.compatEvent.is(v)), "Did not find Basic CC compatEvent although it should be exposed", - ); + ).toBe(true); }, }, ); @@ -99,30 +99,30 @@ integrationTest( // Make sure the custom config is loaded const mapBasicSet = node.deviceConfig?.compat ?.mapBasicSet; - t.is(mapBasicSet, "event"); + t.expect(mapBasicSet).toBe("event"); const valueIDs = node.getDefinedValueIDs(); - t.false( + t.expect( valueIDs.some((v) => BasicCCValues.currentValue.is(v)), "Found Basic CC currentValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.targetValue.is(v)), "Found Basic CC targetValue although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.duration.is(v)), "Found Basic CC duration although it shouldn't be exposed", - ); - t.false( + ).toBe(false); + t.expect( valueIDs.some((v) => BasicCCValues.restorePrevious.is(v)), "Found Basic CC restorePrevious although it shouldn't be exposed", - ); + ).toBe(false); - t.true( + t.expect( valueIDs.some((v) => BasicCCValues.compatEvent.is(v)), "Did not find Basic CC compatEvent although it should be exposed", - ); + ).toBe(true); }, }, ); @@ -142,27 +142,27 @@ integrationTest( async testBody(t, driver, node, mockController, mockNode) { const valueIDs = node.getDefinedValueIDs(); - t.true( + t.expect( valueIDs.some((v) => BasicCCValues.currentValue.is(v)), "Did not find Basic CC currentValue although it should be exposed", - ); - t.true( + ).toBe(true); + t.expect( valueIDs.some((v) => BasicCCValues.targetValue.is(v)), "Did not find Basic CC targetValue although it should be exposed", - ); - t.true( + ).toBe(true); + t.expect( valueIDs.some((v) => BasicCCValues.duration.is(v)), "Did not find Basic CC duration although it should be exposed", - ); - t.true( + ).toBe(true); + t.expect( valueIDs.some((v) => BasicCCValues.restorePrevious.is(v)), "Did not find Basic CC restorePrevious although it should be exposed", - ); + ).toBe(true); - t.false( + t.expect( valueIDs.some((v) => BasicCCValues.compatEvent.is(v)), "Found Basic CC compatEvent although it shouldn't be exposed", - ); + ).toBe(false); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compliance/decodeLowerS2Keys.test.ts b/packages/zwave-js/src/lib/test/compliance/decodeLowerS2Keys.test.ts index 3497bc264da4..01bef4325d68 100644 --- a/packages/zwave-js/src/lib/test/compliance/decodeLowerS2Keys.test.ts +++ b/packages/zwave-js/src/lib/test/compliance/decodeLowerS2Keys.test.ts @@ -15,10 +15,10 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import { randomBytes } from "node:crypto"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "S2 encapsulated commands using a lower security class can be decoded", @@ -206,8 +206,6 @@ integrationTest( && f.payload instanceof Security2CCMessageEncapsulation && f.payload.encapsulated instanceof BasicCCSet, ); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compliance/discardInsecureCommands.test.ts b/packages/zwave-js/src/lib/test/compliance/discardInsecureCommands.test.ts index 3c9732f9c809..b52ba658dd4b 100644 --- a/packages/zwave-js/src/lib/test/compliance/discardInsecureCommands.test.ts +++ b/packages/zwave-js/src/lib/test/compliance/discardInsecureCommands.test.ts @@ -16,9 +16,9 @@ import { type MockNodeBehavior, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Security S2: Completely discard commands that should have been encrypted, but are not", @@ -141,7 +141,7 @@ integrationTest( await wait(100); let currentValue = node.getValue(BasicCCValues.currentValue.id); - t.is(currentValue, 99); + t.expect(currentValue).toBe(99); // Then send an unencypted one that should be discarded nodeToHost = new BasicCCReport({ @@ -159,7 +159,7 @@ integrationTest( await wait(100); currentValue = node.getValue(BasicCCValues.currentValue.id); - t.is(currentValue, 99); // unchanged + t.expect(currentValue).toBe(99); // unchanged }, }, ); diff --git a/packages/zwave-js/src/lib/test/compliance/encapsulationAnswerAsAsked.test.ts b/packages/zwave-js/src/lib/test/compliance/encapsulationAnswerAsAsked.test.ts index 4fd87ee2aa53..2e7478e0c9de 100644 --- a/packages/zwave-js/src/lib/test/compliance/encapsulationAnswerAsAsked.test.ts +++ b/packages/zwave-js/src/lib/test/compliance/encapsulationAnswerAsAsked.test.ts @@ -16,7 +16,7 @@ import { createMockZWaveRequestFrame, } from "@zwave-js/testing"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Responses to encapsulated requests use the same encapsulation (CRC-16)", @@ -52,11 +52,13 @@ integrationTest( (msg) => msg.type === MockZWaveFrameType.Request, ); - t.true(response instanceof CRC16CCCommandEncapsulation); - t.true( + t.expect(response instanceof CRC16CCCommandEncapsulation).toBe( + true, + ); + t.expect( (response as CRC16CCCommandEncapsulation) .encapsulated instanceof ZWavePlusCCReport, - ); + ).toBe(true); }, }, ); @@ -104,11 +106,12 @@ integrationTest( msg.type === MockZWaveFrameType.Request, ); - t.true(response instanceof MultiChannelCCCommandEncapsulation); + t.expect(response instanceof MultiChannelCCCommandEncapsulation) + .toBe(true); const mcc = response as MultiChannelCCCommandEncapsulation; - t.is(mcc.destination, 2); + t.expect(mcc.destination).toBe(2); const inner = mcc.encapsulated; - t.true(inner instanceof ZWavePlusCCReport); + t.expect(inner instanceof ZWavePlusCCReport).toBe(true); }, }, ); @@ -157,7 +160,7 @@ integrationTest( msg.type === MockZWaveFrameType.Request, ); - t.true(response instanceof SupervisionCCReport); + t.expect(response instanceof SupervisionCCReport).toBe(true); }, }, ); @@ -213,11 +216,12 @@ integrationTest( msg.type === MockZWaveFrameType.Request, ); - t.true(response instanceof MultiChannelCCCommandEncapsulation); + t.expect(response instanceof MultiChannelCCCommandEncapsulation) + .toBe(true); const mcc = response as MultiChannelCCCommandEncapsulation; - t.is(mcc.destination, 2); + t.expect(mcc.destination).toBe(2); const inner = mcc.encapsulated; - t.true(inner instanceof SupervisionCCReport); + t.expect(inner instanceof SupervisionCCReport).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compliance/handleMultiCommandPayload.test.ts b/packages/zwave-js/src/lib/test/compliance/handleMultiCommandPayload.test.ts index 0e86c08eb1c1..06872d227434 100644 --- a/packages/zwave-js/src/lib/test/compliance/handleMultiCommandPayload.test.ts +++ b/packages/zwave-js/src/lib/test/compliance/handleMultiCommandPayload.test.ts @@ -10,7 +10,7 @@ import { createMockZWaveRequestFrame, } from "@zwave-js/testing"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("All CCs contained in a Multi Command CC are handled", { // debug: true, @@ -61,7 +61,7 @@ integrationTest("All CCs contained in a Multi Command CC are handled", { }); }); const expectNotification = valueNotification.then((val) => - t.is(val, 7) + t.expect(val).toBe(7) ); await Promise.all([expectResponse, expectNotification]); diff --git a/packages/zwave-js/src/lib/test/compliance/secureNodeSecureEndpoint.test.ts b/packages/zwave-js/src/lib/test/compliance/secureNodeSecureEndpoint.test.ts index f82c2d4da011..7b7eabed1cff 100644 --- a/packages/zwave-js/src/lib/test/compliance/secureNodeSecureEndpoint.test.ts +++ b/packages/zwave-js/src/lib/test/compliance/secureNodeSecureEndpoint.test.ts @@ -22,7 +22,7 @@ import { ZWaveErrorCodes, } from "@zwave-js/core"; import { type MockNodeBehavior, MockZWaveFrameType } from "@zwave-js/testing"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Security S2: Communicate with endpoints of secure nodes securely, even if the endpoint does not list S2 as supported", @@ -320,7 +320,6 @@ integrationTest( "Expected communication with endpoint 2 to be secure", }, ); - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/compliance/zwavePlusInfoResponse.test.ts b/packages/zwave-js/src/lib/test/compliance/zwavePlusInfoResponse.test.ts index d1cd190b1ad3..e33a115a4d75 100644 --- a/packages/zwave-js/src/lib/test/compliance/zwavePlusInfoResponse.test.ts +++ b/packages/zwave-js/src/lib/test/compliance/zwavePlusInfoResponse.test.ts @@ -10,7 +10,7 @@ import { createMockZWaveRequestFrame, } from "@zwave-js/testing"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("Response to Z-Wave Plus Info Get", { // debug: true, @@ -45,8 +45,10 @@ integrationTest("Response to Z-Wave Plus Info Get", { ); // Z-Wave+ v2 specifications, section 3.1 - t.is(response.zwavePlusVersion, 2); + t.expect(response.zwavePlusVersion).toBe(2); // Z-Wave+ v2 specifications, section 4.1 - t.is(response.roleType, ZWavePlusRoleType.CentralStaticController); + t.expect(response.roleType).toBe( + ZWavePlusRoleType.CentralStaticController, + ); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/SerialLogger.test.ts b/packages/zwave-js/src/lib/test/driver/SerialLogger.test.ts index 9a37e114c051..3151423e8e6e 100644 --- a/packages/zwave-js/src/lib/test/driver/SerialLogger.test.ts +++ b/packages/zwave-js/src/lib/test/driver/SerialLogger.test.ts @@ -6,146 +6,152 @@ import { SpyTransport, assertMessage } from "@zwave-js/core/test"; import { SerialLogger } from "@zwave-js/serial"; import { Bytes } from "@zwave-js/shared/safe"; import colors from "ansi-colors"; -import ava, { type TestFn } from "ava"; import { pseudoRandomBytes } from "node:crypto"; +import { beforeEach, test as baseTest } from "vitest"; -interface TestContext { - serialLogger: SerialLogger; - spyTransport: SpyTransport; -} - -const test = ava as TestFn; - -test.before((t) => { - // Replace all defined transports with a spy transport - const spyTransport = new SpyTransport(); - spyTransport.format = createDefaultTransportFormat(true, true); - const serialLogger = new SerialLogger( - new ZWaveLogContainer({ - transports: [spyTransport], - }), - ); - // Uncomment this to debug the log outputs manually - // wasSilenced = unsilence(serialLogger); - - t.context = { - serialLogger, - spyTransport, +interface LocalTestContext { + context: { + serialLogger: SerialLogger; + spyTransport: SpyTransport; }; -}); - -// Don't spam the console when performing the other tests not related to logging -test.after.always((t) => { - t.context.serialLogger.container.updateConfiguration({ enabled: false }); -}); - -test.beforeEach((t) => { - t.context.spyTransport.spy.resetHistory(); -}); +} -test.serial("logs single-byte messages correctly: inbound ACK", (t) => { - const { serialLogger, spyTransport } = t.context; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + // Replace all defined transports with a spy transport + const spyTransport = new SpyTransport(); + spyTransport.format = createDefaultTransportFormat(true, true); + const serialLogger = new SerialLogger( + new ZWaveLogContainer({ + transports: [spyTransport], + }), + ); + // Uncomment this to debug the log outputs manually + // wasSilenced = unsilence(serialLogger); + + // Run tests + await use({ + serialLogger, + spyTransport, + }); + + // Teardown + // Don't spam the console when performing the other tests not related to logging + serialLogger.container.updateConfiguration({ enabled: false }); + }, + { auto: true }, + ], +}); + +beforeEach(({ context, expect }) => { + context.spyTransport.spy.resetHistory(); +}); + +test.sequential("logs single-byte messages correctly: inbound ACK", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.ACK("inbound"); const alignRight = " ".repeat(80 - 14); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« [ACK] ${alignRight}(0x06)`, }); }); -test.serial("logs single-byte messages correctly: outbound ACK", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs single-byte messages correctly: outbound ACK", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.ACK("outbound"); const alignRight = " ".repeat(80 - 14); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `» [ACK] ${alignRight}(0x06)`, }); }); -test.serial("logs single-byte messages correctly: inbound NAK", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs single-byte messages correctly: inbound NAK", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.NAK("inbound"); const alignRight = " ".repeat(80 - 14); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« [NAK] ${alignRight}(0x15)`, }); }); -test.serial("logs single-byte messages correctly: outbound NAK", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs single-byte messages correctly: outbound NAK", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.NAK("outbound"); const alignRight = " ".repeat(80 - 14); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `» [NAK] ${alignRight}(0x15)`, }); }); -test.serial("logs single-byte messages correctly: inbound CAN", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs single-byte messages correctly: inbound CAN", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.CAN("inbound"); const alignRight = " ".repeat(80 - 14); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« [CAN] ${alignRight}(0x18)`, }); }); -test.serial("logs single-byte messages correctly: outbound CAN", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs single-byte messages correctly: outbound CAN", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.CAN("outbound"); const alignRight = " ".repeat(80 - 14); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `» [CAN] ${alignRight}(0x18)`, }); }); for (const msg of ["ACK", "NAK", "CAN"] as const) { - test.serial(`colors single-byte messages like tags: ${msg}`, (t) => { - const { serialLogger, spyTransport } = t.context; + test.sequential(`colors single-byte messages like tags: ${msg}`, ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger[msg]("inbound"); const expected1 = colors.blue( colors.bgBlue("[") + colors.inverse(msg) + colors.bgBlue("]"), ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { predicate: (msg) => msg.includes(expected1), ignoreColor: false, }); }); } -test.serial("logs raw data correctly: short buffer, inbound", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs raw data correctly: short buffer, inbound", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.data("inbound", Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8])); const alignRight = " ".repeat(80 - 30); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« 0x0102030405060708 ${alignRight}(8 bytes)`, }); }); -test.serial("logs raw data correctly: short buffer, outbound", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs raw data correctly: short buffer, outbound", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.data("outbound", Uint8Array.from([0x55, 4, 3, 2, 1])); const alignRight = " ".repeat(80 - 24); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `» 0x5504030201 ${alignRight}(5 bytes)`, }); }); -test.serial("wraps longer buffers into multiple lines", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("wraps longer buffers into multiple lines", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; // We have room for 67 chars in the first line const expected = pseudoRandomBytes(39); const hexBuffer = `0x${expected.toString("hex")}`; const expectedLine1 = hexBuffer.slice(0, 67); const expectedLine2 = hexBuffer.slice(67); serialLogger.data("inbound", expected); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« ${expectedLine1} (39 bytes) ${expectedLine2}`, }); }); -test.serial("correctly groups very long lines", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("correctly groups very long lines", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; // We have room for 67 chars in the first line, that is 32.5 bytes // and 78 chars (39 bytes) in each following line const expected = pseudoRandomBytes(72); @@ -154,37 +160,37 @@ test.serial("correctly groups very long lines", (t) => { const expectedLine2 = hexBuffer.slice(67, 67 + 78); const expectedLine3 = hexBuffer.slice(67 + 78); serialLogger.data("inbound", expected); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« ${expectedLine1} (72 bytes) ${expectedLine2} ${expectedLine3}`, }); }); -test.serial("logs discarded data correctly", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs discarded data correctly", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.discarded(Bytes.from("02020202020202", "hex")); const alignRight = " ".repeat(80 - 53); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: `« [DISCARDED] invalid data 0x02020202020202 ${alignRight}(7 bytes)`, }); }); -test.serial("logs short messages correctly", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs short messages correctly", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.message("Test"); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` Test`, }); }); -test.serial("logs long messages correctly", (t) => { - const { serialLogger, spyTransport } = t.context; +test.sequential("logs long messages correctly", ({ context, expect }) => { + const { serialLogger, spyTransport } = context; serialLogger.message( "This is a very long message that should be broken into multiple lines maybe sometimes...", ); - assertMessage(t, spyTransport, { + assertMessage(expect, spyTransport, { message: ` This is a very long message that should be broken into multiple lines maybe so metimes...`, diff --git a/packages/zwave-js/src/lib/test/driver/assemblePartialCCs.test.ts b/packages/zwave-js/src/lib/test/driver/assemblePartialCCs.test.ts index f1757640238a..813e9228fe89 100644 --- a/packages/zwave-js/src/lib/test/driver/assemblePartialCCs.test.ts +++ b/packages/zwave-js/src/lib/test/driver/assemblePartialCCs.test.ts @@ -7,61 +7,69 @@ import { AssociationCommand } from "@zwave-js/cc/safe"; import { CommandClasses, ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import { ApplicationCommandRequest } from "@zwave-js/serial/serialapi"; import { MockController, MockNode } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.beforeEach(async (t) => { - t.timeout(30000); - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - skipNodeInterview: true, - securityKeys: { - S0_Legacy: new Uint8Array(16).fill(0xff), - }, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - const node2 = new MockNode({ - id: 2, - controller, + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipNodeInterview: true, + securityKeys: { + S0_Legacy: new Uint8Array(16).fill(0xff), + }, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + const node2 = new MockNode({ + id: 2, + controller, + }); + (controller.nodes as Map).set(node2.id, node2); + context.controller = controller; + }, }); - (controller.nodes as Map).set(node2.id, node2); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); + context.driver = driver; + + // Run tests + await use(context); -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test.serial("returns true when a non-partial CC is received", (t) => { - const { driver } = t.context; +test.sequential("returns true when a non-partial CC is received", ({ context, expect }) => { + const { driver } = context; const cc = new BasicCCSet({ nodeId: 2, targetValue: 50 }); const msg = new ApplicationCommandRequest({ command: cc, }); - t.true(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(true); }); -test.serial( +test.sequential( "returns true when a partial CC is received that expects no more reports", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const cc = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -78,14 +86,14 @@ test.serial( const msg = new ApplicationCommandRequest({ command: cc, }); - t.true(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(true); }, ); -test.serial( +test.sequential( "returns false when a partial CC is received that expects more reports", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const cc = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -102,14 +110,14 @@ test.serial( const msg = new ApplicationCommandRequest({ command: cc, }); - t.false(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(false); }, ); -test.serial( +test.sequential( "returns true when the final partial CC is received and merges its data", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const cc1 = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -139,22 +147,21 @@ test.serial( const msg1 = new ApplicationCommandRequest({ command: cc1, }); - t.false(driver["assemblePartialCCs"](msg1)); + expect(driver["assemblePartialCCs"](msg1)).toBe(false); const msg2 = new ApplicationCommandRequest({ command: cc2, }); - t.true(driver["assemblePartialCCs"](msg2)); + expect(driver["assemblePartialCCs"](msg2)).toBe(true); - t.deepEqual( + expect( (msg2.command as AssociationCCReport).nodeIds, - [1, 2, 3, 4, 5, 6], - ); + ).toStrictEqual([1, 2, 3, 4, 5, 6]); }, ); -test.serial("does not crash when receiving a Multi Command CC", (t) => { - const { driver } = t.context; +test.sequential("does not crash when receiving a Multi Command CC", ({ context, expect }) => { + const { driver } = context; const cc1 = new BasicCCSet({ nodeId: 2, targetValue: 25 }); const cc2 = new BasicCCSet({ nodeId: 2, targetValue: 50 }); const cc = new MultiCommandCCCommandEncapsulation({ @@ -164,11 +171,11 @@ test.serial("does not crash when receiving a Multi Command CC", (t) => { const msg = new ApplicationCommandRequest({ command: cc, }); - t.true(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(true); }); -test.serial("supports nested partial/non-partial CCs", (t) => { - const { driver } = t.context; +test.sequential("supports nested partial/non-partial CCs", ({ context, expect }) => { + const { driver } = context; const cc1 = new BasicCCSet({ nodeId: 2, targetValue: 25 }); const cc = new SecurityCCCommandEncapsulation({ nodeId: 2, @@ -179,11 +186,11 @@ test.serial("supports nested partial/non-partial CCs", (t) => { const msg = new ApplicationCommandRequest({ command: cc, }); - t.true(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(true); }); -test.serial("supports nested partial/partial CCs (part 1)", (t) => { - const { driver } = t.context; +test.sequential("supports nested partial/partial CCs (part 1)", ({ context, expect }) => { + const { driver } = context; const cc = new SecurityCCCommandEncapsulation({ nodeId: 2, encapsulated: {} as any, @@ -202,11 +209,11 @@ test.serial("supports nested partial/partial CCs (part 1)", (t) => { const msg = new ApplicationCommandRequest({ command: cc, }); - t.false(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(false); }); -test.serial("supports nested partial/partial CCs (part 2)", (t) => { - const { driver } = t.context; +test.sequential("supports nested partial/partial CCs (part 2)", ({ context, expect }) => { + const { driver } = context; const cc = new SecurityCCCommandEncapsulation({ nodeId: 2, encapsulated: {} as any, @@ -225,13 +232,13 @@ test.serial("supports nested partial/partial CCs (part 2)", (t) => { const msg = new ApplicationCommandRequest({ command: cc, }); - t.true(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(true); }); -test.serial( +test.sequential( "returns false when a partial CC throws Deserialization_NotImplemented during merging", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const cc = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -254,14 +261,14 @@ test.serial( const msg = new ApplicationCommandRequest({ command: cc, }); - t.false(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(false); }, ); -test.serial( +test.sequential( "returns false when a partial CC throws CC_NotImplemented during merging", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const cc = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -284,14 +291,14 @@ test.serial( const msg = new ApplicationCommandRequest({ command: cc, }); - t.false(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(false); }, ); -test.serial( +test.sequential( "returns false when a partial CC throws PacketFormat_InvalidPayload during merging", - (t) => { - const { driver } = t.context; + ({ context, expect }) => { + const { driver } = context; const cc = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -314,12 +321,12 @@ test.serial( const msg = new ApplicationCommandRequest({ command: cc, }); - t.false(driver["assemblePartialCCs"](msg)); + expect(driver["assemblePartialCCs"](msg)).toBe(false); }, ); -test.serial("passes other errors during merging through", (t) => { - const { driver } = t.context; +test.sequential("passes other errors during merging through", ({ context, expect }) => { + const { driver } = context; const cc = CommandClass.parse( Uint8Array.from([ CommandClasses.Association, @@ -339,5 +346,6 @@ test.serial("passes other errors during merging through", (t) => { const msg = new ApplicationCommandRequest({ command: cc, }); - t.throws(() => driver["assemblePartialCCs"](msg), { message: /invalid/ }); + expect(() => driver["assemblePartialCCs"](msg)) + .toThrow("invalid"); }); diff --git a/packages/zwave-js/src/lib/test/driver/bootloaderDetection.test.ts b/packages/zwave-js/src/lib/test/driver/bootloaderDetection.test.ts index 58a43e3cd384..95333ee16136 100644 --- a/packages/zwave-js/src/lib/test/driver/bootloaderDetection.test.ts +++ b/packages/zwave-js/src/lib/test/driver/bootloaderDetection.test.ts @@ -1,7 +1,7 @@ import { Bytes } from "@zwave-js/shared"; import { type MockControllerBehavior } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "The bootloader is detected when received in smaller chunks", @@ -41,7 +41,7 @@ BL >\0`, }, testBody: async (t, driver, node, mockController, mockNode) => { - t.true(driver.isInBootloader()); + t.expect(driver.isInBootloader()).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/computeNetCCPayloadSize.test.ts b/packages/zwave-js/src/lib/test/driver/computeNetCCPayloadSize.test.ts index a44fc72e6362..22c6f8c0f488 100644 --- a/packages/zwave-js/src/lib/test/driver/computeNetCCPayloadSize.test.ts +++ b/packages/zwave-js/src/lib/test/driver/computeNetCCPayloadSize.test.ts @@ -4,45 +4,53 @@ import { SecurityCCCommandEncapsulation } from "@zwave-js/cc/SecurityCC"; import { EncapsulationFlags, TransmitOptions } from "@zwave-js/core"; import { SendDataRequest } from "@zwave-js/serial/serialapi"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.beforeEach(async (t) => { - t.timeout(30000); - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - skipNodeInterview: true, - securityKeys: { - S0_Legacy: new Uint8Array(16).fill(0xff), - }, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipNodeInterview: true, + securityKeys: { + S0_Legacy: new Uint8Array(16).fill(0xff), + }, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test("should compute the correct net payload sizes", (t) => { - const { driver } = t.context; +test("should compute the correct net payload sizes", ({ context, expect }) => { + const { driver } = context; const testMsg1 = new SendDataRequest({ command: new SecurityCCCommandEncapsulation({ nodeId: 2, @@ -51,7 +59,7 @@ test("should compute the correct net payload sizes", (t) => { transmitOptions: TransmitOptions.DEFAULT, }); testMsg1.command!.encapsulated = undefined as any; - t.is(driver.computeNetCCPayloadSize(testMsg1), 26); + expect(driver.computeNetCCPayloadSize(testMsg1)).toBe(26); const multiChannelCC = new MultiChannelCCCommandEncapsulation({ nodeId: 2, @@ -66,11 +74,11 @@ test("should compute the correct net payload sizes", (t) => { transmitOptions: TransmitOptions.NoRoute, }); multiChannelCC.encapsulated = undefined as any; - t.is(driver.computeNetCCPayloadSize(testMsg2), 54 - 20 - 4); + expect(driver.computeNetCCPayloadSize(testMsg2)).toBe(54 - 20 - 4); const testMsg3 = new FirmwareUpdateMetaDataCC({ nodeId: 2, }); testMsg3.toggleEncapsulationFlag(EncapsulationFlags.Security, true); - t.is(driver.computeNetCCPayloadSize(testMsg3), 46 - 20 - 2); + expect(driver.computeNetCCPayloadSize(testMsg3)).toBe(46 - 20 - 2); }); diff --git a/packages/zwave-js/src/lib/test/driver/configImportFallback.test.ts b/packages/zwave-js/src/lib/test/driver/configImportFallback.test.ts index c737749ad27f..74c3856ad413 100644 --- a/packages/zwave-js/src/lib/test/driver/configImportFallback.test.ts +++ b/packages/zwave-js/src/lib/test/driver/configImportFallback.test.ts @@ -1,6 +1,6 @@ import { CommandClasses } from "@zwave-js/core"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "$imports from user-defined config files fall back to the internal DB", @@ -37,8 +37,8 @@ integrationTest( const param1 = node.deviceConfig?.paramInformation?.get({ parameter: 1, }); - t.is(param1?.label, "Param 1"); - t.is(param1!.options?.length, 2); + t.expect(param1?.label).toBe("Param 1"); + t.expect(param1!.options?.length).toBe(2); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/controllerJammed.test.ts b/packages/zwave-js/src/lib/test/driver/controllerJammed.test.ts index 5a7023b04c3f..61fd0610d368 100644 --- a/packages/zwave-js/src/lib/test/driver/controllerJammed.test.ts +++ b/packages/zwave-js/src/lib/test/driver/controllerJammed.test.ts @@ -14,18 +14,33 @@ import { SendDataRequestTransmitReport, SendDataResponse, } from "@zwave-js/serial/serialapi"; -import { type MockControllerBehavior } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { + type MockControllerBehavior, + type MockControllerCapabilities, + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; import sinon from "sinon"; import { MockControllerCommunicationState, MockControllerStateKeys, -} from "../../controller/MockControllerState"; -import { integrationTest } from "../integrationTestSuite"; -import { integrationTest as integrationTestMulti } from "../integrationTestSuiteMulti"; +} from "../../controller/MockControllerState.js"; +import { integrationTest } from "../integrationTestSuite.js"; +import { integrationTest as integrationTestMulti } from "../integrationTestSuiteMulti.js"; let shouldFail = false; +const controllerCapabilitiesNoBridge: MockControllerCapabilities = { + // No support for Bridge API: + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), +}; + integrationTest("update the controller status and wait if TX status is Fail", { // debug: true, // provisioningDirectory: path.join( @@ -33,6 +48,8 @@ integrationTest("update the controller status and wait if TX status is Fail", { // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -121,8 +138,8 @@ integrationTest("update the controller status and wait if TX status is Fail", { await wait(500); // The controller should now be jammed, but the node's status must not change - t.is(driver.controller.status, ControllerStatus.Jammed); - t.is(node.status, NodeStatus.Alive); + t.expect(driver.controller.status).toBe(ControllerStatus.Jammed); + t.expect(node.status).toBe(NodeStatus.Alive); setTimeout(() => { shouldFail = false; @@ -130,11 +147,11 @@ integrationTest("update the controller status and wait if TX status is Fail", { await promise; - t.is(driver.controller.status, ControllerStatus.Ready); - t.is(node.status, NodeStatus.Alive); + t.expect(driver.controller.status).toBe(ControllerStatus.Ready); + t.expect(node.status).toBe(NodeStatus.Alive); sinon.assert.notCalled(nodeDead); - t.deepEqual(statusChanges, [ + t.expect(statusChanges).toStrictEqual([ ControllerStatus.Jammed, ControllerStatus.Ready, ]); @@ -150,6 +167,8 @@ integrationTest( // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -244,8 +263,8 @@ integrationTest( await wait(500); // The controller should now be jammed, but the node's status must not change - t.is(driver.controller.status, ControllerStatus.Jammed); - t.is(node.status, NodeStatus.Alive); + t.expect(driver.controller.status).toBe(ControllerStatus.Jammed); + t.expect(node.status).toBe(NodeStatus.Alive); // After soft-resetting (done automatically), the controller should be sending normally again await promise; @@ -254,11 +273,11 @@ integrationTest( msg.functionType === FunctionType.SoftReset ); - t.is(driver.controller.status, ControllerStatus.Ready); - t.is(node.status, NodeStatus.Alive); + t.expect(driver.controller.status).toBe(ControllerStatus.Ready); + t.expect(node.status).toBe(NodeStatus.Alive); sinon.assert.notCalled(nodeDead); - t.deepEqual(statusChanges, [ + t.expect(statusChanges).toStrictEqual([ ControllerStatus.Jammed, ControllerStatus.Ready, ]); @@ -282,6 +301,7 @@ integrationTestMulti( }, controllerCapabilities: { + ...controllerCapabilitiesNoBridge, // 500 series controller, where the soft-reset workaround does not make sense libraryVersion: "Z-Wave 6.84", zwaveChipType: getZWaveChipType(0x05, 0x00), @@ -378,7 +398,7 @@ integrationTestMulti( // Commands to node 2 will fail forever await assertZWaveError( - t, + t.expect, () => node2.commandClasses.Basic.set(99), { errorCode: ZWaveErrorCodes.Controller_MessageDropped, @@ -386,7 +406,7 @@ integrationTestMulti( ); // But commands to node 3 should still continue afterwards - t.true(await node3.ping()); + t.expect(await node3.ping()).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/createCCValuesUsingKnownVersion.test.ts b/packages/zwave-js/src/lib/test/driver/createCCValuesUsingKnownVersion.test.ts index 42219793a1f7..ca213369b1da 100644 --- a/packages/zwave-js/src/lib/test/driver/createCCValuesUsingKnownVersion.test.ts +++ b/packages/zwave-js/src/lib/test/driver/createCCValuesUsingKnownVersion.test.ts @@ -1,9 +1,9 @@ import { BatteryCCReport, BatteryCCValues } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro for https://github.com/zwave-js/node-zwave-js/issues/5252 // Here, a Battery report is received before the node's CC version is known @@ -39,7 +39,7 @@ integrationTest("CC values are created using the known CC version", { // The level value should be defined because it is included in the report // The overheating value shouldn't, since the interview is not complete - t.deepEqual(updatedMetadata, [ + t.expect(updatedMetadata).toStrictEqual([ levelValue.id.property, isLowValue.id.property, ]); @@ -49,11 +49,11 @@ integrationTest("CC values are created using the known CC version", { .getDefinedValueIDs() .filter((id) => id.commandClass === CommandClasses.Battery) .map((id) => id.property); - t.deepEqual(definedProperties, [ + t.expect(definedProperties).toStrictEqual([ levelValue.id.property, isLowValue.id.property, ]); - t.is(node.getValue(levelValue.id), 0); + t.expect(node.getValue(levelValue.id)).toBe(0); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/getNextCallbackId.test.ts b/packages/zwave-js/src/lib/test/driver/getNextCallbackId.test.ts index 250b6a99a405..0a0c856eaf7d 100644 --- a/packages/zwave-js/src/lib/test/driver/getNextCallbackId.test.ts +++ b/packages/zwave-js/src/lib/test/driver/getNextCallbackId.test.ts @@ -1,31 +1,39 @@ -import ava, { type TestFn } from "ava"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; +import { test as baseTest } from "vitest"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; -interface TestContext { - driver: Driver; +interface LocalTestContext { + context: { + driver: Driver; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.beforeEach(async (t) => { - t.timeout(30000); - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - skipControllerIdentification: true, - skipNodeInterview: true, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipControllerIdentification: true, + skipNodeInterview: true, + }); + context.driver = driver; + + // Run tests + await use(context); -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test("the automatically created callback ID should be incremented and wrap from 0xff back to 1", (t) => { - const { driver } = t.context; +test("the automatically created callback ID should be incremented and wrap from 0xff back to 1", ({ context, expect }) => { + const { driver } = context; let lastCallbackId: number | undefined; for (let i = 0; i <= 300; i++) { if (i === 300) { @@ -35,10 +43,10 @@ test("the automatically created callback ID should be incremented and wrap from } const nextCallbackId = driver.getNextCallbackId(); if (lastCallbackId === 0xff) { - t.is(nextCallbackId, 1); + expect(nextCallbackId).toBe(1); break; } else if (lastCallbackId != null) { - t.is(nextCallbackId, lastCallbackId + 1); + expect(nextCallbackId).toBe(lastCallbackId + 1); } lastCallbackId = nextCallbackId; } diff --git a/packages/zwave-js/src/lib/test/driver/handleNonImplementedCCs.test.ts b/packages/zwave-js/src/lib/test/driver/handleNonImplementedCCs.test.ts index d33ec54f0938..8298d4300174 100644 --- a/packages/zwave-js/src/lib/test/driver/handleNonImplementedCCs.test.ts +++ b/packages/zwave-js/src/lib/test/driver/handleNonImplementedCCs.test.ts @@ -2,7 +2,7 @@ import { CommandClass } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Command classes that are not implemented are passed to awaiters before being dropped", @@ -36,7 +36,7 @@ integrationTest( ); const result = await awaited; - t.like(result, { + t.expect(result).toMatchObject({ ccId: CommandClasses["Anti-Theft"], ccCommand: 0x02, payload: Bytes.from([0x00, 0x01]), diff --git a/packages/zwave-js/src/lib/test/driver/handleUnsolicited.test.ts b/packages/zwave-js/src/lib/test/driver/handleUnsolicited.test.ts index 929f77bdfdbc..80d5f6aa5feb 100644 --- a/packages/zwave-js/src/lib/test/driver/handleUnsolicited.test.ts +++ b/packages/zwave-js/src/lib/test/driver/handleUnsolicited.test.ts @@ -1,189 +1,156 @@ -import { BasicCCValues } from "@zwave-js/cc/BasicCC"; -import { MessageHeaders } from "@zwave-js/serial"; -import type { MockSerialPort } from "@zwave-js/serial/mock"; -import { Bytes, type ThrowingMap, createThrowingMap } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; -import type { Driver } from "../../driver/Driver"; -import { ZWaveNode } from "../../node/Node"; -import { createAndStartDriver } from "../utils"; -import { isFunctionSupported_NoBridge } from "./fixtures"; - -interface TestContext { - driver: Driver; - serialport: MockSerialPort; -} - -const test = ava as TestFn; - -test.beforeEach(async (t) => { - t.timeout(5000); - - const { driver, serialport } = await createAndStartDriver(); - - driver["_controller"] = { - ownNodeId: 1, - isFunctionSupported: isFunctionSupported_NoBridge, - nodes: createThrowingMap(), - incrementStatistics: () => {}, - removeAllListeners: () => {}, - } as any; - - t.context = { driver, serialport }; -}); - -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); -}); - -process.env.LOGLEVEL = "debug"; - -test.serial( +import { BasicCCSet, BasicCCValues } from "@zwave-js/cc/BasicCC"; +import { FunctionType, SendDataResponse } from "@zwave-js/serial"; +import { + type MockControllerBehavior, + createMockZWaveRequestFrame, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; + +integrationTest( "unsolicited commands which need special handling are passed to Node.handleCommand", - async (t) => { - const { driver, serialport } = t.context; + { // Repro from #4467 - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - 2, - node2, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node2["isListening"] = true; - node2["isFrequentListening"] = false; - node2.markAsAlive(); - - const valueId = BasicCCValues.currentValue.id; - t.is(node2.getValue(valueId), undefined); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - serialport.receiveData(Bytes.from("01090004000203200105d7", "hex")); - // « [Node 002] [REQ] [ApplicationCommand] - // └─[BasicCCSet] - // target value: 5 - t.deepEqual(serialport.lastWrite, ACK); - await wait(10); - t.deepEqual(node2.getValue(valueId), 5); + // debug: true, + + additionalDriverOptions: { + testingHooks: { + skipBootloaderCheck: true, + skipNodeInterview: true, + }, + }, + + async testBody(t, driver, node, mockController, mockNode) { + const value = BasicCCValues.currentValue; + t.expect(node.getValue(value.id)).toBeUndefined(); + + const cc = new BasicCCSet({ + nodeId: node.id, + targetValue: 5, + }); + mockNode.sendToController( + createMockZWaveRequestFrame(cc, { + ackRequested: false, + }), + ); + + await new Promise((resolve) => { + node.on("value added", (node, args) => { + if (value.is(args) && args.newValue === 5) resolve(); + }); + }); + }, }, ); -test.serial( +integrationTest( "unsolicited commands are passed to Node.handleCommand while waiting for a controller response", - async (t) => { - const { driver, serialport } = t.context; + { // Repro from #4467 - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - 2, - node2, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node2["isListening"] = true; - node2["isFrequentListening"] = false; - node2.markAsAlive(); - - const valueId = BasicCCValues.currentValue.id; - t.is(node2.getValue(valueId), undefined); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - // Step 1: Send a ping and receive the response - node2.ping(); - await wait(1); - // » [Node 002] [REQ] [SendData] - // │ transmit options: 0x25 - // │ callback id: 1 - // └─[NoOperationCC] - t.deepEqual( - serialport.lastWrite, - Bytes.from("010800130201002501c3", "hex"), - ); - await wait(10); - serialport.receiveData(ACK); - - await wait(10); - - // We're now waiting for a response. The next command must not get lost - - serialport.receiveData(Bytes.from("01090004000203200105d7", "hex")); - // « [Node 002] [REQ] [ApplicationCommand] - // └─[BasicCCSet] - // target value: 5 - t.deepEqual(serialport.lastWrite, ACK); - await wait(10); - t.deepEqual(node2.getValue(valueId), 5); + // debug: true, + + additionalDriverOptions: { + testingHooks: { + skipBootloaderCheck: true, + skipNodeInterview: true, + }, + }, + + async customSetup(driver, mockController, mockNode) { + const noSendDataResponse: MockControllerBehavior = { + onHostMessage(controller, msg) { + if (msg.functionType === FunctionType.SendData) { + // Ignore + return true; + } + }, + }; + mockController.defineBehavior(noSendDataResponse); + }, + + async testBody(t, driver, node, mockController, mockNode) { + const value = BasicCCValues.currentValue; + t.expect(node.getValue(value.id)).toBeUndefined(); + + node.ping(); + + const cc = new BasicCCSet({ + nodeId: node.id, + targetValue: 5, + }); + mockNode.sendToController( + createMockZWaveRequestFrame(cc, { + ackRequested: false, + }), + ); + + await new Promise((resolve) => { + node.on("value added", (node, args) => { + if (value.is(args) && args.newValue === 5) resolve(); + }); + }); + }, }, ); -test.serial( +integrationTest( "unsolicited commands are passed to Node.handleCommand while waiting for a controller callback", - async (t) => { - const { driver, serialport } = t.context; + { // Repro from #4467 - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - 2, - node2, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node2["isListening"] = true; - node2["isFrequentListening"] = false; - node2.markAsAlive(); - - const valueId = BasicCCValues.currentValue.id; - t.is(node2.getValue(valueId), undefined); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - // Step 1: Send a ping and receive the response - node2.ping(); - await wait(1); - // » [Node 002] [REQ] [SendData] - // │ transmit options: 0x25 - // │ callback id: 1 - // └─[NoOperationCC] - t.deepEqual( - serialport.lastWrite, - Bytes.from("010800130201002501c3", "hex"), - ); - await wait(10); - serialport.receiveData(ACK); - - await wait(10); - - // « [RES] [SendData] - // was sent: true - serialport.receiveData(Bytes.from("0104011301e8", "hex")); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); - - await wait(10); - - // We're now waiting for a callback. The next command must not get lost - - serialport.receiveData(Bytes.from("01090004000203200105d7", "hex")); - // « [Node 002] [REQ] [ApplicationCommand] - // └─[BasicCCSet] - // target value: 5 - t.deepEqual(serialport.lastWrite, ACK); - await wait(10); - t.deepEqual(node2.getValue(valueId), 5); + // debug: true, + + additionalDriverOptions: { + testingHooks: { + skipBootloaderCheck: true, + skipNodeInterview: true, + }, + }, + + async customSetup(driver, mockController, mockNode) { + const noSendDataResponse: MockControllerBehavior = { + async onHostMessage(controller, msg) { + if (msg.functionType === FunctionType.SendData) { + // Notify the host that the message was sent + + const res = new SendDataResponse({ + wasSent: true, + }); + await controller.sendMessageToHost(res); + + // But do not send a callback + return true; + } + }, + }; + mockController.defineBehavior(noSendDataResponse); + }, + + async testBody(t, driver, node, mockController, mockNode) { + const value = BasicCCValues.currentValue; + t.expect(node.getValue(value.id)).toBeUndefined(); + + node.ping(); + + await wait(50); + + const cc = new BasicCCSet({ + nodeId: node.id, + targetValue: 5, + }); + mockNode.sendToController( + createMockZWaveRequestFrame(cc, { + ackRequested: false, + }), + ); + + await new Promise((resolve) => { + node.on("value added", (node, args) => { + if (value.is(args) && args.newValue === 5) resolve(); + }); + }); + }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/hasPendingMessages.test.ts b/packages/zwave-js/src/lib/test/driver/hasPendingMessages.test.ts index 060948ffdd2b..c25d0dcf064c 100644 --- a/packages/zwave-js/src/lib/test/driver/hasPendingMessages.test.ts +++ b/packages/zwave-js/src/lib/test/driver/hasPendingMessages.test.ts @@ -1,53 +1,64 @@ import { CommandClasses, type ValueID } from "@zwave-js/core"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; -interface TestContext { - driver: Driver; - node2: ZWaveNode; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + node2: ZWaveNode; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.beforeEach(async (t) => { - t.timeout(30000); - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - skipNodeInterview: true, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + skipNodeInterview: true, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + const node2 = new ZWaveNode(2, driver); + context.node2 = node2; + (driver.controller.nodes as any as Map).set( + node2.id, + node2, ); - t.context.controller = controller; - }, - }); - const node2 = new ZWaveNode(2, driver); - t.context.node2 = node2; - (driver.controller.nodes as any as Map).set(node2.id, node2); - t.context.driver = driver; -}); + context.driver = driver; -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test("should return true when there is a poll scheduled for a node", (t) => { - const { driver, node2 } = t.context; - t.false(driver["hasPendingMessages"](node2)); +test("should return true when there is a poll scheduled for a node", ({ context, expect }) => { + const { driver, node2 } = context; + expect(driver["hasPendingMessages"](node2)).toBe(false); const valueId: ValueID = { commandClass: CommandClasses.Basic, property: "currentValue", }; node2.schedulePoll(valueId, { timeoutMs: 1000 }); - t.true(driver["hasPendingMessages"](node2)); + expect(driver["hasPendingMessages"](node2)).toBe(true); node2.cancelScheduledPoll(valueId); - t.false(driver["hasPendingMessages"](node2)); + expect(driver["hasPendingMessages"](node2)).toBe(false); }); diff --git a/packages/zwave-js/src/lib/test/driver/highestSecurityClass.test.ts b/packages/zwave-js/src/lib/test/driver/highestSecurityClass.test.ts index ff1324a68050..924981260f3e 100644 --- a/packages/zwave-js/src/lib/test/driver/highestSecurityClass.test.ts +++ b/packages/zwave-js/src/lib/test/driver/highestSecurityClass.test.ts @@ -4,7 +4,7 @@ import { SecurityClass, SecurityManager2, } from "@zwave-js/core"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro for https://github.com/zwave-js/node-zwave-js/issues/6098 @@ -24,9 +24,11 @@ integrationTest(`An insecurely-included node has security class None`, { }, testBody: async (t, driver, node, mockController, mockNode) => { - t.is(node.hasSecurityClass(SecurityClass.S0_Legacy), false); - t.is(node.hasSecurityClass(SecurityClass.S2_AccessControl), false); - t.is(node.getHighestSecurityClass(), SecurityClass.None); + t.expect(node.hasSecurityClass(SecurityClass.S0_Legacy)).toBe(false); + t.expect(node.hasSecurityClass(SecurityClass.S2_AccessControl)).toBe( + false, + ); + t.expect(node.getHighestSecurityClass()).toBe(SecurityClass.None); }, }); @@ -49,9 +51,12 @@ integrationTest( }, testBody: async (t, driver, node, mockController, mockNode) => { - t.is(node.hasSecurityClass(SecurityClass.S0_Legacy), false); - t.is(node.hasSecurityClass(SecurityClass.S2_AccessControl), false); - t.is(node.getHighestSecurityClass(), SecurityClass.None); + t.expect(node.hasSecurityClass(SecurityClass.S0_Legacy)).toBe( + false, + ); + t.expect(node.hasSecurityClass(SecurityClass.S2_AccessControl)) + .toBe(false); + t.expect(node.getHighestSecurityClass()).toBe(SecurityClass.None); }, }, ); @@ -114,14 +119,17 @@ integrationTest( }, testBody: async (t, driver, node, mockController, mockNode) => { - t.is(node.hasSecurityClass(SecurityClass.S0_Legacy), false); - t.is( - node.hasSecurityClass(SecurityClass.S2_Unauthenticated), + t.expect(node.hasSecurityClass(SecurityClass.S0_Legacy)).toBe( false, ); - t.is(node.hasSecurityClass(SecurityClass.S2_Authenticated), false); - t.is(node.hasSecurityClass(SecurityClass.S2_AccessControl), false); - t.is(node.getHighestSecurityClass(), SecurityClass.None); + t.expect( + node.hasSecurityClass(SecurityClass.S2_Unauthenticated), + ).toBe(false); + t.expect(node.hasSecurityClass(SecurityClass.S2_Authenticated)) + .toBe(false); + t.expect(node.hasSecurityClass(SecurityClass.S2_AccessControl)) + .toBe(false); + t.expect(node.getHighestSecurityClass()).toBe(SecurityClass.None); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/ignoreCCVersion0ForKnownSupportedCCs.test.ts b/packages/zwave-js/src/lib/test/driver/ignoreCCVersion0ForKnownSupportedCCs.test.ts index aaab6a3edd2e..af0c491a3ac8 100644 --- a/packages/zwave-js/src/lib/test/driver/ignoreCCVersion0ForKnownSupportedCCs.test.ts +++ b/packages/zwave-js/src/lib/test/driver/ignoreCCVersion0ForKnownSupportedCCs.test.ts @@ -29,8 +29,8 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro for https://github.com/zwave-js/node-zwave-js/issues/6305 @@ -172,7 +172,7 @@ integrationTest( }, testBody: async (t, driver, node, mockController, mockNode) => { - t.true(node.supportsCC(CommandClasses["Security 2"])); + t.expect(node.supportsCC(CommandClasses["Security 2"])).toBe(true); }, }, ); @@ -360,7 +360,7 @@ integrationTest( }, testBody: async (t, driver, node, mockController, mockNode) => { - t.true(node.supportsCC(CommandClasses["Security"])); + t.expect(node.supportsCC(CommandClasses["Security"])).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/invalidPayloadLog.test.ts b/packages/zwave-js/src/lib/test/driver/invalidPayloadLog.test.ts index bef61f32dec9..e4b3831cd556 100644 --- a/packages/zwave-js/src/lib/test/driver/invalidPayloadLog.test.ts +++ b/packages/zwave-js/src/lib/test/driver/invalidPayloadLog.test.ts @@ -1,116 +1,57 @@ -import { - ZWaveLogContainer, - createDefaultTransportFormat, -} from "@zwave-js/core"; +import { createDefaultTransportFormat } from "@zwave-js/core"; import { SpyTransport, assertMessage } from "@zwave-js/core/test"; -import { MessageHeaders } from "@zwave-js/serial"; -import type { MockSerialPort } from "@zwave-js/serial/mock"; -import { Bytes, type ThrowingMap } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; -import MockDate from "mockdate"; -import type { Driver } from "../../driver/Driver"; -import { DriverLogger } from "../../log/Driver"; -import { ZWaveNode } from "../../node/Node"; -import { createAndStartDriver } from "../utils"; -import { isFunctionSupported_NoBridge } from "./fixtures"; - -interface TestContext { - driver: Driver; - serialport: MockSerialPort; - driverLogger: DriverLogger; - spyTransport: SpyTransport; -} - -const test = ava as TestFn; - -// Replace all defined transports with a spy transport -test.before((t) => { - process.env.LOGLEVEL = "debug"; - - const spyTransport = new SpyTransport(); - spyTransport.format = createDefaultTransportFormat(true, true); - const driverLogger = new DriverLogger( - undefined as any, - new ZWaveLogContainer({ - transports: [spyTransport], - }), - ); - // Uncomment this to debug the log outputs manually - // wasSilenced = unsilence(driverLogger); - - MockDate.set(new Date().setHours(0, 0, 0, 0)); - - t.context.driverLogger = driverLogger; - t.context.spyTransport = spyTransport; -}); - -// Don't spam the console when performing the other tests not related to logging -test.after.always((t) => { - t.context.driverLogger.container.updateConfiguration({ enabled: false }); - MockDate.reset(); -}); - -test.beforeEach(async (t) => { - t.timeout(5000); - - const { spyTransport, driverLogger } = t.context; - spyTransport.spy.resetHistory(); - - const { driver, serialport } = await createAndStartDriver(); - - driver["_controller"] = { - ownNodeId: 1, - nodes: new Map(), - incrementStatistics: () => {}, - removeAllListeners: () => {}, - } as any; - driver["_driverLog"] = driverLogger; - (driverLogger as any).driver = driver; - - t.context.driver = driver; - t.context.serialport = serialport; -}); - -test.afterEach(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); -}); - -test("when an invalid CC is received, this is printed in the logs", async (t) => { - const { driver, serialport, spyTransport } = t.context; - - // Use the normal SendData commands - driver["_controller"]!.isFunctionSupported = isFunctionSupported_NoBridge; - - const node33 = new ZWaveNode(33, driver); - (driver.controller.nodes as ThrowingMap).set( - node33.id, - node33, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node33["isListening"] = true; - node33["isFrequentListening"] = false; - node33.markAsAlive(); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - // « [Node 033] [REQ] [ApplicationCommand] - // └─[BinarySensorCCReport] - // type: Motion - // value: true - serialport.receiveData(Bytes.from("010800040021043003e5", "hex")); - await wait(10); - assertMessage(t, spyTransport, { - callNumber: 1, - message: `« [Node 033] [REQ] [ApplicationCommand] +import { FunctionType } from "@zwave-js/serial"; +import { Bytes } from "@zwave-js/shared"; +import { + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; + +const spyTransport = new SpyTransport(); +spyTransport.format = createDefaultTransportFormat(true, true); + +integrationTest( + "when an invalid CC is received, this is printed in the logs", + { + // debug: true, + + // No support for Bridge API: + controllerCapabilities: { + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), + }, + + additionalDriverOptions: { + testingHooks: { + skipNodeInterview: true, + }, + logConfig: { + enabled: true, + logToFile: false, + transports: [spyTransport], + level: "verbose", + }, + }, + + async testBody(t, driver, node, mockController, mockNode) { + spyTransport.spy.resetHistory(); + + await mockController.sendToHost( + Bytes.from("010800040021043003e5", "hex"), + ); + + await wait(100); + assertMessage(t.expect, spyTransport, { + callNumber: 1, + message: `« [Node 033] [REQ] [ApplicationCommand] └─[BinarySensorCCReport] [INVALID]`, - }); - // FIXME: The log message should be BinarySensorCCReport, not BinarySensorCCReport2 - t.deepEqual(serialport.lastWrite, ACK); -}); + }); + }, + }, +); diff --git a/packages/zwave-js/src/lib/test/driver/multiChannelUnknownVersions.test.ts b/packages/zwave-js/src/lib/test/driver/multiChannelUnknownVersions.test.ts index 4c659d2049ee..a3784b87fb6e 100644 --- a/packages/zwave-js/src/lib/test/driver/multiChannelUnknownVersions.test.ts +++ b/packages/zwave-js/src/lib/test/driver/multiChannelUnknownVersions.test.ts @@ -4,7 +4,7 @@ import { } from "@zwave-js/cc"; import { MockZWaveFrameType } from "@zwave-js/testing"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When CC versions are unknown, commands are sent using the highest implemented CC version", @@ -27,8 +27,6 @@ integrationTest( instanceof MultiChannelCCCommandEncapsulation && frame.payload.encapsulated instanceof BinarySwitchCCSet, ); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/multiStageResponseNoTimeout.test.ts b/packages/zwave-js/src/lib/test/driver/multiStageResponseNoTimeout.test.ts index abfd5aa06510..f3577fc9ad4f 100644 --- a/packages/zwave-js/src/lib/test/driver/multiStageResponseNoTimeout.test.ts +++ b/packages/zwave-js/src/lib/test/driver/multiStageResponseNoTimeout.test.ts @@ -13,8 +13,8 @@ import { type MockNodeBehavior, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "GET requests don't time out early if the response is split using the 'more to follow' flag", @@ -72,7 +72,7 @@ integrationTest( async testBody(t, driver, node, mockController, mockNode) { const name = await node.commandClasses.Configuration.getName(1); - t.is(name, "Test parameter"); + t.expect(name).toBe("Test parameter"); }, }, ); @@ -152,7 +152,7 @@ integrationTest( async testBody(t, driver, node, mockController, mockNode) { const name = await node.commandClasses.Configuration.getName(1); - t.is(name, longName); + t.expect(name).toBe(longName); }, }, ); @@ -189,6 +189,6 @@ integrationTest("GET requests DO time out if there's no matching response", { async testBody(t, driver, node, mockController, mockNode) { const name = await node.commandClasses.Configuration.getName(1); - t.is(name, undefined); + t.expect(name).toBeUndefined(); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/multicastOptimisticValueUpdate.test.ts b/packages/zwave-js/src/lib/test/driver/multicastOptimisticValueUpdate.test.ts index eee056f29c39..0f9628c95677 100644 --- a/packages/zwave-js/src/lib/test/driver/multicastOptimisticValueUpdate.test.ts +++ b/packages/zwave-js/src/lib/test/driver/multicastOptimisticValueUpdate.test.ts @@ -1,11 +1,28 @@ import { BinarySwitchCCSet, BinarySwitchCCValues } from "@zwave-js/cc"; import { CommandClasses, NOT_KNOWN, UNKNOWN_STATE } from "@zwave-js/core"; -import { MockZWaveFrameType, ccCaps } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuiteMulti"; +import { FunctionType } from "@zwave-js/serial"; +import { + type MockControllerCapabilities, + MockZWaveFrameType, + ccCaps, + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuiteMulti.js"; // Regression test for #5844 +const controllerCapabilitiesNoBridge: MockControllerCapabilities = { + // No support for Bridge API: + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), +}; + integrationTest("multicast setValue: do optimistic value update after ACK", { // debug: true, // provisioningDirectory: path.join( @@ -13,6 +30,8 @@ integrationTest("multicast setValue: do optimistic value update after ACK", { // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + nodeCapabilities: [ { id: 2, @@ -43,16 +62,18 @@ integrationTest("multicast setValue: do optimistic value update after ACK", { testBody: async (t, driver, nodes, mockController, mockNodes) => { const [node2, node3] = nodes; - t.is(node2.getValue(BinarySwitchCCValues.targetValue.id), NOT_KNOWN); - t.is(node3.getValue(BinarySwitchCCValues.targetValue.id), NOT_KNOWN); - t.is( - node2.getValue(BinarySwitchCCValues.currentValue.id), - UNKNOWN_STATE, + t.expect(node2.getValue(BinarySwitchCCValues.targetValue.id)).toBe( + NOT_KNOWN, ); - t.is( - node3.getValue(BinarySwitchCCValues.currentValue.id), - UNKNOWN_STATE, + t.expect(node3.getValue(BinarySwitchCCValues.targetValue.id)).toBe( + NOT_KNOWN, ); + t.expect( + node2.getValue(BinarySwitchCCValues.currentValue.id), + ).toBe(UNKNOWN_STATE); + t.expect( + node3.getValue(BinarySwitchCCValues.currentValue.id), + ).toBe(UNKNOWN_STATE); const mcGroup = driver.controller.getMulticastGroup([2, 3]); @@ -72,7 +93,11 @@ integrationTest("multicast setValue: do optimistic value update after ACK", { await wait(100); - t.is(node2.getValue(BinarySwitchCCValues.currentValue.id), true); - t.is(node3.getValue(BinarySwitchCCValues.currentValue.id), true); + t.expect(node2.getValue(BinarySwitchCCValues.currentValue.id)).toBe( + true, + ); + t.expect(node3.getValue(BinarySwitchCCValues.currentValue.id)).toBe( + true, + ); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/nodeAsleepBlockNonceReport.test.ts b/packages/zwave-js/src/lib/test/driver/nodeAsleepBlockNonceReport.test.ts index 3cb19c10bc05..a63936f3361c 100644 --- a/packages/zwave-js/src/lib/test/driver/nodeAsleepBlockNonceReport.test.ts +++ b/packages/zwave-js/src/lib/test/driver/nodeAsleepBlockNonceReport.test.ts @@ -10,9 +10,9 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "when a NonceReport does not get delivered, it does not block further nonce requests", @@ -139,8 +139,6 @@ integrationTest( errorMessage: "Expected a Nonce Report to be sent", }, ); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/nodeAsleepMessageOrder.test.ts b/packages/zwave-js/src/lib/test/driver/nodeAsleepMessageOrder.test.ts index 994574552cbe..9e8a93067d5d 100644 --- a/packages/zwave-js/src/lib/test/driver/nodeAsleepMessageOrder.test.ts +++ b/packages/zwave-js/src/lib/test/driver/nodeAsleepMessageOrder.test.ts @@ -11,9 +11,9 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuiteMulti"; +import { integrationTest } from "../integrationTestSuiteMulti.js"; // Repro from #1107 // Node 10's awake timer elapses before its ping is rejected, @@ -86,7 +86,7 @@ integrationTest( mockNode10.ackControllerRequestFrame(); // Ping for 10 should be failed now - t.false(await pingPromise10); + t.expect(await pingPromise10).toBe(false); // Now the ping for 17 should go out await wait(500); @@ -100,10 +100,11 @@ integrationTest( ); // Ping 17 does not get resolved by the other callback - t.is(await Promise.race([pingPromise17, wait(50)]), undefined); + t.expect(await Promise.race([pingPromise17, wait(50)])) + .toBeUndefined(); // And it should fail since we don't ack: - t.false(await pingPromise17); + t.expect(await pingPromise17).toBe(false); }, }, ); @@ -195,7 +196,7 @@ integrationTest( && f.payload instanceof BasicCCGet ); // and return a number - t.is(typeof result?.currentValue, "number"); + t.expect(typeof result?.currentValue).toBe("number"); // Query the node's BASIC state again. This should be handled relatively quickly mockNode10.clearReceivedControllerFrames(); @@ -217,7 +218,7 @@ integrationTest( && f.payload instanceof BasicCCGet ); // and return a number - t.is(typeof result?.currentValue, "number"); + t.expect(typeof result?.currentValue).toBe("number"); }, }, ); @@ -286,7 +287,7 @@ integrationTest( wait(500).then(() => "timeout"), commandToNode17.then(() => "ok"), ]); - t.is(result, "ok"); + t.expect(result).toBe("ok"); // The first command should not have been sent mockNode10.assertReceivedControllerFrame( @@ -315,7 +316,7 @@ integrationTest( wait(500).then(() => "timeout"), commandToNode10.then(() => "ok"), ]); - t.is(result, "ok"); + t.expect(result).toBe("ok"); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/nodeAsleepNoReject.test.ts b/packages/zwave-js/src/lib/test/driver/nodeAsleepNoReject.test.ts index d92785fac513..84d4413eb56e 100644 --- a/packages/zwave-js/src/lib/test/driver/nodeAsleepNoReject.test.ts +++ b/packages/zwave-js/src/lib/test/driver/nodeAsleepNoReject.test.ts @@ -2,9 +2,9 @@ import { BasicCCGet, BasicCCSet } from "@zwave-js/cc"; import { MessagePriority, NodeStatus } from "@zwave-js/core"; import { type SendDataRequest } from "@zwave-js/serial/serialapi"; import { MOCK_FRAME_ACK_TIMEOUT, MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro from #1078 @@ -21,7 +21,7 @@ integrationTest( node2.markAsAwake(); mockNode.autoAckControllerFrames = false; - t.is(node2.status, NodeStatus.Awake); + t.expect(node2.status).toBe(NodeStatus.Awake); const command1 = new BasicCCSet({ nodeId: 2, @@ -51,41 +51,37 @@ integrationTest( ); // The command fails due to no ACK, ... - t.is( + t.expect( await Promise.race([ basicSetPromise1, wait(MOCK_FRAME_ACK_TIMEOUT + 100).then(() => "timeout"), ]), - "timeout", - ); + ).toBe("timeout"); // ...but both should still be in the queue const sendQueue = driver["queue"]; driver.driverLog.sendQueue(sendQueue); - t.is(sendQueue.length, 2); + t.expect(sendQueue.length).toBe(2); // with priority WakeUp - t.is( + t.expect( sendQueue.transactions.get(0)?.priority, - MessagePriority.WakeUp, - ); - t.is( + ).toBe(MessagePriority.WakeUp); + t.expect( sendQueue.transactions.get(1)?.priority, - MessagePriority.WakeUp, - ); - t.is(node2.status, NodeStatus.Asleep); + ).toBe(MessagePriority.WakeUp); + t.expect(node2.status).toBe(NodeStatus.Asleep); // And the order should be correct - t.is( + t.expect( ( (sendQueue.transactions.get(0)?.message as SendDataRequest) .command as BasicCCSet ).targetValue, - 99, - ); - t.true( + ).toBe(99); + t.expect( (sendQueue.transactions.get(1)?.message as SendDataRequest) .command instanceof BasicCCGet, - ); + ).toBe(true); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/nodeAsleepPingResolves.test.ts b/packages/zwave-js/src/lib/test/driver/nodeAsleepPingResolves.test.ts index 2dae0ededf10..0b2f77a731ca 100644 --- a/packages/zwave-js/src/lib/test/driver/nodeAsleepPingResolves.test.ts +++ b/packages/zwave-js/src/lib/test/driver/nodeAsleepPingResolves.test.ts @@ -1,7 +1,7 @@ import { NodeStatus } from "@zwave-js/core"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro from #6062 @@ -17,12 +17,12 @@ integrationTest( testBody: async (t, driver, node2, mockController, mockNode) => { mockNode.autoAckControllerFrames = false; - t.is(node2.status, NodeStatus.Asleep); + t.expect(node2.status).toBe(NodeStatus.Asleep); const pingResult = await Promise.race([ node2.ping(), wait(2000).then(() => "timeout"), ]); - t.is(pingResult, false); + t.expect(pingResult).toBe(false); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/nodeDeadReject.test.ts b/packages/zwave-js/src/lib/test/driver/nodeDeadReject.test.ts index a5d07c6e0b85..bdfe70005c52 100644 --- a/packages/zwave-js/src/lib/test/driver/nodeDeadReject.test.ts +++ b/packages/zwave-js/src/lib/test/driver/nodeDeadReject.test.ts @@ -1,9 +1,9 @@ import { BasicCCGet, BasicCCSet } from "@zwave-js/cc"; import { NodeStatus, ZWaveErrorCodes, assertZWaveError } from "@zwave-js/core"; import { MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When a node does not respond because it is dead, the sendCommand() Promise and all pending commands get rejected (maxSendAttempts: 1)", @@ -18,7 +18,7 @@ integrationTest( node2.markAsAlive(); mockNode.autoAckControllerFrames = false; - t.is(node2.status, NodeStatus.Alive); + t.expect(node2.status).toBe(NodeStatus.Alive); const command1 = new BasicCCSet({ nodeId: 2, @@ -58,15 +58,15 @@ integrationTest( ); // The command should be rejected - await assertZWaveError(t, () => basicSetPromise, { + await assertZWaveError(t.expect, () => basicSetPromise, { errorCode: ZWaveErrorCodes.Controller_CallbackNOK, }); - t.is(node2.status, NodeStatus.Dead); + t.expect(node2.status).toBe(NodeStatus.Dead); driver.driverLog.sendQueue(driver["queue"]); // The second command should be rejected immediately because the node is dead - await assertZWaveError(t, () => basicGetPromise, { + await assertZWaveError(t.expect, () => basicGetPromise, { errorCode: ZWaveErrorCodes.Controller_MessageDropped, }); }, @@ -86,7 +86,7 @@ integrationTest( node2.markAsAlive(); mockNode.autoAckControllerFrames = false; - t.is(node2.status, NodeStatus.Alive); + t.expect(node2.status).toBe(NodeStatus.Alive); const command1 = new BasicCCSet({ nodeId: 2, @@ -126,15 +126,15 @@ integrationTest( ); // The command should be rejected - await assertZWaveError(t, () => basicSetPromise, { + await assertZWaveError(t.expect, () => basicSetPromise, { errorCode: ZWaveErrorCodes.Controller_CallbackNOK, }); - t.is(node2.status, NodeStatus.Dead); + t.expect(node2.status).toBe(NodeStatus.Dead); driver.driverLog.sendQueue(driver["queue"]); // The second command should be rejected immediately because the node is dead - await assertZWaveError(t, () => basicGetPromise, { + await assertZWaveError(t.expect, () => basicGetPromise, { errorCode: ZWaveErrorCodes.Controller_MessageDropped, }); }, @@ -154,7 +154,7 @@ integrationTest( node2.markAsAlive(); mockNode.autoAckControllerFrames = false; - t.is(node2.status, NodeStatus.Alive); + t.expect(node2.status).toBe(NodeStatus.Alive); const basicSetPromise = node2.commandClasses.Basic.set(99); basicSetPromise.then(() => { @@ -182,13 +182,13 @@ integrationTest( ); // The command should be rejected - await assertZWaveError(t, () => basicSetPromise, { + await assertZWaveError(t.expect, () => basicSetPromise, { errorCode: ZWaveErrorCodes.Controller_CallbackNOK, }); - t.is(node2.status, NodeStatus.Dead); + t.expect(node2.status).toBe(NodeStatus.Dead); // The second command should be rejected immediately because the node is dead - await assertZWaveError(t, () => basicGetPromise, { + await assertZWaveError(t.expect, () => basicGetPromise, { errorCode: ZWaveErrorCodes.Controller_MessageDropped, }); }, @@ -208,7 +208,7 @@ integrationTest( node2.markAsAlive(); mockNode.autoAckControllerFrames = false; - t.is(node2.status, NodeStatus.Alive); + t.expect(node2.status).toBe(NodeStatus.Alive); const basicSetPromise = node2.commandClasses.Basic.set(99); basicSetPromise.then(() => { @@ -230,10 +230,10 @@ integrationTest( ); // The command should be rejected - await assertZWaveError(t, () => basicSetPromise, { + await assertZWaveError(t.expect, () => basicSetPromise, { errorCode: ZWaveErrorCodes.Controller_CallbackNOK, }); - t.is(node2.status, NodeStatus.Dead); + t.expect(node2.status).toBe(NodeStatus.Dead); const basicGetPromise = node2.commandClasses.Basic.get(); basicGetPromise.then(() => { @@ -254,11 +254,11 @@ integrationTest( ); // The second command should be rejected separately - await assertZWaveError(t, () => basicGetPromise, { + await assertZWaveError(t.expect, () => basicGetPromise, { errorCode: ZWaveErrorCodes.Controller_CallbackNOK, }); // The node is still dead - t.is(node2.status, NodeStatus.Dead); + t.expect(node2.status).toBe(NodeStatus.Dead); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/nodeUpdateBeforeCallback.test.ts b/packages/zwave-js/src/lib/test/driver/nodeUpdateBeforeCallback.test.ts index a76f267286c0..72f615d32cc4 100644 --- a/packages/zwave-js/src/lib/test/driver/nodeUpdateBeforeCallback.test.ts +++ b/packages/zwave-js/src/lib/test/driver/nodeUpdateBeforeCallback.test.ts @@ -3,9 +3,9 @@ import { type MockNodeBehavior, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Correctly capture node updates that arrive before the SendData callback", @@ -49,7 +49,7 @@ integrationTest( mockNode.defineBehavior(respondToBasicGetWithDelayedAck); const result = await node.commandClasses.Basic.get(); - t.is(result?.currentValue, 55); + t.expect(result?.currentValue).toBe(55); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/notificationPushNoAGI.test.ts b/packages/zwave-js/src/lib/test/driver/notificationPushNoAGI.test.ts index 9a684da3dd2c..b805bd535297 100644 --- a/packages/zwave-js/src/lib/test/driver/notificationPushNoAGI.test.ts +++ b/packages/zwave-js/src/lib/test/driver/notificationPushNoAGI.test.ts @@ -5,7 +5,7 @@ import { } from "@zwave-js/cc/NotificationCC"; import { CommandClasses } from "@zwave-js/core"; import { type MockNodeBehavior, ccCaps } from "@zwave-js/testing"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "Notification CC: Push nodes without AGI support are detected as push, not pull", @@ -53,7 +53,7 @@ integrationTest( const notificationMode = node.getValue( NotificationCCValues.notificationMode.id, ); - t.is(notificationMode, "push"); + t.expect(notificationMode).toBe("push"); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/queryVersionOfEndpointOnlyCCs.test.ts b/packages/zwave-js/src/lib/test/driver/queryVersionOfEndpointOnlyCCs.test.ts index 7406a55d8a60..01df4fb3bb33 100644 --- a/packages/zwave-js/src/lib/test/driver/queryVersionOfEndpointOnlyCCs.test.ts +++ b/packages/zwave-js/src/lib/test/driver/queryVersionOfEndpointOnlyCCs.test.ts @@ -1,5 +1,5 @@ import { CommandClasses } from "@zwave-js/core"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "The version of endpoint-only CCs gets queried during the interview", @@ -54,18 +54,16 @@ integrationTest( }, testBody: async (t, driver, node, mockController, mockNode) => { - t.is( + t.expect( node .getEndpoint(1) ?.getCCVersion(CommandClasses["Binary Switch"]), - 2, - ); - t.is( + ).toBe(2); + t.expect( node .getEndpoint(2) ?.getCCVersion(CommandClasses["Binary Switch"]), - 2, - ); + ).toBe(2); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/reInterviewAssumeAwake.test.ts b/packages/zwave-js/src/lib/test/driver/reInterviewAssumeAwake.test.ts index 1c6cfb43015a..084bc638eca3 100644 --- a/packages/zwave-js/src/lib/test/driver/reInterviewAssumeAwake.test.ts +++ b/packages/zwave-js/src/lib/test/driver/reInterviewAssumeAwake.test.ts @@ -1,8 +1,8 @@ import { WakeUpCCWakeUpNotification } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { createMockZWaveRequestFrame } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("Assume a node to be awake at the start of a re-interview", { // debug: true, @@ -62,7 +62,5 @@ integrationTest("Assume a node to be awake at the start of a re-interview", { }); const wait10s = wait(10000, true); await Promise.race([interviewCompleted, wait10s]); - - t.pass(); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/receiveApplicationCommandHandlerBridge.test.ts b/packages/zwave-js/src/lib/test/driver/receiveApplicationCommandHandlerBridge.test.ts index cb16692ce7e3..5018fde8360a 100644 --- a/packages/zwave-js/src/lib/test/driver/receiveApplicationCommandHandlerBridge.test.ts +++ b/packages/zwave-js/src/lib/test/driver/receiveApplicationCommandHandlerBridge.test.ts @@ -1,123 +1,93 @@ +import { SecurityCCNonceReport } from "@zwave-js/cc"; import { CommandClasses, SecurityManager } from "@zwave-js/core"; -import { MessageHeaders } from "@zwave-js/serial"; -import type { MockSerialPort } from "@zwave-js/serial/mock"; -import { Bytes, type ThrowingMap } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; -import type { Driver } from "../../driver/Driver"; -import { ZWaveNode } from "../../node/Node"; -import { createAndStartDriver } from "../utils"; -import { isFunctionSupported_NoBridge } from "./fixtures"; - -interface TestContext { - driver: Driver; - serialport: MockSerialPort; -} - -const test = ava as TestFn; - -test.beforeEach(async (t) => { - t.timeout(30000); - - const { driver, serialport } = await createAndStartDriver({ - securityKeys: { - S0_Legacy: new Uint8Array(16).fill(0), +import { + BridgeApplicationCommandRequest, + FunctionType, +} from "@zwave-js/serial"; +import { Bytes } from "@zwave-js/shared/safe"; +import { + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { integrationTest } from "../integrationTestSuite.js"; + +integrationTest( + "Node responses in a BridgeApplicationCommandRequest should be understood", + { + // Repro for #1100 - Z-Wave JS uses SendData, the controller responds with + // BridgeApplicationCommandRequest + + // debug: true, + + // The controller does not support the bridge API + controllerCapabilities: { + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), }, - }); - - driver["_securityManager"] = new SecurityManager({ - networkKey: driver.options.securityKeys!.S0_Legacy!, - ownNodeId: 1, - nonceTimeout: driver.options.timeouts.nonce, - }); - - driver["_controller"] = { - ownNodeId: 1, - isFunctionSupported: isFunctionSupported_NoBridge, - nodes: new Map(), - incrementStatistics: () => {}, - removeAllListeners: () => {}, - } as any; - - driver.controller.nodes.getOrThrow = (nodeId: number) => { - const node = driver.controller.nodes.get(nodeId); - if (!node) throw new Error(`Node ${nodeId} not found`); - return node; - }; - - t.context = { driver, serialport }; -}); - -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); -}); - -process.env.LOGLEVEL = "debug"; - -test("Node responses in a BridgeApplicationCommandRequest should be understood", async (t) => { - const { driver, serialport } = t.context; - // Repro for #1100 - const node3 = new ZWaveNode(3, driver); - (driver.controller.nodes as ThrowingMap).set(3, node3); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node3.addCC(CommandClasses.Security, { - isSupported: true, - version: 1, - }); - node3.markAsAlive(); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - const getNoncePromise = node3.commandClasses.Security.getNonce(); - await wait(1); - // » [Node 003] [REQ] [SendData] - // │ transmit options: 0x25 - // │ callback id: 1 - // └─[SecurityCCNonceGet] - t.deepEqual( - serialport.lastWrite, - Bytes.from("0109001303029840250118", "hex"), - ); - await wait(10); - serialport.receiveData(ACK); - - await wait(10); - - // « [RES] [SendData] - // was sent: true - serialport.receiveData(Bytes.from("0104011301e8", "hex")); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); - - await wait(10); - - // « [REQ] [SendData] - // callback id: 1 - // transmit status: OK - serialport.receiveData( - Bytes.from( - "011800130100000100c17f7f7f7f000003000000000301000034", - "hex", - ), - ); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); + nodeCapabilities: { + commandClasses: [CommandClasses.Security], + }, - await wait(10); + additionalDriverOptions: { + testingHooks: { + skipNodeInterview: true, + }, + }, - // BridgeApplicationCommandRequest - serialport.receiveData( - Bytes.from("011300a80001030a98803e55e4b714973b9e00c18b", "hex"), - ); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); + customSetup: async (driver, controller, mockNode) => { + // Create a security manager for the node + const sm0Node = new SecurityManager({ + ownNodeId: mockNode.id, + networkKey: driver.options.securityKeys!.S0_Legacy!, + nonceTimeout: 100000, + }); + mockNode.securityManagers.securityManager = sm0Node; + + // Create a security manager for the controller + const sm0Ctrlr = new SecurityManager({ + ownNodeId: controller.ownNodeId, + networkKey: driver.options.securityKeys!.S0_Legacy!, + nonceTimeout: 100000, + }); + controller.securityManagers.securityManager = sm0Ctrlr; + }, - t.deepEqual(await getNoncePromise, Bytes.from("3e55e4b714973b9e", "hex")); -}); + testBody: async (t, driver, node, mockController, mockNode) => { + node.addCC(CommandClasses.Security, { + isSupported: true, + version: 1, + }); + + const noncePromise = node.commandClasses.Security.getNonce(); + const expectedNonce = Uint8Array.from( + Bytes.from("3e55e4b714973b9e", "hex"), + ); + + const nonceReport = new SecurityCCNonceReport({ + nodeId: node.id, + nonce: expectedNonce, + }); + const response = new BridgeApplicationCommandRequest({ + command: nonceReport, + frameType: "singlecast", + ownNodeId: mockController.ownNodeId, + fromForeignHomeId: false, + isExploreFrame: false, + isForeignFrame: false, + routedBusy: false, + nodeId: node.id, + targetNodeId: mockController.ownNodeId, + }); + + mockController.sendMessageToHost(response, mockNode); + + const nonce = Uint8Array.from((await noncePromise)!); + t.expect(nonce).toStrictEqual(expectedNonce); + }, + }, +); diff --git a/packages/zwave-js/src/lib/test/driver/receiveMessages.test.ts b/packages/zwave-js/src/lib/test/driver/receiveMessages.test.ts index bddc867966ea..2fd57017ea9d 100644 --- a/packages/zwave-js/src/lib/test/driver/receiveMessages.test.ts +++ b/packages/zwave-js/src/lib/test/driver/receiveMessages.test.ts @@ -2,41 +2,51 @@ import { WakeUpCCIntervalSet } from "@zwave-js/cc/WakeUpCC"; import { ApplicationCommandRequest } from "@zwave-js/serial/serialapi"; import { Bytes } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; +import { test as baseTest } from "vitest"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.beforeEach(async (t) => { - t.timeout(30000); - const { driver } = await createAndStartTestingDriver({ - loadConfiguration: false, - // We don't need a real interview for this - skipControllerIdentification: true, - skipNodeInterview: true, - beforeStartup(mockPort) { - t.context.controller = new MockController({ serial: mockPort }); - }, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + loadConfiguration: false, + // We don't need a real interview for this + skipControllerIdentification: true, + skipNodeInterview: true, + beforeStartup(mockPort) { + context.controller = new MockController({ + serial: mockPort, + }); + }, + }); + context.driver = driver; -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test.serial( +test.sequential( "should not crash if a message is received that cannot be deserialized", - async (t) => { - const { driver, controller } = t.context; + async ({ context, expect }) => { + const { driver, controller } = context; const req = new ApplicationCommandRequest({ command: new WakeUpCCIntervalSet({ nodeId: 1, @@ -48,14 +58,13 @@ test.serial( req.serialize(driver["getEncodingContext"]()), ); await controller.expectHostACK(1000); - t.pass(); }, ); -test.serial( +test.sequential( "should correctly handle multiple messages in the receive buffer", - async (t) => { - const { controller } = t.context; + async ({ context, expect }) => { + const { controller } = context; // This buffer contains a SendData transmit report and a ManufacturerSpecific report const data = Bytes.from( "010700130f000002e6010e000400020872050086000200828e", @@ -66,6 +75,5 @@ test.serial( // Ensure the driver ACKed two messages await controller.expectHostACK(1000); await controller.expectHostACK(1000); - t.pass(); }, ); diff --git a/packages/zwave-js/src/lib/test/driver/s0AndS2Encapsulation.test.ts b/packages/zwave-js/src/lib/test/driver/s0AndS2Encapsulation.test.ts index f255ee318a9d..a81db906a041 100644 --- a/packages/zwave-js/src/lib/test/driver/s0AndS2Encapsulation.test.ts +++ b/packages/zwave-js/src/lib/test/driver/s0AndS2Encapsulation.test.ts @@ -20,9 +20,9 @@ import { ZWaveErrorCodes, } from "@zwave-js/core"; import { type MockNodeBehavior, MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("S0 commands are S0-encapsulated, even when S2 is supported", { // debug: true, @@ -203,7 +203,5 @@ integrationTest("S0 commands are S0-encapsulated, even when S2 is supported", { && f.payload.encapsulated instanceof SecurityCCCommandsSupportedGet, ); - - t.pass(); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/s0Encapsulation.test.ts b/packages/zwave-js/src/lib/test/driver/s0Encapsulation.test.ts index f378109ff57b..255b7d50e6a7 100644 --- a/packages/zwave-js/src/lib/test/driver/s0Encapsulation.test.ts +++ b/packages/zwave-js/src/lib/test/driver/s0Encapsulation.test.ts @@ -15,7 +15,7 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("Communication via Security S0 works", { // debug: true, @@ -187,8 +187,6 @@ integrationTest("Communication via Security S0 works", { testBody: async (t, driver, node, mockController, mockNode) => { const result = await node.commandClasses.Basic.get(); - t.is(result?.currentValue, 2); - - t.pass(); + t.expect(result?.currentValue).toBe(2); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/s0EncapsulationTwoNodes.test.ts b/packages/zwave-js/src/lib/test/driver/s0EncapsulationTwoNodes.test.ts index 4d18d128968c..97512298c530 100644 --- a/packages/zwave-js/src/lib/test/driver/s0EncapsulationTwoNodes.test.ts +++ b/packages/zwave-js/src/lib/test/driver/s0EncapsulationTwoNodes.test.ts @@ -15,8 +15,8 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuiteMulti"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuiteMulti.js"; integrationTest( "Security S0 Nonce Get is answered while waiting for a reply from another node", @@ -260,9 +260,7 @@ integrationTest( ); }); - t.is((await basicGet)?.currentValue, 2); - - t.pass(); + t.expect((await basicGet)?.currentValue).toBe(2); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/s2Collisions.test.ts b/packages/zwave-js/src/lib/test/driver/s2Collisions.test.ts index 623664cb10a3..2268e862bed6 100644 --- a/packages/zwave-js/src/lib/test/driver/s2Collisions.test.ts +++ b/packages/zwave-js/src/lib/test/driver/s2Collisions.test.ts @@ -25,9 +25,9 @@ import { type MockZWaveRequestFrame, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "S2 Collisions: Both nodes send at the same time, with supervision", @@ -187,10 +187,10 @@ integrationTest( const currentValue = node.getValue( BinarySwitchCCValues.currentValue.id, ); - t.is(currentValue, true); + t.expect(currentValue).toBe(true); // Ensure the Binary Switch Set causing a collision eventually gets resolved - t.like(p2result, { + t.expect(p2result).toMatchObject({ status: SupervisionStatus.Success, }); }, @@ -327,7 +327,7 @@ integrationTest( // If the collision was handled gracefully, we should now have the value reported by the node const currentValue = node.getValue(BasicCCValues.currentValue.id); - t.is(currentValue, 99); + t.expect(currentValue).toBe(99); }, }, ); @@ -507,8 +507,10 @@ integrationTest( const [turnOffResult, reportResult, confirmationResult] = await Promise.all([turnOff, report, reportConfirmation]); - t.deepEqual(turnOffResult, { status: SupervisionStatus.Success }); - t.not(confirmationResult, undefined); + t.expect(turnOffResult).toStrictEqual({ + status: SupervisionStatus.Success, + }); + t.expect(confirmationResult).toBeDefined(); // // Now create a collision by having both parties send at the same time // const nodeToHost = Security2CC.encapsulate( diff --git a/packages/zwave-js/src/lib/test/driver/secureAndSupervisionEncap.test.ts b/packages/zwave-js/src/lib/test/driver/secureAndSupervisionEncap.test.ts index 889d99bcefad..e1872e5e1e1c 100644 --- a/packages/zwave-js/src/lib/test/driver/secureAndSupervisionEncap.test.ts +++ b/packages/zwave-js/src/lib/test/driver/secureAndSupervisionEncap.test.ts @@ -1,8 +1,8 @@ import { SecurityCCNonceGet } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; -import { SendDataRequest } from "@zwave-js/serial/serialapi"; +import { isSendDataSinglecast } from "@zwave-js/serial/serialapi"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "secure encapsulation should be used when encapsulated command requires it", @@ -44,15 +44,13 @@ integrationTest( // We take the driver asking for a nonce for a sign that it correctly identified the CC as needing S0 mockController.assertReceivedHostMessage( (msg) => - msg instanceof SendDataRequest + isSendDataSinglecast(msg) && msg.command instanceof SecurityCCNonceGet, { errorMessage: "The driver should have sent an S0-encapsulated command", }, ); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/sendCommandProgress.test.ts b/packages/zwave-js/src/lib/test/driver/sendCommandProgress.test.ts index 9a699766c21c..4db35ec97776 100644 --- a/packages/zwave-js/src/lib/test/driver/sendCommandProgress.test.ts +++ b/packages/zwave-js/src/lib/test/driver/sendCommandProgress.test.ts @@ -3,9 +3,9 @@ import { CommandClasses, TransactionState } from "@zwave-js/core"; import sinon from "sinon"; import { getEnumMemberName } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "The progress listener passed to sendCommand gets called with status updates", @@ -42,8 +42,6 @@ integrationTest( sinon.assert.calledWith(onProgress, { state: TransactionState.Completed, }); - - t.pass(); }, }, ); @@ -96,7 +94,7 @@ integrationTest( await wait(200); - t.deepEqual(states, [ + t.expect(states).toStrictEqual([ TransactionState.Queued, TransactionState.Active, TransactionState.Queued, @@ -110,7 +108,7 @@ integrationTest( await wait(200); - t.deepEqual(states, [ + t.expect(states).toStrictEqual([ TransactionState.Queued, TransactionState.Active, TransactionState.Queued, diff --git a/packages/zwave-js/src/lib/test/driver/sendDataAbortAfterTimeout.test.ts b/packages/zwave-js/src/lib/test/driver/sendDataAbortAfterTimeout.test.ts index a9206ca96abd..f038821d623f 100644 --- a/packages/zwave-js/src/lib/test/driver/sendDataAbortAfterTimeout.test.ts +++ b/packages/zwave-js/src/lib/test/driver/sendDataAbortAfterTimeout.test.ts @@ -1,9 +1,14 @@ import { FunctionType } from "@zwave-js/serial"; -import { type MockControllerBehavior } from "@zwave-js/testing"; +import { + type MockControllerBehavior, + type MockControllerCapabilities, + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; import { MockControllerCommunicationState, MockControllerStateKeys, -} from "../../controller/MockControllerState"; +} from "../../controller/MockControllerState.js"; import { TransmitStatus } from "@zwave-js/core"; import { SoftResetRequest } from "@zwave-js/serial/serialapi"; @@ -14,11 +19,21 @@ import { SendDataRequestTransmitReport, SendDataResponse, } from "@zwave-js/serial/serialapi"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; let shouldTimeOut: boolean; let lastCallbackId: number; +const controllerCapabilitiesNoBridge: MockControllerCapabilities = { + // No support for Bridge API: + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), +}; + integrationTest( "Abort transmission if the Send Data callback hasn't been received after the sendDataAbort timeout elapses", { @@ -29,6 +44,8 @@ integrationTest( // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -117,16 +134,16 @@ integrationTest( // await wait(3000); // The ping should eventually fail - t.false(await pingPromise); + t.expect(await pingPromise).toBe(false); mockController.assertReceivedHostMessage( (msg) => msg.functionType === FunctionType.SendDataAbort, ); - t.throws(() => + t.expect(() => mockController.assertReceivedHostMessage( (msg) => msg.functionType === FunctionType.SoftReset, ) - ); + ).toThrow(); // mockController.clearReceivedHostMessages(); @@ -337,8 +354,7 @@ integrationTest( // await firstCommand; // await followupCommand; -// t.pass(); -// }, +// // }, // }, // ); @@ -375,7 +391,7 @@ integrationTest( // // Circumvent the options validation so the test doesn't take forever // driver.options.timeouts.sendDataCallback = 1500; -// await assertZWaveError(t, () => node.requestNodeInfo(), { +// await assertZWaveError(t.expect, () => node.requestNodeInfo(), { // errorCode: ZWaveErrorCodes.Controller_Timeout, // context: "callback", // }); diff --git a/packages/zwave-js/src/lib/test/driver/sendDataFailThrow.test.ts b/packages/zwave-js/src/lib/test/driver/sendDataFailThrow.test.ts index 3e2e91de6aa1..5fb7423eae12 100644 --- a/packages/zwave-js/src/lib/test/driver/sendDataFailThrow.test.ts +++ b/packages/zwave-js/src/lib/test/driver/sendDataFailThrow.test.ts @@ -1,181 +1,70 @@ -import { BasicCCSet } from "@zwave-js/cc"; -import { MessageHeaders } from "@zwave-js/serial"; -import type { MockSerialPort } from "@zwave-js/serial/mock"; -import { Bytes, type ThrowingMap } from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; -import type { Driver } from "../../driver/Driver"; -import { ZWaveNode } from "../../node/Node"; -import { createAndStartDriver } from "../utils"; +import { FunctionType } from "@zwave-js/serial"; import { - isFunctionSupported_All, - isFunctionSupported_NoBridge, -} from "./fixtures"; + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { integrationTest } from "../integrationTestSuite.js"; -interface TestContext { - driver: Driver; - serialport: MockSerialPort; -} - -const test = ava as TestFn; - -test.beforeEach(async (t) => { - t.timeout(5000); - - const { driver, serialport } = await createAndStartDriver(); - - driver["_controller"] = { - ownNodeId: 1, - nodes: new Map(), - incrementStatistics: () => {}, - removeAllListeners: () => {}, - } as any; - - t.context = { driver, serialport }; -}); - -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); -}); - -process.env.LOGLEVEL = "debug"; - -test.serial( +integrationTest( "when a SendData request fails, the `sendMessage/sendCommand` call should be rejected", - async (t) => { - const { driver, serialport } = t.context; - - // Use the normal SendData commands - driver["_controller"]!.isFunctionSupported = - isFunctionSupported_NoBridge; - - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - 2, - node2, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node2["isListening"] = true; - node2["isFrequentListening"] = false; - node2.markAsAlive(); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - const command = new BasicCCSet({ - nodeId: 2, - targetValue: 99, - }); - const promise = driver.sendCommand(command, { - maxSendAttempts: 1, - }); - await wait(1); - - // » [Node 002] [REQ] [SendData] - // │ transmit options: 0x25 - // │ callback id: 1 - // └─[BasicCCSet] - // └─ targetValue: 99 - t.deepEqual( - serialport.lastWrite, - Bytes.from("010a00130203200163250181", "hex"), - ); - await wait(10); - serialport.receiveData(ACK); - - await wait(50); + { + // debug: true, + + controllerCapabilities: { + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), + }, - // « [RES] [SendData] - // was sent: true - serialport.receiveData(Bytes.from("0104011301e8", "hex")); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); + additionalDriverOptions: { + testingHooks: { + skipNodeInterview: true, + }, + }, - await wait(50); + async testBody(t, driver, node, mockController, mockNode) { + mockNode.autoAckControllerFrames = false; - // « [REQ] [SendData] - // callback id: 1 - // transmit status: NoACK - serialport.receiveData(Bytes.from("0107001301010002e9", "hex")); - t.deepEqual(serialport.lastWrite, ACK); + const basicSetPromise = node.commandClasses.Basic.withOptions({ + maxSendAttempts: 1, + }).set(99); - await t.throwsAsync(promise); + await t.expect(basicSetPromise).rejects.toThrowError(); + }, }, ); -test.serial( +integrationTest( "when a SendDataBridge request fails, the `sendMessage/sendCommand` call should be rejected", - async (t) => { - const { driver, serialport } = t.context; - - // Use the normal SendData commands - driver["_controller"]!.isFunctionSupported = isFunctionSupported_All; - - const node2 = new ZWaveNode(2, driver); - (driver.controller.nodes as ThrowingMap).set( - 2, - node2, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - node2["isListening"] = true; - node2["isFrequentListening"] = false; - node2.markAsAlive(); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - const command = new BasicCCSet({ - nodeId: 2, - targetValue: 99, - }); - const promise = driver.sendCommand(command, { - maxSendAttempts: 1, - }); - await wait(1); - - // » [Node 002] [REQ] [SendDataBridge] - // │ source node id: 1 - // │ transmit options: 0x25 - // │ route: 0, 0, 0, 0 - // │ callback id: 1 - // └─[BasicCCSet] - // └─ targetValue: 99 - t.deepEqual( - serialport.lastWrite, - Bytes.from("010f00a90102032001632500000000013f", "hex"), - ); - await wait(10); - serialport.receiveData(ACK); - - await wait(50); + { + // debug: true, + + controllerCapabilities: { + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendData + && ft !== FunctionType.SendDataMulticast, + ), + }, - // « [RES] [SendDataBridge] - // was sent: true - serialport.receiveData(Bytes.from("010401a90152", "hex")); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); + additionalDriverOptions: { + testingHooks: { + skipNodeInterview: true, + }, + }, - await wait(50); + async testBody(t, driver, node, mockController, mockNode) { + mockNode.autoAckControllerFrames = false; - // « [REQ] [SendDataBridge] - // callback id: 1 - // transmit status: NoACK - serialport.receiveData( - Bytes.from( - "011800a90101019e007f7f7f7f7f0101070000000002070000ac", - "hex", - ), - ); - t.deepEqual(serialport.lastWrite, ACK); + const basicSetPromise = node.commandClasses.Basic.withOptions({ + maxSendAttempts: 1, + }).set(99); - await t.throwsAsync(promise); + await t.expect(basicSetPromise).rejects.toThrowError(); + }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/sendDataMissingCallbackAbort.test.ts b/packages/zwave-js/src/lib/test/driver/sendDataMissingCallbackAbort.test.ts index 53e9d33900c7..52df3a813cba 100644 --- a/packages/zwave-js/src/lib/test/driver/sendDataMissingCallbackAbort.test.ts +++ b/packages/zwave-js/src/lib/test/driver/sendDataMissingCallbackAbort.test.ts @@ -1,10 +1,15 @@ import { FunctionType } from "@zwave-js/serial"; -import { type MockControllerBehavior } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { + type MockControllerBehavior, + type MockControllerCapabilities, + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; import { MockControllerCommunicationState, MockControllerStateKeys, -} from "../../controller/MockControllerState"; +} from "../../controller/MockControllerState.js"; import { CommandClasses, @@ -29,12 +34,22 @@ import { } from "@zwave-js/serial/serialapi"; import path from "node:path"; import Sinon from "sinon"; -import { determineNIF } from "../../controller/NodeInformationFrame"; -import { integrationTest } from "../integrationTestSuite"; -import { integrationTest as integrationTestMulti } from "../integrationTestSuiteMulti"; +import { determineNIF } from "../../controller/NodeInformationFrame.js"; +import { integrationTest } from "../integrationTestSuite.js"; +import { integrationTest as integrationTestMulti } from "../integrationTestSuiteMulti.js"; let shouldTimeOut: boolean; +const controllerCapabilitiesNoBridge: MockControllerCapabilities = { + // No support for Bridge API: + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), +}; + integrationTest( "Abort transmission and soft-reset stick if SendData is missing the callback", { @@ -45,6 +60,8 @@ integrationTest( // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -132,7 +149,7 @@ integrationTest( ); // And the ping should eventually succeed - t.true(await pingPromise); + t.expect(await pingPromise).toBe(true); }, }, ); @@ -149,6 +166,8 @@ integrationTest( // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -223,13 +242,13 @@ integrationTest( ); // The ping should eventually fail and the node be marked dead - t.false(await pingPromise); + t.expect(await pingPromise).toBe(false); - t.is(node.status, NodeStatus.Dead); + t.expect(node.status).toBe(NodeStatus.Dead); // The error event should not have been emitted await wait(300); - t.is(errorSpy.callCount, 0); + t.expect(errorSpy.callCount).toBe(0); }, }, ); @@ -244,6 +263,8 @@ integrationTest( // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -334,8 +355,6 @@ integrationTest( // The ping and the followup command should eventually succeed await firstCommand; await followupCommand; - - t.pass(); }, }, ); @@ -374,7 +393,7 @@ integrationTest( driver.options.timeouts.sendDataAbort = 1000; driver.options.timeouts.sendDataCallback = 1500; - await assertZWaveError(t, () => node.requestNodeInfo(), { + await assertZWaveError(t.expect, () => node.requestNodeInfo(), { errorCode: ZWaveErrorCodes.Controller_Timeout, context: "callback", }); @@ -393,6 +412,7 @@ integrationTest( // ), controllerCapabilities: { + ...controllerCapabilitiesNoBridge, // Soft-reset cannot be disabled on 700+ series libraryVersion: "Z-Wave 6.84.0", }, @@ -475,20 +495,20 @@ integrationTest( (msg) => msg.functionType === FunctionType.SendDataAbort, ); // but the stick should NOT have been soft-reset - t.throws(() => + t.expect(() => mockController.assertReceivedHostMessage( (msg) => msg.functionType === FunctionType.SoftReset, ) - ); + ).toThrow(); mockController.clearReceivedHostMessages(); // The first command should be failed - t.is(await firstCommand, ZWaveErrorCodes.Controller_Timeout); + t.expect(await firstCommand).toBe( + ZWaveErrorCodes.Controller_Timeout, + ); // The followup command should eventually succeed await followupCommand; - - t.pass(); }, }, ); @@ -504,6 +524,7 @@ integrationTest( // ), controllerCapabilities: { + ...controllerCapabilitiesNoBridge, // Soft-reset cannot be disabled on 700+ series libraryVersion: "Z-Wave 6.84.0", }, @@ -574,15 +595,19 @@ integrationTest( shouldTimeOut = true; - await assertZWaveError(t, () => node.commandClasses.Basic.set(99), { - errorCode: ZWaveErrorCodes.Controller_Timeout, - context: "callback", - }); + await assertZWaveError( + t.expect, + () => node.commandClasses.Basic.set(99), + { + errorCode: ZWaveErrorCodes.Controller_Timeout, + context: "callback", + }, + ); const aborts = mockController.receivedHostMessages.filter((m) => m.functionType === FunctionType.SendDataAbort ); - t.is(aborts.length, 1); + t.expect(aborts.length).toBe(1); }, }, ); @@ -597,6 +622,8 @@ integrationTestMulti( "fixtures/sendDataMissingCallbackImmediateToSleepingNode", ), + controllerCapabilities: controllerCapabilitiesNoBridge, + nodeCapabilities: [ { id: 2, @@ -715,8 +742,6 @@ integrationTestMulti( await immediateCommand; await followupCommand; - - t.pass(); }, }, ); @@ -731,6 +756,8 @@ integrationTest( // "__fixtures/supervision_binary_switch", // ), + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -815,14 +842,14 @@ integrationTest( }); // And the ping should eventually succeed - t.true(await pingPromise); + t.expect(await pingPromise).toBe(true); // But the transmission should not have been aborted - t.throws(() => + t.expect(() => mockController.assertReceivedHostMessage( (msg) => msg.functionType === FunctionType.SendDataAbort, ) - ); + ).toThrow(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/sendDataMissingResponse.test.ts b/packages/zwave-js/src/lib/test/driver/sendDataMissingResponse.test.ts index a54177c9a97d..d74976f3dd27 100644 --- a/packages/zwave-js/src/lib/test/driver/sendDataMissingResponse.test.ts +++ b/packages/zwave-js/src/lib/test/driver/sendDataMissingResponse.test.ts @@ -1,10 +1,15 @@ import { FunctionType } from "@zwave-js/serial"; -import { type MockControllerBehavior } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { + type MockControllerBehavior, + type MockControllerCapabilities, + getDefaultMockControllerCapabilities, + getDefaultSupportedFunctionTypes, +} from "@zwave-js/testing"; +import { wait } from "alcalzone-shared/async/index.js"; import { MockControllerCommunicationState, MockControllerStateKeys, -} from "../../controller/MockControllerState"; +} from "../../controller/MockControllerState.js"; import { NodeStatus, @@ -18,16 +23,28 @@ import { SendDataRequest, SendDataRequestTransmitReport, } from "@zwave-js/serial/serialapi"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; let shouldTimeOut: boolean; let lastCallbackId: number; +const controllerCapabilitiesNoBridge: MockControllerCapabilities = { + // No support for Bridge API: + ...getDefaultMockControllerCapabilities(), + supportedFunctionTypes: getDefaultSupportedFunctionTypes().filter( + (ft) => + ft !== FunctionType.SendDataBridge + && ft !== FunctionType.SendDataMulticastBridge, + ), +}; + integrationTest( "Abort transmission and wait for callback if SendData is missing the response", { // debug: true, + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -89,7 +106,8 @@ integrationTest( node.markAsAlive(); shouldTimeOut = true; - const basicSetPromise = node.commandClasses.Basic.set(99); + const basicSetPromise = node.commandClasses.Basic.set(99) + .catch((e) => e); await wait(2000); @@ -98,21 +116,21 @@ integrationTest( ); mockController.clearReceivedHostMessages(); - await assertZWaveError(t, () => basicSetPromise, { + await assertZWaveError(t.expect, await basicSetPromise, { errorCode: ZWaveErrorCodes.Controller_Timeout, context: "response", }); // The stick should NOT have been soft-reset await wait(1000); - t.throws(() => + t.expect(() => mockController.assertReceivedHostMessage( (msg) => msg.functionType === FunctionType.SoftReset, ) - ); + ).toThrow(); // And the node should be marked dead - t.is(node.status, NodeStatus.Dead); + t.expect(node.status).toBe(NodeStatus.Dead); }, }, ); @@ -122,6 +140,8 @@ integrationTest( { // debug: true, + controllerCapabilities: controllerCapabilitiesNoBridge, + additionalDriverOptions: { testingHooks: { skipNodeInterview: true, @@ -187,7 +207,6 @@ integrationTest( // And the command should eventually succeed await basicSetPromise; - t.pass(); }, }, ); @@ -390,8 +409,7 @@ integrationTest( // await firstCommand; // await followupCommand; -// t.pass(); -// }, +// // }, // }, // ); @@ -428,7 +446,7 @@ integrationTest( // // Circumvent the options validation so the test doesn't take forever // driver.options.timeouts.sendDataCallback = 1500; -// await assertZWaveError(t, () => node.requestNodeInfo(), { +// await assertZWaveError(t.expect, () => node.requestNodeInfo(), { // errorCode: ZWaveErrorCodes.Controller_Timeout, // context: "callback", // }); diff --git a/packages/zwave-js/src/lib/test/driver/setValueFailedSupervisionGet.test.ts b/packages/zwave-js/src/lib/test/driver/setValueFailedSupervisionGet.test.ts index 07d31ad25340..0553247c7805 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueFailedSupervisionGet.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueFailedSupervisionGet.test.ts @@ -8,8 +8,8 @@ import { } from "@zwave-js/cc"; import { CommandClasses, SupervisionStatus } from "@zwave-js/core"; import { type MockNodeBehavior, MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "setValue with failed supervised command: expect validation GET", @@ -96,8 +96,6 @@ integrationTest( "Node should have sent a BinarySwitchCCReport with currentValue false", }, ); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/setValueNoSupervision.test.ts b/packages/zwave-js/src/lib/test/driver/setValueNoSupervision.test.ts index e956097502aa..56c5325ad77a 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueNoSupervision.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueNoSupervision.test.ts @@ -6,8 +6,8 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { type MockNodeBehavior, MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest("setValue without supervision: expect validation GET", { // debug: true, @@ -73,7 +73,5 @@ integrationTest("setValue without supervision: expect validation GET", { "Node should have sent a BinarySwitchCCReport with currentValue false", }, ); - - t.pass(); }, }); diff --git a/packages/zwave-js/src/lib/test/driver/setValueSucceedAfterFailure.test.ts b/packages/zwave-js/src/lib/test/driver/setValueSucceedAfterFailure.test.ts index 216ec6dadf6f..57855a9356c1 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueSucceedAfterFailure.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueSucceedAfterFailure.test.ts @@ -6,8 +6,8 @@ import { MOCK_FRAME_ACK_TIMEOUT, type MockNodeBehavior, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; // Repro for https://github.com/home-assistant/core/issues/98491 @@ -76,7 +76,7 @@ integrationTest( }, }; - t.is(node2.status, NodeStatus.Alive); + t.expect(node2.status).toBe(NodeStatus.Alive); const basicSetPromise0 = node2.setValue( BasicCCValues.targetValue.endpoint(0), @@ -118,7 +118,7 @@ integrationTest( mockNode.autoAckControllerFrames = true; await basicSetPromise2; - t.is(node2.status, NodeStatus.Alive); + t.expect(node2.status).toBe(NodeStatus.Alive); await wait(10000); }, diff --git a/packages/zwave-js/src/lib/test/driver/setValueSuccessfulSupervisionNoGet.test.ts b/packages/zwave-js/src/lib/test/driver/setValueSuccessfulSupervisionNoGet.test.ts index b33e29ec0735..5b39df891f0b 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueSuccessfulSupervisionNoGet.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueSuccessfulSupervisionNoGet.test.ts @@ -7,9 +7,9 @@ import { } from "@zwave-js/cc"; import { CommandClasses, SupervisionStatus } from "@zwave-js/core"; import { type MockNodeBehavior, MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import sinon from "sinon"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "setValue with successful supervised command: expect NO validation GET", @@ -77,7 +77,7 @@ integrationTest( const currentValue = node.getValue( BinarySwitchCCValues.currentValue.id, ); - t.true(currentValue); + t.expect(currentValue).toBe(true); // And make sure the value event handlers are called sinon.assert.calledWith( diff --git a/packages/zwave-js/src/lib/test/driver/setValueSupervision255Get.test.ts b/packages/zwave-js/src/lib/test/driver/setValueSupervision255Get.test.ts index ff0c5d8d4e75..36d71368453f 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueSupervision255Get.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueSupervision255Get.test.ts @@ -12,8 +12,8 @@ import { MockZWaveFrameType, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "successful supervised setValue(255) with duration: expect validation GET", @@ -171,7 +171,7 @@ integrationTest( const currentValue = node.getValue( MultilevelSwitchCCValues.currentValue.id, ); - t.is(currentValue, 88); + t.expect(currentValue).toBe(88); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/setValueSupervisionSuccessMoreUpdates.test.ts b/packages/zwave-js/src/lib/test/driver/setValueSupervisionSuccessMoreUpdates.test.ts index 37646ee63fec..4ac31c6bc8bc 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueSupervisionSuccessMoreUpdates.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueSupervisionSuccessMoreUpdates.test.ts @@ -6,9 +6,9 @@ import { } from "@zwave-js/cc"; import { CommandClasses, SupervisionStatus } from "@zwave-js/core"; import { type MockNodeBehavior } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import sinon from "sinon"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( `Regression test for #4957: Treat Supervision Report with Success but "more updates follow" as final`, @@ -60,7 +60,7 @@ integrationTest( await wait(500); const setpoint = node.getValue(setpointValueId); - t.is(setpoint, 20); + t.expect(setpoint).toBe(20); // And make sure the value event handlers are called sinon.assert.calledWith( diff --git a/packages/zwave-js/src/lib/test/driver/setValueSupervisionWorking.test.ts b/packages/zwave-js/src/lib/test/driver/setValueSupervisionWorking.test.ts index a5b315070b79..721b74de6f0e 100644 --- a/packages/zwave-js/src/lib/test/driver/setValueSupervisionWorking.test.ts +++ b/packages/zwave-js/src/lib/test/driver/setValueSupervisionWorking.test.ts @@ -14,8 +14,8 @@ import { ccCaps, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( `Regression test for #5825: Update values when "Success" is received after an initial "Working" result`, @@ -81,23 +81,23 @@ integrationTest( const targetValueId = MultilevelSwitchCCValues.targetValue.id; const currentValueId = MultilevelSwitchCCValues.currentValue.id; - t.is(node.getValue(targetValueId), UNKNOWN_STATE); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(UNKNOWN_STATE); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); await node.setValue(targetValueId, 55); - t.is(node.getValue(targetValueId), 55); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(55); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); // Unchanged after 0.5s await wait(500); - t.is(node.getValue(targetValueId), 55); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(55); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); // Updated after 2.5s await wait(2000); - t.is(node.getValue(targetValueId), 55); - t.is(node.getValue(currentValueId), 55); + t.expect(node.getValue(targetValueId)).toBe(55); + t.expect(node.getValue(currentValueId)).toBe(55); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/successfulPingChangeNodeStatus.test.ts b/packages/zwave-js/src/lib/test/driver/successfulPingChangeNodeStatus.test.ts index 4c5f4d61f7fe..4d4926c91d60 100644 --- a/packages/zwave-js/src/lib/test/driver/successfulPingChangeNodeStatus.test.ts +++ b/packages/zwave-js/src/lib/test/driver/successfulPingChangeNodeStatus.test.ts @@ -1,49 +1,8 @@ -import { MessageHeaders } from "@zwave-js/serial"; -import type { MockSerialPort } from "@zwave-js/serial/mock"; -import { - Bytes, - type ThrowingMap, - createThrowingMap, - getEnumMemberName, -} from "@zwave-js/shared"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; -import type { Driver } from "../../driver/Driver"; -import { ZWaveNode } from "../../node/Node"; -import { NodeStatus } from "../../node/_Types"; -import { createAndStartDriver } from "../utils"; -import { isFunctionSupported_NoBridge } from "./fixtures"; - -interface TestContext { - driver: Driver; - serialport: MockSerialPort; -} - -const test = ava as TestFn; - -test.beforeEach(async (t) => { - t.timeout(5000); - - const { driver, serialport } = await createAndStartDriver(); - - driver["_controller"] = { - ownNodeId: 1, - isFunctionSupported: isFunctionSupported_NoBridge, - nodes: createThrowingMap(), - incrementStatistics: () => {}, - removeAllListeners: () => {}, - } as any; - - t.context = { driver, serialport }; -}); - -test.afterEach.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); - driver.removeAllListeners(); -}); +import { getEnumMemberName } from "@zwave-js/shared"; +import { NodeStatus } from "../../node/_Types.js"; +import { integrationTest } from "../integrationTestSuite.js"; -process.env.LOGLEVEL = "debug"; +// https://github.com/zwave-js/node-zwave-js/issues/1364#issuecomment-760006591 for ( const initialStatus of [ @@ -63,85 +22,109 @@ for ( const expectedStatus = canSleep ? NodeStatus.Awake : NodeStatus.Alive; - test.serial( + integrationTest( `When a ping succeeds, the node should be marked awake/alive (Can sleep: ${canSleep}, initial status: ${ getEnumMemberName( NodeStatus, initialStatus, ) })`, - async (t) => { - const { driver, serialport } = t.context; - - // https://github.com/zwave-js/node-zwave-js/issues/1364#issuecomment-760006591 - - const node4 = new ZWaveNode(4, driver); - (driver.controller.nodes as ThrowingMap).set( - node4.id, - node4, - ); - // Add event handlers for the nodes - for (const node of driver.controller.nodes.values()) { - driver["addNodeEventHandlers"](node); - } - - if (canSleep) { - node4["isListening"] = false; - node4["isFrequentListening"] = false; - } else { - node4["isListening"] = true; - node4["isFrequentListening"] = false; - } - - if (initialStatus === NodeStatus.Asleep) { - node4.markAsAsleep(); - } else if (initialStatus === NodeStatus.Dead) { - node4.markAsDead(); - } - t.is(node4.status, initialStatus); - - const ACK = Uint8Array.from([MessageHeaders.ACK]); - - const pingPromise = node4.ping(); - await wait(1); - // » [Node 004] [REQ] [SendData] - // │ transmit options: 0x25 - // │ callback id: 1 - // └─[NoOperationCC] - t.deepEqual( - serialport.lastWrite, - Bytes.from("010800130401002501c5", "hex"), - ); - await wait(10); - serialport.receiveData(ACK); - - await wait(10); - - // « [RES] [SendData] - // was sent: true - serialport.receiveData(Bytes.from("0104011301e8", "hex")); - // » [ACK] - t.deepEqual(serialport.lastWrite, ACK); - - await wait(10); - - // « [REQ] [SendData] - // callback id: 1 - // transmit status: OK - serialport.receiveData( - Bytes.from( - "011800130100000100bd7f7f7f7f010103000000000201000049", - "hex", - ), - ); - t.deepEqual(serialport.lastWrite, ACK); - - await wait(10); - - await pingPromise; - - t.is(node4.status, expectedStatus); + { + // debug: true, + + additionalDriverOptions: { + testingHooks: { + skipNodeInterview: true, + }, + }, + + async testBody(t, driver, node, mockController, mockNode) { + node["isFrequentListening"] = false; + node["isListening"] = !canSleep; + + if (initialStatus === NodeStatus.Asleep) { + node.markAsAsleep(); + } else if (initialStatus === NodeStatus.Dead) { + node.markAsDead(); + } + t.expect(node.status).toBe(initialStatus); + + await node.ping(); + + t.expect(node.status).toBe(expectedStatus); + }, }, + // async ({ context, expect }) => { + // const { driver, serialport } = context; + + // // https://github.com/zwave-js/node-zwave-js/issues/1364#issuecomment-760006591 + + // const node4 = new ZWaveNode(4, driver); + // (driver.controller.nodes as ThrowingMap).set( + // node4.id, + // node4, + // ); + // // Add event handlers for the nodes + // for (const node of driver.controller.nodes.values()) { + // driver["addNodeEventHandlers"](node); + // } + + // if (canSleep) { + // node4["isListening"] = false; + // node4["isFrequentListening"] = false; + // } else { + // node4["isListening"] = true; + // node4["isFrequentListening"] = false; + // } + + // if (initialStatus === NodeStatus.Asleep) { + // node4.markAsAsleep(); + // } else if (initialStatus === NodeStatus.Dead) { + // node4.markAsDead(); + // } + // expect(node4.status).toBe(initialStatus); + + // const ACK = Uint8Array.from([MessageHeaders.ACK]); + + // const pingPromise = node4.ping(); + // await wait(1); + // // » [Node 004] [REQ] [SendData] + // // │ transmit options: 0x25 + // // │ callback id: 1 + // // └─[NoOperationCC] + // expect( + // serialport.lastWrite, + // ).toStrictEqual(Bytes.from("010800130401002501c5", "hex")); + // await wait(10); + // serialport.receiveData(ACK); + + // await wait(10); + + // // « [RES] [SendData] + // // was sent: true + // serialport.receiveData(Bytes.from("0104011301e8", "hex")); + // // » [ACK] + // expect(serialport.lastWrite).toStrictEqual(ACK); + + // await wait(10); + + // // « [REQ] [SendData] + // // callback id: 1 + // // transmit status: OK + // serialport.receiveData( + // Bytes.from( + // "011800130100000100bd7f7f7f7f010103000000000201000049", + // "hex", + // ), + // ); + // expect(serialport.lastWrite).toStrictEqual(ACK); + + // await wait(10); + + // await pingPromise; + + // expect(node4.status).toBe(expectedStatus); + // }, ); } } diff --git a/packages/zwave-js/src/lib/test/driver/supervisionRepeatedReport.test.ts b/packages/zwave-js/src/lib/test/driver/supervisionRepeatedReport.test.ts index 1883f8109adc..16894b6c5787 100644 --- a/packages/zwave-js/src/lib/test/driver/supervisionRepeatedReport.test.ts +++ b/packages/zwave-js/src/lib/test/driver/supervisionRepeatedReport.test.ts @@ -6,7 +6,7 @@ import { import { CommandClasses, SupervisionStatus } from "@zwave-js/core"; import { type MockNodeBehavior } from "@zwave-js/testing"; import path from "node:path"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "value updates work correctly when SupervisionReport is repeated", @@ -64,14 +64,14 @@ integrationTest( let currentValue = node.getValue( MultilevelSwitchCCValues.currentValue.id, ); - t.not(currentValue, 77); + t.expect(currentValue).not.toBe(77); await promise; currentValue = node.getValue( MultilevelSwitchCCValues.currentValue.id, ); - t.is(currentValue, 77); + t.expect(currentValue).toBe(77); // await node.commandClasses["Multilevel Switch"].startLevelChange({ // direction: "up", diff --git a/packages/zwave-js/src/lib/test/driver/targetValueVersionUnknown.test.ts b/packages/zwave-js/src/lib/test/driver/targetValueVersionUnknown.test.ts index eee929d1fc53..3ab6a8ad5b8f 100644 --- a/packages/zwave-js/src/lib/test/driver/targetValueVersionUnknown.test.ts +++ b/packages/zwave-js/src/lib/test/driver/targetValueVersionUnknown.test.ts @@ -6,7 +6,7 @@ import { } from "@zwave-js/cc"; import { CommandClasses } from "@zwave-js/core"; import { type MockNodeBehavior } from "@zwave-js/testing"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( `targetValue properties are exposed for CCs where the version could not be queried`, @@ -52,7 +52,7 @@ integrationTest( const defined = node.getDefinedValueIDs(); const targetValue = BinarySwitchCCValues.targetValue; const existing = defined.find((v) => targetValue.is(v)); - t.not(existing, undefined, "targetValue should be defined"); + t.expect(existing, "targetValue should be defined").toBeDefined(); }, }, ); @@ -88,7 +88,7 @@ integrationTest( const defined = node.getDefinedValueIDs(); const targetValue = BinarySwitchCCValues.targetValue; const existing = defined.find((v) => targetValue.is(v)); - t.not(existing, undefined, "targetValue should be defined"); + t.expect(existing, "targetValue should be defined").toBeDefined(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/unknownValues.test.ts b/packages/zwave-js/src/lib/test/driver/unknownValues.test.ts index a8d0b7d34dae..1399e1d679e0 100644 --- a/packages/zwave-js/src/lib/test/driver/unknownValues.test.ts +++ b/packages/zwave-js/src/lib/test/driver/unknownValues.test.ts @@ -18,8 +18,8 @@ import { ccCaps, createMockZWaveRequestFrame, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest(`Basic Reports with the UNKNOWN state are correctly handled`, { // debug: true, @@ -62,8 +62,8 @@ integrationTest(`Basic Reports with the UNKNOWN state are correctly handled`, { const currentValueId = BasicCCValues.currentValue.id; // At the start, values should be 0 as per the interview - t.is(node.getValue(targetValueId), 0); - t.is(node.getValue(currentValueId), 0); + t.expect(node.getValue(targetValueId)).toBe(0); + t.expect(node.getValue(currentValueId)).toBe(0); // Send an update with UNKNOWN state const cc = new BasicCCReport({ @@ -81,8 +81,8 @@ integrationTest(`Basic Reports with the UNKNOWN state are correctly handled`, { // wait a bit for the change to propagate await wait(100); - t.is(node.getValue(targetValueId), UNKNOWN_STATE); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(UNKNOWN_STATE); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); }, }); @@ -109,8 +109,8 @@ integrationTest( const currentValueId = MultilevelSwitchCCValues.currentValue.id; // At the start, values are not known yet - t.is(node.getValue(targetValueId), UNKNOWN_STATE); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(UNKNOWN_STATE); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); // Send an initial state let cc = new MultilevelSwitchCCReport({ @@ -127,8 +127,8 @@ integrationTest( // wait a bit for the change to propagate await wait(100); - t.is(node.getValue(targetValueId), 0); - t.is(node.getValue(currentValueId), 0); + t.expect(node.getValue(targetValueId)).toBe(0); + t.expect(node.getValue(currentValueId)).toBe(0); // Send an update with UNKNOWN state cc = new MultilevelSwitchCCReport({ @@ -145,8 +145,8 @@ integrationTest( // wait a bit for the change to propagate await wait(100); - t.is(node.getValue(targetValueId), UNKNOWN_STATE); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(UNKNOWN_STATE); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); }, }, ); @@ -181,8 +181,8 @@ integrationTest( const currentValueId = BinarySwitchCCValues.currentValue.id; // At the start, values are not known yet, because the interview was skipped - t.is(node.getValue(targetValueId), NOT_KNOWN); - t.is(node.getValue(currentValueId), NOT_KNOWN); + t.expect(node.getValue(targetValueId)).toBe(NOT_KNOWN); + t.expect(node.getValue(currentValueId)).toBe(NOT_KNOWN); // Send an initial state let cc = new BinarySwitchCCReport({ @@ -200,8 +200,8 @@ integrationTest( // wait a bit for the change to propagate await wait(100); - t.is(node.getValue(targetValueId), false); - t.is(node.getValue(currentValueId), false); + t.expect(node.getValue(targetValueId)).toBe(false); + t.expect(node.getValue(currentValueId)).toBe(false); // Send an update with UNKNOWN state cc = new BinarySwitchCCReport({ @@ -219,8 +219,8 @@ integrationTest( // wait a bit for the change to propagate await wait(100); - t.is(node.getValue(targetValueId), UNKNOWN_STATE); - t.is(node.getValue(currentValueId), UNKNOWN_STATE); + t.expect(node.getValue(targetValueId)).toBe(UNKNOWN_STATE); + t.expect(node.getValue(currentValueId)).toBe(UNKNOWN_STATE); }, }, ); diff --git a/packages/zwave-js/src/lib/test/driver/unresponsiveStick.test.ts b/packages/zwave-js/src/lib/test/driver/unresponsiveStick.test.ts index a3b3009c460a..0ef4dcf403c9 100644 --- a/packages/zwave-js/src/lib/test/driver/unresponsiveStick.test.ts +++ b/packages/zwave-js/src/lib/test/driver/unresponsiveStick.test.ts @@ -6,9 +6,9 @@ import { } from "@zwave-js/serial/serialapi"; import { SoftResetRequest } from "@zwave-js/serial/serialapi"; import { type MockControllerBehavior } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; +import { wait } from "alcalzone-shared/async/index.js"; import Sinon from "sinon"; -import { integrationTest } from "../integrationTestSuite"; +import { integrationTest } from "../integrationTestSuite.js"; let shouldRespond = true; @@ -50,7 +50,7 @@ integrationTest( { supportCheck: false }, ); - t.is(ids.ownNodeId, mockController.ownNodeId); + t.expect(ids.ownNodeId).toBe(mockController.ownNodeId); }, }, ); @@ -94,7 +94,7 @@ integrationTest( await wait(1000); await assertZWaveError( - t, + t.expect, () => driver.sendMessage( new GetControllerIdRequest(), @@ -108,7 +108,7 @@ integrationTest( // The serial port should have been closed and reopened await wait(100); - t.true(serialPortCloseSpy.called); + t.expect(serialPortCloseSpy.called).toBe(true); // FIXME: When closing the serial port, we lose the connection between the mock port instance and the controller // Fix it at some point, then enable the below test. @@ -161,7 +161,7 @@ integrationTest( // The command fails await assertZWaveError( - t, + t.expect, () => driver.sendMessage( new GetControllerIdRequest(), @@ -176,11 +176,11 @@ integrationTest( await wait(500); // And the controller does not get soft-reset - t.throws(() => + t.expect(() => mockController.assertReceivedHostMessage((msg) => msg.functionType === FunctionType.SoftReset ) - ); + ).toThrow(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/integrationTestSuite.ts b/packages/zwave-js/src/lib/test/integrationTestSuite.ts index 2034d10074ff..29734c12a9d7 100644 --- a/packages/zwave-js/src/lib/test/integrationTestSuite.ts +++ b/packages/zwave-js/src/lib/test/integrationTestSuite.ts @@ -6,16 +6,16 @@ import { type MockNode, type MockNodeOptions, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import test, { type ExecutionContext } from "ava"; +import { wait } from "alcalzone-shared/async/index.js"; import crypto from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import type { Driver } from "../driver/Driver"; -import type { PartialZWaveOptions } from "../driver/ZWaveOptions"; -import type { ZWaveNode } from "../node/Node"; -import { prepareDriver, prepareMocks } from "./integrationTestSuiteShared"; +import { type TestContext, test } from "vitest"; +import type { Driver } from "../driver/Driver.js"; +import type { PartialZWaveOptions } from "../driver/ZWaveOptions.js"; +import type { ZWaveNode } from "../node/Node.js"; +import { prepareDriver, prepareMocks } from "./integrationTestSuiteShared.js"; interface IntegrationTestOptions { /** Enable debugging for this integration tests. When enabled, a driver logfile will be written and the test directory will not be deleted after each test. Default: false */ @@ -32,7 +32,7 @@ interface IntegrationTestOptions { mockNode: MockNode, ) => Promise; testBody: ( - t: ExecutionContext, + t: TestContext, driver: Driver, node: ZWaveNode, mockController: MockController, @@ -157,13 +157,12 @@ function suite( // Integration tests need to run in serial, or they might block the serial port on CI const fn = modifier === "only" - ? test.serial.only + ? test.sequential.only : modifier === "skip" - ? test.serial.skip - : test.serial; + ? test.sequential.skip + : test.sequential; fn(name, async (t) => { - t.timeout(30000); - t.teardown(async () => { + t.onTestFinished(async () => { // Give everything a chance to settle before destroying the driver. await wait(100); @@ -176,7 +175,7 @@ function suite( await prepareTest(); await testBody(t, driver, node, mockController, mockNode); - }); + }, 30000); } /** Performs an integration test with a real driver using a mock controller and one mock node */ diff --git a/packages/zwave-js/src/lib/test/integrationTestSuiteMulti.ts b/packages/zwave-js/src/lib/test/integrationTestSuiteMulti.ts index 6b1a288225a0..9ec7096430a1 100644 --- a/packages/zwave-js/src/lib/test/integrationTestSuiteMulti.ts +++ b/packages/zwave-js/src/lib/test/integrationTestSuiteMulti.ts @@ -6,16 +6,16 @@ import { type MockNode, type MockNodeOptions, } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import test, { type ExecutionContext } from "ava"; +import { wait } from "alcalzone-shared/async/index.js"; import crypto from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import type { Driver } from "../driver/Driver"; -import type { PartialZWaveOptions } from "../driver/ZWaveOptions"; -import type { ZWaveNode } from "../node/Node"; -import { prepareDriver, prepareMocks } from "./integrationTestSuiteShared"; +import { type TestContext, test } from "vitest"; +import type { Driver } from "../driver/Driver.js"; +import type { PartialZWaveOptions } from "../driver/ZWaveOptions.js"; +import type { ZWaveNode } from "../node/Node.js"; +import { prepareDriver, prepareMocks } from "./integrationTestSuiteShared.js"; interface IntegrationTestOptions { /** Enable debugging for this integration tests. When enabled, a driver logfile will be written and the test directory will not be deleted after each test. Default: false */ @@ -32,7 +32,7 @@ interface IntegrationTestOptions { mockNodes: MockNode[], ) => Promise; testBody: ( - t: ExecutionContext, + t: TestContext, driver: Driver, nodes: ZWaveNode[], mockController: MockController, @@ -159,13 +159,12 @@ function suite( // Integration tests need to run in serial, or they might block the serial port on CI const fn = modifier === "only" - ? test.serial.only + ? test.sequential.only : modifier === "skip" - ? test.serial.skip - : test.serial; + ? test.sequential.skip + : test.sequential; fn(name, async (t) => { - t.timeout(30000); - t.teardown(async () => { + t.onTestFinished(async () => { // Give everything a chance to settle before destroying the driver. await wait(100); @@ -178,7 +177,7 @@ function suite( await prepareTest(); await testBody(t, driver, nodes, mockController, mockNodes); - }); + }, 30000); } /** Performs an integration test with a real driver using a mock controller and one mock node */ diff --git a/packages/zwave-js/src/lib/test/integrationTestSuiteShared.ts b/packages/zwave-js/src/lib/test/integrationTestSuiteShared.ts index 68ae205f27e1..ae4b9aa40255 100644 --- a/packages/zwave-js/src/lib/test/integrationTestSuiteShared.ts +++ b/packages/zwave-js/src/lib/test/integrationTestSuiteShared.ts @@ -7,38 +7,45 @@ import { type MockNodeOptions, } from "@zwave-js/testing"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { createDefaultMockControllerBehaviors, createDefaultMockNodeBehaviors, -} from "../../Utils"; +} from "../../Utils.js"; import { type CreateAndStartDriverWithMockPortResult, createAndStartDriverWithMockPort, -} from "../driver/DriverMock"; -import { type PartialZWaveOptions } from "../driver/ZWaveOptions"; +} from "../driver/DriverMock.js"; +import { type PartialZWaveOptions } from "../driver/ZWaveOptions.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export function prepareDriver( cacheDir: string = path.join(__dirname, "cache"), logToFile: boolean = false, additionalOptions: PartialZWaveOptions = {}, ): Promise { + // Skipping the bootloader check speeds up tests a lot + additionalOptions.testingHooks ??= {}; + additionalOptions.testingHooks.skipBootloaderCheck = !additionalOptions + .allowBootloaderOnly; + + const logConfig = additionalOptions.logConfig ?? {}; + if (logToFile) { + logConfig.enabled = true; + logConfig.logToFile = true; + logConfig.filename = path.join( + cacheDir, + "logs", + "zwavejs_%DATE%.log", + ); + logConfig.level ??= "debug"; + } + return createAndStartDriverWithMockPort({ ...additionalOptions, portAddress: "/tty/FAKE", - ...(logToFile - ? { - logConfig: { - filename: path.join( - cacheDir, - "logs", - "zwavejs_%DATE%.log", - ), - logToFile: true, - enabled: true, - level: additionalOptions.logConfig?.level ?? "debug", - }, - } - : {}), + logConfig, securityKeys: { S0_Legacy: Bytes.from("0102030405060708090a0b0c0d0e0f10", "hex"), S2_Unauthenticated: Bytes.from( diff --git a/packages/zwave-js/src/lib/test/mocks.ts b/packages/zwave-js/src/lib/test/mocks.ts index ac993ddadc22..9598e48540d8 100644 --- a/packages/zwave-js/src/lib/test/mocks.ts +++ b/packages/zwave-js/src/lib/test/mocks.ts @@ -30,8 +30,8 @@ import { } from "@zwave-js/serial"; import { SendDataRequest } from "@zwave-js/serial/serialapi"; import sinon from "sinon"; -import type { ZWaveNode } from "../node/Node"; -import * as nodeUtils from "../node/utils"; +import type { ZWaveNode } from "../node/Node.js"; +import * as nodeUtils from "../node/utils.js"; const MockRequestMessageWithExpectation_FunctionType = 0xfa as unknown as FunctionType; diff --git a/packages/zwave-js/src/lib/test/node/Node.ccVersions.test.ts b/packages/zwave-js/src/lib/test/node/Node.ccVersions.test.ts index 9352ea9c848d..3a05f9e4e79c 100644 --- a/packages/zwave-js/src/lib/test/node/Node.ccVersions.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.ccVersions.test.ts @@ -1,68 +1,76 @@ import { CommandClasses } from "@zwave-js/core"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.before(async (t) => { - t.timeout(30000); + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test("getCCVersion() should return 0 if a command class is not supported", (t) => { - const { driver } = t.context; +test("getCCVersion() should return 0 if a command class is not supported", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver); - t.is(node.getCCVersion(CommandClasses["Anti-Theft"]), 0); + expect(node.getCCVersion(CommandClasses["Anti-Theft"])).toBe(0); node.destroy(); }); -test("getCCVersion() should return the supported version otherwise", (t) => { - const { driver } = t.context; +test("getCCVersion() should return the supported version otherwise", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver); node.addCC(CommandClasses["Anti-Theft"], { isSupported: true, version: 5, }); - t.is(node.getCCVersion(CommandClasses["Anti-Theft"]), 5); + expect(node.getCCVersion(CommandClasses["Anti-Theft"])).toBe(5); node.destroy(); }); -test("removeCC() should mark a CC as not supported", (t) => { - const { driver } = t.context; +test("removeCC() should mark a CC as not supported", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver); node.addCC(CommandClasses["Anti-Theft"], { isSupported: true, version: 7, }); - t.is(node.getCCVersion(CommandClasses["Anti-Theft"]), 7); + expect(node.getCCVersion(CommandClasses["Anti-Theft"])).toBe(7); node.removeCC(CommandClasses["Anti-Theft"]); - t.is(node.getCCVersion(CommandClasses["Anti-Theft"]), 0); + expect(node.getCCVersion(CommandClasses["Anti-Theft"])).toBe(0); node.destroy(); }); diff --git a/packages/zwave-js/src/lib/test/node/Node.constructor.test.ts b/packages/zwave-js/src/lib/test/node/Node.constructor.test.ts index 033b5d96228d..56ef6506355e 100644 --- a/packages/zwave-js/src/lib/test/node/Node.constructor.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.constructor.test.ts @@ -3,80 +3,88 @@ import "@zwave-js/cc"; import { CommandClasses, ValueDB } from "@zwave-js/core"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { DeviceClass } from "../../node/DeviceClass"; -import { ZWaveNode } from "../../node/Node"; - -interface TestContext { - driver: Driver; - controller: MockController; +import { afterEach, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { DeviceClass } from "../../node/DeviceClass.js"; +import { ZWaveNode } from "../../node/Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; - -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); }, - }); - t.context.driver = driver; -}); - -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + { auto: true }, + ], }); -test.afterEach((t) => { - const { driver } = t.context; +afterEach(({ context, expect }) => { + const { driver } = context; driver.networkCache.clear(); }); -test.serial("stores the given Node ID", (t) => { - const { driver } = t.context; +test.sequential("stores the given Node ID", ({ context, expect }) => { + const { driver } = context; const node1 = new ZWaveNode(1, driver); - t.is(node1.id, 1); + expect(node1.id).toBe(1); const node3 = new ZWaveNode(3, driver); - t.is(node3.id, 3); + expect(node3.id).toBe(3); node1.destroy(); node3.destroy(); }); -test.serial("stores the given device class", (t) => { - const { driver } = t.context; +test.sequential("stores the given device class", ({ context, expect }) => { + const { driver } = context; function makeNode(cls: DeviceClass): ZWaveNode { return new ZWaveNode(1, driver, cls); } const nodeUndef = makeNode(undefined as any); - t.is(nodeUndef.deviceClass, undefined); + expect(nodeUndef.deviceClass).toBeUndefined(); const devCls = new DeviceClass(0x02, 0x01, 0x03); const nodeWithClass = makeNode(devCls); - t.is(nodeWithClass.deviceClass, devCls); - t.is(nodeWithClass.deviceClass?.specific.key, 0x03); + expect(nodeWithClass.deviceClass).toBe(devCls); + expect(nodeWithClass.deviceClass?.specific.key).toBe(0x03); nodeUndef.destroy(); nodeWithClass.destroy(); }); -test.serial("remembers all given command classes", (t) => { - const { driver } = t.context; +test.sequential("remembers all given command classes", ({ context, expect }) => { + const { driver } = context; function makeNode( supportedCCs: CommandClasses[] = [], @@ -98,20 +106,20 @@ test.serial("remembers all given command classes", (t) => { const node = makeNode(supported, controlled); for (const supp of supported) { - t.true(node.supportsCC(supp)); + expect(node.supportsCC(supp)).toBe(true); } for (const ctrl of controlled) { - t.true(node.controlsCC(ctrl)); + expect(node.controlsCC(ctrl)).toBe(true); } node.destroy(); } }); -test.serial("initializes the node's value DB", (t) => { - const { driver } = t.context; +test.sequential("initializes the node's value DB", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(1, driver); - t.true(node.valueDB instanceof ValueDB); + expect(node.valueDB instanceof ValueDB).toBe(true); node.destroy(); }); diff --git a/packages/zwave-js/src/lib/test/node/Node.createCCInstance.test.ts b/packages/zwave-js/src/lib/test/node/Node.createCCInstance.test.ts index 5cbf9b5900aa..1b1e36a3f052 100644 --- a/packages/zwave-js/src/lib/test/node/Node.createCCInstance.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.createCCInstance.test.ts @@ -6,51 +6,65 @@ import { } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.before(async (t) => { - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test("should throw if the CC is not supported", (t) => { - const { driver } = t.context; +test("should throw if the CC is not supported", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver); - assertZWaveError(t, () => node.createCCInstance(CommandClasses.Basic), { - errorCode: ZWaveErrorCodes.CC_NotSupported, - messageMatches: "unsupported", - }); + assertZWaveError( + expect, + () => node.createCCInstance(CommandClasses.Basic), + { + errorCode: ZWaveErrorCodes.CC_NotSupported, + messageMatches: "unsupported", + }, + ); node.destroy(); }); -test("should return a linked instance of the correct CC", (t) => { - const { driver } = t.context; +test("should return a linked instance of the correct CC", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(2, driver); (driver.controller.nodes as ThrowingMap).set( node.id, @@ -59,7 +73,7 @@ test("should return a linked instance of the correct CC", (t) => { node.addCC(CommandClasses.Basic, { isSupported: true }); const cc = node.createCCInstance(BasicCC)!; - t.true(cc instanceof BasicCC); - t.is(cc.getNode(driver), node); + expect(cc instanceof BasicCC).toBe(true); + expect(cc.getNode(driver)).toBe(node); node.destroy(); }); diff --git a/packages/zwave-js/src/lib/test/node/Node.getEndpoint.test.ts b/packages/zwave-js/src/lib/test/node/Node.getEndpoint.test.ts index c06730dc4ea4..8ca17b6cd643 100644 --- a/packages/zwave-js/src/lib/test/node/Node.getEndpoint.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.getEndpoint.test.ts @@ -5,45 +5,53 @@ import { } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { DeviceClass } from "../../node/DeviceClass"; -import { ZWaveNode } from "../../node/Node"; - -interface TestContext { - driver: Driver; - controller: MockController; - node: ZWaveNode; +import { afterEach, beforeEach, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { DeviceClass } from "../../node/DeviceClass.js"; +import { ZWaveNode } from "../../node/Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + node: ZWaveNode; + }; } -const test = ava as TestFn; - -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); }, - }); - t.context.driver = driver; -}); - -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + { auto: true }, + ], }); -test.beforeEach((t) => { - const { driver } = t.context; +beforeEach(({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode( 2, driver, @@ -53,11 +61,11 @@ test.beforeEach((t) => { node.id, node, ); - t.context.node = node; + context.node = node; }); -test.afterEach((t) => { - const { driver, node } = t.context; +afterEach(({ context, expect }) => { + const { driver, node } = context; (driver.controller.nodes as ThrowingMap).delete(node.id); node.valueDB.clear(); @@ -65,23 +73,23 @@ test.afterEach((t) => { driver.networkCache.clear(); }); -test.serial("throws when a negative endpoint index is requested", (t) => { - const { node } = t.context; - assertZWaveError(t, () => node.getEndpoint(-1), { +test.sequential("throws when a negative endpoint index is requested", ({ context, expect }) => { + const { node } = context; + assertZWaveError(expect, () => node.getEndpoint(-1), { errorCode: ZWaveErrorCodes.Argument_Invalid, messageMatches: "must be positive", }); }); -test.serial("returns the node itself when endpoint 0 is requested", (t) => { - const { node } = t.context; - t.is(node.getEndpoint(0), node); +test.sequential("returns the node itself when endpoint 0 is requested", ({ context, expect }) => { + const { node } = context; + expect(node.getEndpoint(0)).toBe(node); }); -test.serial( +test.sequential( "returns a new endpoint with the correct endpoint index otherwise", - (t) => { - const { node } = t.context; + ({ context, expect }) => { + const { node } = context; // interviewComplete needs to be true for getEndpoint to work node.valueDB.setValue( @@ -99,13 +107,13 @@ test.serial( 5, ); const actual = node.getEndpoint(5)!; - t.is(actual.index, 5); - t.is(actual.nodeId, 2); + expect(actual.index).toBe(5); + expect(actual.nodeId).toBe(2); }, ); -test.serial("caches the created endpoint instances", (t) => { - const { node } = t.context; +test.sequential("caches the created endpoint instances", ({ context, expect }) => { + const { node } = context; // interviewComplete needs to be true for getEndpoint to work node.valueDB.setValue( @@ -124,21 +132,21 @@ test.serial("caches the created endpoint instances", (t) => { ); const first = node.getEndpoint(5); const second = node.getEndpoint(5); - t.not(first, undefined); - t.is(first, second); + expect(first).toBeDefined(); + expect(first).toBe(second); }); -test.serial( +test.sequential( "returns undefined if a non-existent endpoint is requested", - (t) => { - const { node } = t.context; + ({ context, expect }) => { + const { node } = context; const actual = node.getEndpoint(5); - t.is(actual, undefined); + expect(actual).toBeUndefined(); }, ); -test.serial("sets the correct device class for the endpoint", async (t) => { - const { node } = t.context; +test.sequential("sets the correct device class for the endpoint", async ({ context, expect }) => { + const { node } = context; // interviewComplete needs to be true for getEndpoint to work node.valueDB.setValue( @@ -169,5 +177,5 @@ test.serial("sets the correct device class for the endpoint", async (t) => { ); const actual = node.getEndpoint(5); - t.is(actual?.deviceClass?.specific.label, "Doorbell"); + expect(actual?.deviceClass?.specific.label).toBe("Doorbell"); }); diff --git a/packages/zwave-js/src/lib/test/node/Node.getSetValue.test.ts b/packages/zwave-js/src/lib/test/node/Node.getSetValue.test.ts index f84bb18d3f7a..2c3211792847 100644 --- a/packages/zwave-js/src/lib/test/node/Node.getSetValue.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.getSetValue.test.ts @@ -3,43 +3,53 @@ import { BasicCC, BasicCCValues } from "@zwave-js/cc/BasicCC"; import { CommandClasses, type ValueID, ValueMetadata } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type ExecutionContext, type TestFn } from "ava"; import sinon from "sinon"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; -import { assertCC } from "../assertCC"; - -interface TestContext { - driver: Driver; - controller: MockController; +import { type TaskContext, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; +import { assertCC } from "../assertCC.js"; + +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; - -test.before(async (t) => { - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); -test.serial("getValue() returns the values stored in the value DB", (t) => { - const { driver } = t.context; +test.sequential("getValue() returns the values stored in the value DB", ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(1, driver); const valueId: ValueID = { @@ -50,13 +60,13 @@ test.serial("getValue() returns the values stored in the value DB", (t) => { node.valueDB.setValue(valueId, 4); - t.is(node.getValue(valueId), 4); + expect(node.getValue(valueId)).toBe(4); node.destroy(); }); -test.serial("setValue() issues the correct xyzCCSet command", async (t) => { - const { driver } = t.context; +test.sequential("setValue() issues the correct xyzCCSet command", async ({ context, expect }) => { + const { driver } = context; // We test with a BasicCC const node = new ZWaveNode(1, driver); @@ -80,10 +90,10 @@ test.serial("setValue() issues the correct xyzCCSet command", async (t) => { 5, ); - t.is(result.status, SetValueStatus.SuccessUnsupervised); + expect(result.status).toBe(SetValueStatus.SuccessUnsupervised); sinon.assert.called(sendMessage); - assertCC(t, sendMessage.getCall(0).args[0], { + assertCC(expect, sendMessage.getCall(0).args[0], { cc: BasicCC, nodeId: node.id, ccValues: { @@ -93,10 +103,10 @@ test.serial("setValue() issues the correct xyzCCSet command", async (t) => { node.destroy(); }); -test.serial( +test.sequential( "setValue() returns false if the CC is not implemented", - async (t) => { - const { driver } = t.context; + async ({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(1, driver); const result = await node.setValue( @@ -107,8 +117,10 @@ test.serial( }, 1, ); - t.is(result.status, SetValueStatus.NotImplemented); - t.regex(result.message!, /Command Class 12245589 is not implemented/); + expect(result.status).toBe(SetValueStatus.NotImplemented); + expect(result.message).toMatch( + /Command Class 12245589 is not implemented/, + ); node.destroy(); }, ); @@ -117,25 +129,28 @@ test.serial( const valueDefinition = BasicCCValues.currentValue; const valueId = BasicCCValues.currentValue.id; - function prepareTest(t: ExecutionContext): ZWaveNode { - const { driver } = t.context; + function prepareTest({ + onTestFinished, + context, + }: Pick & LocalTestContext): ZWaveNode { + const { driver } = context; const node = new ZWaveNode(1, driver); (driver.controller.nodes as ThrowingMap).set( node.id, node, ); - t.teardown(() => node.destroy()); + onTestFinished(() => node.destroy()); return node; } - test.serial( + test.sequential( "getValueMetadata() returns the defined metadata for the given value", - (t) => { - const node = prepareTest(t); + ({ context, expect, onTestFinished }) => { + const node = prepareTest({ onTestFinished, context }); // We test this with the BasicCC // currentValue is readonly, 0-99 const currentValueMeta = node.getValueMetadata(valueId); - t.like(currentValueMeta, { + expect(currentValueMeta).toMatchObject({ readable: true, writeable: false, min: 0, @@ -147,16 +162,16 @@ test.serial( }, ); - test.serial( + test.sequential( "writing to the value DB with setValueMetadata() overwrites the statically defined metadata", - (t) => { - const node = prepareTest(t); + ({ context, expect, onTestFinished }) => { + const node = prepareTest({ onTestFinished, context }); // Create dynamic metadata node.valueDB.setMetadata(valueId, ValueMetadata.WriteOnlyInt32); const currentValueMeta = node.getValueMetadata(valueId); - t.deepEqual(currentValueMeta, { + expect(currentValueMeta).toStrictEqual({ ...ValueMetadata.WriteOnlyInt32, secret: valueDefinition.options.secret, stateful: valueDefinition.options.stateful, @@ -164,10 +179,10 @@ test.serial( }, ); - test.serial( + test.sequential( "writing to the value DB with setValueMetadata() preserves the secret/stateful flags", - (t) => { - const node = prepareTest(t); + ({ context, expect, onTestFinished }) => { + const node = prepareTest({ onTestFinished, context }); // Create dynamic metadata node.valueDB.setMetadata(valueId, { ...ValueMetadata.WriteOnlyInt32, @@ -176,7 +191,7 @@ test.serial( }); const currentValueMeta = node.getValueMetadata(valueId); - t.like(currentValueMeta, { + expect(currentValueMeta).toMatchObject({ secret: valueDefinition.options.secret, stateful: valueDefinition.options.stateful, }); diff --git a/packages/zwave-js/src/lib/test/node/Node.handleCommand.test.ts b/packages/zwave-js/src/lib/test/node/Node.handleCommand.test.ts index 16d13c722b0f..101a31940fd2 100644 --- a/packages/zwave-js/src/lib/test/node/Node.handleCommand.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.handleCommand.test.ts @@ -3,15 +3,15 @@ import { BinarySwitchCCReport } from "@zwave-js/cc/BinarySwitchCC"; import { type EntryControlCCNotification } from "@zwave-js/cc/EntryControlCC"; import { type CommandClassInfo, CommandClasses } from "@zwave-js/core"; import { Bytes } from "@zwave-js/shared"; -import test from "ava"; import sinon from "sinon"; -import type { Driver } from "../../driver/Driver"; -import { ZWaveNode } from "../../node/Node"; +import { beforeEach, test } from "vitest"; +import type { Driver } from "../../driver/Driver.js"; +import { ZWaveNode } from "../../node/Node.js"; import { EntryControlDataTypes, EntryControlEventTypes, -} from "../../node/_Types"; -import { createEmptyMockDriver } from "../mocks"; +} from "../../node/_Types.js"; +import { createEmptyMockDriver } from "../mocks.js"; const fakeDriver = createEmptyMockDriver(); @@ -26,9 +26,9 @@ function makeNode( return node; } -test.beforeEach(() => fakeDriver.sendMessage.resetHistory()); +beforeEach(() => fakeDriver.sendMessage.resetHistory()); -test.serial( +test.sequential( "should map commands from the root endpoint to endpoint 1 if configured", async (t) => { const node = makeNode([ @@ -71,19 +71,19 @@ test.serial( }); await node.handleCommand(command); - t.true( + t.expect( node.getValue({ commandClass: CommandClasses["Binary Switch"], endpoint: 1, property: "currentValue", }), - ); + ).toBe(true); node.destroy(); }, ); -test.serial( +test.sequential( "a notification event is sent when receiving an EntryControlNotification", async (t) => { const node = makeNode([ @@ -133,7 +133,6 @@ test.serial( eventData: "1234", }, ); - t.pass(); node.destroy(); }, diff --git a/packages/zwave-js/src/lib/test/node/Node.interviewOrder.test.ts b/packages/zwave-js/src/lib/test/node/Node.interviewOrder.test.ts index 046495c42fd8..e98847c9ff39 100644 --- a/packages/zwave-js/src/lib/test/node/Node.interviewOrder.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.interviewOrder.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ import { getCCConstructor } from "@zwave-js/cc"; import { CommandClasses, @@ -7,13 +6,12 @@ import { nonApplicationCCs, topologicalSort, } from "@zwave-js/core"; -import test from "ava"; -import { ZWaveNode } from "../../node/Node"; -import { createEmptyMockDriver } from "../mocks"; +import { test } from "vitest"; +import { ZWaveNode } from "../../node/Node.js"; +import { createEmptyMockDriver } from "../mocks.js"; test("the CC interviews happen in the correct order", (t) => { - require("@zwave-js/cc"); - t.not(getCCConstructor(49), undefined); + t.expect(getCCConstructor(49)).toBeDefined(); const fakeDriver = createEmptyMockDriver(); @@ -54,28 +52,26 @@ test("the CC interviews happen in the correct order", (t) => { const rootInterviewOrderPart1 = topologicalSort(rootInterviewGraphPart1); const rootInterviewOrderPart2 = topologicalSort(rootInterviewGraphPart2); - t.deepEqual( + t.expect( rootInterviewOrderPart1.map((cc) => getCCName(cc)), - [ - "Z-Wave Plus Info", - "Device Reset Locally", - "Firmware Update Meta Data", - "CRC-16 Encapsulation", - "Multi Channel", - "Association", - "Multi Channel Association", - "Association Group Information", - ], - ); - t.deepEqual( + ).toStrictEqual([ + "Z-Wave Plus Info", + "Device Reset Locally", + "Firmware Update Meta Data", + "CRC-16 Encapsulation", + "Multi Channel", + "Association", + "Multi Channel Association", + "Association Group Information", + ]); + t.expect( rootInterviewOrderPart2.map((cc) => getCCName(cc)), - [ - "Multilevel Switch", - "Configuration", - "Multilevel Sensor", - "Meter", - "Protection", - "Notification", - ], - ); + ).toStrictEqual([ + "Multilevel Switch", + "Configuration", + "Multilevel Sensor", + "Meter", + "Protection", + "Notification", + ]); }); diff --git a/packages/zwave-js/src/lib/test/node/Node.sendNoMoreInformation.test.ts b/packages/zwave-js/src/lib/test/node/Node.sendNoMoreInformation.test.ts index 7b9a51816b7b..d5da32401233 100644 --- a/packages/zwave-js/src/lib/test/node/Node.sendNoMoreInformation.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.sendNoMoreInformation.test.ts @@ -1,12 +1,12 @@ import { WakeUpCommand } from "@zwave-js/cc"; import { WakeUpCC } from "@zwave-js/cc/WakeUpCC"; import { CommandClasses, InterviewStage } from "@zwave-js/core"; -import test from "ava"; import sinon from "sinon"; -import type { Driver } from "../../driver/Driver"; -import { ZWaveNode } from "../../node/Node"; -import { assertCC } from "../assertCC"; -import { createEmptyMockDriver } from "../mocks"; +import { beforeEach, test } from "vitest"; +import type { Driver } from "../../driver/Driver.js"; +import { ZWaveNode } from "../../node/Node.js"; +import { assertCC } from "../assertCC.js"; +import { createEmptyMockDriver } from "../mocks.js"; const fakeDriver = createEmptyMockDriver(); @@ -19,52 +19,52 @@ function makeNode(): ZWaveNode { return node; } -test.beforeEach(() => fakeDriver.sendMessage.resetHistory()); +beforeEach(() => fakeDriver.sendMessage.resetHistory()); -test.serial( +test.sequential( "should not do anything and return false if the node is asleep", async (t) => { const node = makeNode(); node.markAsAsleep(); - t.false(await node.sendNoMoreInformation()); + t.expect(await node.sendNoMoreInformation()).toBe(false); sinon.assert.notCalled(fakeDriver.sendMessage); node.destroy(); }, ); -test.serial( +test.sequential( "should not do anything and return false if the node interview is not complete", async (t) => { const node = makeNode(); node.interviewStage = InterviewStage.CommandClasses; - t.false(await node.sendNoMoreInformation()); + t.expect(await node.sendNoMoreInformation()).toBe(false); sinon.assert.notCalled(fakeDriver.sendMessage); node.destroy(); }, ); -test.serial( +test.sequential( "should not send anything if the node should be kept awake", async (t) => { const node = makeNode(); node.markAsAwake(); node.keepAwake = true; - t.false(await node.sendNoMoreInformation()); + t.expect(await node.sendNoMoreInformation()).toBe(false); sinon.assert.notCalled(fakeDriver.sendMessage); node.destroy(); }, ); -test.serial("should send a WakeupCC.NoMoreInformation otherwise", async (t) => { +test.sequential("should send a WakeupCC.NoMoreInformation otherwise", async (t) => { const node = makeNode(); node.interviewStage = InterviewStage.Complete; node.markAsAwake(); - t.true(await node.sendNoMoreInformation()); + t.expect(await node.sendNoMoreInformation()).toBe(true); sinon.assert.called(fakeDriver.sendMessage); - assertCC(t, fakeDriver.sendMessage.getCall(0).args[0], { + assertCC(t.expect, fakeDriver.sendMessage.getCall(0).args[0], { cc: WakeUpCC, nodeId: node.id, ccValues: { diff --git a/packages/zwave-js/src/lib/test/node/Node.status.test.ts b/packages/zwave-js/src/lib/test/node/Node.status.test.ts index 9a258ff75a95..7f95024c4020 100644 --- a/packages/zwave-js/src/lib/test/node/Node.status.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.status.test.ts @@ -1,38 +1,48 @@ import { NodeStatus } from "@zwave-js/core"; import { MockController } from "@zwave-js/testing"; -import ava, { type ExecutionContext, type TestFn } from "ava"; import sinon from "sinon"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; -import type { ZWaveNodeEvents } from "../../node/_Types"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; +import type { ZWaveNodeEvents } from "../../node/_Types.js"; -interface TestContext { - driver: Driver; - controller: MockController; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.before(async (t) => { - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); interface TestOptions { @@ -41,43 +51,50 @@ interface TestOptions { } function performTest( - t: ExecutionContext, + context: LocalTestContext["context"], options: TestOptions, ): void { - const node = new ZWaveNode(1, t.context.driver); + const node = new ZWaveNode(1, context.driver); node["_status"] = undefined as any; const spy = sinon.spy(); node.on(options.expectedEvent, spy); node["onStatusChange"](options.targetStatus); node.destroy(); sinon.assert.called(spy); - t.pass(); } test( "Changing the status to awake should raise the wake up event", - performTest, - { - targetStatus: NodeStatus.Awake, - expectedEvent: "wake up", - }, + ({ context }) => + performTest(context, { + targetStatus: NodeStatus.Awake, + expectedEvent: "wake up", + }), ); test( "Changing the status to asleep should raise the sleep event", - performTest, - { - targetStatus: NodeStatus.Asleep, - expectedEvent: "sleep", - }, + ({ context }) => + performTest(context, { + targetStatus: NodeStatus.Asleep, + expectedEvent: "sleep", + }), ); -test("Changing the status to dead should raise the dead event", performTest, { - targetStatus: NodeStatus.Dead, - expectedEvent: "dead", -}); +test( + "Changing the status to dead should raise the dead event", + ({ context }) => + performTest(context, { + targetStatus: NodeStatus.Dead, + expectedEvent: "dead", + }), +); -test("Changing the status to alive should raise the alive event", performTest, { - targetStatus: NodeStatus.Alive, - expectedEvent: "alive", -}); +test( + "Changing the status to alive should raise the alive event", + ({ context }) => + performTest(context, { + targetStatus: NodeStatus.Alive, + expectedEvent: "alive", + }), +); diff --git a/packages/zwave-js/src/lib/test/node/Node.updateNodeInfo.test.ts b/packages/zwave-js/src/lib/test/node/Node.updateNodeInfo.test.ts index 716b6dbddde6..6985372ff54f 100644 --- a/packages/zwave-js/src/lib/test/node/Node.updateNodeInfo.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.updateNodeInfo.test.ts @@ -4,16 +4,18 @@ import "@zwave-js/cc"; import { CommandClasses, InterviewStage, NodeStatus } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; - -interface TestContext { - driver: Driver; - controller: MockController; - makeNode: (canSleep?: boolean) => ZWaveNode; +import { afterEach, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; + +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + makeNode: (canSleep?: boolean) => ZWaveNode; + }; } const emptyNodeInfo = { @@ -21,73 +23,79 @@ const emptyNodeInfo = { controlledCCs: [], }; -const test = ava as TestFn; - -test.before(async (t) => { - t.timeout(30000); - - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; + + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; + + context.makeNode = (canSleep: boolean = false): ZWaveNode => { + const node = new ZWaveNode(2, driver); + node["isListening"] = !canSleep; + node["isFrequentListening"] = false; + // If the node doesn't support Z-Wave+ Info CC, the node instance + // will try to poll the device for changes. We don't want this to happen in tests. + node.addCC(CommandClasses["Z-Wave Plus Info"], { + isSupported: true, + }); + // node.addCC(CommandClasses["Wake Up"], { isSupported: true }); + (driver.controller.nodes as ThrowingMap).set( + node.id, + node, + ); + return node; + }; + + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); }, - }); - t.context.driver = driver; - - t.context.makeNode = (canSleep: boolean = false): ZWaveNode => { - const node = new ZWaveNode(2, driver); - node["isListening"] = !canSleep; - node["isFrequentListening"] = false; - // If the node doesn't support Z-Wave+ Info CC, the node instance - // will try to poll the device for changes. We don't want this to happen in tests. - node.addCC(CommandClasses["Z-Wave Plus Info"], { - isSupported: true, - }); - // node.addCC(CommandClasses["Wake Up"], { isSupported: true }); - (driver.controller.nodes as ThrowingMap).set( - node.id, - node, - ); - return node; - }; -}); - -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + { auto: true }, + ], }); -test.afterEach((t) => { - const { driver } = t.context; +afterEach(({ context, expect }) => { + const { driver } = context; driver.networkCache.clear(); }); -test.serial("marks a sleeping node as awake", (t) => { - const { makeNode } = t.context; +test.sequential("marks a sleeping node as awake", ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(true); node.markAsAsleep(); node.updateNodeInfo(emptyNodeInfo as any); - t.is(node.status, NodeStatus.Awake); + expect(node.status).toBe(NodeStatus.Awake); node.destroy(); }); -test.serial("does not throw when called on a non-sleeping node", (t) => { - const { makeNode } = t.context; +test.sequential("does not throw when called on a non-sleeping node", ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(false); - t.notThrows(() => node.updateNodeInfo(emptyNodeInfo as any)); + expect(() => node.updateNodeInfo(emptyNodeInfo as any)).not.toThrow(); node.destroy(); }); -test.serial("remembers all received CCs", (t) => { - const { makeNode } = t.context; +test.sequential("remembers all received CCs", ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(); node.addCC(CommandClasses.Battery, { @@ -100,13 +108,13 @@ test.serial("remembers all received CCs", (t) => { node.updateNodeInfo({ supportedCCs: [CommandClasses.Battery, CommandClasses.Configuration], } as any); - t.true(node.supportsCC(CommandClasses.Battery)); - t.true(node.supportsCC(CommandClasses.Configuration)); + expect(node.supportsCC(CommandClasses.Battery)).toBe(true); + expect(node.supportsCC(CommandClasses.Configuration)).toBe(true); node.destroy(); }); -test.serial("ignores the data in an NIF if it was received already", (t) => { - const { makeNode } = t.context; +test.sequential("ignores the data in an NIF if it was received already", ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(); node.interviewStage = InterviewStage.Complete; @@ -115,7 +123,7 @@ test.serial("ignores the data in an NIF if it was received already", (t) => { supportedCCs: [CommandClasses.Battery], } as any); - t.false(node.supportsCC(CommandClasses.Battery)); - t.false(node.controlsCC(CommandClasses.Configuration)); + expect(node.supportsCC(CommandClasses.Battery)).toBe(false); + expect(node.controlsCC(CommandClasses.Configuration)).toBe(false); node.destroy(); }); diff --git a/packages/zwave-js/src/lib/test/node/Node.valueEvents.test.ts b/packages/zwave-js/src/lib/test/node/Node.valueEvents.test.ts index c3341f84976a..9451eaf16fab 100644 --- a/packages/zwave-js/src/lib/test/node/Node.valueEvents.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.valueEvents.test.ts @@ -1,47 +1,57 @@ import { CommandClasses, type ValueID } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import ava, { type TestFn } from "ava"; import sinon from "sinon"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; +import { afterEach, beforeEach, test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; -interface TestContext { - driver: Driver; - controller: MockController; - node: ZWaveNode; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + node: ZWaveNode; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.before(async (t) => { - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; -}); + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + // Run tests + await use(context); + + // Teardown + driver.removeAllListeners(); + await driver.destroy(); + }, + { auto: true }, + ], }); const onValueAdded = sinon.spy(); const onValueUpdated = sinon.spy(); const onValueRemoved = sinon.spy(); -test.beforeEach((t) => { - const { driver } = t.context; +beforeEach(({ context, expect }) => { + const { driver } = context; const node = new ZWaveNode(1, driver) .on("value added", onValueAdded) .on("value updated", onValueUpdated) @@ -50,23 +60,23 @@ test.beforeEach((t) => { node.id, node, ); - t.context.node = node; + context.node = node; onValueAdded.resetHistory(); onValueUpdated.resetHistory(); onValueRemoved.resetHistory(); }); -test.afterEach((t) => { - const { node, driver } = t.context; +afterEach(({ context, expect }) => { + const { node, driver } = context; node.destroy(); (driver.controller.nodes as ThrowingMap).delete(node.id); }); -test.serial( +test.sequential( "the emitted events should contain a speaking name for the CC", - (t) => { - const { node } = t.context; + ({ context, expect }) => { + const { node } = context; const cc = CommandClasses["Wake Up"]; const ccName = CommandClasses[cc]; @@ -83,15 +93,15 @@ test.serial( for (const method of [onValueAdded, onValueUpdated, onValueRemoved]) { const cbArg = method.getCall(0).args[1]; - t.is(cbArg.commandClassName, ccName); + expect(cbArg.commandClassName).toBe(ccName); } }, ); -test.serial( +test.sequential( "the emitted events should contain a speaking name for the propertyKey", - (t) => { - const { node } = t.context; + ({ context, expect }) => { + const { node } = context; node.valueDB.setValue( { commandClass: CommandClasses["Thermostat Setpoint"], @@ -102,14 +112,14 @@ test.serial( ); sinon.assert.called(onValueAdded); const cbArg = onValueAdded.getCall(0).args[1]; - t.is(cbArg.propertyKeyName, "Heating"); + expect(cbArg.propertyKeyName).toBe("Heating"); }, ); -test.serial( +test.sequential( "the emitted events should not be emitted for internal values", - (t) => { - const { node } = t.context; + ({ context, expect }) => { + const { node } = context; node.valueDB.setValue( { commandClass: CommandClasses.Battery, @@ -118,6 +128,5 @@ test.serial( true, ); sinon.assert.notCalled(onValueAdded); - t.pass(); }, ); diff --git a/packages/zwave-js/src/lib/test/node/Node.waitForWakeup.test.ts b/packages/zwave-js/src/lib/test/node/Node.waitForWakeup.test.ts index 8672acff5072..99068ef0e1d7 100644 --- a/packages/zwave-js/src/lib/test/node/Node.waitForWakeup.test.ts +++ b/packages/zwave-js/src/lib/test/node/Node.waitForWakeup.test.ts @@ -5,88 +5,95 @@ import { } from "@zwave-js/core"; import type { ThrowingMap } from "@zwave-js/shared"; import { MockController } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import ava, { type TestFn } from "ava"; -import { createDefaultMockControllerBehaviors } from "../../../Utils"; -import type { Driver } from "../../driver/Driver"; -import { createAndStartTestingDriver } from "../../driver/DriverMock"; -import { ZWaveNode } from "../../node/Node"; +import { wait } from "alcalzone-shared/async/index.js"; +import { test as baseTest } from "vitest"; +import { createDefaultMockControllerBehaviors } from "../../../Utils.js"; +import type { Driver } from "../../driver/Driver.js"; +import { createAndStartTestingDriver } from "../../driver/DriverMock.js"; +import { ZWaveNode } from "../../node/Node.js"; -interface TestContext { - driver: Driver; - controller: MockController; - makeNode: (canSleep?: boolean) => ZWaveNode; +interface LocalTestContext { + context: { + driver: Driver; + controller: MockController; + makeNode: (canSleep?: boolean) => ZWaveNode; + }; } -const test = ava as TestFn; +const test = baseTest.extend({ + context: [ + async ({}, use) => { + // Setup + const context = {} as LocalTestContext["context"]; -test.before(async (t) => { - t.timeout(30000); + const { driver } = await createAndStartTestingDriver({ + skipNodeInterview: true, + loadConfiguration: false, + beforeStartup(mockPort) { + const controller = new MockController({ serial: mockPort }); + controller.defineBehavior( + ...createDefaultMockControllerBehaviors(), + ); + context.controller = controller; + }, + }); + context.driver = driver; - const { driver } = await createAndStartTestingDriver({ - skipNodeInterview: true, - loadConfiguration: false, - beforeStartup(mockPort) { - const controller = new MockController({ serial: mockPort }); - controller.defineBehavior( - ...createDefaultMockControllerBehaviors(), - ); - t.context.controller = controller; - }, - }); - t.context.driver = driver; + context.makeNode = (canSleep: boolean = false): ZWaveNode => { + const node = new ZWaveNode(2, driver); + node["isListening"] = !canSleep; + node["isFrequentListening"] = false; + if (canSleep) { + node.addCC(CommandClasses["Wake Up"], { + isSupported: true, + }); + } + (driver.controller.nodes as ThrowingMap).set( + node.id, + node, + ); + return node; + }; - t.context.makeNode = (canSleep: boolean = false): ZWaveNode => { - const node = new ZWaveNode(2, driver); - node["isListening"] = !canSleep; - node["isFrequentListening"] = false; - if (canSleep) { - node.addCC(CommandClasses["Wake Up"], { isSupported: true }); - } - (driver.controller.nodes as ThrowingMap).set( - node.id, - node, - ); - return node; - }; -}); + // Run tests + await use(context); -test.after.always(async (t) => { - const { driver } = t.context; - await driver.destroy(); + // Teardown + await driver.destroy(); + }, + { auto: true }, + ], }); -test("resolves when a sleeping node wakes up", async (t) => { - const { makeNode } = t.context; +test("resolves when a sleeping node wakes up", async ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(true); node.markAsAsleep(); const promise = node.waitForWakeup(); await wait(1); node.markAsAwake(); - await t.notThrowsAsync(() => promise); + await promise; node.destroy(); }); -test("resolves immediately when called on an awake node", async (t) => { - const { makeNode } = t.context; +test("resolves immediately when called on an awake node", async ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(true); node.markAsAwake(); - await t.notThrowsAsync(() => node.waitForWakeup()); + await node.waitForWakeup(); node.destroy(); }); -test("throws when called on a non-sleeping node", async (t) => { - const { makeNode } = t.context; +test("throws when called on a non-sleeping node", async ({ context, expect }) => { + const { makeNode } = context; const node = makeNode(false); - await assertZWaveError(t, () => node.waitForWakeup(), { + await assertZWaveError(expect, () => node.waitForWakeup(), { errorCode: ZWaveErrorCodes.CC_NotSupported, }); - t.pass(); - node.destroy(); }); diff --git a/packages/zwave-js/src/lib/test/node/legacyRefreshActuatorSensorCCs.test.ts b/packages/zwave-js/src/lib/test/node/legacyRefreshActuatorSensorCCs.test.ts index 623f835c33e3..40d0d6cba976 100644 --- a/packages/zwave-js/src/lib/test/node/legacyRefreshActuatorSensorCCs.test.ts +++ b/packages/zwave-js/src/lib/test/node/legacyRefreshActuatorSensorCCs.test.ts @@ -6,8 +6,8 @@ import { import { CommandClasses } from "@zwave-js/core"; import { ApplicationUpdateRequestNodeInfoReceived } from "@zwave-js/serial/serialapi"; import { type MockNodeBehavior, MockZWaveFrameType } from "@zwave-js/testing"; -import { wait } from "alcalzone-shared/async"; -import { integrationTest } from "../integrationTestSuite"; +import { wait } from "alcalzone-shared/async/index.js"; +import { integrationTest } from "../integrationTestSuite.js"; integrationTest( "When a NIF is received for a node that does not send unsolicited reports, refresh actuator and sensor CCs", @@ -84,8 +84,6 @@ integrationTest( f.type === MockZWaveFrameType.Request && f.payload instanceof MultilevelSwitchCCGet, ); - - t.pass(); }, }, ); diff --git a/packages/zwave-js/src/lib/test/utils.ts b/packages/zwave-js/src/lib/test/utils.ts deleted file mode 100644 index d37fb5a648ed..000000000000 --- a/packages/zwave-js/src/lib/test/utils.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { MockSerialPort } from "@zwave-js/serial/mock"; -import type { DeepPartial } from "@zwave-js/shared"; -import proxyquire from "proxyquire"; -import type { ZWaveOptions } from "../driver/ZWaveOptions"; - -// load the driver with stubbed out Serialport -const { Driver } = proxyquire( - "../driver/Driver", - { - "@zwave-js/serial": { - ZWaveSerialPort: MockSerialPort, - }, - }, -); - -export const PORT_ADDRESS = "/tty/FAKE"; - -/** Creates a real driver instance with a mocked serial port to enable end to end tests */ -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export async function createAndStartDriver( - options: DeepPartial = {}, -) { - // Usually we don't want logs in these tests - if (!options.logConfig) { - options.logConfig = { - enabled: false, - }; - } - - const driver = new Driver(PORT_ADDRESS, { - ...options, - testingHooks: { - skipBootloaderCheck: true, - skipControllerIdentification: true, - skipNodeInterview: true, - }, - }); - driver.on("error", () => { - /* swallow error events during testing */ - }); - // We don't need to test the soft reset logic in CI - // Return a promise that never resolves, so we don't accidentally stumble into interview code - driver.softReset = () => new Promise(() => {}); - await driver.start(); - const portInstance = MockSerialPort.getInstance(PORT_ADDRESS)!; - - portInstance.openStub.resetHistory(); - portInstance.closeStub.resetHistory(); - portInstance.writeStub.resetHistory(); - portInstance["_lastWrite"] = undefined; - - // Mock the value DB, because the original one will not be initialized - // with skipInterview: true - driver["_valueDB"] = new Map() as any; - driver["_valueDB"]!.close = () => Promise.resolve(); - driver["_metadataDB"] = new Map() as any; - driver["_metadataDB"]!.close = () => Promise.resolve(); - driver["_networkCache"] = new Map() as any; - driver["_networkCache"]!.close = () => Promise.resolve(); - - // Mock the controller as it will not be initialized with skipInterview: true - driver["_controller"] = { - ownNodeId: 1, - isFunctionSupported: () => true, - nodes: new Map(), - incrementStatistics: () => {}, - removeAllListeners: () => {}, - } as any; - - return { - driver, - serialport: portInstance, - }; -} diff --git a/packages/zwave-js/src/lib/zniffer/MPDU.ts b/packages/zwave-js/src/lib/zniffer/MPDU.ts index 7996a4f122de..fdd1ee174e65 100644 --- a/packages/zwave-js/src/lib/zniffer/MPDU.ts +++ b/packages/zwave-js/src/lib/zniffer/MPDU.ts @@ -30,12 +30,12 @@ import { pick, staticExtends, } from "@zwave-js/shared"; -import { padStart } from "alcalzone-shared/strings"; +import { padStart } from "alcalzone-shared/strings/index.js"; import { ExplorerFrameCommand, LongRangeFrameType, ZWaveFrameType, -} from "./_Types"; +} from "./_Types.js"; function getChannelConfiguration(region: ZnifferRegion): "1/2" | "3" | "4" { switch (region) { diff --git a/packages/zwave-js/src/lib/zniffer/Zniffer.ts b/packages/zwave-js/src/lib/zniffer/Zniffer.ts index f8f5240164ef..350909071c04 100644 --- a/packages/zwave-js/src/lib/zniffer/Zniffer.ts +++ b/packages/zwave-js/src/lib/zniffer/Zniffer.ts @@ -69,10 +69,10 @@ import { import { type DeferredPromise, createDeferredPromise, -} from "alcalzone-shared/deferred-promise"; +} from "alcalzone-shared/deferred-promise/index.js"; import fs from "node:fs/promises"; -import { type ZWaveOptions } from "../driver/ZWaveOptions"; -import { ZnifferLogger } from "../log/Zniffer"; +import { type ZWaveOptions } from "../driver/ZWaveOptions.js"; +import { ZnifferLogger } from "../log/Zniffer.js"; import { type CorruptedFrame, type Frame, @@ -81,7 +81,7 @@ import { parseBeamFrame, parseMPDU, znifferDataMessageToCorruptedFrame, -} from "./MPDU"; +} from "./MPDU.js"; const logo: string = ` ███████╗ ███╗ ██╗ ██╗ ██████╗ ██████╗ ███████╗ ██████╗ ██╗ ███████╗ diff --git a/packages/zwave-js/src/mockServer.ts b/packages/zwave-js/src/mockServer.ts index eabf1fa5b3d6..7cbfb2f1842c 100644 --- a/packages/zwave-js/src/mockServer.ts +++ b/packages/zwave-js/src/mockServer.ts @@ -40,14 +40,14 @@ import { getDefaultMockEndpointCapabilities, getDefaultMockNodeCapabilities, } from "@zwave-js/testing"; -import { createDeferredPromise } from "alcalzone-shared/deferred-promise"; +import { createDeferredPromise } from "alcalzone-shared/deferred-promise/index.js"; import { type AddressInfo, type Server, createServer } from "node:net"; import { ProtocolVersion, createDefaultMockControllerBehaviors, createDefaultMockNodeBehaviors, -} from "./Utils"; -import { type CommandClassDump, type NodeDump } from "./lib/node/Dump"; +} from "./Utils.js"; +import { type CommandClassDump, type NodeDump } from "./lib/node/Dump.js"; export type MockServerControllerOptions = & Pick< diff --git a/packages/zwave-js/tsconfig.build.json b/packages/zwave-js/tsconfig.build.json index 39f4caf40cdc..195e0bf9cad0 100644 --- a/packages/zwave-js/tsconfig.build.json +++ b/packages/zwave-js/tsconfig.build.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "rootDir": "src", - "outDir": "build", + "outDir": "build/esm", "typeRoots": [ "src/lib/@types", "node_modules/@types", @@ -45,5 +45,5 @@ } ], "include": ["src/**/*.ts"], - "exclude": ["src/lib/test", "src/**/*.test.ts", "src/**/*.test.ava.ts"] + "exclude": ["src/lib/test", "src/**/*.test.ts"] } diff --git a/server_config.js b/server_config.js index eabf48f1cd14..10fc913f0cd8 100644 --- a/server_config.js +++ b/server_config.js @@ -5,7 +5,7 @@ const { CommandClasses, ConfigValueFormat, SupervisionStatus } = require( const { ccCaps, MockZWaveFrameType, createMockZWaveRequestFrame } = require( "@zwave-js/testing", ); -const { wait } = require("alcalzone-shared/async"); +const { wait } = require("alcalzone-shared/async/index.js"); const { SupervisionCCGet, SupervisionCCReport, ConfigurationCCSet } = require( "zwave-js", ); diff --git a/test/run.ts b/test/run.cts similarity index 74% rename from test/run.ts rename to test/run.cts index 185bda23d839..c12bf6cec7a3 100644 --- a/test/run.ts +++ b/test/run.cts @@ -1,8 +1,13 @@ -import { wait as _wait } from "alcalzone-shared/async"; +import { wait as _wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; import "reflect-metadata"; +import { Bytes } from "@zwave-js/shared/safe"; +import os from "node:os"; +import { fileURLToPath } from "node:url"; import { Driver } from "zwave-js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const wait = _wait; process.on("unhandledRejection", (_r) => { @@ -16,7 +21,7 @@ process.on("unhandledRejection", (_r) => { // : "/dev/ttyACM0"; // const port = require("os").platform() === "win32" ? "COM5" : "/dev/ttyUSB0"; // 800 series -const port = require("node:os").platform() === "win32" +const port = os.platform() === "win32" ? "COM5" : "/dev/serial/by-id/usb-Zooz_800_Z-Wave_Stick_533D004242-if00"; @@ -29,26 +34,26 @@ const driver = new Driver(port, { // skipNodeInterview: true, // }, securityKeys: { - S0_Legacy: Buffer.from("0102030405060708090a0b0c0d0e0f10", "hex"), - S2_Unauthenticated: Buffer.from( + S0_Legacy: Bytes.from("0102030405060708090a0b0c0d0e0f10", "hex"), + S2_Unauthenticated: Bytes.from( "5369389EFA18EE2A4894C7FB48347FEA", "hex", ), - S2_Authenticated: Buffer.from( + S2_Authenticated: Bytes.from( "656EF5C0F020F3C14238C04A1748B7E1", "hex", ), - S2_AccessControl: Buffer.from( + S2_AccessControl: Bytes.from( "31132050077310B6F7032F91C79C2EB8", "hex", ), }, securityKeysLongRange: { - S2_Authenticated: Buffer.from( + S2_Authenticated: Bytes.from( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "hex", ), - S2_AccessControl: Buffer.from( + S2_AccessControl: Bytes.from( "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "hex", ), diff --git a/test/run_duplex.ts b/test/run_duplex.ts index b788fdbb165f..e160e0d7d6e5 100644 --- a/test/run_duplex.ts +++ b/test/run_duplex.ts @@ -1,8 +1,12 @@ -import { wait as _wait } from "alcalzone-shared/async"; +import { wait as _wait } from "alcalzone-shared/async/index.js"; import path from "node:path"; import "reflect-metadata"; +import { Bytes } from "@zwave-js/shared/safe"; +import { fileURLToPath } from "node:url"; import { Driver, RFRegion } from "zwave-js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const wait = _wait; process.on("unhandledRejection", (_r) => { @@ -33,26 +37,26 @@ const driver_primary = new Driver(port_primary, { skipNodeInterview: true, }, securityKeys: { - S0_Legacy: Buffer.from("0102030405060708090a0b0c0d0e0f10", "hex"), - S2_Unauthenticated: Buffer.from( + S0_Legacy: Bytes.from("0102030405060708090a0b0c0d0e0f10", "hex"), + S2_Unauthenticated: Bytes.from( "5369389EFA18EE2A4894C7FB48347FEA", "hex", ), - S2_Authenticated: Buffer.from( + S2_Authenticated: Bytes.from( "656EF5C0F020F3C14238C04A1748B7E1", "hex", ), - S2_AccessControl: Buffer.from( + S2_AccessControl: Bytes.from( "31132050077310B6F7032F91C79C2EB8", "hex", ), }, securityKeysLongRange: { - S2_Authenticated: Buffer.from( + S2_Authenticated: Bytes.from( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "hex", ), - S2_AccessControl: Buffer.from( + S2_AccessControl: Bytes.from( "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "hex", ), @@ -117,26 +121,26 @@ const driver_secondary = new Driver(port_secondary, { // skipNodeInterview: true, // }, securityKeys: { - S0_Legacy: Buffer.from("0102030405060708090a0b0c0d0e0f10", "hex"), - S2_Unauthenticated: Buffer.from( + S0_Legacy: Bytes.from("0102030405060708090a0b0c0d0e0f10", "hex"), + S2_Unauthenticated: Bytes.from( "5369389EFA18EE2A4894C7FB48347FEA", "hex", ), - S2_Authenticated: Buffer.from( + S2_Authenticated: Bytes.from( "656EF5C0F020F3C14238C04A1748B7E1", "hex", ), - S2_AccessControl: Buffer.from( + S2_AccessControl: Bytes.from( "31132050077310B6F7032F91C79C2EB8", "hex", ), }, securityKeysLongRange: { - S2_Authenticated: Buffer.from( + S2_Authenticated: Bytes.from( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "hex", ), - S2_AccessControl: Buffer.from( + S2_AccessControl: Bytes.from( "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "hex", ), diff --git a/test/run_zniffer.ts b/test/run_zniffer.ts index df0ad4a5aba6..911b922bdb83 100644 --- a/test/run_zniffer.ts +++ b/test/run_zniffer.ts @@ -1,4 +1,4 @@ -import { wait as _wait } from "alcalzone-shared/async"; +import { wait as _wait } from "alcalzone-shared/async/index.js"; import "reflect-metadata"; import { Zniffer } from "zwave-js"; diff --git a/test/tsconfig.json b/test/tsconfig.json index 217a20995603..e83bdf4cd316 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "../tsconfig.base.json", - "include": ["*.ts"] + "include": ["*.ts", "run.cts"] } diff --git a/tsconfig.all.json b/tsconfig.all.json index 6e076145f93d..e22b232ef18c 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -2,6 +2,6 @@ // This is used for linting and other maintenance tasks { "extends": "./tsconfig.base.json", - "include": ["**/*.ts"], + "include": ["**/*.ts", "**/*.cts", "**/*.mts"], "exclude": ["**/build/**", "**/node_modules/**"] } diff --git a/tsconfig.docs.json b/tsconfig.docs.json index e14e3fd8c033..a11a148af5a2 100644 --- a/tsconfig.docs.json +++ b/tsconfig.docs.json @@ -2,7 +2,11 @@ { "extends": "./tsconfig.base.json", "compilerOptions": { - "customConditions": [] + "customConditions": ["@@dev"] }, - "include": ["packages/**/src/**/*.ts"] + "include": [ + "packages/**/src/**/*.ts", + "packages/**/src/**/*.cts", + "packages/**/src/**/*.mts" + ] } diff --git a/turbo.json b/turbo.json index 6154fc70d830..69c08b6be9b3 100644 --- a/turbo.json +++ b/turbo.json @@ -48,7 +48,7 @@ "inputs": [ // https://github.com/vercel/turborepo/issues/1407 ":!:build/", - "**/*.{ts,json}", + "**/*.{ts,cts,mts,json}", // The style based linting tasks depend on the corresponding configuration in the repo root "../../eslint.config.mjs", "../../tsconfig.all.json" @@ -59,12 +59,12 @@ "inputs": [ // https://github.com/vercel/turborepo/issues/1407 ":!:build/", - "**/*.{ts,json}", + "**/*.{ts,cts,mts,json}", // The style based linting tasks depend on the corresponding configuration in the repo root "../../eslint.config.mjs", "../../tsconfig.all.json" ], - "outputs": ["**/*.{ts,json}"] + "outputs": ["**/*.{ts,cts,mts,json}"] }, "lint:zwave": { @@ -73,7 +73,7 @@ }, "@zwave-js/config#lint:zwave": { "inputs": [ - "**/*.ts", + "**/*.{ts,cts,mts}", "config/**/*.json", "config/eslint.config.mjs" ] @@ -81,14 +81,14 @@ "extract-api": { "dependsOn": ["//#build:turbo"], - "inputs": ["src/**/*.ts", "build/**"], + "inputs": ["src/**/*.{ts,cts,mts}", "build/**"], "cache": false // "outputs": [".tmp/api.md", "api.md"] }, "test:ts": { // "dependsOn": ["//#build:turbo"], - "inputs": ["src/**/*.ts", "ava.config.cjs", "../../ava.config.cjs"] + "inputs": ["src/**/*.{ts,cts,mts}", "vitest.config.mjs"] // TODO: consider snapshot files } }, diff --git a/vitest.config.mjs b/vitest.config.mjs new file mode 100644 index 000000000000..5c23e04fd0af --- /dev/null +++ b/vitest.config.mjs @@ -0,0 +1,17 @@ +import { defaultExclude, defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: [ + ...defaultExclude, + "build/**", + ".vscode/extensions/**", + // Transformer tests require dependencies to be compiled + // and cannot use the @@dev condition.. + "packages/transformers/**", + ], + }, + resolve: { + conditions: ["@@dev"], + }, +}); diff --git a/yarn.lock b/yarn.lock index 5b1846ab9b57..3255fee52019 100644 --- a/yarn.lock +++ b/yarn.lock @@ -69,6 +69,20 @@ __metadata: languageName: node linkType: hard +"@alcalzone/esm2cjs@npm:^1.2.3": + version: 1.2.3 + resolution: "@alcalzone/esm2cjs@npm:1.2.3" + dependencies: + esbuild: "npm:^0.24.0" + fs-extra: "npm:^10.1.0" + tiny-glob: "npm:^0.2.9" + yargs: "npm:^17.5.1" + bin: + esm2cjs: bin/esm2cjs.cjs + checksum: 10/fc472f63d091db4f3888e2f4be61992ba349a9e98036371713f08fa9a02a38ac611db0dcb1e7967f251f0cdd8a246406fa1557cd9a106718eaca32bacd17573f + languageName: node + linkType: hard + "@alcalzone/jsonl-db@npm:^3.1.1": version: 3.1.1 resolution: "@alcalzone/jsonl-db@npm:3.1.1" @@ -590,6 +604,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/aix-ppc64@npm:0.24.0" @@ -597,6 +625,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/android-arm64@npm:0.24.0" @@ -604,6 +646,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/android-arm@npm:0.24.0" @@ -611,6 +667,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/android-x64@npm:0.24.0" @@ -618,6 +688,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/darwin-arm64@npm:0.24.0" @@ -625,6 +709,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/darwin-x64@npm:0.24.0" @@ -632,6 +730,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/freebsd-arm64@npm:0.24.0" @@ -639,6 +751,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/freebsd-x64@npm:0.24.0" @@ -646,6 +772,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-arm64@npm:0.24.0" @@ -653,6 +793,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-arm@npm:0.24.0" @@ -660,6 +814,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-ia32@npm:0.24.0" @@ -667,6 +835,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-loong64@npm:0.24.0" @@ -674,6 +856,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-mips64el@npm:0.24.0" @@ -681,6 +877,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-ppc64@npm:0.24.0" @@ -688,6 +898,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-riscv64@npm:0.24.0" @@ -695,6 +919,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-s390x@npm:0.24.0" @@ -702,6 +940,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-x64@npm:0.24.0" @@ -709,6 +961,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/netbsd-x64@npm:0.24.0" @@ -716,6 +982,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/openbsd-arm64@npm:0.24.0" @@ -723,6 +996,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/openbsd-x64@npm:0.24.0" @@ -730,6 +1017,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/sunos-x64@npm:0.24.0" @@ -737,6 +1038,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/win32-arm64@npm:0.24.0" @@ -744,6 +1059,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/win32-ia32@npm:0.24.0" @@ -751,6 +1080,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/win32-x64@npm:0.24.0" @@ -900,6 +1243,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 10/4ed6123217569a1484419ac53f6ea0d9f3b57e5b57ab30d7c267bdb27792a27eb0e4b08e84a2680aa55cc2f2b411ffd6ec3db01c44fdc6dc43aca4b55f8374fd + languageName: node + linkType: hard + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.4 resolution: "@leichtgewicht/ip-codec@npm:2.0.4" @@ -907,25 +1257,6 @@ __metadata: languageName: node linkType: hard -"@mapbox/node-pre-gyp@npm:^1.0.5": - version: 1.0.11 - resolution: "@mapbox/node-pre-gyp@npm:1.0.11" - dependencies: - detect-libc: "npm:^2.0.0" - https-proxy-agent: "npm:^5.0.0" - make-dir: "npm:^3.1.0" - node-fetch: "npm:^2.6.7" - nopt: "npm:^5.0.0" - npmlog: "npm:^5.0.1" - rimraf: "npm:^3.0.2" - semver: "npm:^7.3.5" - tar: "npm:^6.1.11" - bin: - node-pre-gyp: bin/node-pre-gyp - checksum: 10/59529a2444e44fddb63057152452b00705aa58059079191126c79ac1388ae4565625afa84ed4dd1bf017d1111ab6e47907f7c5192e06d83c9496f2f3e708680a - languageName: node - linkType: hard - "@microsoft/api-extractor-model@npm:7.29.8": version: 7.29.8 resolution: "@microsoft/api-extractor-model@npm:7.29.8" @@ -1316,13 +1647,129 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^4.0.0": - version: 4.2.1 - resolution: "@rollup/pluginutils@npm:4.2.1" - dependencies: - estree-walker: "npm:^2.0.1" - picomatch: "npm:^2.2.2" - checksum: 10/503a6f0a449e11a2873ac66cfdfb9a3a0b77ffa84c5cad631f5e4bc1063c850710e8d5cd5dab52477c0d66cda2ec719865726dbe753318cd640bab3fff7ca476 +"@rollup/rollup-android-arm-eabi@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.24.3" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-android-arm64@npm:4.24.3" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-darwin-arm64@npm:4.24.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-darwin-x64@npm:4.24.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.24.3" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-freebsd-x64@npm:4.24.3" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.24.3" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.24.3" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.24.3" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.24.3" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.3" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.24.3" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.24.3" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.24.3" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.24.3" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.24.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.24.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.24.3": + version: 4.24.3 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.24.3" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1408,13 +1855,20 @@ __metadata: languageName: node linkType: hard -"@serialport/bindings-interface@npm:*, @serialport/bindings-interface@npm:1.2.2, @serialport/bindings-interface@npm:^1.2.1": +"@serialport/bindings-interface@npm:1.2.2": version: 1.2.2 resolution: "@serialport/bindings-interface@npm:1.2.2" checksum: 10/f0c0d67ed89582184d117cf2eb22c0b2d157604ca7a816851bcd8af0b447c68b587a8a21a61b7bda390ce142981bfb3115a7cf44c6c258a98c28fd9f0c30bcd6 languageName: node linkType: hard +"@serialport/bindings-interface@patch:@serialport/bindings-interface@npm%3A1.2.2#~/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch": + version: 1.2.2 + resolution: "@serialport/bindings-interface@patch:@serialport/bindings-interface@npm%3A1.2.2#~/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch::version=1.2.2&hash=e2bd74" + checksum: 10/3e36ee3c08c7cfd62977243230976bc63b9bf64176f01b64603e4f1405b6ccafeb71cc938ce676f643d49edadf21d7a8928e1db9aad23d99434254d3ddfd3a43 + languageName: node + linkType: hard + "@serialport/parser-byte-length@npm:12.0.0": version: 12.0.0 resolution: "@serialport/parser-byte-length@npm:12.0.0" @@ -1642,7 +2096,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.6": +"@types/estree@npm:1.0.6, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6": version: 1.0.6 resolution: "@types/estree@npm:1.0.6" checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d @@ -1998,25 +2452,84 @@ __metadata: languageName: node linkType: hard -"@vercel/nft@npm:^0.26.2": - version: 0.26.4 - resolution: "@vercel/nft@npm:0.26.4" +"@vitest/expect@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/expect@npm:2.1.4" dependencies: - "@mapbox/node-pre-gyp": "npm:^1.0.5" - "@rollup/pluginutils": "npm:^4.0.0" - acorn: "npm:^8.6.0" - acorn-import-attributes: "npm:^1.9.2" - async-sema: "npm:^3.1.1" - bindings: "npm:^1.4.0" - estree-walker: "npm:2.0.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - micromatch: "npm:^4.0.2" - node-gyp-build: "npm:^4.2.2" - resolve-from: "npm:^5.0.0" - bin: - nft: out/cli.js - checksum: 10/2d1c55ab84801206a94532edd1a24627bd3309d26837b8c6a301b0b8228ff8a166e63dbd479b1e349313776ae87abd267f27b5e7b4be2691cae843ce045f7e31 + "@vitest/spy": "npm:2.1.4" + "@vitest/utils": "npm:2.1.4" + chai: "npm:^5.1.2" + tinyrainbow: "npm:^1.2.0" + checksum: 10/0b3806d39233843a9661f6d5ccde489c9b6d278426f889198a862d601dcc186f107398487374195eb0dae90c9f69628f3f216200d644f817fa25d64ae1bc537e + languageName: node + linkType: hard + +"@vitest/mocker@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/mocker@npm:2.1.4" + dependencies: + "@vitest/spy": "npm:2.1.4" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.12" + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10/00f323cc184977b247a1f0b9c51fdcceb97377031d728c69ef0bd14ebf0256742a94c68c6caa90eb073ed3de4277febd7d54715508bff05bb2fb7767ce11afbe + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:2.1.4, @vitest/pretty-format@npm:^2.1.4": + version: 2.1.4 + resolution: "@vitest/pretty-format@npm:2.1.4" + dependencies: + tinyrainbow: "npm:^1.2.0" + checksum: 10/434e6a7903f72a3796f26516ad728aca92724909e18fd3f2cd4b9b8b0ae2cc7b4cd86e92ab9f2ac7bc005c7a7ef0bcb9d768c0264b4b0625f1f0748cc615f1f6 + languageName: node + linkType: hard + +"@vitest/runner@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/runner@npm:2.1.4" + dependencies: + "@vitest/utils": "npm:2.1.4" + pathe: "npm:^1.1.2" + checksum: 10/51dbea968ace6edefb058d88c9736fa524a64f4dc750ec163b43f5015a31b31f2d80a7b20de4c2a819fbfb172162ad4d0f8428c78fa7ca832c1a1b135161ac4b + languageName: node + linkType: hard + +"@vitest/snapshot@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/snapshot@npm:2.1.4" + dependencies: + "@vitest/pretty-format": "npm:2.1.4" + magic-string: "npm:^0.30.12" + pathe: "npm:^1.1.2" + checksum: 10/785f74cf5f7745eb0dcb73fe3c628bc1f687c6341e8ba63d722fa83609d21465302ebd208405b9f91ce87fb36720a0f361c949983d5caccbcb8ec2119f995483 + languageName: node + linkType: hard + +"@vitest/spy@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/spy@npm:2.1.4" + dependencies: + tinyspy: "npm:^3.0.2" + checksum: 10/4dd3e7c28928abb047c567b3711d1cbccd59aaae294c57efaab83cdd723b568882de5376fc086c919a4cb6d1df5e6cc0502b3171cce06dfce87863c731fd5d36 + languageName: node + linkType: hard + +"@vitest/utils@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/utils@npm:2.1.4" + dependencies: + "@vitest/pretty-format": "npm:2.1.4" + loupe: "npm:^3.1.2" + tinyrainbow: "npm:^1.2.0" + checksum: 10/aaaf5310943abca0f0080d9638e67838f7e519d5670ec32e61184915efdfa5ec61d9b495cad6cb7dc492e8caeed14593e78dda77c8ea59c1671a231661f57142 languageName: node linkType: hard @@ -2045,6 +2558,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/cc@workspace:packages/cc" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@types/node": "npm:^18.19.63" "@zwave-js/core": "workspace:*" @@ -2054,10 +2568,12 @@ __metadata: "@zwave-js/transformers": "workspace:*" alcalzone-shared: "npm:^4.0.8" ansi-colors: "npm:^4.1.3" - ava: "npm:^6.1.3" del-cli: "npm:^6.0.0" + es-main: "npm:^1.3.0" reflect-metadata: "npm:^0.2.2" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" languageName: unknown linkType: soft @@ -2065,6 +2581,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/config@workspace:packages/config" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@types/js-levenshtein": "npm:^1.1.3" "@types/json-logic-js": "npm:^2.0.7" @@ -2079,11 +2596,9 @@ __metadata: "@zwave-js/shared": "workspace:*" alcalzone-shared: "npm:^4.0.8" ansi-colors: "npm:^4.1.3" - ava: "npm:^6.1.3" comment-json: "npm:^4.2.5" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" + es-main: "npm:^1.3.0" got: "npm:^13.0.0" js-levenshtein: "npm:^1.1.6" json-logic-js: "npm:^2.0.5" @@ -2092,8 +2607,10 @@ __metadata: proxyquire: "npm:^2.1.3" semver: "npm:^7.6.3" sinon: "npm:^19.0.2" - ts-pegjs: "npm:^4.2.1" + ts-pegjs: "patch:ts-pegjs@npm%3A4.2.1#~/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" winston: "npm:^3.15.0" xml2js: "npm:^0.6.2" yargs: "npm:^17.7.2" @@ -2104,6 +2621,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/core@workspace:packages/core" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@alcalzone/jsonl-db": "npm:^3.1.1" "@microsoft/api-extractor": "npm:^7.47.9" "@types/node": "npm:^18.19.63" @@ -2113,18 +2631,17 @@ __metadata: "@zwave-js/shared": "workspace:*" alcalzone-shared: "npm:^4.0.8" ansi-colors: "npm:^4.1.3" - ava: "npm:^6.1.3" dayjs: "npm:^1.11.13" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" logform: "npm:^2.6.1" nrf-intel-hex: "npm:^1.4.0" reflect-metadata: "npm:^0.2.2" semver: "npm:^7.6.3" sinon: "npm:^19.0.2" triple-beam: "npm:*" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" winston: "npm:^3.15.0" winston-daily-rotate-file: "npm:^5.0.0" winston-transport: "npm:^4.8.0" @@ -2135,6 +2652,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/eslint-plugin@workspace:packages/eslint-plugin" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@types/eslint": "npm:^9.6.1" "@typescript-eslint/utils": "npm:^8.8.1" "@zwave-js/core": "workspace:*" @@ -2157,7 +2675,7 @@ __metadata: yargs: "npm:^17.7.2" zwave-js: "workspace:*" bin: - flash: bin/flash.js + flash: bin/flash.mjs languageName: unknown linkType: soft @@ -2179,6 +2697,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/host@workspace:packages/host" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@types/node": "npm:^18.19.63" "@zwave-js/config": "workspace:*" @@ -2194,6 +2713,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/maintenance@workspace:packages/maintenance" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@dprint/formatter": "npm:^0.4.1" "@dprint/json": "npm:^0.19.4" "@dprint/markdown": "npm:^0.17.8" @@ -2208,14 +2728,14 @@ __metadata: cli-highlight: "npm:^2.1.11" del-cli: "npm:^6.0.0" dprint: "npm:^0.47.2" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" + es-main: "npm:^1.3.0" execa: "npm:^5.1.1" globrex: "npm:^0.1.2" json5: "npm:^2.2.3" piscina: "npm:^4.7.0" reflect-metadata: "npm:^0.2.2" ts-morph: "npm:^24.0.0" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" yargs: "npm:^17.7.2" languageName: unknown @@ -2225,6 +2745,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/nvmedit@workspace:packages/nvmedit" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@types/node": "npm:^18.19.63" "@types/semver": "npm:^7.5.8" @@ -2232,13 +2753,12 @@ __metadata: "@zwave-js/core": "workspace:*" "@zwave-js/shared": "workspace:*" alcalzone-shared: "npm:^4.0.8" - ava: "npm:^6.1.3" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" reflect-metadata: "npm:^0.2.2" semver: "npm:^7.6.3" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" yargs: "npm:^17.7.2" bin: nvmedit: bin/nvmedit.js @@ -2252,6 +2772,7 @@ __metadata: "@actions/core": "npm:^1.11.1" "@actions/exec": "npm:^1.1.1" "@actions/github": "npm:^6.0.0" + "@alcalzone/esm2cjs": "npm:^1.2.3" "@alcalzone/jsonl-db": "npm:^3.1.1" "@alcalzone/monopack": "npm:^1.3.0" "@alcalzone/release-script": "npm:~3.8.0" @@ -2288,8 +2809,6 @@ __metadata: cz-conventional-changelog: "npm:^3.3.0" del-cli: "npm:^6.0.0" dprint: "npm:^0.47.2" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" eslint: "npm:^9.12.0" eslint-plugin-unicorn: "npm:^56.0.0" eslint-plugin-unused-imports: "patch:eslint-plugin-unused-imports@npm%3A4.1.4#~/.yarn/patches/eslint-plugin-unused-imports-npm-4.1.4-a7d7c7cdf3.patch" @@ -2303,9 +2822,11 @@ __metadata: semver: "npm:^7.6.3" source-map-support: "npm:^0.5.21" ts-patch: "npm:3.2.1" + tsx: "npm:^4.19.2" turbo: "npm:2.2.3" typescript: "npm:5.6.2" typescript-eslint: "npm:^8.12.2" + vitest: "npm:^2.1.4" xml2js: "npm:^0.6.2" zwave-js: "workspace:*" languageName: unknown @@ -2315,9 +2836,10 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/serial@workspace:packages/serial" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@serialport/binding-mock": "npm:^10.2.2" - "@serialport/bindings-interface": "npm:*" + "@serialport/bindings-interface": "patch:@serialport/bindings-interface@npm%3A1.2.2#~/.yarn/patches/@serialport-bindings-interface-npm-1.2.2-e597dbc676.patch" "@serialport/stream": "npm:^12.0.0" "@types/node": "npm:^18.19.63" "@types/sinon": "npm:^17.0.3" @@ -2327,13 +2849,12 @@ __metadata: "@zwave-js/shared": "workspace:*" alcalzone-shared: "npm:^4.0.8" ansi-colors: "npm:^4.1.3" - ava: "npm:^6.1.3" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" serialport: "npm:^12.0.0" sinon: "npm:^19.0.2" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" winston: "npm:^3.15.0" languageName: unknown linkType: soft @@ -2342,16 +2863,16 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/shared@workspace:packages/shared" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@types/node": "npm:^18.19.63" "@types/sinon": "npm:^17.0.3" alcalzone-shared: "npm:^4.0.8" - ava: "npm:^6.1.3" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" sinon: "npm:^19.0.2" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" languageName: unknown linkType: soft @@ -2359,6 +2880,7 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/testing@workspace:packages/testing" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@microsoft/api-extractor": "npm:^7.47.9" "@types/node": "npm:^18.19.63" "@types/triple-beam": "npm:^1.3.5" @@ -2370,9 +2892,8 @@ __metadata: alcalzone-shared: "npm:^4.0.8" ansi-colors: "npm:^4.1.3" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" triple-beam: "npm:*" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" winston-transport: "npm:^4.8.0" languageName: unknown @@ -2382,12 +2903,12 @@ __metadata: version: 0.0.0-use.local resolution: "@zwave-js/transformers@workspace:packages/transformers" dependencies: - ava: "npm:^6.1.3" cpy-cli: "npm:^5.0.0" del-cli: "npm:^6.0.0" execa: "npm:^5.1.1" tsutils: "npm:^3.21.0" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" languageName: unknown linkType: soft @@ -2419,15 +2940,6 @@ __metadata: languageName: node linkType: hard -"acorn-import-attributes@npm:^1.9.2": - version: 1.9.5 - resolution: "acorn-import-attributes@npm:1.9.5" - peerDependencies: - acorn: ^8 - checksum: 10/8bfbfbb6e2467b9b47abb4d095df717ab64fce2525da65eabee073e85e7975fb3a176b6c8bba17c99a7d8ede283a10a590272304eb54a93c4aa1af9790d47a8b - languageName: node - linkType: hard - "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -2437,22 +2949,6 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.3.2": - version: 8.3.2 - resolution: "acorn-walk@npm:8.3.2" - checksum: 10/57dbe2fd8cf744f562431775741c5c087196cd7a65ce4ccb3f3981cdfad25cd24ad2bad404997b88464ac01e789a0a61e5e355b2a84876f13deef39fb39686ca - languageName: node - linkType: hard - -"acorn@npm:^8.11.3, acorn@npm:^8.6.0": - version: 8.11.3 - resolution: "acorn@npm:8.11.3" - bin: - acorn: bin/acorn - checksum: 10/b688e7e3c64d9bfb17b596e1b35e4da9d50553713b3b3630cf5690f2b023a84eac90c56851e6912b483fe60e8b4ea28b254c07e92f17ef83d72d78745a8352dd - languageName: node - linkType: hard - "acorn@npm:^8.12.0": version: 8.12.1 resolution: "acorn@npm:8.12.1" @@ -2735,23 +3231,6 @@ __metadata: languageName: node linkType: hard -"aproba@npm:^1.0.3 || ^2.0.0": - version: 2.0.0 - resolution: "aproba@npm:2.0.0" - checksum: 10/c2b9a631298e8d6f3797547e866db642f68493808f5b37cd61da778d5f6ada890d16f668285f7d60bd4fc3b03889bd590ffe62cf81b700e9bb353431238a0a7b - languageName: node - linkType: hard - -"are-we-there-yet@npm:^2.0.0": - version: 2.0.0 - resolution: "are-we-there-yet@npm:2.0.0" - dependencies: - delegates: "npm:^1.0.0" - readable-stream: "npm:^3.6.0" - checksum: 10/ea6f47d14fc33ae9cbea3e686eeca021d9d7b9db83a306010dd04ad5f2c8b7675291b127d3fcbfcbd8fec26e47b3324ad5b469a6cc3733a582f2fe4e12fc6756 - languageName: node - linkType: hard - "are-we-there-yet@npm:~1.1.2": version: 1.1.5 resolution: "are-we-there-yet@npm:1.1.5" @@ -2762,15 +3241,6 @@ __metadata: languageName: node linkType: hard -"argparse@npm:^1.0.7, argparse@npm:~1.0.9": - version: 1.0.10 - resolution: "argparse@npm:1.0.10" - dependencies: - sprintf-js: "npm:~1.0.2" - checksum: 10/c6a621343a553ff3779390bb5ee9c2263d6643ebcd7843227bdde6cc7adbed796eb5540ca98db19e3fd7b4714e1faa51551f8849b268bb62df27ddb15cbcd91e - languageName: node - linkType: hard - "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -2778,10 +3248,12 @@ __metadata: languageName: node linkType: hard -"array-find-index@npm:^1.0.1": - version: 1.0.2 - resolution: "array-find-index@npm:1.0.2" - checksum: 10/aac128bf369e1ac6c06ff0bb330788371c0e256f71279fb92d745e26fb4b9db8920e485b4ec25e841c93146bf71a34dcdbcefa115e7e0f96927a214d237b7081 +"argparse@npm:~1.0.9": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: 10/c6a621343a553ff3779390bb5ee9c2263d6643ebcd7843227bdde6cc7adbed796eb5540ca98db19e3fd7b4714e1faa51551f8849b268bb62df27ddb15cbcd91e languageName: node linkType: hard @@ -2806,13 +3278,6 @@ __metadata: languageName: node linkType: hard -"arrgv@npm:^1.0.2": - version: 1.0.2 - resolution: "arrgv@npm:1.0.2" - checksum: 10/470bbb406ea3b34810dd8b03c0b33282617a42d9fce0ab45d58596efefd042fc548eda49161fa8e3f607cbe9df90e7a67003a09043ab9081eff70f97c63dd0e2 - languageName: node - linkType: hard - "arrify@npm:^1.0.1": version: 1.0.1 resolution: "arrify@npm:1.0.1" @@ -2827,10 +3292,10 @@ __metadata: languageName: node linkType: hard -"async-sema@npm:^3.1.1": - version: 3.1.1 - resolution: "async-sema@npm:3.1.1" - checksum: 10/ee0225c2e7b72ae76d66157499f61a881a050824019edc54fa6ec789313076790729557556fbbe237af0083173c66fb2edf1c9cc45c522c5f846b66c0a94ddb3 +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10/a0789dd882211b87116e81e2648ccb7f60340b34f19877dd020b39ebb4714e475eb943e14ba3e22201c221ef6645b7bfe10297e76b6ac95b48a9898c1211ce66 languageName: node linkType: hard @@ -2855,61 +3320,6 @@ __metadata: languageName: node linkType: hard -"ava@npm:^6.1.3": - version: 6.1.3 - resolution: "ava@npm:6.1.3" - dependencies: - "@vercel/nft": "npm:^0.26.2" - acorn: "npm:^8.11.3" - acorn-walk: "npm:^8.3.2" - ansi-styles: "npm:^6.2.1" - arrgv: "npm:^1.0.2" - arrify: "npm:^3.0.0" - callsites: "npm:^4.1.0" - cbor: "npm:^9.0.1" - chalk: "npm:^5.3.0" - chunkd: "npm:^2.0.1" - ci-info: "npm:^4.0.0" - ci-parallel-vars: "npm:^1.0.1" - cli-truncate: "npm:^4.0.0" - code-excerpt: "npm:^4.0.0" - common-path-prefix: "npm:^3.0.0" - concordance: "npm:^5.0.4" - currently-unhandled: "npm:^0.4.1" - debug: "npm:^4.3.4" - emittery: "npm:^1.0.1" - figures: "npm:^6.0.1" - globby: "npm:^14.0.0" - ignore-by-default: "npm:^2.1.0" - indent-string: "npm:^5.0.0" - is-plain-object: "npm:^5.0.0" - is-promise: "npm:^4.0.0" - matcher: "npm:^5.0.0" - memoize: "npm:^10.0.0" - ms: "npm:^2.1.3" - p-map: "npm:^7.0.1" - package-config: "npm:^5.0.0" - picomatch: "npm:^3.0.1" - plur: "npm:^5.1.0" - pretty-ms: "npm:^9.0.0" - resolve-cwd: "npm:^3.0.0" - stack-utils: "npm:^2.0.6" - strip-ansi: "npm:^7.1.0" - supertap: "npm:^3.0.1" - temp-dir: "npm:^3.0.0" - write-file-atomic: "npm:^5.0.1" - yargs: "npm:^17.7.2" - peerDependencies: - "@ava/typescript": "*" - peerDependenciesMeta: - "@ava/typescript": - optional: true - bin: - ava: entrypoints/cli.mjs - checksum: 10/89d2ba8b3b6f60e1c12094d84f0087455e43a4a4c7191ae33b462c653ec7343efc5475ffb9c93f1e27effd1fbd9e0e5b1392f7b70693246d0ba726c554bff830 - languageName: node - linkType: hard - "axios@npm:^1.6.2": version: 1.7.7 resolution: "axios@npm:1.7.7" @@ -2942,15 +3352,6 @@ __metadata: languageName: node linkType: hard -"bindings@npm:^1.4.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: "npm:1.0.0" - checksum: 10/593d5ae975ffba15fbbb4788fe5abd1e125afbab849ab967ab43691d27d6483751805d98cb92f7ac24a2439a8a8678cd0131c535d5d63de84e383b0ce2786133 - languageName: node - linkType: hard - "bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" @@ -2962,13 +3363,6 @@ __metadata: languageName: node linkType: hard -"blueimp-md5@npm:^2.10.0": - version: 2.19.0 - resolution: "blueimp-md5@npm:2.19.0" - checksum: 10/84dc5f86e0d890e50c067a52b85654ec02e56d019c6af88f5a2810b1353adfd37b09ae34f540ef5cd1f19fe0023cb69d0dd68877123044cc49fbf6e7ff4c9a18 - languageName: node - linkType: hard - "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -3045,6 +3439,13 @@ __metadata: languageName: node linkType: hard +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 10/002769a0fbfc51c062acd2a59df465a2a947916b02ac50b56c69ec6c018ee99ac3e7f4dd7366334ea847f1ecacf4defaa61bcd2ac283db50156ce1f1d8c8ad42 + languageName: node + linkType: hard + "cacache@npm:^15.0.5": version: 15.2.0 resolution: "cacache@npm:15.2.0" @@ -3113,13 +3514,6 @@ __metadata: languageName: node linkType: hard -"callsites@npm:^4.1.0": - version: 4.1.0 - resolution: "callsites@npm:4.1.0" - checksum: 10/4ad31de7b7615fa25bdab9c2373865209d2d5190f895cdf2e2f518bd1dafa7ebcda2e6e9cc9640f2dfde6b3893d82fa4359a78ffc27baad2503227553c6882fa - languageName: node - linkType: hard - "camelcase-keys@npm:^6.2.2": version: 6.2.2 resolution: "camelcase-keys@npm:6.2.2" @@ -3145,12 +3539,16 @@ __metadata: languageName: node linkType: hard -"cbor@npm:^9.0.1": - version: 9.0.2 - resolution: "cbor@npm:9.0.2" +"chai@npm:^5.1.2": + version: 5.1.2 + resolution: "chai@npm:5.1.2" dependencies: - nofilter: "npm:^3.1.0" - checksum: 10/a64f7d4dafed933adeafe7745e2ce9f39a2e669eba73db96de6bd1b39c2dbde4bdd51d0240beed179cc429a7dc8653c8d7c991c5addb9f4e0cee8cd167d87116 + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10/e8c2bbc83cb5a2f87130d93056d4cfbbe04106e12aa798b504816dbe3fa538a9f68541b472e56cbf0f54558b501d7e31867d74b8218abcd5a8cc8ba536fba46c languageName: node linkType: hard @@ -3199,6 +3597,13 @@ __metadata: languageName: node linkType: hard +"check-error@npm:^2.1.1": + version: 2.1.1 + resolution: "check-error@npm:2.1.1" + checksum: 10/d785ed17b1d4a4796b6e75c765a9a290098cf52ff9728ce0756e8ffd4293d2e419dd30c67200aee34202463b474306913f2fcfaf1890641026d9fc6966fea27a + languageName: node + linkType: hard + "chokidar@npm:^4.0.1": version: 4.0.1 resolution: "chokidar@npm:4.0.1" @@ -3215,13 +3620,6 @@ __metadata: languageName: node linkType: hard -"chunkd@npm:^2.0.1": - version: 2.0.1 - resolution: "chunkd@npm:2.0.1" - checksum: 10/bab8cc08c752a3648984385dc6f61d751e89dbeef648d22a3b661e1d470eaa0f5182f0b4303710f13ae83d2f85144f8eb2dde7a975861d9021b5c56b881f457b - languageName: node - linkType: hard - "ci-info@npm:^4.0.0": version: 4.0.0 resolution: "ci-info@npm:4.0.0" @@ -3229,13 +3627,6 @@ __metadata: languageName: node linkType: hard -"ci-parallel-vars@npm:^1.0.1": - version: 1.0.1 - resolution: "ci-parallel-vars@npm:1.0.1" - checksum: 10/ae859831f7e8e3585db731b8306c336616e37bd709dad1d7775ea4c0731aefd94741dabb48201edc6827d000008fd7fb72cb977967614ee2d99d6b499f0c35fe - languageName: node - linkType: hard - "clean-regexp@npm:^1.0.0": version: 1.0.0 resolution: "clean-regexp@npm:1.0.0" @@ -3378,15 +3769,6 @@ __metadata: languageName: node linkType: hard -"code-excerpt@npm:^4.0.0": - version: 4.0.0 - resolution: "code-excerpt@npm:4.0.0" - dependencies: - convert-to-spaces: "npm:^2.0.1" - checksum: 10/d57137d8f4825879283a828cc02a1115b56858dc54ed06c625c8f67d6685d1becd2fbaa7f0ab19ecca1f5cca03f8c97bbc1f013cab40261e4d3275032e65efe9 - languageName: node - linkType: hard - "code-point-at@npm:^1.0.0": version: 1.1.0 resolution: "code-point-at@npm:1.1.0" @@ -3436,15 +3818,6 @@ __metadata: languageName: node linkType: hard -"color-support@npm:^1.1.2": - version: 1.1.3 - resolution: "color-support@npm:1.1.3" - bin: - color-support: bin.js - checksum: 10/4bcfe30eea1498fe1cabc852bbda6c9770f230ea0e4faf4611c5858b1b9e4dde3730ac485e65f54ca182f4c50b626c1bea7c8441ceda47367a54a818c248aa7a - languageName: node - linkType: hard - "color@npm:3.0.x": version: 3.0.0 resolution: "color@npm:3.0.0" @@ -3579,13 +3952,6 @@ __metadata: languageName: node linkType: hard -"common-path-prefix@npm:^3.0.0": - version: 3.0.0 - resolution: "common-path-prefix@npm:3.0.0" - checksum: 10/09c180e8d8495d42990d617f4d4b7522b5da20f6b236afe310192d401d1da8147a7835ae1ea37797ba0c2238ef3d06f3492151591451df34539fdb4b2630f2b3 - languageName: node - linkType: hard - "compare-func@npm:^2.0.0": version: 2.0.0 resolution: "compare-func@npm:2.0.0" @@ -3603,23 +3969,7 @@ __metadata: languageName: node linkType: hard -"concordance@npm:^5.0.4": - version: 5.0.4 - resolution: "concordance@npm:5.0.4" - dependencies: - date-time: "npm:^3.1.0" - esutils: "npm:^2.0.3" - fast-diff: "npm:^1.2.0" - js-string-escape: "npm:^1.0.1" - lodash: "npm:^4.17.15" - md5-hex: "npm:^3.0.1" - semver: "npm:^7.3.2" - well-known-symbols: "npm:^2.0.0" - checksum: 10/156bb786746c2f0f821fd8339da2e38f4307e30ad9c078c24e636892a3c98ae5fcabf8812ff4baa54f1fcd4d88e9efe3050279d928abd524f48d551be26814c2 - languageName: node - linkType: hard - -"console-control-strings@npm:^1.0.0, console-control-strings@npm:^1.1.0, console-control-strings@npm:~1.1.0": +"console-control-strings@npm:^1.0.0, console-control-strings@npm:~1.1.0": version: 1.1.0 resolution: "console-control-strings@npm:1.1.0" checksum: 10/27b5fa302bc8e9ae9e98c03c66d76ca289ad0c61ce2fe20ab288d288bee875d217512d2edb2363fc83165e88f1c405180cf3f5413a46e51b4fe1a004840c6cdb @@ -3665,13 +4015,6 @@ __metadata: languageName: node linkType: hard -"convert-to-spaces@npm:^2.0.1": - version: 2.0.1 - resolution: "convert-to-spaces@npm:2.0.1" - checksum: 10/bbb324e5916fe9866f65c0ff5f9c1ea933764d0bdb09fccaf59542e40545ed483db6b2339c6d9eb56a11965a58f1a6038f3174f0e2fb7601343c7107ca5e2751 - languageName: node - linkType: hard - "core-js-compat@npm:^3.38.1": version: 3.38.1 resolution: "core-js-compat@npm:3.38.1" @@ -3788,15 +4131,6 @@ __metadata: languageName: node linkType: hard -"currently-unhandled@npm:^0.4.1": - version: 0.4.1 - resolution: "currently-unhandled@npm:0.4.1" - dependencies: - array-find-index: "npm:^1.0.1" - checksum: 10/53fb803e582737bdb5de6b150f0924dd9abf7be606648b4c2871db1c682bf288e248e8066ef10548979732a680cfb6c047294e3877846c2cf2f8d40437d8a741 - languageName: node - linkType: hard - "cz-conventional-changelog@npm:3.2.0": version: 3.2.0 resolution: "cz-conventional-changelog@npm:3.2.0" @@ -3840,15 +4174,6 @@ __metadata: languageName: node linkType: hard -"date-time@npm:^3.1.0": - version: 3.1.0 - resolution: "date-time@npm:3.1.0" - dependencies: - time-zone: "npm:^1.0.0" - checksum: 10/f9cfcd1b15dfeabab15c0b9d18eb9e4e2d9d4371713564178d46a8f91ad577a290b5178b80050718d02d9c0cf646f8a875011e12d1ed05871e9f72c72c8a8fe6 - languageName: node - linkType: hard - "dayjs@npm:^1.11.13": version: 1.11.13 resolution: "dayjs@npm:1.11.13" @@ -3892,7 +4217,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.3.6, debug@npm:~4.3.6": +"debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:~4.3.6": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -3937,6 +4262,13 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10/a529b81e2ef8821621d20a36959a0328873a3e49d393ad11f8efe8559f31239494c2eb889b80342808674c475802ba95b9d6c4c27641b9a029405104c1b59fcf + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.3 resolution: "deep-is@npm:0.1.3" @@ -4036,13 +4368,6 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.0": - version: 2.0.3 - resolution: "detect-libc@npm:2.0.3" - checksum: 10/b4ea018d623e077bd395f168a9e81db77370dde36a5b01d067f2ad7989924a81d31cb547ff764acb2aa25d50bb7fdde0b0a93bec02212b0cb430621623246d39 - languageName: node - linkType: hard - "diff@npm:^7.0.0": version: 7.0.0 resolution: "diff@npm:7.0.0" @@ -4119,13 +4444,6 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^1.0.1": - version: 1.0.1 - resolution: "emittery@npm:1.0.1" - checksum: 10/65dacfa022e5d412eac767fc1e62c4b89dbdf52d8fe96c25435149ca656907e7d87a325d1e5b1dab063315a154f56f5ea4fdaa0f12f228370af1dc0d91b017c2 - languageName: node - linkType: hard - "emoji-regex@npm:^10.3.0": version: 10.3.0 resolution: "emoji-regex@npm:10.3.0" @@ -4195,18 +4513,94 @@ __metadata: languageName: node linkType: hard -"esbuild-register@npm:^3.6.0": - version: 3.6.0 - resolution: "esbuild-register@npm:3.6.0" - dependencies: - debug: "npm:^4.3.4" - peerDependencies: - esbuild: ">=0.12 <1" - checksum: 10/4ae1a016e3dad5b53c3d68cf07e31d8c1cec1a0b584038ece726097ac80bd33ab48fb224c766c9b341c04793837e652461eaca9327a116e7564f553b61ccca71 +"es-main@npm:^1.3.0": + version: 1.3.0 + resolution: "es-main@npm:1.3.0" + checksum: 10/7e9f21106caec29215f440ea6d1a872f40fd03a373aad1054688f5d9b162da9ff6af1e563f5a4eeab0a23a81a0e708296b069a0bbdbf641a8682259cffd0a4cf + languageName: node + linkType: hard + +"esbuild@npm:^0.21.3": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@esbuild/aix-ppc64": "npm:0.21.5" + "@esbuild/android-arm": "npm:0.21.5" + "@esbuild/android-arm64": "npm:0.21.5" + "@esbuild/android-x64": "npm:0.21.5" + "@esbuild/darwin-arm64": "npm:0.21.5" + "@esbuild/darwin-x64": "npm:0.21.5" + "@esbuild/freebsd-arm64": "npm:0.21.5" + "@esbuild/freebsd-x64": "npm:0.21.5" + "@esbuild/linux-arm": "npm:0.21.5" + "@esbuild/linux-arm64": "npm:0.21.5" + "@esbuild/linux-ia32": "npm:0.21.5" + "@esbuild/linux-loong64": "npm:0.21.5" + "@esbuild/linux-mips64el": "npm:0.21.5" + "@esbuild/linux-ppc64": "npm:0.21.5" + "@esbuild/linux-riscv64": "npm:0.21.5" + "@esbuild/linux-s390x": "npm:0.21.5" + "@esbuild/linux-x64": "npm:0.21.5" + "@esbuild/netbsd-x64": "npm:0.21.5" + "@esbuild/openbsd-x64": "npm:0.21.5" + "@esbuild/sunos-x64": "npm:0.21.5" + "@esbuild/win32-arm64": "npm:0.21.5" + "@esbuild/win32-ia32": "npm:0.21.5" + "@esbuild/win32-x64": "npm:0.21.5" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/d2ff2ca84d30cce8e871517374d6c2290835380dc7cd413b2d49189ed170d45e407be14de2cb4794cf76f75cf89955c4714726ebd3de7444b3046f5cab23ab6b languageName: node linkType: hard -"esbuild@npm:0.24.0": +"esbuild@npm:^0.24.0": version: 0.24.0 resolution: "esbuild@npm:0.24.0" dependencies: @@ -4289,6 +4683,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": "npm:0.23.1" + "@esbuild/android-arm": "npm:0.23.1" + "@esbuild/android-arm64": "npm:0.23.1" + "@esbuild/android-x64": "npm:0.23.1" + "@esbuild/darwin-arm64": "npm:0.23.1" + "@esbuild/darwin-x64": "npm:0.23.1" + "@esbuild/freebsd-arm64": "npm:0.23.1" + "@esbuild/freebsd-x64": "npm:0.23.1" + "@esbuild/linux-arm": "npm:0.23.1" + "@esbuild/linux-arm64": "npm:0.23.1" + "@esbuild/linux-ia32": "npm:0.23.1" + "@esbuild/linux-loong64": "npm:0.23.1" + "@esbuild/linux-mips64el": "npm:0.23.1" + "@esbuild/linux-ppc64": "npm:0.23.1" + "@esbuild/linux-riscv64": "npm:0.23.1" + "@esbuild/linux-s390x": "npm:0.23.1" + "@esbuild/linux-x64": "npm:0.23.1" + "@esbuild/netbsd-x64": "npm:0.23.1" + "@esbuild/openbsd-arm64": "npm:0.23.1" + "@esbuild/openbsd-x64": "npm:0.23.1" + "@esbuild/sunos-x64": "npm:0.23.1" + "@esbuild/win32-arm64": "npm:0.23.1" + "@esbuild/win32-ia32": "npm:0.23.1" + "@esbuild/win32-x64": "npm:0.23.1" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/f55fbd0bfb0f86ce67a6d2c6f6780729d536c330999ecb9f5a38d578fb9fda820acbbc67d6d1d377eed8fed50fc38f14ff9cb014f86dafab94269a7fb2177018 + languageName: node + linkType: hard + "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -4303,7 +4780,7 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:5.0.0, escape-string-regexp@npm:^5.0.0": +"escape-string-regexp@npm:5.0.0": version: 5.0.0 resolution: "escape-string-regexp@npm:5.0.0" checksum: 10/20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e @@ -4317,13 +4794,6 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^2.0.0": - version: 2.0.0 - resolution: "escape-string-regexp@npm:2.0.0" - checksum: 10/9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 - languageName: node - linkType: hard - "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -4539,7 +5009,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0, esprima@npm:^4.0.1": +"esprima@npm:^4.0.1": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -4583,14 +5053,16 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:2.0.2, estree-walker@npm:^2.0.1": - version: 2.0.2 - resolution: "estree-walker@npm:2.0.2" - checksum: 10/b02109c5d46bc2ed47de4990eef770f7457b1159a229f0999a09224d2b85ffeed2d7679cffcff90aeb4448e94b0168feb5265b209cdec29aad50a3d6e93d21e2 +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: 10/a65728d5727b71de172c5df323385755a16c0fdab8234dc756c3854cfee343261ddfbb72a809a5660fac8c75d960bb3e21aa898c2d7e9b19bb298482ca58a3af languageName: node linkType: hard -"esutils@npm:^2.0.2, esutils@npm:^2.0.3": +"esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" checksum: 10/b23acd24791db11d8f65be5ea58fd9a6ce2df5120ae2da65c16cfc5331ff59d5ac4ef50af66cd4bde238881503ec839928a0135b99a036a9cdfa22d17fd56cdb @@ -4678,6 +5150,13 @@ __metadata: languageName: node linkType: hard +"expect-type@npm:^1.1.0": + version: 1.1.0 + resolution: "expect-type@npm:1.1.0" + checksum: 10/05fca80ddc7d493a89361f783c6b000750fa04a8226bc24701f3b90adb0efc2fb467f2a0baaed4015a02d8b9034ef5bb87521df9dba980f50b1105bd596ef833 + languageName: node + linkType: hard + "external-editor@npm:^3.0.3": version: 3.1.0 resolution: "external-editor@npm:3.1.0" @@ -4696,14 +5175,7 @@ __metadata: languageName: node linkType: hard -"fast-diff@npm:^1.2.0": - version: 1.2.0 - resolution: "fast-diff@npm:1.2.0" - checksum: 10/f62419b3d770f201d51c3ee8c4443b752b3ba2d548a6639026b7e09a08203ed2699a8d1fe21efcb8c5186135002d5d2916c12a687cac63785626456a92915adc - languageName: node - linkType: hard - -"fast-glob@npm:^3.2.12, fast-glob@npm:^3.3.2": +"fast-glob@npm:^3.2.12, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.2": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -4729,19 +5201,6 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.3.0": - version: 3.3.1 - resolution: "fast-glob@npm:3.3.1" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 10/51bcd15472879dfe51d4b01c5b70bbc7652724d39cdd082ba11276dbd7d84db0f6b33757e1938af8b2768a4bf485d9be0c89153beae24ee8331d6dcc7550379f - languageName: node - linkType: hard - "fast-json-stable-stringify@npm:^2.0.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" @@ -4802,15 +5261,6 @@ __metadata: languageName: node linkType: hard -"figures@npm:^6.0.1": - version: 6.1.0 - resolution: "figures@npm:6.1.0" - dependencies: - is-unicode-supported: "npm:^2.0.0" - checksum: 10/9822d13630bee8e6a9f2da866713adf13854b07e0bfde042defa8bba32d47a1c0b2afa627ce73837c674cf9a5e3edce7e879ea72cb9ea7960b2390432d8e1167 - languageName: node - linkType: hard - "file-entry-cache@npm:^8.0.0": version: 8.0.0 resolution: "file-entry-cache@npm:8.0.0" @@ -4829,13 +5279,6 @@ __metadata: languageName: node linkType: hard -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: 10/b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 - languageName: node - linkType: hard - "fill-keys@npm:^1.0.2": version: 1.0.2 resolution: "fill-keys@npm:1.0.2" @@ -4872,13 +5315,6 @@ __metadata: languageName: node linkType: hard -"find-up-simple@npm:^1.0.0": - version: 1.0.0 - resolution: "find-up-simple@npm:1.0.0" - checksum: 10/91c3d51c1111b5eb4e6e6d71d21438f6571a37a69dc288d4222b98996756e2f472fa5393a4dddb5e1a84929405d87e86f4bdce798ba84ee513b79854960ec140 - languageName: node - linkType: hard - "find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -5035,6 +5471,25 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10/4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "function-bind@npm:^1.1.1": version: 1.1.1 resolution: "function-bind@npm:1.1.1" @@ -5049,23 +5504,6 @@ __metadata: languageName: node linkType: hard -"gauge@npm:^3.0.0": - version: 3.0.2 - resolution: "gauge@npm:3.0.2" - dependencies: - aproba: "npm:^1.0.3 || ^2.0.0" - color-support: "npm:^1.1.2" - console-control-strings: "npm:^1.0.0" - has-unicode: "npm:^2.0.1" - object-assign: "npm:^4.1.1" - signal-exit: "npm:^3.0.0" - string-width: "npm:^4.2.3" - strip-ansi: "npm:^6.0.1" - wide-align: "npm:^1.1.2" - checksum: 10/46df086451672a5fecd58f7ec86da74542c795f8e00153fbef2884286ce0e86653c3eb23be2d0abb0c4a82b9b2a9dec3b09b6a1cf31c28085fa0376599a26589 - languageName: node - linkType: hard - "gauge@npm:~2.7.3": version: 2.7.4 resolution: "gauge@npm:2.7.4" @@ -5110,6 +5548,15 @@ __metadata: languageName: node linkType: hard +"get-tsconfig@npm:^4.7.5": + version: 4.8.1 + resolution: "get-tsconfig@npm:4.8.1" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: 10/3fb5a8ad57b9633eaea085d81661e9e5c9f78b35d8f8689eaf8b8b45a2a3ebf3b3422266d4d7df765e308cc1e6231648d114803ab3d018332e29916f2c1de036 + languageName: node + linkType: hard + "git-raw-commits@npm:^4.0.0": version: 4.0.0 resolution: "git-raw-commits@npm:4.0.0" @@ -5284,20 +5731,6 @@ __metadata: languageName: node linkType: hard -"globby@npm:^14.0.0": - version: 14.0.1 - resolution: "globby@npm:14.0.1" - dependencies: - "@sindresorhus/merge-streams": "npm:^2.1.0" - fast-glob: "npm:^3.3.2" - ignore: "npm:^5.2.4" - path-type: "npm:^5.0.0" - slash: "npm:^5.1.0" - unicorn-magic: "npm:^0.1.0" - checksum: 10/b36f57afc45a857a884d82657603c7e1663b1e6f3f9afbeb53d12e42230469fc5b26a7e14a01e51086f3f25c138f58a7002036fcc8f3ca054097b6dd7c71d639 - languageName: node - linkType: hard - "globby@npm:^14.0.2": version: 14.0.2 resolution: "globby@npm:14.0.2" @@ -5338,14 +5771,14 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.2.10": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.2.10": +"graceful-fs@npm:^4.1.2": version: 4.2.10 resolution: "graceful-fs@npm:4.2.10" checksum: 10/0c83c52b62c68a944dcfb9d66b0f9f10f7d6e3d081e8067b9bfdc9e5f3a8896584d576036f82915773189eec1eba599397fc620e75c03c0610fb3d67c6713c1a @@ -5394,7 +5827,7 @@ __metadata: languageName: node linkType: hard -"has-unicode@npm:^2.0.0, has-unicode@npm:^2.0.1": +"has-unicode@npm:^2.0.0": version: 2.0.1 resolution: "has-unicode@npm:2.0.1" checksum: 10/041b4293ad6bf391e21c5d85ed03f412506d6623786b801c4ab39e4e6ca54993f13201bceb544d92963f9e0024e6e7fbf0cb1d84c9d6b31cb9c79c8c990d13d8 @@ -5537,13 +5970,6 @@ __metadata: languageName: node linkType: hard -"ignore-by-default@npm:^2.1.0": - version: 2.1.0 - resolution: "ignore-by-default@npm:2.1.0" - checksum: 10/2b2df4622b6a07a3e91893987be8f060dc553f7736b67e72aa2312041c450a6fa8371733d03c42f45a02e47ec824e961c2fba63a3d94fc59cbd669220a5b0d7a - languageName: node - linkType: hard - "ignore@npm:^5.2.0": version: 5.2.0 resolution: "ignore@npm:5.2.0" @@ -5699,13 +6125,6 @@ __metadata: languageName: node linkType: hard -"irregular-plurals@npm:^3.3.0": - version: 3.3.0 - resolution: "irregular-plurals@npm:3.3.0" - checksum: 10/603dfdc83128f2c9d8f6eb807db87a450edb307a63a1594aa38c6587b35a13b3723583a7634d6976143bf9f59669c8b8a6fed40f436f06ab8dab86a5c80a3359 - languageName: node - linkType: hard - "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -5885,20 +6304,6 @@ __metadata: languageName: node linkType: hard -"is-plain-object@npm:^5.0.0": - version: 5.0.0 - resolution: "is-plain-object@npm:5.0.0" - checksum: 10/e32d27061eef62c0847d303125440a38660517e586f2f3db7c9d179ae5b6674ab0f469d519b2e25c147a1a3bc87156d0d5f4d8821e0ce4a9ee7fe1fcf11ce45c - languageName: node - linkType: hard - -"is-promise@npm:^4.0.0": - version: 4.0.0 - resolution: "is-promise@npm:4.0.0" - checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a - languageName: node - linkType: hard - "is-stream@npm:^2.0.0": version: 2.0.0 resolution: "is-stream@npm:2.0.0" @@ -5929,13 +6334,6 @@ __metadata: languageName: node linkType: hard -"is-unicode-supported@npm:^2.0.0": - version: 2.0.0 - resolution: "is-unicode-supported@npm:2.0.0" - checksum: 10/000b80639dedaf59a385f1c0a57f97a4d1435e0723716f24cc19ad94253a7a0a9f838bdc9ac49b10a29ac93b01f52ae9b2ed358a8876caf1eb74d73b4ede92b2 - languageName: node - linkType: hard - "is-utf8@npm:^0.2.1": version: 0.2.1 resolution: "is-utf8@npm:0.2.1" @@ -5987,13 +6385,6 @@ __metadata: languageName: node linkType: hard -"js-string-escape@npm:^1.0.1": - version: 1.0.1 - resolution: "js-string-escape@npm:1.0.1" - checksum: 10/f11e0991bf57e0c183b55c547acec85bd2445f043efc9ea5aa68b41bd2a3e7d3ce94636cb233ae0d84064ba4c1a505d32e969813c5b13f81e7d4be12c59256fe - languageName: node - linkType: hard - "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -6001,18 +6392,6 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.14.1": - version: 3.14.1 - resolution: "js-yaml@npm:3.14.1" - dependencies: - argparse: "npm:^1.0.7" - esprima: "npm:^4.0.0" - bin: - js-yaml: bin/js-yaml.js - checksum: 10/9e22d80b4d0105b9899135365f746d47466ed53ef4223c529b3c0f7a39907743fdbd3c4379f94f1106f02755b5e90b2faaf84801a891135544e1ea475d1a1379 - languageName: node - linkType: hard - "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -6253,13 +6632,6 @@ __metadata: languageName: node linkType: hard -"load-json-file@npm:^7.0.1": - version: 7.0.1 - resolution: "load-json-file@npm:7.0.1" - checksum: 10/a560288da6891778321ef993e4bdbdf05374a4f3a3aeedd5ba6b64672798c830d748cfc59a2ec9891a3db30e78b3d04172e0dcb0d4828168289a393147ca0e74 - languageName: node - linkType: hard - "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -6364,7 +6736,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4.17.12, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:~4.17.15": +"lodash@npm:4.17.21, lodash@npm:^4.17.12, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:~4.17.15": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 @@ -6442,6 +6814,13 @@ __metadata: languageName: node linkType: hard +"loupe@npm:^3.1.0, loupe@npm:^3.1.2": + version: 3.1.2 + resolution: "loupe@npm:3.1.2" + checksum: 10/8f5734e53fb64cd914aa7d986e01b6d4c2e3c6c56dcbd5428d71c2703f0ab46b5ab9f9eeaaf2b485e8a1c43f865bdd16ec08ae1a661c8f55acdbd9f4d59c607a + languageName: node + linkType: hard + "lowercase-keys@npm:^3.0.0": version: 3.0.0 resolution: "lowercase-keys@npm:3.0.0" @@ -6458,12 +6837,12 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^3.1.0": - version: 3.1.0 - resolution: "make-dir@npm:3.1.0" +"magic-string@npm:^0.30.12": + version: 0.30.12 + resolution: "magic-string@npm:0.30.12" dependencies: - semver: "npm:^6.0.0" - checksum: 10/484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + checksum: 10/98016180a52b28efc1362152b45671067facccdaead6b70c1c14c566cba98491bc2e1336474b0996397730dca24400e85649da84d3da62b2560ed03c067573e6 languageName: node linkType: hard @@ -6504,24 +6883,6 @@ __metadata: languageName: node linkType: hard -"matcher@npm:^5.0.0": - version: 5.0.0 - resolution: "matcher@npm:5.0.0" - dependencies: - escape-string-regexp: "npm:^5.0.0" - checksum: 10/28f191c2d23fee0f6f32fd0181d9fe173b0ab815a919edba55605438a2f9fa40372e002574a1b17add981b0a8669c75bc6194318d065ed2dceffd8b160c38118 - languageName: node - linkType: hard - -"md5-hex@npm:^3.0.1": - version: 3.0.1 - resolution: "md5-hex@npm:3.0.1" - dependencies: - blueimp-md5: "npm:^2.10.0" - checksum: 10/4af5252998a525a01fc899b0df222a505ca6400f9de58d2fed26473ac91919331436a84cc5bf376a5fe1b1b45d3057a214ddaf86668b608e9be26221ca1585cc - languageName: node - linkType: hard - "mdns-server@npm:^1.0.11": version: 1.0.11 resolution: "mdns-server@npm:1.0.11" @@ -6531,15 +6892,6 @@ __metadata: languageName: node linkType: hard -"memoize@npm:^10.0.0": - version: 10.0.0 - resolution: "memoize@npm:10.0.0" - dependencies: - mimic-function: "npm:^5.0.0" - checksum: 10/2239451cc0b26f9e99e6107c2a24f069b8ccd98877b4fe4f28fe3a1e977521fe23a53fa7fb5e7ad485577e0f30ab61aed97cf29facbc701b88facf27b8f12ce3 - languageName: node - linkType: hard - "meow@npm:^12.0.1": version: 12.1.1 resolution: "meow@npm:12.1.1" @@ -6885,6 +7237,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" + bin: + nanoid: bin/nanoid.cjs + checksum: 10/ac1eb60f615b272bccb0e2b9cd933720dad30bf9708424f691b8113826bb91aca7e9d14ef5d9415a6ba15c266b37817256f58d8ce980c82b0ba3185352565679 + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -6921,20 +7282,6 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.7": - version: 2.7.0 - resolution: "node-fetch@npm:2.7.0" - dependencies: - whatwg-url: "npm:^5.0.0" - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - checksum: 10/b24f8a3dc937f388192e59bcf9d0857d7b6940a2496f328381641cb616efccc9866e89ec43f2ec956bbd6c3d3ee05524ce77fe7b29ccd34692b3a16f237d6676 - languageName: node - linkType: hard - "node-gyp-build@npm:4.6.0": version: 4.6.0 resolution: "node-gyp-build@npm:4.6.0" @@ -6946,17 +7293,6 @@ __metadata: languageName: node linkType: hard -"node-gyp-build@npm:^4.2.2": - version: 4.2.3 - resolution: "node-gyp-build@npm:4.2.3" - bin: - node-gyp-build: bin.js - node-gyp-build-optional: optional.js - node-gyp-build-test: build-test.js - checksum: 10/450d7b2016290d269343f8a33d13f4d7ccd0a38057af0d71a4d714fe06e6051da50b677a411ea9e240706253c4b53eb41e1b050df72d75d796b2e4d91b2757ae - languageName: node - linkType: hard - "node-gyp@npm:latest": version: 8.1.0 resolution: "node-gyp@npm:8.1.0" @@ -6978,16 +7314,9 @@ __metadata: linkType: hard "node-releases@npm:^2.0.18": - version: 2.0.18 - resolution: "node-releases@npm:2.0.18" - checksum: 10/241e5fa9556f1c12bafb83c6c3e94f8cf3d8f2f8f904906ecef6e10bcaa1d59aa61212d4651bec70052015fc54bd3fdcdbe7fc0f638a17e6685aa586c076ec4e - languageName: node - linkType: hard - -"nofilter@npm:^3.1.0": - version: 3.1.0 - resolution: "nofilter@npm:3.1.0" - checksum: 10/f63d87231dfda4b783db17d75b15aac948f78e65f4f1043096ef441147f6667ff74cd4b3f57ada5dbe240be282d3e9838558ac863a66cb04ef25fff7b2b4be4e + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: 10/241e5fa9556f1c12bafb83c6c3e94f8cf3d8f2f8f904906ecef6e10bcaa1d59aa61212d4651bec70052015fc54bd3fdcdbe7fc0f638a17e6685aa586c076ec4e languageName: node linkType: hard @@ -7051,18 +7380,6 @@ __metadata: languageName: node linkType: hard -"npmlog@npm:^5.0.1": - version: 5.0.1 - resolution: "npmlog@npm:5.0.1" - dependencies: - are-we-there-yet: "npm:^2.0.0" - console-control-strings: "npm:^1.1.0" - gauge: "npm:^3.0.0" - set-blocking: "npm:^2.0.0" - checksum: 10/f42c7b9584cdd26a13c41a21930b6f5912896b6419ab15be88cc5721fc792f1c3dd30eb602b26ae08575694628ba70afdcf3675d86e4f450fc544757e52726ec - languageName: node - linkType: hard - "nrf-intel-hex@npm:^1.4.0": version: 1.4.0 resolution: "nrf-intel-hex@npm:1.4.0" @@ -7077,7 +7394,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": +"object-assign@npm:^4.0.1, object-assign@npm:^4.1.0": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10/fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f @@ -7287,7 +7604,7 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^7.0.1, p-map@npm:^7.0.2": +"p-map@npm:^7.0.2": version: 7.0.2 resolution: "p-map@npm:7.0.2" checksum: 10/b4a590038b991c17b9c1484aa8c24cb9d3aa8a6167d02b9f9459c9200c7d392202a860c95b6dcd190d51f5f083ed256b32f9cb5976785022b0111bab853ec58b @@ -7325,16 +7642,6 @@ __metadata: languageName: node linkType: hard -"package-config@npm:^5.0.0": - version: 5.0.0 - resolution: "package-config@npm:5.0.0" - dependencies: - find-up-simple: "npm:^1.0.0" - load-json-file: "npm:^7.0.1" - checksum: 10/dfff5264c51a0dad7af9a55b02e3b8b6e457075e9c4f02d0ffacfeee9af4dd5db2b566dae41486412161292b8741483cd89d5a8404a5742fc54d718dadacac4a - languageName: node - linkType: hard - "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -7356,13 +7663,6 @@ __metadata: languageName: node linkType: hard -"parse-ms@npm:^4.0.0": - version: 4.0.0 - resolution: "parse-ms@npm:4.0.0" - checksum: 10/673c801d9f957ff79962d71ed5a24850163f4181a90dd30c4e3666b3a804f53b77f1f0556792e8b2adbb5d58757907d1aa51d7d7dc75997c2a56d72937cbc8b7 - languageName: node - linkType: hard - "parse-passwd@npm:^1.0.0": version: 1.0.0 resolution: "parse-passwd@npm:1.0.0" @@ -7463,6 +7763,20 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.1.2": + version: 1.1.2 + resolution: "pathe@npm:1.1.2" + checksum: 10/f201d796351bf7433d147b92c20eb154a4e0ea83512017bf4ec4e492a5d6e738fb45798be4259a61aa81270179fce11026f6ff0d3fa04173041de044defe9d80 + languageName: node + linkType: hard + +"pathval@npm:^2.0.0": + version: 2.0.0 + resolution: "pathval@npm:2.0.0" + checksum: 10/b91575bf9cdf01757afd7b5e521eb8a0b874a49bc972d08e0047cfea0cd3c019f5614521d4bc83d2855e3fcc331db6817dfd533dd8f3d90b16bc76fad2450fc1 + languageName: node + linkType: hard + "peggy@npm:^3.0.2": version: 3.0.2 resolution: "peggy@npm:3.0.2" @@ -7489,17 +7803,17 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc +"picocolors@npm:^1.1.0": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 languageName: node linkType: hard -"picomatch@npm:^3.0.1": - version: 3.0.1 - resolution: "picomatch@npm:3.0.1" - checksum: 10/65ac837fedbd0640586f7c214f6c7481e1e12f41cdcd22a95eb6a2914d1773707ed0f0b5bd2d1e39b5ec7860b43a4c9150152332a3884cd8dd1d419b2a2fa5b5 +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc languageName: node linkType: hard @@ -7531,15 +7845,6 @@ __metadata: languageName: node linkType: hard -"plur@npm:^5.1.0": - version: 5.1.0 - resolution: "plur@npm:5.1.0" - dependencies: - irregular-plurals: "npm:^3.3.0" - checksum: 10/57e400dc4b926768fb0abab7f8688fe17e85673712134546e7beaaee188bae7e0504976e847d7e41d0d6103ff2fd61204095f03c2a45de19a8bad15aecb45cc1 - languageName: node - linkType: hard - "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -7547,6 +7852,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.43": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" + dependencies: + nanoid: "npm:^3.3.7" + picocolors: "npm:^1.1.0" + source-map-js: "npm:^1.2.1" + checksum: 10/f2b50ba9b6fcb795232b6bb20de7cdc538c0025989a8ed9c4438d1960196ba3b7eaff41fdb1a5c701b3504651ea87aeb685577707f0ae4d6ce6f3eae5df79a81 + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -7563,15 +7879,6 @@ __metadata: languageName: node linkType: hard -"pretty-ms@npm:^9.0.0": - version: 9.0.0 - resolution: "pretty-ms@npm:9.0.0" - dependencies: - parse-ms: "npm:^4.0.0" - checksum: 10/b11e1eda41a2efcc16aab218392c8e457a8ae5c8edf63aafba0477123426b1268136b9b532cbfd84625bcb826739120ec8490286dab66102b9f09e717bdb4e45 - languageName: node - linkType: hard - "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -7794,15 +8101,6 @@ __metadata: languageName: node linkType: hard -"resolve-cwd@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-cwd@npm:3.0.0" - dependencies: - resolve-from: "npm:^5.0.0" - checksum: 10/546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 - languageName: node - linkType: hard - "resolve-dir@npm:^1.0.0, resolve-dir@npm:^1.0.1": version: 1.0.1 resolution: "resolve-dir@npm:1.0.1" @@ -7836,6 +8134,13 @@ __metadata: languageName: node linkType: hard +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e + languageName: node + linkType: hard + "resolve@npm:^1.10.0": version: 1.20.0 resolution: "resolve@npm:1.20.0" @@ -8031,6 +8336,75 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.20.0": + version: 4.24.3 + resolution: "rollup@npm:4.24.3" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.24.3" + "@rollup/rollup-android-arm64": "npm:4.24.3" + "@rollup/rollup-darwin-arm64": "npm:4.24.3" + "@rollup/rollup-darwin-x64": "npm:4.24.3" + "@rollup/rollup-freebsd-arm64": "npm:4.24.3" + "@rollup/rollup-freebsd-x64": "npm:4.24.3" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.24.3" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.24.3" + "@rollup/rollup-linux-arm64-gnu": "npm:4.24.3" + "@rollup/rollup-linux-arm64-musl": "npm:4.24.3" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.24.3" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.24.3" + "@rollup/rollup-linux-s390x-gnu": "npm:4.24.3" + "@rollup/rollup-linux-x64-gnu": "npm:4.24.3" + "@rollup/rollup-linux-x64-musl": "npm:4.24.3" + "@rollup/rollup-win32-arm64-msvc": "npm:4.24.3" + "@rollup/rollup-win32-ia32-msvc": "npm:4.24.3" + "@rollup/rollup-win32-x64-msvc": "npm:4.24.3" + "@types/estree": "npm:1.0.6" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10/23d9851bf9ac7f61590e401a790d2f266d46ce71b938429eae3523392a17147637420dfdd8344541b7b54e03ef4af7fa3deac7199f6a4bf5f06a286bd3b3ed97 + languageName: node + linkType: hard + "run-async@npm:^2.2.0, run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" @@ -8125,16 +8499,18 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0": - version: 6.3.1 - resolution: "semver@npm:6.3.1" +"semver@npm:^7.3.5": + version: 7.3.5 + resolution: "semver@npm:7.3.5" + dependencies: + lru-cache: "npm:^6.0.0" bin: semver: bin/semver.js - checksum: 10/1ef3a85bd02a760c6ef76a45b8c1ce18226de40831e02a00bad78485390b98b6ccaa31046245fc63bba4a47a6a592b6c7eedc65cc47126e60489f9cc1ce3ed7e + checksum: 10/22854378594943f2988ee853c02a7471dd02eba7bf75e286b98538114590a148dd59b22775edf42fcfb354438f304b8f32a53c136d228e99068ac52c60259324 languageName: node linkType: hard -"semver@npm:^7.3.2, semver@npm:^7.3.7": +"semver@npm:^7.3.7": version: 7.3.7 resolution: "semver@npm:7.3.7" dependencies: @@ -8145,17 +8521,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5": - version: 7.3.5 - resolution: "semver@npm:7.3.5" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 10/22854378594943f2988ee853c02a7471dd02eba7bf75e286b98538114590a148dd59b22775edf42fcfb354438f304b8f32a53c136d228e99068ac52c60259324 - languageName: node - linkType: hard - "semver@npm:^7.5.2": version: 7.5.3 resolution: "semver@npm:7.5.3" @@ -8198,15 +8563,6 @@ __metadata: languageName: node linkType: hard -"serialize-error@npm:^7.0.1": - version: 7.0.1 - resolution: "serialize-error@npm:7.0.1" - dependencies: - type-fest: "npm:^0.13.1" - checksum: 10/e0aba4dca2fc9fe74ae1baf38dbd99190e1945445a241ba646290f2176cdb2032281a76443b02ccf0caf30da5657d510746506368889a593b9835a497fc0732e - languageName: node - linkType: hard - "serialport@npm:^12.0.0": version: 12.0.0 resolution: "serialport@npm:12.0.0" @@ -8229,7 +8585,7 @@ __metadata: languageName: node linkType: hard -"set-blocking@npm:^2.0.0, set-blocking@npm:~2.0.0": +"set-blocking@npm:~2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" checksum: 10/8980ebf7ae9eb945bb036b6e283c547ee783a1ad557a82babf758a065e2fb6ea337fd82cac30dd565c1e606e423f30024a19fff7afbf4977d784720c4026a8ef @@ -8252,6 +8608,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10/e93ff66c6531a079af8fb217240df01f980155b5dc408d2d7bebc398dd284e383eb318153bf8acd4db3c4fe799aa5b9a641e38b0ba3b1975700b1c89547ea4e7 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.3 resolution: "signal-exit@npm:3.0.3" @@ -8259,7 +8622,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": +"signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" checksum: 10/c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f @@ -8365,6 +8728,13 @@ __metadata: languageName: node linkType: hard +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3 + languageName: node + linkType: hard + "source-map-support@npm:^0.5.21": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" @@ -8446,12 +8816,17 @@ __metadata: languageName: node linkType: hard -"stack-utils@npm:^2.0.6": - version: 2.0.6 - resolution: "stack-utils@npm:2.0.6" - dependencies: - escape-string-regexp: "npm:^2.0.0" - checksum: 10/cdc988acbc99075b4b036ac6014e5f1e9afa7e564482b687da6384eee6a1909d7eaffde85b0a17ffbe186c5247faf6c2b7544e802109f63b72c7be69b13151bb +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10/2d4dc4e64e2db796de4a3c856d5943daccdfa3dd092e452a1ce059c81e9a9c29e0b9badba91b43ef0d5ff5c04ee62feb3bcc559a804e16faf447bac2d883aa99 + languageName: node + linkType: hard + +"std-env@npm:^3.7.0": + version: 3.7.0 + resolution: "std-env@npm:3.7.0" + checksum: 10/6ee0cca1add3fd84656b0002cfbc5bfa20340389d9ba4720569840f1caa34bce74322aef4c93f046391583e50649d0cf81a5f8fe1d411e50b659571690a45f12 languageName: node linkType: hard @@ -8480,17 +8855,6 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.2.3": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: "npm:^8.0.0" - is-fullwidth-code-point: "npm:^3.0.0" - strip-ansi: "npm:^6.0.1" - checksum: 10/e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb - languageName: node - linkType: hard - "string-width@npm:^1.0.2 || 2, string-width@npm:^2.1.0": version: 2.1.1 resolution: "string-width@npm:2.1.1" @@ -8512,6 +8876,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10/e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + "string-width@npm:^7.0.0": version: 7.1.0 resolution: "string-width@npm:7.1.0" @@ -8586,15 +8961,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^7.0.1": - version: 7.0.1 - resolution: "strip-ansi@npm:7.0.1" - dependencies: - ansi-regex: "npm:^6.0.1" - checksum: 10/07b3142f515d673e05d2da1ae07bba1eb2ba3b588135a38dea598ca11913b6e9487a9f2c9bed4c74cd31e554012b4503d9fb7e6034c7324973854feea2319110 - languageName: node - linkType: hard - "strip-ansi@npm:^7.1.0": version: 7.1.0 resolution: "strip-ansi@npm:7.1.0" @@ -8648,18 +9014,6 @@ __metadata: languageName: node linkType: hard -"supertap@npm:^3.0.1": - version: 3.0.1 - resolution: "supertap@npm:3.0.1" - dependencies: - indent-string: "npm:^5.0.0" - js-yaml: "npm:^3.14.1" - serialize-error: "npm:^7.0.1" - strip-ansi: "npm:^7.0.1" - checksum: 10/2074334f793eef87a960b2dbee7e5106a9002ba83b2df507df6fe70b0014430e54f145e5ef6e9de507d413c2aadbf569b9f4c1dd600725ea295b9dec8bd6aaa3 - languageName: node - linkType: hard - "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -8703,7 +9057,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.0.2, tar@npm:^6.1.0, tar@npm:^6.1.11, tar@npm:^6.1.13": +"tar@npm:^6.0.2, tar@npm:^6.1.0, tar@npm:^6.1.13": version: 6.2.1 resolution: "tar@npm:6.2.1" dependencies: @@ -8717,13 +9071,6 @@ __metadata: languageName: node linkType: hard -"temp-dir@npm:^3.0.0": - version: 3.0.0 - resolution: "temp-dir@npm:3.0.0" - checksum: 10/577211e995d1d584dd60f1469351d45e8a5b4524e4a9e42d3bdd12cfde1d0bb8f5898311bef24e02aaafb69514c1feb58c7b4c33dcec7129da3b0861a4ca935b - languageName: node - linkType: hard - "text-extensions@npm:^2.0.0": version: 2.4.0 resolution: "text-extensions@npm:2.4.0" @@ -8770,13 +9117,6 @@ __metadata: languageName: node linkType: hard -"time-zone@npm:^1.0.0": - version: 1.0.0 - resolution: "time-zone@npm:1.0.0" - checksum: 10/e46f5a69b8c236dcd8e91e29d40d4e7a3495ed4f59888c3f84ce1d9678e20461421a6ba41233509d47dd94bc18f1a4377764838b21b584663f942b3426dcbce8 - languageName: node - linkType: hard - "tiny-glob@npm:^0.2.9": version: 0.2.9 resolution: "tiny-glob@npm:0.2.9" @@ -8787,6 +9127,13 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10/cfa1e1418e91289219501703c4693c70708c91ffb7f040fd318d24aef419fb5a43e0c0160df9471499191968b2451d8da7f8087b08c3133c251c40d24aced06c + languageName: node + linkType: hard + "tinyexec@npm:^0.3.0": version: 0.3.0 resolution: "tinyexec@npm:0.3.0" @@ -8794,6 +9141,13 @@ __metadata: languageName: node linkType: hard +"tinyexec@npm:^0.3.1": + version: 0.3.1 + resolution: "tinyexec@npm:0.3.1" + checksum: 10/0537c70590d52d354f40c0255ff0f654a3d18ddb3812b440ddf9d436edf516c8057838ad5a38744c0c59670ec03e3cf23fbe04ae3d49f031d948274e99002569 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.9": version: 0.2.9 resolution: "tinyglobby@npm:0.2.9" @@ -8804,6 +9158,27 @@ __metadata: languageName: node linkType: hard +"tinypool@npm:^1.0.1": + version: 1.0.1 + resolution: "tinypool@npm:1.0.1" + checksum: 10/eaceb93784b8e27e60c0e3e2c7d11c29e1e79b2a025b2c232215db73b90fe22bd4753ad53fc8e801c2b5a63b94a823af549555d8361272bc98271de7dd4a9925 + languageName: node + linkType: hard + +"tinyrainbow@npm:^1.2.0": + version: 1.2.0 + resolution: "tinyrainbow@npm:1.2.0" + checksum: 10/2924444db6804355e5ba2b6e586c7f77329d93abdd7257a069a0f4530dff9f16de484e80479094e3f39273462541b003a65ee3a6afc2d12555aa745132deba5d + languageName: node + linkType: hard + +"tinyspy@npm:^3.0.2": + version: 3.0.2 + resolution: "tinyspy@npm:3.0.2" + checksum: 10/5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 + languageName: node + linkType: hard + "tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" @@ -8822,13 +9197,6 @@ __metadata: languageName: node linkType: hard -"tr46@npm:~0.0.3": - version: 0.0.3 - resolution: "tr46@npm:0.0.3" - checksum: 10/8f1f5aa6cb232f9e1bdc86f485f916b7aa38caee8a778b378ffec0b70d9307873f253f5cbadbe2955ece2ac5c83d0dc14a77513166ccd0a0c7fe197e21396695 - languageName: node - linkType: hard - "trim-newlines@npm:^3.0.0": version: 3.0.1 resolution: "trim-newlines@npm:3.0.1" @@ -8889,7 +9257,7 @@ __metadata: languageName: node linkType: hard -"ts-pegjs@npm:^4.2.1": +"ts-pegjs@npm:4.2.1": version: 4.2.1 resolution: "ts-pegjs@npm:4.2.1" dependencies: @@ -8903,6 +9271,20 @@ __metadata: languageName: node linkType: hard +"ts-pegjs@patch:ts-pegjs@npm%3A4.2.1#~/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch": + version: 4.2.1 + resolution: "ts-pegjs@patch:ts-pegjs@npm%3A4.2.1#~/.yarn/patches/ts-pegjs-npm-4.2.1-0f567a1059.patch::version=4.2.1&hash=9d46d8" + dependencies: + prettier: "npm:^2.8.8" + ts-morph: "npm:^18.0.0" + peerDependencies: + peggy: ^3.0.2 + bin: + tspegjs: dist/cli.mjs + checksum: 10/ca77ccf6a288b6653d076071c78b3d787c95365825cffd3affe17df58171b5744e761b564d43d17ea9e411dc4f6802044bd05ac6337bbe048b91113f307f5291 + languageName: node + linkType: hard + "tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -8942,6 +9324,22 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.19.2": + version: 4.19.2 + resolution: "tsx@npm:4.19.2" + dependencies: + esbuild: "npm:~0.23.0" + fsevents: "npm:~2.3.3" + get-tsconfig: "npm:^4.7.5" + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 10/4c5610ed1fb2f80d766681f8ac7827e1e8118dfe354c18f74800691f3ef1e9ed676a29842ab818806bcf8613cdc97c6af84b5645e768ddb7f4b0527b9100deda + languageName: node + linkType: hard + "tunnel@npm:^0.0.6": version: 0.0.6 resolution: "tunnel@npm:0.0.6" @@ -9234,36 +9632,119 @@ __metadata: languageName: node linkType: hard -"wcwidth@npm:^1.0.1": - version: 1.0.1 - resolution: "wcwidth@npm:1.0.1" +"vite-node@npm:2.1.4": + version: 2.1.4 + resolution: "vite-node@npm:2.1.4" dependencies: - defaults: "npm:^1.0.3" - checksum: 10/182ebac8ca0b96845fae6ef44afd4619df6987fe5cf552fdee8396d3daa1fb9b8ec5c6c69855acb7b3c1231571393bd1f0a4cdc4028d421575348f64bb0a8817 + cac: "npm:^6.7.14" + debug: "npm:^4.3.7" + pathe: "npm:^1.1.2" + vite: "npm:^5.0.0" + bin: + vite-node: vite-node.mjs + checksum: 10/3c3fbe6e41ab1716f4e6e0b52dcb80e027cb481df03e31d9bb5d16bb0ffabc5c884cca705ef8a5dea60f787e5eb78a428977d0d40e61e1f331bfb8c3d486d3e2 languageName: node linkType: hard -"webidl-conversions@npm:^3.0.0": - version: 3.0.1 - resolution: "webidl-conversions@npm:3.0.1" - checksum: 10/b65b9f8d6854572a84a5c69615152b63371395f0c5dcd6729c45789052296df54314db2bc3e977df41705eacb8bc79c247cee139a63fa695192f95816ed528ad +"vite@npm:^5.0.0": + version: 5.4.10 + resolution: "vite@npm:5.4.10" + dependencies: + esbuild: "npm:^0.21.3" + fsevents: "npm:~2.3.3" + postcss: "npm:^8.4.43" + rollup: "npm:^4.20.0" + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 10/5d4a427d585d6f9114fc383114f707dca46408f54b221709e5eb6b0c16e0b4dec4baf908a7db9a8f1e5b16e64b655900ac14629abe61c698cbe296115c65ed8a languageName: node linkType: hard -"well-known-symbols@npm:^2.0.0": - version: 2.0.0 - resolution: "well-known-symbols@npm:2.0.0" - checksum: 10/4f54bbc3012371cb4d228f436891b8e7536d34ac61a57541890257e96788608e096231e0121ac24d08ef2f908b3eb2dc0adba35023eaeb2a7df655da91415402 +"vitest@npm:^2.1.4": + version: 2.1.4 + resolution: "vitest@npm:2.1.4" + dependencies: + "@vitest/expect": "npm:2.1.4" + "@vitest/mocker": "npm:2.1.4" + "@vitest/pretty-format": "npm:^2.1.4" + "@vitest/runner": "npm:2.1.4" + "@vitest/snapshot": "npm:2.1.4" + "@vitest/spy": "npm:2.1.4" + "@vitest/utils": "npm:2.1.4" + chai: "npm:^5.1.2" + debug: "npm:^4.3.7" + expect-type: "npm:^1.1.0" + magic-string: "npm:^0.30.12" + pathe: "npm:^1.1.2" + std-env: "npm:^3.7.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.1" + tinypool: "npm:^1.0.1" + tinyrainbow: "npm:^1.2.0" + vite: "npm:^5.0.0" + vite-node: "npm:2.1.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/node": ^18.0.0 || >=20.0.0 + "@vitest/browser": 2.1.4 + "@vitest/ui": 2.1.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10/bf0bb39e6148678ccc0d856a6a08e99458e80266558f97757bd20980812cd439f51599bcb64c807805594bf6fdb2111fdca688bc8884524819cc4a84a4598109 languageName: node linkType: hard -"whatwg-url@npm:^5.0.0": - version: 5.0.0 - resolution: "whatwg-url@npm:5.0.0" +"wcwidth@npm:^1.0.1": + version: 1.0.1 + resolution: "wcwidth@npm:1.0.1" dependencies: - tr46: "npm:~0.0.3" - webidl-conversions: "npm:^3.0.0" - checksum: 10/f95adbc1e80820828b45cc671d97da7cd5e4ef9deb426c31bcd5ab00dc7103042291613b3ef3caec0a2335ed09e0d5ed026c940755dbb6d404e2b27f940fdf07 + defaults: "npm:^1.0.3" + checksum: 10/182ebac8ca0b96845fae6ef44afd4619df6987fe5cf552fdee8396d3daa1fb9b8ec5c6c69855acb7b3c1231571393bd1f0a4cdc4028d421575348f64bb0a8817 languageName: node linkType: hard @@ -9289,6 +9770,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10/0de6e6cd8f2f94a8b5ca44e84cf1751eadcac3ebedcdc6e5fbbe6c8011904afcbc1a2777c53496ec02ced7b81f2e7eda61e76bf8262a8bc3ceaa1f6040508051 + languageName: node + linkType: hard + "wide-align@npm:^1.1.0": version: 1.1.3 resolution: "wide-align@npm:1.1.3" @@ -9298,15 +9791,6 @@ __metadata: languageName: node linkType: hard -"wide-align@npm:^1.1.2": - version: 1.1.5 - resolution: "wide-align@npm:1.1.5" - dependencies: - string-width: "npm:^1.0.2 || 2 || 3 || 4" - checksum: 10/d5f8027b9a8255a493a94e4ec1b74a27bff6679d5ffe29316a3215e4712945c84ef73ca4045c7e20ae7d0c72f5f57f296e04a4928e773d4276a2f1222e4c2e99 - languageName: node - linkType: hard - "winston-daily-rotate-file@npm:^5.0.0": version: 5.0.0 resolution: "winston-daily-rotate-file@npm:5.0.0" @@ -9398,16 +9882,6 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^5.0.1": - version: 5.0.1 - resolution: "write-file-atomic@npm:5.0.1" - dependencies: - imurmurhash: "npm:^0.1.4" - signal-exit: "npm:^4.0.1" - checksum: 10/648efddba54d478d0e4330ab6f239976df3b9752b123db5dc9405d9b5af768fa9d70ce60c52fdbe61d1200d24350bc4fbcbaf09288496c2be050de126bd95b7e - languageName: node - linkType: hard - "xml2js@npm:^0.6.2": version: 0.6.2 resolution: "xml2js@npm:0.6.2" @@ -9545,7 +10019,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.7.2": +"yargs@npm:^17.5.1, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -9578,6 +10052,7 @@ __metadata: version: 0.0.0-use.local resolution: "zwave-js@workspace:packages/zwave-js" dependencies: + "@alcalzone/esm2cjs": "npm:^1.2.3" "@alcalzone/jsonl-db": "npm:^3.1.1" "@alcalzone/pak": "npm:^0.11.0" "@homebridge/ciao": "npm:^1.3.1" @@ -9601,10 +10076,7 @@ __metadata: "@zwave-js/transformers": "workspace:*" alcalzone-shared: "npm:^4.0.8" ansi-colors: "npm:^4.1.3" - ava: "npm:^6.1.3" del-cli: "npm:^6.0.0" - esbuild: "npm:0.24.0" - esbuild-register: "npm:^3.6.0" execa: "npm:^5.1.1" got: "npm:^13.0.0" mdns-server: "npm:^1.0.11" @@ -9617,7 +10089,9 @@ __metadata: serialport: "npm:^12.0.0" sinon: "npm:^19.0.2" source-map-support: "npm:^0.5.21" + tsx: "npm:^4.19.2" typescript: "npm:5.6.2" + vitest: "npm:^2.1.4" winston: "npm:^3.15.0" xstate: "npm:4.38.3" bin: