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,184 @@
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 Structured logging utilities
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.StructuredLogger = exports.LeveledLogger = exports.DEFAULT_STRUCTURED_LOGGER_CONFIG = exports.DEFAULT_LOG_LEVEL = exports.LOG_LEVELS = void 0;
12
+ exports.createLogger = createLogger;
13
+ exports.createStructuredLogger = createStructuredLogger;
14
+ const sanitizers_1 = require("./sanitizers");
15
+ /**
16
+ * Log levels in order of severity
17
+ */
18
+ exports.LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
19
+ /**
20
+ * Default log level
21
+ */
22
+ exports.DEFAULT_LOG_LEVEL = 'info';
23
+ /**
24
+ * Default structured logger configuration
25
+ */
26
+ exports.DEFAULT_STRUCTURED_LOGGER_CONFIG = {
27
+ structured: false,
28
+ includeCorrelationId: true,
29
+ includeTimestamp: true,
30
+ };
31
+ /**
32
+ * Logger wrapper that supports level filtering and structured output
33
+ */
34
+ class LeveledLogger {
35
+ baseLog;
36
+ minLevel;
37
+ debug;
38
+ info;
39
+ warn;
40
+ error;
41
+ constructor(log, level = exports.DEFAULT_LOG_LEVEL) {
42
+ this.baseLog = typeof log === 'function' ? log : (msg) => log.info(msg);
43
+ this.minLevel = exports.LOG_LEVELS.indexOf(level);
44
+ // Create level methods
45
+ this.debug = this.createLevelMethod('debug');
46
+ this.info = this.createLevelMethod('info');
47
+ this.warn = this.createLevelMethod('warn');
48
+ this.error = this.createLevelMethod('error');
49
+ }
50
+ createLevelMethod(level) {
51
+ const levelIndex = exports.LOG_LEVELS.indexOf(level);
52
+ return (message) => {
53
+ if (levelIndex >= this.minLevel) {
54
+ this.baseLog(message);
55
+ }
56
+ };
57
+ }
58
+ }
59
+ exports.LeveledLogger = LeveledLogger;
60
+ /**
61
+ * Structured logger with correlation ID support
62
+ */
63
+ class StructuredLogger {
64
+ log;
65
+ config;
66
+ correlationId = null;
67
+ constructor(log, config = {}) {
68
+ this.log = log instanceof LeveledLogger ? log : new LeveledLogger(log);
69
+ this.config = { ...exports.DEFAULT_STRUCTURED_LOGGER_CONFIG, ...config };
70
+ }
71
+ /**
72
+ * Set correlation ID for request tracing
73
+ */
74
+ setCorrelationId(id) {
75
+ this.correlationId = id;
76
+ }
77
+ /**
78
+ * Generate a new correlation ID
79
+ */
80
+ generateCorrelationId() {
81
+ this.correlationId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
82
+ return this.correlationId;
83
+ }
84
+ /**
85
+ * Clear correlation ID
86
+ */
87
+ clearCorrelationId() {
88
+ this.correlationId = null;
89
+ }
90
+ /**
91
+ * Format a log entry
92
+ */
93
+ format(level, message, context) {
94
+ if (this.config.structured) {
95
+ const entry = {
96
+ timestamp: new Date().toISOString(),
97
+ level,
98
+ message: typeof message === 'string' ? message : '',
99
+ ...(typeof message === 'object' ? (0, sanitizers_1.sanitizeObject)(message) : {}),
100
+ ...(context ? (0, sanitizers_1.sanitizeObject)(context) : {}),
101
+ };
102
+ if (this.config.includeCorrelationId && this.correlationId) {
103
+ entry.correlationId = this.correlationId;
104
+ }
105
+ return JSON.stringify(entry);
106
+ }
107
+ // Traditional string format
108
+ let result = '';
109
+ if (typeof message === 'object') {
110
+ const { event, ...rest } = message;
111
+ const contextStr = Object.keys(rest).length > 0
112
+ ? ` ${JSON.stringify((0, sanitizers_1.sanitizeObject)(rest))}`
113
+ : '';
114
+ result = `[${event || 'log'}]${contextStr}`;
115
+ }
116
+ else {
117
+ result = message;
118
+ }
119
+ if (context) {
120
+ result += ` ${JSON.stringify((0, sanitizers_1.sanitizeObject)(context))}`;
121
+ }
122
+ return result;
123
+ }
124
+ /**
125
+ * Log debug message
126
+ */
127
+ debug(message, context) {
128
+ this.log.debug(this.format('debug', message, context));
129
+ }
130
+ /**
131
+ * Log info message
132
+ */
133
+ info(message, context) {
134
+ this.log.info(this.format('info', message, context));
135
+ }
136
+ /**
137
+ * Log warning message
138
+ */
139
+ warn(message, context) {
140
+ this.log.warn(this.format('warn', message, context));
141
+ }
142
+ /**
143
+ * Log error message
144
+ */
145
+ error(message, context) {
146
+ this.log.error(this.format('error', message, context));
147
+ }
148
+ /**
149
+ * Log an error with stack trace
150
+ */
151
+ logError(message, error, context) {
152
+ const errorInfo = {
153
+ code: error instanceof Error ? error.name : 'UNKNOWN',
154
+ message: (0, sanitizers_1.sanitizeError)(error),
155
+ };
156
+ this.error(message, { ...context, error: errorInfo });
157
+ }
158
+ /**
159
+ * Create a child logger with additional context
160
+ */
161
+ child(context) {
162
+ // Create a new logger that includes the context in every message
163
+ const childLogger = new StructuredLogger(this.log, this.config);
164
+ const originalFormat = childLogger.format.bind(childLogger);
165
+ childLogger['format'] = (level, message, ctx) => {
166
+ return originalFormat(level, message, { ...context, ...ctx });
167
+ };
168
+ return childLogger;
169
+ }
170
+ }
171
+ exports.StructuredLogger = StructuredLogger;
172
+ /**
173
+ * Create a leveled logger from Homebridge logger
174
+ */
175
+ function createLogger(log, level = exports.DEFAULT_LOG_LEVEL) {
176
+ return new LeveledLogger(log, level);
177
+ }
178
+ /**
179
+ * Create a structured logger
180
+ */
181
+ function createStructuredLogger(log, config) {
182
+ return new StructuredLogger(log, config);
183
+ }
184
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
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 Centralized retry logic with configurable policies
8
+ */
9
+ import type { RetryPolicy } from '../types';
10
+ /**
11
+ * Default retry policy
12
+ */
13
+ export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
14
+ /**
15
+ * Aggressive retry policy for critical operations
16
+ */
17
+ export declare const AGGRESSIVE_RETRY_POLICY: RetryPolicy;
18
+ /**
19
+ * Conservative retry policy for non-critical operations
20
+ */
21
+ export declare const CONSERVATIVE_RETRY_POLICY: RetryPolicy;
22
+ /**
23
+ * Sleep for a specified duration
24
+ */
25
+ export declare function sleep(ms: number): Promise<void>;
26
+ /**
27
+ * Calculate delay with exponential backoff and jitter
28
+ */
29
+ export declare function calculateBackoffDelay(attempt: number, baseDelay: number, maxDelay: number, multiplier: number): number;
30
+ /**
31
+ * Execute a function with retry logic
32
+ */
33
+ export declare function withRetry<T>(fn: () => Promise<T>, policy?: Partial<RetryPolicy>): Promise<T>;
34
+ /**
35
+ * Create a retryable version of a function
36
+ */
37
+ export declare function makeRetryable<T extends unknown[], R>(fn: (...args: T) => Promise<R>, policy?: Partial<RetryPolicy>): (...args: T) => Promise<R>;
38
+ /**
39
+ * Retry with timeout
40
+ */
41
+ export declare function withRetryAndTimeout<T>(fn: () => Promise<T>, timeoutMs: number, policy?: Partial<RetryPolicy>): Promise<T>;
42
+ /**
43
+ * Context for retry operations (for logging)
44
+ */
45
+ export interface RetryContext {
46
+ operation: string;
47
+ attempt: number;
48
+ maxAttempts: number;
49
+ error?: Error;
50
+ delay?: number;
51
+ }
52
+ /**
53
+ * Execute with retry and context logging
54
+ */
55
+ export declare function withRetryContext<T>(operation: string, fn: () => Promise<T>, policy?: Partial<RetryPolicy>, logger?: (context: RetryContext) => void): Promise<T>;
56
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAMlC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAMrC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAMvC,CAAA;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CASR;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,OAAO,CAAC,CAAC,CAAC,CA4CZ;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,EAClD,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAE5B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,EACjC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GACvC,OAAO,CAAC,CAAC,CAAC,CA0BZ"}
@@ -0,0 +1,141 @@
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 Centralized retry logic with configurable policies
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.CONSERVATIVE_RETRY_POLICY = exports.AGGRESSIVE_RETRY_POLICY = exports.DEFAULT_RETRY_POLICY = void 0;
12
+ exports.sleep = sleep;
13
+ exports.calculateBackoffDelay = calculateBackoffDelay;
14
+ exports.withRetry = withRetry;
15
+ exports.makeRetryable = makeRetryable;
16
+ exports.withRetryAndTimeout = withRetryAndTimeout;
17
+ exports.withRetryContext = withRetryContext;
18
+ const errors_1 = require("../errors");
19
+ /**
20
+ * Default retry policy
21
+ */
22
+ exports.DEFAULT_RETRY_POLICY = {
23
+ maxAttempts: 3,
24
+ baseDelay: 1000,
25
+ maxDelay: 30000,
26
+ backoffMultiplier: 2,
27
+ retryableErrors: ['AUTH_ERROR', 'TOKEN_EXPIRED', 'NETWORK_ERROR', 'TIMEOUT', 'RATE_LIMITED'],
28
+ };
29
+ /**
30
+ * Aggressive retry policy for critical operations
31
+ */
32
+ exports.AGGRESSIVE_RETRY_POLICY = {
33
+ maxAttempts: 5,
34
+ baseDelay: 500,
35
+ maxDelay: 60000,
36
+ backoffMultiplier: 2,
37
+ retryableErrors: ['AUTH_ERROR', 'TOKEN_EXPIRED', 'NETWORK_ERROR', 'TIMEOUT', 'RATE_LIMITED', 'API_ERROR'],
38
+ };
39
+ /**
40
+ * Conservative retry policy for non-critical operations
41
+ */
42
+ exports.CONSERVATIVE_RETRY_POLICY = {
43
+ maxAttempts: 2,
44
+ baseDelay: 2000,
45
+ maxDelay: 10000,
46
+ backoffMultiplier: 1.5,
47
+ retryableErrors: ['NETWORK_ERROR', 'TIMEOUT'],
48
+ };
49
+ /**
50
+ * Sleep for a specified duration
51
+ */
52
+ function sleep(ms) {
53
+ return new Promise(resolve => setTimeout(resolve, ms));
54
+ }
55
+ /**
56
+ * Calculate delay with exponential backoff and jitter
57
+ */
58
+ function calculateBackoffDelay(attempt, baseDelay, maxDelay, multiplier) {
59
+ // Exponential backoff
60
+ const exponentialDelay = baseDelay * Math.pow(multiplier, attempt - 1);
61
+ // Add jitter (±25%)
62
+ const jitter = exponentialDelay * 0.25 * (Math.random() * 2 - 1);
63
+ // Cap at max delay
64
+ return Math.min(exponentialDelay + jitter, maxDelay);
65
+ }
66
+ /**
67
+ * Execute a function with retry logic
68
+ */
69
+ async function withRetry(fn, policy = {}) {
70
+ const { maxAttempts, baseDelay, maxDelay, backoffMultiplier, retryableErrors, onRetry, } = { ...exports.DEFAULT_RETRY_POLICY, ...policy };
71
+ let lastError;
72
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
73
+ try {
74
+ return await fn();
75
+ }
76
+ catch (error) {
77
+ lastError = error;
78
+ const errorCode = (0, errors_1.getErrorCode)(error);
79
+ // Check if error is retryable
80
+ const isRetryable = (0, errors_1.isRetryableError)(error) || retryableErrors.includes(errorCode);
81
+ if (!isRetryable || attempt === maxAttempts) {
82
+ throw error;
83
+ }
84
+ // Calculate delay
85
+ let delay;
86
+ if (error instanceof errors_1.RateLimitError) {
87
+ // Use retry-after from rate limit error if available
88
+ delay = error.retryAfter * 1000;
89
+ }
90
+ else {
91
+ delay = calculateBackoffDelay(attempt, baseDelay, maxDelay, backoffMultiplier);
92
+ }
93
+ // Call retry callback if provided
94
+ onRetry?.(attempt, error);
95
+ // Wait before retrying
96
+ await sleep(delay);
97
+ }
98
+ }
99
+ throw lastError;
100
+ }
101
+ /**
102
+ * Create a retryable version of a function
103
+ */
104
+ function makeRetryable(fn, policy = {}) {
105
+ return (...args) => withRetry(() => fn(...args), policy);
106
+ }
107
+ /**
108
+ * Retry with timeout
109
+ */
110
+ async function withRetryAndTimeout(fn, timeoutMs, policy = {}) {
111
+ return withRetry(async () => {
112
+ return Promise.race([
113
+ fn(),
114
+ new Promise((_, reject) => {
115
+ setTimeout(() => reject(new Error(`Operation timed out after ${timeoutMs}ms`)), timeoutMs);
116
+ }),
117
+ ]);
118
+ }, policy);
119
+ }
120
+ /**
121
+ * Execute with retry and context logging
122
+ */
123
+ async function withRetryContext(operation, fn, policy = {}, logger) {
124
+ const mergedPolicy = { ...exports.DEFAULT_RETRY_POLICY, ...policy };
125
+ const policyWithLogging = {
126
+ ...mergedPolicy,
127
+ onRetry: (attempt, error) => {
128
+ const delay = calculateBackoffDelay(attempt, mergedPolicy.baseDelay, mergedPolicy.maxDelay, mergedPolicy.backoffMultiplier);
129
+ logger?.({
130
+ operation,
131
+ attempt,
132
+ maxAttempts: mergedPolicy.maxAttempts,
133
+ error,
134
+ delay,
135
+ });
136
+ mergedPolicy.onRetry?.(attempt, error);
137
+ },
138
+ };
139
+ return withRetry(fn, policyWithLogging);
140
+ }
141
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
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 Data sanitization utilities for security
8
+ */
9
+ /**
10
+ * Sanitize error messages to prevent exposing sensitive data
11
+ */
12
+ export declare function sanitizeError(err: unknown): string;
13
+ /**
14
+ * Sanitize a string by removing sensitive data
15
+ */
16
+ export declare function sanitizeString(str: string): string;
17
+ /**
18
+ * Sanitize an object by redacting sensitive fields
19
+ */
20
+ export declare function sanitizeObject<T extends Record<string, unknown>>(obj: T): T;
21
+ /**
22
+ * Truncate a string to a maximum length
23
+ */
24
+ export declare function truncate(str: string, maxLength: number, suffix?: string): string;
25
+ /**
26
+ * Mask a token for logging (show first and last few characters)
27
+ */
28
+ export declare function maskToken(token: string, visibleChars?: number): string;
29
+ /**
30
+ * Create a safe preview of a response body for logging
31
+ */
32
+ export declare function createResponsePreview(body: string, maxLength?: number): string;
33
+ /**
34
+ * Sanitize stack trace by removing file paths that might expose system info
35
+ */
36
+ export declare function sanitizeStackTrace(stack: string | undefined): string | undefined;
37
+ //# sourceMappingURL=sanitizers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizers.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAYlD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CA6B3E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAQ,GAAG,MAAM,CAK/E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,SAAI,GAAG,MAAM,CAKjE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAG3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAQhF"}
@@ -0,0 +1,128 @@
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 Data sanitization utilities for security
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.sanitizeError = sanitizeError;
12
+ exports.sanitizeString = sanitizeString;
13
+ exports.sanitizeObject = sanitizeObject;
14
+ exports.truncate = truncate;
15
+ exports.maskToken = maskToken;
16
+ exports.createResponsePreview = createResponsePreview;
17
+ exports.sanitizeStackTrace = sanitizeStackTrace;
18
+ /**
19
+ * Patterns for sensitive data that should be redacted
20
+ */
21
+ const SENSITIVE_PATTERNS = [
22
+ { pattern: /password[=:]\s*\S+/gi, replacement: 'password=***' },
23
+ { pattern: /token[=:]\s*\S+/gi, replacement: 'token=***' },
24
+ { pattern: /email[=:]\s*\S+/gi, replacement: 'email=***' },
25
+ { pattern: /authorization[=:]\s*\S+/gi, replacement: 'Authorization=***' },
26
+ { pattern: /bearer\s+\S+/gi, replacement: 'Bearer ***' },
27
+ { pattern: /"password"\s*:\s*"[^"]+"/gi, replacement: '"password":"***"' },
28
+ { pattern: /"token"\s*:\s*"[^"]+"/gi, replacement: '"token":"***"' },
29
+ { pattern: /"id"\s*:\s*"[a-zA-Z0-9]{20,}"/gi, replacement: '"id":"***"' },
30
+ ];
31
+ /**
32
+ * Sanitize error messages to prevent exposing sensitive data
33
+ */
34
+ function sanitizeError(err) {
35
+ let message;
36
+ if (err instanceof Error) {
37
+ message = err.message;
38
+ }
39
+ else if (typeof err === 'string') {
40
+ message = err;
41
+ }
42
+ else {
43
+ message = String(err);
44
+ }
45
+ return sanitizeString(message);
46
+ }
47
+ /**
48
+ * Sanitize a string by removing sensitive data
49
+ */
50
+ function sanitizeString(str) {
51
+ let result = str;
52
+ for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
53
+ result = result.replace(pattern, replacement);
54
+ }
55
+ return result;
56
+ }
57
+ /**
58
+ * Sanitize an object by redacting sensitive fields
59
+ */
60
+ function sanitizeObject(obj) {
61
+ const sensitiveKeys = new Set([
62
+ 'password',
63
+ 'token',
64
+ 'authorization',
65
+ 'secret',
66
+ 'apiKey',
67
+ 'api_key',
68
+ 'accessToken',
69
+ 'access_token',
70
+ 'refreshToken',
71
+ 'refresh_token',
72
+ ]);
73
+ const result = {};
74
+ for (const [key, value] of Object.entries(obj)) {
75
+ if (sensitiveKeys.has(key.toLowerCase())) {
76
+ result[key] = '***';
77
+ }
78
+ else if (typeof value === 'object' && value !== null) {
79
+ result[key] = sanitizeObject(value);
80
+ }
81
+ else if (typeof value === 'string') {
82
+ result[key] = sanitizeString(value);
83
+ }
84
+ else {
85
+ result[key] = value;
86
+ }
87
+ }
88
+ return result;
89
+ }
90
+ /**
91
+ * Truncate a string to a maximum length
92
+ */
93
+ function truncate(str, maxLength, suffix = '...') {
94
+ if (str.length <= maxLength) {
95
+ return str;
96
+ }
97
+ return str.substring(0, maxLength - suffix.length) + suffix;
98
+ }
99
+ /**
100
+ * Mask a token for logging (show first and last few characters)
101
+ */
102
+ function maskToken(token, visibleChars = 4) {
103
+ if (token.length <= visibleChars * 2) {
104
+ return '***';
105
+ }
106
+ return `${token.substring(0, visibleChars)}...${token.substring(token.length - visibleChars)}`;
107
+ }
108
+ /**
109
+ * Create a safe preview of a response body for logging
110
+ */
111
+ function createResponsePreview(body, maxLength = 200) {
112
+ const sanitized = sanitizeString(body);
113
+ return truncate(sanitized, maxLength);
114
+ }
115
+ /**
116
+ * Sanitize stack trace by removing file paths that might expose system info
117
+ */
118
+ function sanitizeStackTrace(stack) {
119
+ if (!stack) {
120
+ return undefined;
121
+ }
122
+ // Remove absolute paths, keep relative
123
+ return stack.replace(/\s+at\s+.*\((\/[^)]+)\)/g, (match, path) => {
124
+ const filename = path.split('/').pop() || path;
125
+ return match.replace(path, filename);
126
+ });
127
+ }
128
+ //# sourceMappingURL=sanitizers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizers.js","sourceRoot":"","sources":["../../src/utils/sanitizers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
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 Input validation utilities
8
+ */
9
+ import type { LevitonConfig, PowerState } from '../types';
10
+ /**
11
+ * Validate email format
12
+ */
13
+ export declare function validateEmail(email: unknown): string;
14
+ /**
15
+ * Validate password
16
+ */
17
+ export declare function validatePassword(password: unknown): string;
18
+ /**
19
+ * Validate device ID
20
+ * Accepts strings or numbers (Leviton API returns numeric IDs)
21
+ */
22
+ export declare function validateDeviceId(id: unknown): string;
23
+ /**
24
+ * Validate device serial
25
+ */
26
+ export declare function validateSerial(serial: unknown): string;
27
+ /**
28
+ * Validate authentication token
29
+ */
30
+ export declare function validateToken(token: unknown): string;
31
+ /**
32
+ * Validate power state
33
+ */
34
+ export declare function validatePowerState(power: unknown): PowerState;
35
+ /**
36
+ * Validate brightness value (0-100)
37
+ */
38
+ export declare function validateBrightness(brightness: unknown): number;
39
+ /**
40
+ * Validate plugin configuration
41
+ */
42
+ export declare function validateConfig(config: unknown): LevitonConfig;
43
+ /**
44
+ * Validate that a value is defined (not null or undefined)
45
+ */
46
+ export declare function assertDefined<T>(value: T | null | undefined, name: string): T;
47
+ /**
48
+ * Validate that a value is a non-empty array
49
+ */
50
+ export declare function validateNonEmptyArray<T>(arr: unknown, name: string): T[];
51
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAiBzD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAmBpD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAc1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAoBpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAetD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAK7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,CAc9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CAqF7D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAK7E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,CAQxE"}