homebridge-myleviton 3.0.0
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/LICENSE +202 -0
- package/README.md +112 -0
- package/config.schema.json +136 -0
- package/dist/api/cache.d.ts +108 -0
- package/dist/api/cache.d.ts.map +1 -0
- package/dist/api/cache.js +206 -0
- package/dist/api/cache.js.map +1 -0
- package/dist/api/circuit-breaker.d.ts +118 -0
- package/dist/api/circuit-breaker.d.ts.map +1 -0
- package/dist/api/circuit-breaker.js +223 -0
- package/dist/api/circuit-breaker.js.map +1 -0
- package/dist/api/client.d.ts +116 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +358 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/index.d.ts +23 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +47 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/persistence.d.ts +107 -0
- package/dist/api/persistence.d.ts.map +1 -0
- package/dist/api/persistence.js +285 -0
- package/dist/api/persistence.js.map +1 -0
- package/dist/api/rate-limiter.d.ts +102 -0
- package/dist/api/rate-limiter.d.ts.map +1 -0
- package/dist/api/rate-limiter.js +173 -0
- package/dist/api/rate-limiter.js.map +1 -0
- package/dist/api/request-queue.d.ts +104 -0
- package/dist/api/request-queue.d.ts.map +1 -0
- package/dist/api/request-queue.js +223 -0
- package/dist/api/request-queue.js.map +1 -0
- package/dist/api/websocket.d.ts +116 -0
- package/dist/api/websocket.d.ts.map +1 -0
- package/dist/api/websocket.js +319 -0
- package/dist/api/websocket.js.map +1 -0
- package/dist/errors/index.d.ts +182 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +273 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +139 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +664 -0
- package/dist/platform.js.map +1 -0
- package/dist/types/index.d.ts +225 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +34 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +15 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +52 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +103 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +184 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retry.d.ts +56 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +141 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/sanitizers.d.ts +37 -0
- package/dist/utils/sanitizers.d.ts.map +1 -0
- package/dist/utils/sanitizers.js +128 -0
- package/dist/utils/sanitizers.js.map +1 -0
- package/dist/utils/validators.d.ts +51 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +243 -0
- package/dist/utils/validators.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 tbaur
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0
|
|
6
|
+
* See LICENSE file for full license text
|
|
7
|
+
*
|
|
8
|
+
* @fileoverview Input validation utilities
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.validateEmail = validateEmail;
|
|
12
|
+
exports.validatePassword = validatePassword;
|
|
13
|
+
exports.validateDeviceId = validateDeviceId;
|
|
14
|
+
exports.validateSerial = validateSerial;
|
|
15
|
+
exports.validateToken = validateToken;
|
|
16
|
+
exports.validatePowerState = validatePowerState;
|
|
17
|
+
exports.validateBrightness = validateBrightness;
|
|
18
|
+
exports.validateConfig = validateConfig;
|
|
19
|
+
exports.assertDefined = assertDefined;
|
|
20
|
+
exports.validateNonEmptyArray = validateNonEmptyArray;
|
|
21
|
+
const errors_1 = require("../errors");
|
|
22
|
+
/**
|
|
23
|
+
* Email regex pattern
|
|
24
|
+
*/
|
|
25
|
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
26
|
+
/**
|
|
27
|
+
* Device ID pattern (alphanumeric)
|
|
28
|
+
*/
|
|
29
|
+
const DEVICE_ID_REGEX = /^[a-zA-Z0-9-]+$/;
|
|
30
|
+
/**
|
|
31
|
+
* Serial number pattern
|
|
32
|
+
*/
|
|
33
|
+
const SERIAL_REGEX = /^[A-Za-z0-9]+$/;
|
|
34
|
+
/**
|
|
35
|
+
* Validate email format
|
|
36
|
+
*/
|
|
37
|
+
function validateEmail(email) {
|
|
38
|
+
if (!email || typeof email !== 'string') {
|
|
39
|
+
throw new errors_1.ValidationError('email', 'must be a non-empty string');
|
|
40
|
+
}
|
|
41
|
+
const trimmed = email.trim();
|
|
42
|
+
if (trimmed.length === 0) {
|
|
43
|
+
throw new errors_1.ValidationError('email', 'cannot be empty');
|
|
44
|
+
}
|
|
45
|
+
if (trimmed.length > 254) {
|
|
46
|
+
throw new errors_1.ValidationError('email', 'exceeds maximum length of 254 characters');
|
|
47
|
+
}
|
|
48
|
+
if (!EMAIL_REGEX.test(trimmed)) {
|
|
49
|
+
throw new errors_1.ValidationError('email', 'invalid format');
|
|
50
|
+
}
|
|
51
|
+
return trimmed.toLowerCase();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate password
|
|
55
|
+
*/
|
|
56
|
+
function validatePassword(password) {
|
|
57
|
+
if (!password || typeof password !== 'string') {
|
|
58
|
+
throw new errors_1.ValidationError('password', 'must be a non-empty string');
|
|
59
|
+
}
|
|
60
|
+
if (password.length === 0) {
|
|
61
|
+
throw new errors_1.ValidationError('password', 'cannot be empty');
|
|
62
|
+
}
|
|
63
|
+
if (password.length > 128) {
|
|
64
|
+
throw new errors_1.ValidationError('password', 'exceeds maximum length of 128 characters');
|
|
65
|
+
}
|
|
66
|
+
return password;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validate device ID
|
|
70
|
+
* Accepts strings or numbers (Leviton API returns numeric IDs)
|
|
71
|
+
*/
|
|
72
|
+
function validateDeviceId(id) {
|
|
73
|
+
// Handle numeric IDs from API
|
|
74
|
+
if (typeof id === 'number' && Number.isFinite(id)) {
|
|
75
|
+
return String(id);
|
|
76
|
+
}
|
|
77
|
+
if (!id || typeof id !== 'string') {
|
|
78
|
+
throw new errors_1.ValidationError('deviceId', 'must be a non-empty string or number');
|
|
79
|
+
}
|
|
80
|
+
const trimmed = id.trim();
|
|
81
|
+
if (trimmed.length === 0) {
|
|
82
|
+
throw new errors_1.ValidationError('deviceId', 'cannot be empty');
|
|
83
|
+
}
|
|
84
|
+
if (!DEVICE_ID_REGEX.test(trimmed)) {
|
|
85
|
+
throw new errors_1.ValidationError('deviceId', 'contains invalid characters');
|
|
86
|
+
}
|
|
87
|
+
return trimmed;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validate device serial
|
|
91
|
+
*/
|
|
92
|
+
function validateSerial(serial) {
|
|
93
|
+
if (!serial || typeof serial !== 'string') {
|
|
94
|
+
throw new errors_1.ValidationError('serial', 'must be a non-empty string');
|
|
95
|
+
}
|
|
96
|
+
const trimmed = serial.trim();
|
|
97
|
+
if (trimmed.length === 0) {
|
|
98
|
+
throw new errors_1.ValidationError('serial', 'cannot be empty');
|
|
99
|
+
}
|
|
100
|
+
if (!SERIAL_REGEX.test(trimmed)) {
|
|
101
|
+
throw new errors_1.ValidationError('serial', 'contains invalid characters');
|
|
102
|
+
}
|
|
103
|
+
return trimmed;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Validate authentication token
|
|
107
|
+
*/
|
|
108
|
+
function validateToken(token) {
|
|
109
|
+
if (!token || typeof token !== 'string') {
|
|
110
|
+
throw new errors_1.ValidationError('token', 'must be a non-empty string');
|
|
111
|
+
}
|
|
112
|
+
const trimmed = token.trim();
|
|
113
|
+
if (trimmed.length === 0) {
|
|
114
|
+
throw new errors_1.ValidationError('token', 'cannot be empty');
|
|
115
|
+
}
|
|
116
|
+
return trimmed;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Validate power state
|
|
120
|
+
*/
|
|
121
|
+
function validatePowerState(power) {
|
|
122
|
+
if (power !== 'ON' && power !== 'OFF') {
|
|
123
|
+
throw new errors_1.ValidationError('power', "must be 'ON' or 'OFF'", power);
|
|
124
|
+
}
|
|
125
|
+
return power;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Validate brightness value (0-100)
|
|
129
|
+
*/
|
|
130
|
+
function validateBrightness(brightness) {
|
|
131
|
+
if (typeof brightness !== 'number') {
|
|
132
|
+
throw new errors_1.ValidationError('brightness', 'must be a number', brightness);
|
|
133
|
+
}
|
|
134
|
+
if (!Number.isFinite(brightness)) {
|
|
135
|
+
throw new errors_1.ValidationError('brightness', 'must be a finite number', brightness);
|
|
136
|
+
}
|
|
137
|
+
if (brightness < 0 || brightness > 100) {
|
|
138
|
+
throw new errors_1.ValidationError('brightness', 'must be between 0 and 100', brightness);
|
|
139
|
+
}
|
|
140
|
+
return Math.round(brightness);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Validate plugin configuration
|
|
144
|
+
*/
|
|
145
|
+
function validateConfig(config) {
|
|
146
|
+
const errors = [];
|
|
147
|
+
if (!config || typeof config !== 'object') {
|
|
148
|
+
throw new errors_1.ConfigurationError('Configuration must be an object');
|
|
149
|
+
}
|
|
150
|
+
const cfg = config;
|
|
151
|
+
// Required fields
|
|
152
|
+
if (!cfg.email) {
|
|
153
|
+
errors.push('email is required');
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
try {
|
|
157
|
+
validateEmail(cfg.email);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
errors.push(`email: ${e.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!cfg.password) {
|
|
164
|
+
errors.push('password is required');
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
try {
|
|
168
|
+
validatePassword(cfg.password);
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
errors.push(`password: ${e.message}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Optional fields
|
|
175
|
+
if (cfg.loglevel !== undefined) {
|
|
176
|
+
const validLevels = ['debug', 'info', 'warn', 'error'];
|
|
177
|
+
if (!validLevels.includes(cfg.loglevel)) {
|
|
178
|
+
errors.push(`loglevel must be one of: ${validLevels.join(', ')}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (cfg.excludedModels !== undefined) {
|
|
182
|
+
if (!Array.isArray(cfg.excludedModels)) {
|
|
183
|
+
errors.push('excludedModels must be an array');
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
cfg.excludedModels.forEach((model, i) => {
|
|
187
|
+
if (typeof model !== 'string') {
|
|
188
|
+
errors.push(`excludedModels[${i}] must be a string`);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (cfg.excludedSerials !== undefined) {
|
|
194
|
+
if (!Array.isArray(cfg.excludedSerials)) {
|
|
195
|
+
errors.push('excludedSerials must be an array');
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
cfg.excludedSerials.forEach((serial, i) => {
|
|
199
|
+
if (typeof serial !== 'string') {
|
|
200
|
+
errors.push(`excludedSerials[${i}] must be a string`);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (cfg.pollingInterval !== undefined) {
|
|
206
|
+
const interval = cfg.pollingInterval;
|
|
207
|
+
if (typeof interval !== 'number' || interval < 10 || interval > 3600) {
|
|
208
|
+
errors.push('pollingInterval must be a number between 10 and 3600');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (cfg.connectionTimeout !== undefined) {
|
|
212
|
+
const timeout = cfg.connectionTimeout;
|
|
213
|
+
if (typeof timeout !== 'number' || timeout < 5000 || timeout > 60000) {
|
|
214
|
+
errors.push('connectionTimeout must be a number between 5000 and 60000');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (errors.length > 0) {
|
|
218
|
+
throw new errors_1.ConfigurationError(`Configuration validation failed: ${errors.join('; ')}`, undefined, errors);
|
|
219
|
+
}
|
|
220
|
+
return cfg;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Validate that a value is defined (not null or undefined)
|
|
224
|
+
*/
|
|
225
|
+
function assertDefined(value, name) {
|
|
226
|
+
if (value === null || value === undefined) {
|
|
227
|
+
throw new errors_1.ValidationError(name, 'is required but was not provided');
|
|
228
|
+
}
|
|
229
|
+
return value;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Validate that a value is a non-empty array
|
|
233
|
+
*/
|
|
234
|
+
function validateNonEmptyArray(arr, name) {
|
|
235
|
+
if (!Array.isArray(arr)) {
|
|
236
|
+
throw new errors_1.ValidationError(name, 'must be an array');
|
|
237
|
+
}
|
|
238
|
+
if (arr.length === 0) {
|
|
239
|
+
throw new errors_1.ValidationError(name, 'cannot be empty');
|
|
240
|
+
}
|
|
241
|
+
return arr;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "homebridge-myleviton",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "A homebridge plugin for My Leviton Decora Smart devices",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"homebridge-plugin",
|
|
9
|
+
"leviton",
|
|
10
|
+
"decora",
|
|
11
|
+
"smart",
|
|
12
|
+
"homekit"
|
|
13
|
+
],
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "tbaur",
|
|
16
|
+
"url": "https://github.com/tbaur"
|
|
17
|
+
},
|
|
18
|
+
"funding": {
|
|
19
|
+
"type": "github",
|
|
20
|
+
"url": "https://github.com/sponsors/tbaur"
|
|
21
|
+
},
|
|
22
|
+
"license": "Apache-2.0",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/tbaur/homebridge-myleviton.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/tbaur/homebridge-myleviton/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/tbaur/homebridge-myleviton#readme",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"sockjs-client": "^1.6.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/jest": "^29.5.14",
|
|
36
|
+
"@types/node": "^22.10.2",
|
|
37
|
+
"@types/sockjs-client": "^1.5.4",
|
|
38
|
+
"@typescript-eslint/eslint-plugin": "^8.51.0",
|
|
39
|
+
"@typescript-eslint/parser": "^8.51.0",
|
|
40
|
+
"eslint": "^9.0.0",
|
|
41
|
+
"globals": "^15.0.0",
|
|
42
|
+
"jest": "^29.7.0",
|
|
43
|
+
"nock": "^13.4.0",
|
|
44
|
+
"ts-jest": "29.1.5",
|
|
45
|
+
"typescript": "^5.7.2"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"homebridge": "^1.6.0 || ^2.0.0",
|
|
49
|
+
"node": ">=20.0.0"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc",
|
|
53
|
+
"build:watch": "tsc --watch",
|
|
54
|
+
"clean": "rm -rf dist",
|
|
55
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
56
|
+
"test": "NODE_ENV=test jest --coverage",
|
|
57
|
+
"test:watch": "NODE_ENV=test jest --watch",
|
|
58
|
+
"test:unit": "NODE_ENV=test jest --coverage --testPathPattern=tests/unit",
|
|
59
|
+
"test:integration": "NODE_ENV=test jest --testPathPattern=tests/integration",
|
|
60
|
+
"lint": "eslint . --ignore-pattern node_modules --ignore-pattern dist --ignore-pattern coverage",
|
|
61
|
+
"lint:fix": "eslint . --fix --ignore-pattern node_modules --ignore-pattern dist --ignore-pattern coverage"
|
|
62
|
+
},
|
|
63
|
+
"files": [
|
|
64
|
+
"dist/**/*",
|
|
65
|
+
"config.schema.json",
|
|
66
|
+
"LICENSE",
|
|
67
|
+
"README.md"
|
|
68
|
+
]
|
|
69
|
+
}
|