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.
Files changed (72) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +112 -0
  3. package/config.schema.json +136 -0
  4. package/dist/api/cache.d.ts +108 -0
  5. package/dist/api/cache.d.ts.map +1 -0
  6. package/dist/api/cache.js +206 -0
  7. package/dist/api/cache.js.map +1 -0
  8. package/dist/api/circuit-breaker.d.ts +118 -0
  9. package/dist/api/circuit-breaker.d.ts.map +1 -0
  10. package/dist/api/circuit-breaker.js +223 -0
  11. package/dist/api/circuit-breaker.js.map +1 -0
  12. package/dist/api/client.d.ts +116 -0
  13. package/dist/api/client.d.ts.map +1 -0
  14. package/dist/api/client.js +358 -0
  15. package/dist/api/client.js.map +1 -0
  16. package/dist/api/index.d.ts +23 -0
  17. package/dist/api/index.d.ts.map +1 -0
  18. package/dist/api/index.js +47 -0
  19. package/dist/api/index.js.map +1 -0
  20. package/dist/api/persistence.d.ts +107 -0
  21. package/dist/api/persistence.d.ts.map +1 -0
  22. package/dist/api/persistence.js +285 -0
  23. package/dist/api/persistence.js.map +1 -0
  24. package/dist/api/rate-limiter.d.ts +102 -0
  25. package/dist/api/rate-limiter.d.ts.map +1 -0
  26. package/dist/api/rate-limiter.js +173 -0
  27. package/dist/api/rate-limiter.js.map +1 -0
  28. package/dist/api/request-queue.d.ts +104 -0
  29. package/dist/api/request-queue.d.ts.map +1 -0
  30. package/dist/api/request-queue.js +223 -0
  31. package/dist/api/request-queue.js.map +1 -0
  32. package/dist/api/websocket.d.ts +116 -0
  33. package/dist/api/websocket.d.ts.map +1 -0
  34. package/dist/api/websocket.js +319 -0
  35. package/dist/api/websocket.js.map +1 -0
  36. package/dist/errors/index.d.ts +182 -0
  37. package/dist/errors/index.d.ts.map +1 -0
  38. package/dist/errors/index.js +273 -0
  39. package/dist/errors/index.js.map +1 -0
  40. package/dist/index.d.ts +16 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +42 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/platform.d.ts +139 -0
  45. package/dist/platform.d.ts.map +1 -0
  46. package/dist/platform.js +664 -0
  47. package/dist/platform.js.map +1 -0
  48. package/dist/types/index.d.ts +225 -0
  49. package/dist/types/index.d.ts.map +1 -0
  50. package/dist/types/index.js +34 -0
  51. package/dist/types/index.js.map +1 -0
  52. package/dist/utils/index.d.ts +15 -0
  53. package/dist/utils/index.d.ts.map +1 -0
  54. package/dist/utils/index.js +52 -0
  55. package/dist/utils/index.js.map +1 -0
  56. package/dist/utils/logger.d.ts +103 -0
  57. package/dist/utils/logger.d.ts.map +1 -0
  58. package/dist/utils/logger.js +184 -0
  59. package/dist/utils/logger.js.map +1 -0
  60. package/dist/utils/retry.d.ts +56 -0
  61. package/dist/utils/retry.d.ts.map +1 -0
  62. package/dist/utils/retry.js +141 -0
  63. package/dist/utils/retry.js.map +1 -0
  64. package/dist/utils/sanitizers.d.ts +37 -0
  65. package/dist/utils/sanitizers.d.ts.map +1 -0
  66. package/dist/utils/sanitizers.js +128 -0
  67. package/dist/utils/sanitizers.js.map +1 -0
  68. package/dist/utils/validators.d.ts +51 -0
  69. package/dist/utils/validators.d.ts.map +1 -0
  70. package/dist/utils/validators.js +243 -0
  71. package/dist/utils/validators.js.map +1 -0
  72. package/package.json +69 -0
@@ -0,0 +1,206 @@
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 Response caching with TTL and LRU eviction
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.ResponseCache = exports.DEFAULT_CACHE_CONFIG = void 0;
12
+ exports.getResponseCache = getResponseCache;
13
+ exports.resetGlobalCache = resetGlobalCache;
14
+ /**
15
+ * Default cache configuration
16
+ */
17
+ exports.DEFAULT_CACHE_CONFIG = {
18
+ ttlMs: 2000, // 2 seconds
19
+ maxSize: 1000,
20
+ updateOnAccess: false,
21
+ };
22
+ /**
23
+ * Response cache with TTL and optional LRU eviction
24
+ */
25
+ class ResponseCache {
26
+ cache = new Map();
27
+ ttlMs;
28
+ maxSize;
29
+ updateOnAccess;
30
+ // Metrics
31
+ hits = 0;
32
+ misses = 0;
33
+ constructor(config = {}) {
34
+ const merged = { ...exports.DEFAULT_CACHE_CONFIG, ...config };
35
+ this.ttlMs = merged.ttlMs;
36
+ this.maxSize = merged.maxSize;
37
+ this.updateOnAccess = merged.updateOnAccess ?? false;
38
+ }
39
+ /**
40
+ * Check if entry is expired
41
+ */
42
+ isExpired(entry) {
43
+ return Date.now() - entry.timestamp > this.ttlMs;
44
+ }
45
+ /**
46
+ * Evict oldest entries if over capacity
47
+ */
48
+ evictIfNeeded() {
49
+ while (this.cache.size >= this.maxSize) {
50
+ // Remove oldest entry (first in map)
51
+ const oldestKey = this.cache.keys().next().value;
52
+ if (oldestKey) {
53
+ this.cache.delete(oldestKey);
54
+ }
55
+ else {
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * Get cached value if still valid
62
+ * @returns Cached data or null if expired/missing
63
+ */
64
+ get(key) {
65
+ const entry = this.cache.get(key);
66
+ if (!entry) {
67
+ this.misses++;
68
+ return null;
69
+ }
70
+ if (this.isExpired(entry)) {
71
+ this.cache.delete(key);
72
+ this.misses++;
73
+ return null;
74
+ }
75
+ this.hits++;
76
+ // Optionally update timestamp on access (LRU-style)
77
+ if (this.updateOnAccess) {
78
+ entry.timestamp = Date.now();
79
+ // Move to end of map for LRU ordering
80
+ this.cache.delete(key);
81
+ this.cache.set(key, entry);
82
+ }
83
+ return entry.data;
84
+ }
85
+ /**
86
+ * Set cache value
87
+ */
88
+ set(key, data) {
89
+ this.evictIfNeeded();
90
+ this.cache.set(key, {
91
+ data,
92
+ timestamp: Date.now(),
93
+ });
94
+ }
95
+ /**
96
+ * Check if key exists and is not expired
97
+ */
98
+ has(key) {
99
+ const entry = this.cache.get(key);
100
+ if (!entry) {
101
+ return false;
102
+ }
103
+ if (this.isExpired(entry)) {
104
+ this.cache.delete(key);
105
+ return false;
106
+ }
107
+ return true;
108
+ }
109
+ /**
110
+ * Delete a specific key
111
+ */
112
+ delete(key) {
113
+ return this.cache.delete(key);
114
+ }
115
+ /**
116
+ * Clear expired entries
117
+ */
118
+ clearExpired() {
119
+ let cleared = 0;
120
+ for (const [key, entry] of this.cache.entries()) {
121
+ if (this.isExpired(entry)) {
122
+ this.cache.delete(key);
123
+ cleared++;
124
+ }
125
+ }
126
+ return cleared;
127
+ }
128
+ /**
129
+ * Clear all cache entries
130
+ */
131
+ clear() {
132
+ this.cache.clear();
133
+ }
134
+ /**
135
+ * Get number of entries
136
+ */
137
+ get size() {
138
+ return this.cache.size;
139
+ }
140
+ /**
141
+ * Get cache hit ratio
142
+ */
143
+ get hitRatio() {
144
+ const total = this.hits + this.misses;
145
+ return total === 0 ? 0 : this.hits / total;
146
+ }
147
+ /**
148
+ * Get cache statistics
149
+ */
150
+ getStats() {
151
+ return {
152
+ size: this.size,
153
+ maxSize: this.maxSize,
154
+ ttlMs: this.ttlMs,
155
+ hits: this.hits,
156
+ misses: this.misses,
157
+ hitRatio: this.hitRatio,
158
+ };
159
+ }
160
+ /**
161
+ * Reset statistics
162
+ */
163
+ resetStats() {
164
+ this.hits = 0;
165
+ this.misses = 0;
166
+ }
167
+ /**
168
+ * Get all keys
169
+ */
170
+ keys() {
171
+ return Array.from(this.cache.keys());
172
+ }
173
+ /**
174
+ * Get or set a value using a factory function
175
+ */
176
+ async getOrSet(key, factory) {
177
+ const cached = this.get(key);
178
+ if (cached !== null) {
179
+ return cached;
180
+ }
181
+ const data = await factory();
182
+ this.set(key, data);
183
+ return data;
184
+ }
185
+ }
186
+ exports.ResponseCache = ResponseCache;
187
+ /**
188
+ * Global response cache instance
189
+ */
190
+ let globalCache = null;
191
+ /**
192
+ * Get or create the global cache
193
+ */
194
+ function getResponseCache(config) {
195
+ if (!globalCache) {
196
+ globalCache = new ResponseCache(config);
197
+ }
198
+ return globalCache;
199
+ }
200
+ /**
201
+ * Reset the global cache (for testing)
202
+ */
203
+ function resetGlobalCache() {
204
+ globalCache = null;
205
+ }
206
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/api/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Copyright (c) 2026 tbaur
3
+ *
4
+ * Licensed under the Apache License, Version 2.0
5
+ * See LICENSE file for full license text
6
+ *
7
+ * @fileoverview Circuit breaker pattern for API resilience
8
+ */
9
+ /**
10
+ * Circuit breaker states
11
+ */
12
+ export declare enum CircuitState {
13
+ /** Normal operation - requests flow through */
14
+ CLOSED = "CLOSED",
15
+ /** Circuit tripped - requests fail immediately */
16
+ OPEN = "OPEN",
17
+ /** Testing if service recovered */
18
+ HALF_OPEN = "HALF_OPEN"
19
+ }
20
+ /**
21
+ * Circuit breaker configuration
22
+ */
23
+ export interface CircuitBreakerConfig {
24
+ /** Number of failures before opening circuit */
25
+ failureThreshold: number;
26
+ /** Time in ms before trying half-open */
27
+ resetTimeout: number;
28
+ /** Max requests allowed in half-open state */
29
+ halfOpenMax: number;
30
+ /** Window for counting failures (ms) */
31
+ failureWindow?: number;
32
+ }
33
+ /**
34
+ * Default circuit breaker configuration
35
+ */
36
+ export declare const DEFAULT_CIRCUIT_BREAKER_CONFIG: CircuitBreakerConfig;
37
+ /**
38
+ * Circuit breaker status
39
+ */
40
+ export interface CircuitBreakerStatus {
41
+ state: CircuitState;
42
+ failures: number;
43
+ successes: number;
44
+ lastFailureTime: number | null;
45
+ halfOpenRequests: number;
46
+ isOpen: boolean;
47
+ remainingResetTime: number | null;
48
+ }
49
+ /**
50
+ * Circuit breaker implementation for API resilience
51
+ * Prevents cascading failures when the Leviton API is down
52
+ */
53
+ export declare class CircuitBreaker {
54
+ private readonly failureThreshold;
55
+ private readonly resetTimeout;
56
+ private readonly halfOpenMax;
57
+ private readonly failureWindow;
58
+ private _state;
59
+ private failures;
60
+ private successes;
61
+ private lastFailureTime;
62
+ private halfOpenRequests;
63
+ private failureTimestamps;
64
+ constructor(config?: Partial<CircuitBreakerConfig>);
65
+ /**
66
+ * Current circuit state
67
+ */
68
+ get state(): CircuitState;
69
+ /**
70
+ * Check if circuit is open
71
+ */
72
+ get isOpen(): boolean;
73
+ /**
74
+ * Clean up old failure timestamps
75
+ */
76
+ private cleanupFailures;
77
+ /**
78
+ * Check if circuit allows requests
79
+ */
80
+ canRequest(): boolean;
81
+ /**
82
+ * Record a successful request
83
+ */
84
+ recordSuccess(): void;
85
+ /**
86
+ * Record a failed request
87
+ */
88
+ recordFailure(): void;
89
+ /**
90
+ * Track half-open request
91
+ */
92
+ trackHalfOpenRequest(): void;
93
+ /**
94
+ * Reset the circuit breaker to closed state
95
+ */
96
+ reset(): void;
97
+ /**
98
+ * Get current circuit breaker status
99
+ */
100
+ getStatus(): CircuitBreakerStatus;
101
+ /**
102
+ * Execute a function with circuit breaker protection
103
+ */
104
+ execute<T>(fn: () => Promise<T>): Promise<T>;
105
+ /**
106
+ * Create a wrapped version of a function with circuit breaker protection
107
+ */
108
+ wrap<T extends unknown[], R>(fn: (...args: T) => Promise<R>): (...args: T) => Promise<R>;
109
+ }
110
+ /**
111
+ * Get or create the global circuit breaker
112
+ */
113
+ export declare function getCircuitBreaker(config?: Partial<CircuitBreakerConfig>): CircuitBreaker;
114
+ /**
115
+ * Reset the global circuit breaker (for testing)
116
+ */
117
+ export declare function resetGlobalCircuitBreaker(): void;
118
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/api/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,oBAAY,YAAY;IACtB,+CAA+C;IAC/C,MAAM,WAAW;IACjB,kDAAkD;IAClD,IAAI,SAAS;IACb,mCAAmC;IACnC,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAA;IACxB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,8BAA8B,EAAE,oBAK5C,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,OAAO,CAAA;IACf,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IAEtC,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAe;gBAE5B,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAQtD;;OAEG;IACH,IAAI,KAAK,IAAI,YAAY,CAExB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACH,UAAU,IAAI,OAAO;IAwBrB;;OAEG;IACH,aAAa,IAAI,IAAI;IAarB;;OAEG;IACH,aAAa,IAAI,IAAI;IAkBrB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAM5B;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACH,SAAS,IAAI,oBAAoB;IAmBjC;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBlD;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;CAGzF;AAOD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,cAAc,CAKxF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
@@ -0,0 +1,223 @@
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 Circuit breaker pattern for API resilience
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.CircuitBreaker = exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = exports.CircuitState = void 0;
12
+ exports.getCircuitBreaker = getCircuitBreaker;
13
+ exports.resetGlobalCircuitBreaker = resetGlobalCircuitBreaker;
14
+ const errors_1 = require("../errors");
15
+ /**
16
+ * Circuit breaker states
17
+ */
18
+ var CircuitState;
19
+ (function (CircuitState) {
20
+ /** Normal operation - requests flow through */
21
+ CircuitState["CLOSED"] = "CLOSED";
22
+ /** Circuit tripped - requests fail immediately */
23
+ CircuitState["OPEN"] = "OPEN";
24
+ /** Testing if service recovered */
25
+ CircuitState["HALF_OPEN"] = "HALF_OPEN";
26
+ })(CircuitState || (exports.CircuitState = CircuitState = {}));
27
+ /**
28
+ * Default circuit breaker configuration
29
+ */
30
+ exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = {
31
+ failureThreshold: 5,
32
+ resetTimeout: 30000,
33
+ halfOpenMax: 3,
34
+ failureWindow: 60000,
35
+ };
36
+ /**
37
+ * Circuit breaker implementation for API resilience
38
+ * Prevents cascading failures when the Leviton API is down
39
+ */
40
+ class CircuitBreaker {
41
+ failureThreshold;
42
+ resetTimeout;
43
+ halfOpenMax;
44
+ failureWindow;
45
+ _state = CircuitState.CLOSED;
46
+ failures = 0;
47
+ successes = 0;
48
+ lastFailureTime = null;
49
+ halfOpenRequests = 0;
50
+ failureTimestamps = [];
51
+ constructor(config = {}) {
52
+ const merged = { ...exports.DEFAULT_CIRCUIT_BREAKER_CONFIG, ...config };
53
+ this.failureThreshold = merged.failureThreshold;
54
+ this.resetTimeout = merged.resetTimeout;
55
+ this.halfOpenMax = merged.halfOpenMax;
56
+ this.failureWindow = merged.failureWindow ?? 60000;
57
+ }
58
+ /**
59
+ * Current circuit state
60
+ */
61
+ get state() {
62
+ return this._state;
63
+ }
64
+ /**
65
+ * Check if circuit is open
66
+ */
67
+ get isOpen() {
68
+ return this._state === CircuitState.OPEN;
69
+ }
70
+ /**
71
+ * Clean up old failure timestamps
72
+ */
73
+ cleanupFailures() {
74
+ const cutoff = Date.now() - this.failureWindow;
75
+ this.failureTimestamps = this.failureTimestamps.filter(ts => ts > cutoff);
76
+ this.failures = this.failureTimestamps.length;
77
+ }
78
+ /**
79
+ * Check if circuit allows requests
80
+ */
81
+ canRequest() {
82
+ if (this._state === CircuitState.CLOSED) {
83
+ return true;
84
+ }
85
+ if (this._state === CircuitState.OPEN) {
86
+ // Check if enough time has passed to try again
87
+ if (this.lastFailureTime && (Date.now() - this.lastFailureTime) >= this.resetTimeout) {
88
+ this._state = CircuitState.HALF_OPEN;
89
+ this.halfOpenRequests = 0;
90
+ this.successes = 0;
91
+ return true;
92
+ }
93
+ return false;
94
+ }
95
+ if (this._state === CircuitState.HALF_OPEN) {
96
+ // Allow limited requests in half-open state
97
+ return this.halfOpenRequests < this.halfOpenMax;
98
+ }
99
+ return false;
100
+ }
101
+ /**
102
+ * Record a successful request
103
+ */
104
+ recordSuccess() {
105
+ if (this._state === CircuitState.HALF_OPEN) {
106
+ this.successes++;
107
+ // After enough successes in half-open, close the circuit
108
+ if (this.successes >= this.halfOpenMax) {
109
+ this.reset();
110
+ }
111
+ }
112
+ else if (this._state === CircuitState.CLOSED) {
113
+ // Gradually reduce failure count on success
114
+ this.cleanupFailures();
115
+ }
116
+ }
117
+ /**
118
+ * Record a failed request
119
+ */
120
+ recordFailure() {
121
+ const now = Date.now();
122
+ this.lastFailureTime = now;
123
+ this.failureTimestamps.push(now);
124
+ if (this._state === CircuitState.HALF_OPEN) {
125
+ // Any failure in half-open state opens the circuit again
126
+ this._state = CircuitState.OPEN;
127
+ this.halfOpenRequests = 0;
128
+ this.successes = 0;
129
+ }
130
+ else if (this._state === CircuitState.CLOSED) {
131
+ this.cleanupFailures();
132
+ if (this.failures >= this.failureThreshold) {
133
+ this._state = CircuitState.OPEN;
134
+ }
135
+ }
136
+ }
137
+ /**
138
+ * Track half-open request
139
+ */
140
+ trackHalfOpenRequest() {
141
+ if (this._state === CircuitState.HALF_OPEN) {
142
+ this.halfOpenRequests++;
143
+ }
144
+ }
145
+ /**
146
+ * Reset the circuit breaker to closed state
147
+ */
148
+ reset() {
149
+ this._state = CircuitState.CLOSED;
150
+ this.failures = 0;
151
+ this.successes = 0;
152
+ this.lastFailureTime = null;
153
+ this.halfOpenRequests = 0;
154
+ this.failureTimestamps = [];
155
+ }
156
+ /**
157
+ * Get current circuit breaker status
158
+ */
159
+ getStatus() {
160
+ const now = Date.now();
161
+ let remainingResetTime = null;
162
+ if (this._state === CircuitState.OPEN && this.lastFailureTime) {
163
+ remainingResetTime = Math.max(0, this.resetTimeout - (now - this.lastFailureTime));
164
+ }
165
+ return {
166
+ state: this._state,
167
+ failures: this.failures,
168
+ successes: this.successes,
169
+ lastFailureTime: this.lastFailureTime,
170
+ halfOpenRequests: this.halfOpenRequests,
171
+ isOpen: this.isOpen,
172
+ remainingResetTime,
173
+ };
174
+ }
175
+ /**
176
+ * Execute a function with circuit breaker protection
177
+ */
178
+ async execute(fn) {
179
+ if (!this.canRequest()) {
180
+ const status = this.getStatus();
181
+ throw new errors_1.CircuitBreakerError(status.remainingResetTime ?? this.resetTimeout);
182
+ }
183
+ if (this._state === CircuitState.HALF_OPEN) {
184
+ this.trackHalfOpenRequest();
185
+ }
186
+ try {
187
+ const result = await fn();
188
+ this.recordSuccess();
189
+ return result;
190
+ }
191
+ catch (error) {
192
+ this.recordFailure();
193
+ throw error;
194
+ }
195
+ }
196
+ /**
197
+ * Create a wrapped version of a function with circuit breaker protection
198
+ */
199
+ wrap(fn) {
200
+ return (...args) => this.execute(() => fn(...args));
201
+ }
202
+ }
203
+ exports.CircuitBreaker = CircuitBreaker;
204
+ /**
205
+ * Global circuit breaker instance
206
+ */
207
+ let globalCircuitBreaker = null;
208
+ /**
209
+ * Get or create the global circuit breaker
210
+ */
211
+ function getCircuitBreaker(config) {
212
+ if (!globalCircuitBreaker) {
213
+ globalCircuitBreaker = new CircuitBreaker(config);
214
+ }
215
+ return globalCircuitBreaker;
216
+ }
217
+ /**
218
+ * Reset the global circuit breaker (for testing)
219
+ */
220
+ function resetGlobalCircuitBreaker() {
221
+ globalCircuitBreaker = null;
222
+ }
223
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/api/circuit-breaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Copyright (c) 2026 tbaur
3
+ *
4
+ * Licensed under the Apache License, Version 2.0
5
+ * See LICENSE file for full license text
6
+ *
7
+ * @fileoverview Leviton API HTTP client
8
+ */
9
+ import { RateLimiter } from './rate-limiter';
10
+ import { CircuitBreaker } from './circuit-breaker';
11
+ import { ResponseCache } from './cache';
12
+ import type { DeviceInfo, DeviceStatus, LoginResponse, ResidentialPermission, ResidentialAccount, Residence, PowerState } from '../types';
13
+ /**
14
+ * API configuration
15
+ */
16
+ export interface ApiClientConfig {
17
+ /** Base URL for Leviton API */
18
+ baseUrl: string;
19
+ /** Request timeout in ms */
20
+ timeout: number;
21
+ /** Whether to use response caching */
22
+ useCache: boolean;
23
+ /** Cache TTL in ms */
24
+ cacheTtl: number;
25
+ }
26
+ /**
27
+ * Default API configuration
28
+ */
29
+ export declare const DEFAULT_API_CONFIG: ApiClientConfig;
30
+ /**
31
+ * Leviton API client
32
+ */
33
+ export declare class LevitonApiClient {
34
+ private readonly config;
35
+ private readonly rateLimiter;
36
+ private readonly circuitBreaker;
37
+ private readonly cache;
38
+ private readonly deduplicator;
39
+ constructor(config?: Partial<ApiClientConfig>);
40
+ /**
41
+ * Make an API request with all protections
42
+ */
43
+ private request;
44
+ /**
45
+ * Execute the actual request
46
+ */
47
+ private executeRequest;
48
+ /**
49
+ * Login and get authentication token
50
+ */
51
+ login(email: string, password: string, debugLog?: (msg: string) => void): Promise<LoginResponse>;
52
+ /**
53
+ * Get residential permissions for a person
54
+ */
55
+ getResidentialPermissions(personId: string, token: string, debugLog?: (msg: string) => void): Promise<ResidentialPermission[]>;
56
+ /**
57
+ * Get residential account details
58
+ */
59
+ getResidentialAccount(accountId: string, token: string, debugLog?: (msg: string) => void): Promise<ResidentialAccount>;
60
+ /**
61
+ * Get residences using v2 API
62
+ */
63
+ getResidences(residenceObjectId: string, token: string, debugLog?: (msg: string) => void): Promise<Residence[]>;
64
+ /**
65
+ * Get IoT switches for a residence
66
+ */
67
+ getDevices(residenceId: string, token: string, debugLog?: (msg: string) => void): Promise<DeviceInfo[]>;
68
+ /**
69
+ * Get status of a specific device
70
+ */
71
+ getDeviceStatus(deviceId: string, token: string, debugLog?: (msg: string) => void): Promise<DeviceStatus>;
72
+ /**
73
+ * Update device state
74
+ */
75
+ setDeviceState(deviceId: string, token: string, state: {
76
+ power?: PowerState;
77
+ brightness?: number;
78
+ }, debugLog?: (msg: string) => void): Promise<DeviceStatus>;
79
+ /**
80
+ * Set device power
81
+ */
82
+ setPower(deviceId: string, token: string, power: boolean, debugLog?: (msg: string) => void): Promise<DeviceStatus>;
83
+ /**
84
+ * Set device brightness
85
+ */
86
+ setBrightness(deviceId: string, token: string, brightness: number, debugLog?: (msg: string) => void): Promise<DeviceStatus>;
87
+ /**
88
+ * Clear response cache
89
+ */
90
+ clearCache(): void;
91
+ /**
92
+ * Invalidate cache for a specific device
93
+ */
94
+ invalidateDeviceCache(deviceId: string): void;
95
+ /**
96
+ * Get client status
97
+ */
98
+ getStatus(): {
99
+ circuitBreaker: ReturnType<CircuitBreaker['getStatus']>;
100
+ rateLimiter: ReturnType<RateLimiter['getStatus']>;
101
+ cache: ReturnType<ResponseCache['getStats']>;
102
+ };
103
+ /**
104
+ * Reset all client state (for testing)
105
+ */
106
+ reset(): void;
107
+ }
108
+ /**
109
+ * Get or create the global API client
110
+ */
111
+ export declare function getApiClient(config?: Partial<ApiClientConfig>): LevitonApiClient;
112
+ /**
113
+ * Reset the global client (for testing)
114
+ */
115
+ export declare function resetGlobalClient(): void;
116
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAmC,MAAM,mBAAmB,CAAA;AACnF,OAAO,EAAE,aAAa,EAAoB,MAAM,SAAS,CAAA;AAIzD,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,SAAS,EACT,UAAU,EAEX,MAAM,UAAU,CAAA;AAEjB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,sCAAsC;IACtC,QAAQ,EAAE,OAAO,CAAA;IACjB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAKhC,CAAA;AAkBD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAEtC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM;IAQjD;;OAEG;YACW,OAAO;IAuCrB;;OAEG;YACW,cAAc;IAkI5B;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IA6BtG;;OAEG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAgBnC;;OAEG;IACG,qBAAqB,CACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,kBAAkB,CAAC;IAgB9B;;OAEG;IACG,aAAa,CACjB,iBAAiB,EAAE,MAAM,EACzB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,SAAS,EAAE,CAAC;IAgBvB;;OAEG;IACG,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,UAAU,EAAE,CAAC;IAgBxB;;OAEG;IACG,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,YAAY,CAAC;IAqBxB;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,UAAU,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,YAAY,CAAC;IAsCxB;;OAEG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,YAAY,CAAC;IAIxB;;OAEG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,YAAY,CAAC;IAIxB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI7C;;OAEG;IACH,SAAS,IAAI;QACX,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QACvD,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAA;QACjD,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAA;KAC7C;IAQD;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd;AAOD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,gBAAgB,CAKhF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}