node-switchbot 2.5.0-beta.9 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/beta-release.yml +25 -2
- package/.github/workflows/release.yml +13 -0
- package/BLE.md +1144 -0
- package/CHANGELOG.md +22 -0
- package/OpenAPI.md +185 -0
- package/README.md +20 -1189
- package/branding/Node_x_SwitchBot.svg +9 -0
- package/branding/icon.png +0 -0
- package/branding/switchbot.png +0 -0
- package/dist/advertising.d.ts +3 -3
- package/dist/advertising.d.ts.map +1 -1
- package/dist/advertising.js +26 -26
- package/dist/advertising.js.map +1 -1
- package/dist/device/woblindtilt.d.ts +19 -50
- package/dist/device/woblindtilt.d.ts.map +1 -1
- package/dist/device/woblindtilt.js +41 -100
- package/dist/device/woblindtilt.js.map +1 -1
- package/dist/device/wobulb.d.ts +41 -15
- package/dist/device/wobulb.d.ts.map +1 -1
- package/dist/device/wobulb.js +72 -128
- package/dist/device/wobulb.js.map +1 -1
- package/dist/device/woceilinglight.d.ts +47 -21
- package/dist/device/woceilinglight.d.ts.map +1 -1
- package/dist/device/woceilinglight.js +96 -171
- package/dist/device/woceilinglight.js.map +1 -1
- package/dist/device/wocontact.d.ts +11 -1
- package/dist/device/wocontact.d.ts.map +1 -1
- package/dist/device/wocontact.js +23 -22
- package/dist/device/wocontact.js.map +1 -1
- package/dist/device/wocurtain.d.ts +39 -1
- package/dist/device/wocurtain.d.ts.map +1 -1
- package/dist/device/wocurtain.js +69 -103
- package/dist/device/wocurtain.js.map +1 -1
- package/dist/device/wohand.d.ts +37 -2
- package/dist/device/wohand.d.ts.map +1 -1
- package/dist/device/wohand.js +55 -89
- package/dist/device/wohand.js.map +1 -1
- package/dist/device/wohub2.d.ts +11 -1
- package/dist/device/wohub2.d.ts.map +1 -1
- package/dist/device/wohub2.js +21 -29
- package/dist/device/wohub2.js.map +1 -1
- package/dist/device/wohumi.d.ts +37 -2
- package/dist/device/wohumi.d.ts.map +1 -1
- package/dist/device/wohumi.js +52 -83
- package/dist/device/wohumi.js.map +1 -1
- package/dist/device/woiosensorth.d.ts +12 -1
- package/dist/device/woiosensorth.d.ts.map +1 -1
- package/dist/device/woiosensorth.js +25 -29
- package/dist/device/woiosensorth.js.map +1 -1
- package/dist/device/woplugmini.d.ts +45 -12
- package/dist/device/woplugmini.d.ts.map +1 -1
- package/dist/device/woplugmini.js +71 -77
- package/dist/device/woplugmini.js.map +1 -1
- package/dist/device/wopresence.d.ts +11 -1
- package/dist/device/wopresence.d.ts.map +1 -1
- package/dist/device/wopresence.js +21 -27
- package/dist/device/wopresence.js.map +1 -1
- package/dist/device/wosensorth.d.ts +18 -2
- package/dist/device/wosensorth.d.ts.map +1 -1
- package/dist/device/wosensorth.js +34 -50
- package/dist/device/wosensorth.js.map +1 -1
- package/dist/device/wosmartlock.d.ts +63 -13
- package/dist/device/wosmartlock.d.ts.map +1 -1
- package/dist/device/wosmartlock.js +114 -195
- package/dist/device/wosmartlock.js.map +1 -1
- package/dist/device/wosmartlockpro.d.ts +16 -12
- package/dist/device/wosmartlockpro.d.ts.map +1 -1
- package/dist/device/wosmartlockpro.js +34 -29
- package/dist/device/wosmartlockpro.js.map +1 -1
- package/dist/device/wostrip.d.ts +4 -3
- package/dist/device/wostrip.d.ts.map +1 -1
- package/dist/device/wostrip.js +5 -4
- package/dist/device/wostrip.js.map +1 -1
- package/dist/device.d.ts +13 -5
- package/dist/device.d.ts.map +1 -1
- package/dist/device.js +13 -2
- package/dist/device.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/parameter-checker.d.ts +10 -13
- package/dist/parameter-checker.d.ts.map +1 -1
- package/dist/parameter-checker.js +16 -1
- package/dist/parameter-checker.js.map +1 -1
- package/dist/settings.d.ts +47 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +49 -0
- package/dist/settings.js.map +1 -1
- package/dist/{switchbot.d.ts → switchbot-ble.d.ts} +12 -9
- package/dist/switchbot-ble.d.ts.map +1 -0
- package/dist/switchbot-ble.js +426 -0
- package/dist/switchbot-ble.js.map +1 -0
- package/dist/switchbot-openapi.d.ts +131 -0
- package/dist/switchbot-openapi.d.ts.map +1 -0
- package/dist/switchbot-openapi.js +311 -0
- package/dist/switchbot-openapi.js.map +1 -0
- package/dist/test/advertising.test.d.ts +2 -0
- package/dist/test/advertising.test.d.ts.map +1 -0
- package/dist/test/advertising.test.js +99 -0
- package/dist/test/advertising.test.js.map +1 -0
- package/dist/test/device.test.d.ts +2 -0
- package/dist/test/device.test.d.ts.map +1 -0
- package/dist/test/device.test.js +38 -0
- package/dist/test/device.test.js.map +1 -0
- package/dist/test/index.test.d.ts +2 -0
- package/dist/test/index.test.d.ts.map +1 -0
- package/dist/test/index.test.js +35 -0
- package/dist/test/index.test.js.map +1 -0
- package/dist/test/parameter-checker.test.d.ts +2 -0
- package/dist/test/parameter-checker.test.d.ts.map +1 -0
- package/dist/test/parameter-checker.test.js +108 -0
- package/dist/test/parameter-checker.test.js.map +1 -0
- package/dist/test/settings.test.d.ts +2 -0
- package/dist/test/settings.test.d.ts.map +1 -0
- package/dist/test/settings.test.js +49 -0
- package/dist/test/settings.test.js.map +1 -0
- package/dist/test/switchbot-openapi.test.d.ts +2 -0
- package/dist/test/switchbot-openapi.test.d.ts.map +1 -0
- package/dist/test/switchbot-openapi.test.js +96 -0
- package/dist/test/switchbot-openapi.test.js.map +1 -0
- package/dist/test/switchbot.test.d.ts +2 -0
- package/dist/test/switchbot.test.d.ts.map +1 -0
- package/dist/test/switchbot.test.js +106 -0
- package/dist/test/switchbot.test.js.map +1 -0
- package/dist/test/woblindtilt.test.js +70 -20
- package/dist/test/woblindtilt.test.js.map +1 -1
- package/dist/test/wobulb.test.js +87 -44
- package/dist/test/wobulb.test.js.map +1 -1
- package/dist/test/woceilinglight.test.js +72 -54
- package/dist/test/woceilinglight.test.js.map +1 -1
- package/dist/test/wocontact.test.js +51 -20
- package/dist/test/wocontact.test.js.map +1 -1
- package/dist/test/wocurtain.test.js +65 -23
- package/dist/test/wocurtain.test.js.map +1 -1
- package/dist/test/wohand.test.js +34 -40
- package/dist/test/wohand.test.js.map +1 -1
- package/dist/test/wohub2.test.d.ts +2 -0
- package/dist/test/wohub2.test.d.ts.map +1 -0
- package/dist/test/wohub2.test.js +80 -0
- package/dist/test/wohub2.test.js.map +1 -0
- package/dist/test/wohumi.test.js +70 -49
- package/dist/test/wohumi.test.js.map +1 -1
- package/dist/test/woiosensorth.test.js +33 -32
- package/dist/test/woiosensorth.test.js.map +1 -1
- package/dist/test/woplugmini.test.js +80 -57
- package/dist/test/woplugmini.test.js.map +1 -1
- package/dist/test/wopresence.test.js +44 -18
- package/dist/test/wopresence.test.js.map +1 -1
- package/dist/test/wosensorth.test.js +44 -52
- package/dist/test/wosensorth.test.js.map +1 -1
- package/dist/test/wosmartlock.test.js +126 -59
- package/dist/test/wosmartlock.test.js.map +1 -1
- package/dist/test/wosmartlockpro.test.js +96 -69
- package/dist/test/wosmartlockpro.test.js.map +1 -1
- package/dist/test/wostrip.test.js +70 -83
- package/dist/test/wostrip.test.js.map +1 -1
- package/dist/types/bledevicestatus.d.ts +4 -12
- package/dist/types/bledevicestatus.d.ts.map +1 -1
- package/dist/types/devicelist.d.ts.map +1 -1
- package/dist/types/devicelist.js +0 -4
- package/dist/types/devicelist.js.map +1 -1
- package/dist/types/devicepush.d.ts +13 -0
- package/dist/types/devicepush.d.ts.map +1 -0
- package/dist/types/devicepush.js +2 -0
- package/dist/types/devicepush.js.map +1 -0
- package/dist/types/deviceresponse.d.ts +2 -3
- package/dist/types/deviceresponse.d.ts.map +1 -1
- package/dist/types/devicestatus.d.ts.map +1 -1
- package/dist/types/devicewebhookstatus.d.ts +32 -0
- package/dist/types/devicewebhookstatus.d.ts.map +1 -1
- package/dist/types/irdevicelist.d.ts.map +1 -1
- package/dist/types/types.d.ts +24 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +14 -0
- package/dist/types/types.js.map +1 -1
- package/docs/assets/highlight.css +12 -47
- package/docs/assets/main.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/SwitchBotBLE.html +62 -0
- package/docs/classes/SwitchBotOpenAPI.html +47 -0
- package/docs/classes/SwitchbotDevice.html +32 -33
- package/docs/enums/LogLevel.html +10 -0
- package/docs/enums/SwitchBotBLEModel.html +2 -2
- package/docs/enums/SwitchBotBLEModelFriendlyName.html +2 -2
- package/docs/enums/SwitchBotBLEModelName.html +2 -2
- package/docs/enums/SwitchBotModel.html +2 -2
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +16 -993
- package/docs/interfaces/Ad-1.html +5 -0
- package/docs/interfaces/AdvertisementData.html +3 -0
- package/docs/interfaces/Chars.html +4 -0
- package/docs/interfaces/ErrorObject.html +3 -0
- package/docs/interfaces/Params.html +6 -0
- package/docs/interfaces/Rule.html +9 -0
- package/docs/interfaces/ServiceData.html +2 -0
- package/docs/interfaces/SwitchBotBLEDevice.html +21 -0
- package/docs/interfaces/WebhookDetail.html +6 -0
- package/docs/interfaces/ad.html +5 -0
- package/docs/interfaces/body.html +3 -0
- package/docs/interfaces/bodyChange.html +4 -0
- package/docs/interfaces/deleteWebhookResponse.html +4 -0
- package/docs/interfaces/device.html +7 -0
- package/docs/interfaces/deviceList.html +2 -0
- package/docs/interfaces/deviceStatus.html +7 -0
- package/docs/interfaces/deviceStatusRequest.html +4 -0
- package/docs/interfaces/deviceWebhook.html +4 -0
- package/docs/interfaces/deviceWebhookContext.html +4 -0
- package/docs/interfaces/devices.html +4 -0
- package/docs/interfaces/infraredRemoteList.html +2 -0
- package/docs/interfaces/irdevice.html +5 -0
- package/docs/interfaces/pushResponse.html +4 -0
- package/docs/interfaces/queryWebhookResponse.html +4 -0
- package/docs/interfaces/setupWebhookResponse.html +4 -0
- package/docs/interfaces/switchbot.html +3 -0
- package/docs/interfaces/updateWebhookResponse.html +4 -0
- package/docs/interfaces/webhookRequest.html +4 -0
- package/docs/media/BLE.md +1144 -0
- package/docs/media/OpenAPI.md +185 -0
- package/docs/modules.html +137 -3
- package/docs/types/MacAddress.html +1 -0
- package/docs/types/batteryCirculatorFan.html +1 -0
- package/docs/types/batteryCirculatorFanServiceData.html +1 -0
- package/docs/types/batteryCirculatorFanStatus.html +1 -0
- package/docs/types/batteryCirculatorFanWebhookContext.html +1 -0
- package/docs/types/blindTilt.html +1 -0
- package/docs/types/blindTiltServiceData.html +1 -0
- package/docs/types/blindTiltStatus.html +1 -0
- package/docs/types/blindTiltWebhookContext.html +1 -0
- package/docs/types/bot.html +1 -0
- package/docs/types/botServiceData.html +1 -0
- package/docs/types/botStatus.html +1 -0
- package/docs/types/botWebhookContext.html +1 -0
- package/docs/types/ceilingLight.html +1 -0
- package/docs/types/ceilingLightPro.html +1 -0
- package/docs/types/ceilingLightProServiceData.html +1 -0
- package/docs/types/ceilingLightProStatus.html +1 -0
- package/docs/types/ceilingLightProWebhookContext.html +1 -0
- package/docs/types/ceilingLightServiceData.html +1 -0
- package/docs/types/ceilingLightStatus.html +1 -0
- package/docs/types/ceilingLightWebhookContext.html +1 -0
- package/docs/types/colorBulb.html +1 -0
- package/docs/types/colorBulbServiceData.html +1 -0
- package/docs/types/colorBulbStatus.html +1 -0
- package/docs/types/colorBulbWebhookContext.html +1 -0
- package/docs/types/contactSensor.html +1 -0
- package/docs/types/contactSensorServiceData.html +1 -0
- package/docs/types/contactSensorStatus.html +1 -0
- package/docs/types/contactSensorWebhookContext.html +1 -0
- package/docs/types/curtain.html +1 -0
- package/docs/types/curtain3.html +1 -0
- package/docs/types/curtain3ServiceData.html +1 -0
- package/docs/types/curtain3WebhookContext.html +1 -0
- package/docs/types/curtainServiceData.html +1 -0
- package/docs/types/curtainStatus.html +1 -0
- package/docs/types/curtainWebhookContext.html +1 -0
- package/docs/types/floorCleaningRobotS10.html +1 -0
- package/docs/types/floorCleaningRobotS10Status.html +1 -0
- package/docs/types/floorCleaningRobotS10WebhookContext.html +1 -0
- package/docs/types/hub2.html +1 -0
- package/docs/types/hub2ServiceData.html +1 -0
- package/docs/types/hub2Status.html +1 -0
- package/docs/types/hub2WebhookContext.html +1 -0
- package/docs/types/humidifier.html +1 -0
- package/docs/types/humidifierServiceData.html +1 -0
- package/docs/types/humidifierStatus.html +1 -0
- package/docs/types/humidifierWebhookContext.html +1 -0
- package/docs/types/indoorCam.html +1 -0
- package/docs/types/indoorCameraWebhookContext.html +1 -0
- package/docs/types/keypad.html +1 -0
- package/docs/types/keypadTouch.html +1 -0
- package/docs/types/keypadTouchWebhookContext.html +1 -0
- package/docs/types/keypadWebhookContext.html +1 -0
- package/docs/types/lock.html +1 -0
- package/docs/types/lockPro.html +1 -0
- package/docs/types/lockProServiceData.html +1 -0
- package/docs/types/lockProStatus.html +1 -0
- package/docs/types/lockProWebhookContext.html +1 -0
- package/docs/types/lockServiceData.html +1 -0
- package/docs/types/lockStatus.html +1 -0
- package/docs/types/lockWebhookContext.html +1 -0
- package/docs/types/meter.html +1 -0
- package/docs/types/meterPlus.html +1 -0
- package/docs/types/meterPlusServiceData.html +1 -0
- package/docs/types/meterPlusStatus.html +1 -0
- package/docs/types/meterPlusWebhookContext.html +1 -0
- package/docs/types/meterServiceData.html +1 -0
- package/docs/types/meterStatus.html +1 -0
- package/docs/types/meterWebhookContext.html +1 -0
- package/docs/types/motionSensor.html +1 -0
- package/docs/types/motionSensorServiceData.html +1 -0
- package/docs/types/motionSensorStatus.html +1 -0
- package/docs/types/motionSensorWebhookContext.html +1 -0
- package/docs/types/outdoorMeter.html +1 -0
- package/docs/types/outdoorMeterServiceData.html +1 -0
- package/docs/types/outdoorMeterStatus.html +1 -0
- package/docs/types/outdoorMeterWebhookContext.html +1 -0
- package/docs/types/panTiltCamWebhookContext.html +1 -0
- package/docs/types/pantiltCam.html +1 -0
- package/docs/types/pantiltCam2k.html +1 -0
- package/docs/types/plug.html +1 -0
- package/docs/types/plugMini.html +1 -0
- package/docs/types/plugMiniJPServiceData.html +1 -0
- package/docs/types/plugMiniJPWebhookContext.html +1 -0
- package/docs/types/plugMiniStatus.html +1 -0
- package/docs/types/plugMiniUSServiceData.html +1 -0
- package/docs/types/plugMiniUSWebhookContext.html +1 -0
- package/docs/types/plugStatus.html +1 -0
- package/docs/types/plugWebhookContext.html +1 -0
- package/docs/types/remote.html +1 -0
- package/docs/types/robotVacuumCleanerS1.html +1 -0
- package/docs/types/robotVacuumCleanerS1Plus.html +1 -0
- package/docs/types/robotVacuumCleanerS1PlusStatus.html +1 -0
- package/docs/types/robotVacuumCleanerS1PlusWebhookContext.html +1 -0
- package/docs/types/robotVacuumCleanerS1Status.html +1 -0
- package/docs/types/robotVacuumCleanerS1WebhookContext.html +1 -0
- package/docs/types/robotVacuumCleanerServiceData.html +1 -0
- package/docs/types/stripLight.html +1 -0
- package/docs/types/stripLightServiceData.html +1 -0
- package/docs/types/stripLightStatus.html +1 -0
- package/docs/types/stripLightWebhookContext.html +1 -0
- package/docs/types/waterLeakDetector.html +1 -0
- package/docs/types/waterLeakDetectorServiceData.html +1 -0
- package/docs/types/waterLeakDetectorStatus.html +1 -0
- package/docs/types/waterLeakDetectorWebhookContext.html +1 -0
- package/package.json +15 -13
- package/.github/npm-version-script.cjs +0 -81
- package/dist/switchbot.d.ts.map +0 -1
- package/dist/switchbot.js +0 -259
- package/dist/switchbot.js.map +0 -1
- package/dist/test/wohand2.test.d.ts +0 -2
- package/dist/test/wohand2.test.d.ts.map +0 -1
- package/dist/test/wohand2.test.js +0 -50
- package/dist/test/wohand2.test.js.map +0 -1
- package/dist/types/pushbody.d.ts +0 -6
- package/dist/types/pushbody.d.ts.map +0 -1
- package/dist/types/pushbody.js +0 -2
- package/dist/types/pushbody.js.map +0 -1
- package/docs/classes/SwitchBot.html +0 -16
- package/docs/types/SwitchBotBLEDevice.html +0 -1
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import crypto, { randomUUID } from 'node:crypto';
|
|
3
|
+
import { EventEmitter } from 'node:events';
|
|
4
|
+
import { createServer } from 'node:http';
|
|
5
|
+
import { request } from 'undici';
|
|
6
|
+
import { baseURL, deleteWebhook, devicesURL, queryWebhook, setupWebhook, updateWebhook } from './settings.js';
|
|
7
|
+
/**
|
|
8
|
+
* The `SwitchBotOpenAPI` class provides methods to interact with the SwitchBot OpenAPI.
|
|
9
|
+
* It allows you to retrieve device information, control devices, and manage webhooks.
|
|
10
|
+
*
|
|
11
|
+
* @extends EventEmitter
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const switchBotAPI = new SwitchBotOpenAPI('your-token', 'your-secret');
|
|
16
|
+
*
|
|
17
|
+
* // Get devices
|
|
18
|
+
* switchBotAPI.getDevices().then(response => {
|
|
19
|
+
* console.log(response);
|
|
20
|
+
* }).catch(error => {
|
|
21
|
+
* console.error(error);
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Control a device
|
|
25
|
+
* switchBotAPI.controlDevice('device-id', 'turnOn', 'default').then(response => {
|
|
26
|
+
* console.log(response);
|
|
27
|
+
* }).catch(error => {
|
|
28
|
+
* console.error(error);
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Setup webhook
|
|
32
|
+
* switchBotAPI.setupWebhook('http://your-webhook-url').then(() => {
|
|
33
|
+
* console.log('Webhook setup successfully');
|
|
34
|
+
* }).catch(error => {
|
|
35
|
+
* console.error(error);
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param {string} token - The API token used for authentication.
|
|
40
|
+
* @param {string} secret - The secret key used for signing requests.
|
|
41
|
+
*/
|
|
42
|
+
export class SwitchBotOpenAPI extends EventEmitter {
|
|
43
|
+
token;
|
|
44
|
+
secret;
|
|
45
|
+
baseURL;
|
|
46
|
+
webhookEventListener = null;
|
|
47
|
+
/**
|
|
48
|
+
* Creates an instance of the SwitchBot OpenAPI client.
|
|
49
|
+
*
|
|
50
|
+
* @param token - The API token used for authentication.
|
|
51
|
+
* @param secret - The secret key used for signing requests.
|
|
52
|
+
*/
|
|
53
|
+
constructor(token, secret) {
|
|
54
|
+
super();
|
|
55
|
+
this.token = token;
|
|
56
|
+
this.secret = secret;
|
|
57
|
+
this.baseURL = baseURL;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Emits a log event with the specified log level and message.
|
|
61
|
+
*
|
|
62
|
+
* @param level - The severity level of the log (e.g., 'info', 'warn', 'error').
|
|
63
|
+
* @param message - The log message to be emitted.
|
|
64
|
+
*/
|
|
65
|
+
async emitLog(level, message) {
|
|
66
|
+
this.emit('log', { level, message });
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves the list of devices from the SwitchBot OpenAPI.
|
|
70
|
+
*
|
|
71
|
+
* @returns {Promise<{ response: body, statusCode: number }>} A promise that resolves to an object containing the API response.
|
|
72
|
+
* @throws {Error} Throws an error if the request to get devices fails.
|
|
73
|
+
*/
|
|
74
|
+
async getDevices() {
|
|
75
|
+
try {
|
|
76
|
+
const { body, statusCode } = await request(devicesURL, { headers: this.generateHeaders() });
|
|
77
|
+
const response = await body.json();
|
|
78
|
+
this.emitLog('debug', `Got devices: ${JSON.stringify(response)}`);
|
|
79
|
+
this.emitLog('debug', `statusCode: ${statusCode}`);
|
|
80
|
+
return { response, statusCode };
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
this.emitLog('error', `Failed to get devices: ${error.message}`);
|
|
84
|
+
throw new Error(`Failed to get devices: ${error.message}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Controls a device by sending a command to the SwitchBot API.
|
|
89
|
+
*
|
|
90
|
+
* @param deviceId - The unique identifier of the device to control.
|
|
91
|
+
* @param command - The command to send to the device.
|
|
92
|
+
* @param parameter - The parameter for the command.
|
|
93
|
+
* @param commandType - The type of the command, defaults to 'command'.
|
|
94
|
+
* @returns {Promise<{ response: pushResponse['body'], statusCode: number }>} A promise that resolves to an object containing the API response.
|
|
95
|
+
* @throws An error if the device control fails.
|
|
96
|
+
*/
|
|
97
|
+
async controlDevice(deviceId, command, parameter, commandType = 'command') {
|
|
98
|
+
try {
|
|
99
|
+
const { body, statusCode } = await request(`${this.baseURL}/devices/${deviceId}/commands`, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
headers: this.generateHeaders(),
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
command,
|
|
104
|
+
parameter,
|
|
105
|
+
commandType,
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
const response = await body.json();
|
|
109
|
+
this.emitLog('debug', `Controlled device: ${deviceId} with command: ${command} and parameter: ${parameter}`);
|
|
110
|
+
this.emitLog('debug', `statusCode: ${statusCode}`);
|
|
111
|
+
return { response, statusCode };
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
this.emitLog('error', `Failed to control device: ${error.message}`);
|
|
115
|
+
throw new Error(`Failed to control device: ${error.message}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Retrieves the status of a specific device.
|
|
120
|
+
*
|
|
121
|
+
* @param deviceId - The unique identifier of the device.
|
|
122
|
+
* @returns {Promise<{ response: deviceStatus, statusCode: number }>} A promise that resolves to the device status.
|
|
123
|
+
* @throws An error if the request fails.
|
|
124
|
+
*/
|
|
125
|
+
async getDeviceStatus(deviceId) {
|
|
126
|
+
try {
|
|
127
|
+
const { body, statusCode } = await request(`${this.baseURL}/devices/${deviceId}/status`, {
|
|
128
|
+
method: 'GET',
|
|
129
|
+
headers: this.generateHeaders(),
|
|
130
|
+
});
|
|
131
|
+
const response = await body.json();
|
|
132
|
+
this.emitLog('debug', `Got device status: ${deviceId}`);
|
|
133
|
+
this.emitLog('debug', `statusCode: ${statusCode}`);
|
|
134
|
+
return { response, statusCode };
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
this.emitLog('error', `Failed to get device status: ${error.message}`);
|
|
138
|
+
throw new Error(`Failed to get device status: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Generates the headers required for authentication with the SwitchBot OpenAPI.
|
|
143
|
+
*
|
|
144
|
+
* @returns An object containing the following headers:
|
|
145
|
+
* - `Authorization`: The token used for authorization.
|
|
146
|
+
* - `sign`: The HMAC-SHA256 signature of the concatenated token, timestamp, and nonce.
|
|
147
|
+
* - `nonce`: A unique identifier for the request, formatted as a UUID.
|
|
148
|
+
* - `t`: The current timestamp in milliseconds since the Unix epoch.
|
|
149
|
+
* - `Content-Type`: The content type of the request, set to `application/json`.
|
|
150
|
+
*/
|
|
151
|
+
generateHeaders = () => {
|
|
152
|
+
const t = `${Date.now()}`;
|
|
153
|
+
const nonce = randomUUID();
|
|
154
|
+
const data = this.token + t + nonce;
|
|
155
|
+
const signTerm = crypto
|
|
156
|
+
.createHmac('sha256', this.secret)
|
|
157
|
+
.update(Buffer.from(data, 'utf-8'))
|
|
158
|
+
.digest();
|
|
159
|
+
const sign = signTerm.toString('base64');
|
|
160
|
+
return {
|
|
161
|
+
'Authorization': this.token,
|
|
162
|
+
'sign': sign,
|
|
163
|
+
'nonce': nonce,
|
|
164
|
+
't': t,
|
|
165
|
+
'Content-Type': 'application/json',
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Sets up a webhook listener and configures the webhook on the server.
|
|
170
|
+
*
|
|
171
|
+
* This method performs the following steps:
|
|
172
|
+
* 1. Creates a local server to listen for incoming webhook events.
|
|
173
|
+
* 2. Sends a request to set up the webhook with the provided URL.
|
|
174
|
+
* 3. Sends a request to update the webhook configuration.
|
|
175
|
+
* 4. Sends a request to query the current webhook URL.
|
|
176
|
+
*
|
|
177
|
+
* @param url - The URL to which the webhook events will be sent.
|
|
178
|
+
* @returns A promise that resolves when the webhook setup is complete.
|
|
179
|
+
*
|
|
180
|
+
* @throws Will log an error if any step in the webhook setup process fails.
|
|
181
|
+
*/
|
|
182
|
+
async setupWebhook(url) {
|
|
183
|
+
try {
|
|
184
|
+
const xurl = new URL(url);
|
|
185
|
+
const port = Number(xurl.port);
|
|
186
|
+
const path = xurl.pathname;
|
|
187
|
+
this.webhookEventListener = createServer(async (request, response) => {
|
|
188
|
+
try {
|
|
189
|
+
if (request.url === path && request.method === 'POST') {
|
|
190
|
+
request.on('data', async (data) => {
|
|
191
|
+
try {
|
|
192
|
+
const body = JSON.parse(data);
|
|
193
|
+
await this.emitLog('debug', `Received Webhook: ${JSON.stringify(body)}`);
|
|
194
|
+
this.emit('webhookEvent', body);
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
await this.emitLog('error', `Failed to handle webhook event data. Error:${e}`);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
201
|
+
response.end('OK');
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
await this.emitLog('error', `Invalid request received. URL:${request.url}, Method:${request.method}`);
|
|
205
|
+
response.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
206
|
+
response.end(`NG`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
await this.emitLog('error', `Failed to handle webhook event. Error:${e}`);
|
|
211
|
+
}
|
|
212
|
+
}).listen(port || 80);
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
await this.emitLog('error', `Failed to create webhook listener. Error:${e.message}`);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const { body, statusCode } = await request(setupWebhook, {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers: this.generateHeaders(),
|
|
222
|
+
body: JSON.stringify({
|
|
223
|
+
action: 'setupWebhook',
|
|
224
|
+
url,
|
|
225
|
+
deviceList: 'ALL',
|
|
226
|
+
}),
|
|
227
|
+
});
|
|
228
|
+
const response = await body.json();
|
|
229
|
+
await this.emitLog('debug', `setupWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
230
|
+
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
231
|
+
await this.emitLog('error', `Failed to configure webhook. Existing webhook well be overridden. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (e) {
|
|
235
|
+
await this.emitLog('error', `Failed to configure webhook. Error: ${e.message}`);
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const { body, statusCode } = await request(updateWebhook, {
|
|
239
|
+
method: 'POST',
|
|
240
|
+
headers: this.generateHeaders(),
|
|
241
|
+
body: JSON.stringify({
|
|
242
|
+
action: 'updateWebhook',
|
|
243
|
+
config: {
|
|
244
|
+
url,
|
|
245
|
+
enable: true,
|
|
246
|
+
},
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
249
|
+
const response = await body.json();
|
|
250
|
+
await this.emitLog('debug', `updateWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
251
|
+
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
252
|
+
await this.emitLog('error', `Failed to update webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (e) {
|
|
256
|
+
await this.emitLog('error', `Failed to update webhook. Error:${e.message}`);
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
const { body, statusCode } = await request(queryWebhook, {
|
|
260
|
+
method: 'POST',
|
|
261
|
+
headers: this.generateHeaders(),
|
|
262
|
+
body: JSON.stringify({
|
|
263
|
+
action: 'queryUrl',
|
|
264
|
+
}),
|
|
265
|
+
});
|
|
266
|
+
const response = await body.json();
|
|
267
|
+
await this.emitLog('debug', `queryWebhook: body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
268
|
+
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
269
|
+
await this.emitLog('error', `Failed to query webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
await this.emitLog('info', `Listening webhook on ${response?.body?.urls[0]}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch (e) {
|
|
276
|
+
await this.emitLog('error', `Failed to query webhook. Error:${e}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Deletes a webhook by sending a request to the specified URL.
|
|
281
|
+
*
|
|
282
|
+
* @param url - The URL of the webhook to be deleted.
|
|
283
|
+
* @returns A promise that resolves when the webhook is successfully deleted.
|
|
284
|
+
*
|
|
285
|
+
* @throws Will log an error if the deletion fails.
|
|
286
|
+
*/
|
|
287
|
+
async deleteWebhook(url) {
|
|
288
|
+
try {
|
|
289
|
+
const { body, statusCode } = await request(deleteWebhook, {
|
|
290
|
+
method: 'POST',
|
|
291
|
+
headers: this.generateHeaders(),
|
|
292
|
+
body: JSON.stringify({
|
|
293
|
+
action: 'deleteWebhook',
|
|
294
|
+
url,
|
|
295
|
+
}),
|
|
296
|
+
});
|
|
297
|
+
const response = await body.json();
|
|
298
|
+
await this.emitLog('debug', `deleteWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
299
|
+
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
300
|
+
await this.emitLog('error', `Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
await this.emitLog('info', 'Unregistered webhook to close listening.');
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (e) {
|
|
307
|
+
await this.emitLog('error', `Failed to delete webhook. Error:${e.message}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=switchbot-openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switchbot-openapi.js","sourceRoot":"","sources":["../src/switchbot-openapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advertising.test.d.ts","sourceRoot":"","sources":["../../src/test/advertising.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { Advertising } from '../advertising.js';
|
|
4
|
+
describe('advertising', () => {
|
|
5
|
+
describe('parse', () => {
|
|
6
|
+
it('should return null if advertisement or serviceData is missing', async () => {
|
|
7
|
+
const peripheral = {
|
|
8
|
+
advertisement: null,
|
|
9
|
+
};
|
|
10
|
+
const mockLog = vi.fn();
|
|
11
|
+
const result = await Advertising.parse(peripheral, mockLog);
|
|
12
|
+
expect(result).toBeNull();
|
|
13
|
+
});
|
|
14
|
+
it('should return null if serviceData or manufacturerData is invalid', async () => {
|
|
15
|
+
const peripheral = {
|
|
16
|
+
advertisement: {
|
|
17
|
+
serviceData: [{ data: null }],
|
|
18
|
+
manufacturerData: null,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const mockLog = vi.fn();
|
|
22
|
+
const result = await Advertising.parse(peripheral, mockLog);
|
|
23
|
+
expect(result).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
it('should return parsed data for a recognized device model', async () => {
|
|
26
|
+
const serviceData = Buffer.from('010203', 'hex');
|
|
27
|
+
const manufacturerData = Buffer.from('040506', 'hex');
|
|
28
|
+
const peripheral = {
|
|
29
|
+
id: 'test-id',
|
|
30
|
+
advertisement: {
|
|
31
|
+
serviceData: [{ data: serviceData }],
|
|
32
|
+
manufacturerData,
|
|
33
|
+
},
|
|
34
|
+
rssi: -60,
|
|
35
|
+
address: '00:11:22:33:44:55',
|
|
36
|
+
};
|
|
37
|
+
const mockLog = vi.fn();
|
|
38
|
+
const mockParseServiceData = vi.fn().mockResolvedValue({ key: 'value' });
|
|
39
|
+
vi.spyOn(Advertising, 'parseServiceData').mockImplementation(mockParseServiceData);
|
|
40
|
+
const result = await Advertising.parse(peripheral, mockLog);
|
|
41
|
+
expect(result).toEqual({
|
|
42
|
+
id: 'test-id',
|
|
43
|
+
address: '00:11:22:33:44:55',
|
|
44
|
+
rssi: -60,
|
|
45
|
+
serviceData: { model: '\x01', key: 'value' },
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
it('should log and return null if parsed serviceData is empty', async () => {
|
|
49
|
+
const serviceData = Buffer.from('010203', 'hex');
|
|
50
|
+
const manufacturerData = Buffer.from('040506', 'hex');
|
|
51
|
+
const peripheral = {
|
|
52
|
+
id: 'test-id',
|
|
53
|
+
advertisement: {
|
|
54
|
+
serviceData: [{ data: serviceData }],
|
|
55
|
+
manufacturerData,
|
|
56
|
+
},
|
|
57
|
+
rssi: -60,
|
|
58
|
+
address: '00:11:22:33:44:55',
|
|
59
|
+
};
|
|
60
|
+
const mockLog = vi.fn();
|
|
61
|
+
vi.spyOn(Advertising, 'parseServiceData').mockResolvedValue(null);
|
|
62
|
+
const result = await Advertising.parse(peripheral, mockLog);
|
|
63
|
+
expect(result).toBeNull();
|
|
64
|
+
expect(mockLog).toHaveBeenCalledWith('[parseAdvertising.test-id.\x01] return null, parsed serviceData empty!');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('validateBuffer', () => {
|
|
68
|
+
it('should return true for valid buffer', () => {
|
|
69
|
+
const buffer = Buffer.from('010203', 'hex');
|
|
70
|
+
const result = Advertising.validateBuffer(buffer);
|
|
71
|
+
expect(result).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
it('should return false for invalid buffer', () => {
|
|
74
|
+
const buffer = null;
|
|
75
|
+
const result = Advertising.validateBuffer(buffer);
|
|
76
|
+
expect(result).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe('formatAddress', () => {
|
|
80
|
+
it('should format address correctly', () => {
|
|
81
|
+
const peripheral = {
|
|
82
|
+
address: '00-11-22-33-44-55',
|
|
83
|
+
};
|
|
84
|
+
const result = Advertising.formatAddress(peripheral);
|
|
85
|
+
expect(result).toBe('00:11:22:33:44:55');
|
|
86
|
+
});
|
|
87
|
+
it('should format address from manufacturerData if address is empty', () => {
|
|
88
|
+
const peripheral = {
|
|
89
|
+
address: '',
|
|
90
|
+
advertisement: {
|
|
91
|
+
manufacturerData: Buffer.from('0000112233445566', 'hex'),
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
const result = Advertising.formatAddress(peripheral);
|
|
95
|
+
expect(result).toBe('11:22:33:44:55:66');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=advertising.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advertising.test.js","sourceRoot":"","sources":["../../src/test/advertising.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.test.d.ts","sourceRoot":"","sources":["../../src/test/device.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SwitchbotDevice } from '../device.js';
|
|
2
|
+
describe('switchbotDevice', () => {
|
|
3
|
+
let mockPeripheral;
|
|
4
|
+
let mockNoble;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
mockPeripheral = {
|
|
7
|
+
connectAsync: jest.fn().mockResolvedValue(undefined),
|
|
8
|
+
disconnectAsync: jest.fn().mockResolvedValue(undefined),
|
|
9
|
+
discoverServicesAsync: jest.fn().mockResolvedValue([]),
|
|
10
|
+
state: 'disconnected',
|
|
11
|
+
once: jest.fn(),
|
|
12
|
+
removeAllListeners: jest.fn(),
|
|
13
|
+
discoverCharacteristicsAsync: jest.fn().mockResolvedValue([]),
|
|
14
|
+
};
|
|
15
|
+
mockNoble = {
|
|
16
|
+
_state: 'poweredOn',
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
it('should initialize with correct properties', async () => {
|
|
20
|
+
const device = new SwitchbotDevice(mockPeripheral, mockNoble);
|
|
21
|
+
expect(device.id).toBe('');
|
|
22
|
+
expect(device.address).toBe('');
|
|
23
|
+
expect(device.model).toBe('');
|
|
24
|
+
expect(device.modelName).toBe('');
|
|
25
|
+
expect(device.connectionState).toBe('disconnected');
|
|
26
|
+
});
|
|
27
|
+
it('should connect to the device', async () => {
|
|
28
|
+
const device = new SwitchbotDevice(mockPeripheral, mockNoble);
|
|
29
|
+
await device.connect();
|
|
30
|
+
expect(mockPeripheral.connectAsync).toHaveBeenCalled();
|
|
31
|
+
});
|
|
32
|
+
it('should disconnect from the device', async () => {
|
|
33
|
+
const device = new SwitchbotDevice(mockPeripheral, mockNoble);
|
|
34
|
+
await device.disconnect();
|
|
35
|
+
expect(mockPeripheral.disconnectAsync).toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=device.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.test.js","sourceRoot":"","sources":["../../src/test/device.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,cAA6C,CAAA;IACjD,IAAI,SAAoC,CAAA;IAExC,UAAU,CAAC,GAAG,EAAE;QACd,cAAc,GAAG;YACf,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACpD,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACvD,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACtD,KAAK,EAAE,cAA+E;YACtF,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACf,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC7B,4BAA4B,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;SAClB,CAAA;QAE7C,SAAS,GAAG;YACV,MAAM,EAAE,WAAW;SACoB,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;QAC7D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC1B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC7B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;QAC7D,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;QACtB,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,gBAAgB,EAAE,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;QAC7D,MAAM,MAAM,CAAC,UAAU,EAAE,CAAA;QACzB,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,CAAA;IAC3D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/test/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import * as index from '../index.js';
|
|
3
|
+
describe('index module exports', () => {
|
|
4
|
+
it('should export switchbot', () => {
|
|
5
|
+
expect(index).toHaveProperty('switchbot');
|
|
6
|
+
});
|
|
7
|
+
it('should export switchbot-openapi', () => {
|
|
8
|
+
expect(index).toHaveProperty('switchbot-openapi');
|
|
9
|
+
});
|
|
10
|
+
it('should export bledevicestatus', () => {
|
|
11
|
+
expect(index).toHaveProperty('bledevicestatus');
|
|
12
|
+
});
|
|
13
|
+
it('should export devicelist', () => {
|
|
14
|
+
expect(index).toHaveProperty('devicelist');
|
|
15
|
+
});
|
|
16
|
+
it('should export devicepush', () => {
|
|
17
|
+
expect(index).toHaveProperty('devicepush');
|
|
18
|
+
});
|
|
19
|
+
it('should export deviceresponse', () => {
|
|
20
|
+
expect(index).toHaveProperty('deviceresponse');
|
|
21
|
+
});
|
|
22
|
+
it('should export devicestatus', () => {
|
|
23
|
+
expect(index).toHaveProperty('devicestatus');
|
|
24
|
+
});
|
|
25
|
+
it('should export devicewebhookstatus', () => {
|
|
26
|
+
expect(index).toHaveProperty('devicewebhookstatus');
|
|
27
|
+
});
|
|
28
|
+
it('should export irdevicelist', () => {
|
|
29
|
+
expect(index).toHaveProperty('irdevicelist');
|
|
30
|
+
});
|
|
31
|
+
it('should export types', () => {
|
|
32
|
+
expect(index).toHaveProperty('types');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/test/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AAEpC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,qBAAqB,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-checker.test.d.ts","sourceRoot":"","sources":["../../src/test/parameter-checker.test.ts"],"names":[],"mappings":""}
|