@felixgeelhaar/govee-api-client 2.0.0 → 2.1.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.
@@ -0,0 +1,974 @@
1
+ # Govee API Client - Type Definitions
2
+
3
+ This document provides comprehensive type definitions for the Govee API Client library. All types are fully documented with TypeScript definitions.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Configuration Types](#configuration-types)
8
+ - [Domain Entity Types](#domain-entity-types)
9
+ - [Value Object Types](#value-object-types)
10
+ - [Command Types](#command-types)
11
+ - [State Types](#state-types)
12
+ - [Error Types](#error-types)
13
+ - [Validation Types](#validation-types)
14
+ - [Retry & Rate Limiting Types](#retry--rate-limiting-types)
15
+ - [Utility Types](#utility-types)
16
+
17
+ ## Configuration Types
18
+
19
+ ### GoveeClientConfig
20
+
21
+ Main configuration interface for initializing the GoveeClient.
22
+
23
+ ```typescript
24
+ interface GoveeClientConfig {
25
+ apiKey: string; // Required: Govee API key
26
+ timeout?: number; // Optional: Request timeout in milliseconds (default: 30000)
27
+ rateLimit?: number; // Optional: Max requests per minute (default: 95)
28
+ logger?: Logger; // Optional: Pino logger instance
29
+ enableRetries?: boolean; // Optional: Enable retry logic (default: false)
30
+ retryPolicy?: RetryPolicyType; // Optional: Retry policy configuration
31
+ }
32
+
33
+ type RetryPolicyType = 'development' | 'testing' | 'production' | 'custom' | RetryPolicy;
34
+ ```
35
+
36
+ ### GoveeControlServiceConfig
37
+
38
+ Configuration for the internal control service.
39
+
40
+ ```typescript
41
+ interface GoveeControlServiceConfig {
42
+ repository: IGoveeDeviceRepository;
43
+ logger?: Logger;
44
+ rateLimit?: number;
45
+ enableRetries?: boolean;
46
+ retryPolicy?: RetryPolicyType;
47
+ }
48
+ ```
49
+
50
+ ### GoveeDeviceRepositoryConfig
51
+
52
+ Configuration for the device repository.
53
+
54
+ ```typescript
55
+ interface GoveeDeviceRepositoryConfig {
56
+ apiKey: string;
57
+ timeout?: number;
58
+ logger?: Logger;
59
+ }
60
+ ```
61
+
62
+ ## Domain Entity Types
63
+
64
+ ### GoveeDevice
65
+
66
+ Represents a Govee smart device.
67
+
68
+ ```typescript
69
+ class GoveeDevice {
70
+ readonly deviceId: string;
71
+ readonly model: string; // Alias for sku (backward compatibility)
72
+ readonly sku: string;
73
+ readonly deviceName: string;
74
+ readonly controllable: boolean;
75
+ readonly retrievable: boolean;
76
+ readonly supportedCmds: readonly string[];
77
+ readonly capabilities: readonly GoveeCapability[];
78
+
79
+ equals(other: GoveeDevice): boolean;
80
+ supportsCommand(command: string): boolean;
81
+ canControl(): boolean;
82
+ canRetrieve(): boolean;
83
+ toString(): string;
84
+ toObject(): DeviceObject;
85
+ static fromObject(obj: DeviceObject): GoveeDevice;
86
+ }
87
+
88
+ interface DeviceObject {
89
+ deviceId: string;
90
+ model: string;
91
+ deviceName: string;
92
+ controllable: boolean;
93
+ retrievable: boolean;
94
+ supportedCmds: string[];
95
+ }
96
+
97
+ interface GoveeCapability {
98
+ type: string;
99
+ instance: string;
100
+ parameters?: {
101
+ dataType: string;
102
+ options?: Array<{
103
+ name: string;
104
+ value: unknown;
105
+ }>;
106
+ };
107
+ }
108
+ ```
109
+
110
+ ### DeviceState
111
+
112
+ Represents the current state of a device.
113
+
114
+ ```typescript
115
+ class DeviceState {
116
+ readonly deviceId: string;
117
+ readonly model: string;
118
+ readonly properties: readonly StateProperty[];
119
+
120
+ getPowerState(): PowerState | undefined;
121
+ getBrightness(): number | undefined; // 0-100
122
+ getColor(): ColorState | undefined;
123
+ getColorTemperature(): number | undefined; // Kelvin
124
+ isOnline(): boolean;
125
+ hasProperty(type: string, instance: string): boolean;
126
+ getProperty(type: string, instance: string): StateProperty | undefined;
127
+ }
128
+
129
+ interface StateProperty {
130
+ type: string;
131
+ instance: string;
132
+ value: unknown;
133
+ }
134
+
135
+ type PowerState = 'on' | 'off';
136
+ type ColorState = { r: number; g: number; b: number };
137
+ type ColorTemperatureState = number; // Kelvin
138
+ type BrightnessState = number; // 0-100
139
+ ```
140
+
141
+ ### Command Types
142
+
143
+ Base command class and specific command implementations.
144
+
145
+ ```typescript
146
+ abstract class Command {
147
+ abstract readonly name: string;
148
+ abstract readonly value: unknown;
149
+ abstract toApiFormat(): { name: string; value: unknown };
150
+ }
151
+
152
+ class PowerOnCommand extends Command {
153
+ readonly name = 'turn';
154
+ readonly value = 1;
155
+ toApiFormat(): { name: string; value: number };
156
+ }
157
+
158
+ class PowerOffCommand extends Command {
159
+ readonly name = 'turn';
160
+ readonly value = 0;
161
+ toApiFormat(): { name: string; value: number };
162
+ }
163
+
164
+ class BrightnessCommand extends Command {
165
+ readonly name = 'brightness';
166
+ readonly value: number;
167
+ constructor(brightness: Brightness);
168
+ toApiFormat(): { name: string; value: number };
169
+ }
170
+
171
+ class ColorCommand extends Command {
172
+ readonly name = 'color';
173
+ readonly value: { r: number; g: number; b: number };
174
+ constructor(color: ColorRgb);
175
+ toApiFormat(): { name: string; value: { r: number; g: number; b: number } };
176
+ }
177
+
178
+ class ColorTemperatureCommand extends Command {
179
+ readonly name = 'colorTem';
180
+ readonly value: number;
181
+ constructor(colorTemperature: ColorTemperature);
182
+ toApiFormat(): { name: string; value: number };
183
+ }
184
+ ```
185
+
186
+ ### CommandFactory
187
+
188
+ Static factory for creating commands.
189
+
190
+ ```typescript
191
+ class CommandFactory {
192
+ static powerOn(): PowerOnCommand;
193
+ static powerOff(): PowerOffCommand;
194
+ static brightness(brightness: Brightness): BrightnessCommand;
195
+ static color(color: ColorRgb): ColorCommand;
196
+ static colorTemperature(temp: ColorTemperature): ColorTemperatureCommand;
197
+ }
198
+ ```
199
+
200
+ ## Value Object Types
201
+
202
+ ### ColorRgb
203
+
204
+ Represents RGB color values (0-255 per component).
205
+
206
+ ```typescript
207
+ class ColorRgb {
208
+ readonly r: number; // 0-255
209
+ readonly g: number; // 0-255
210
+ readonly b: number; // 0-255
211
+
212
+ constructor(r: number, g: number, b: number);
213
+ equals(other: ColorRgb): boolean;
214
+ toString(): string; // "rgb(r, g, b)"
215
+ toHex(): string; // "#rrggbb"
216
+ toObject(): ColorRgbObject;
217
+
218
+ static fromHex(hex: string): ColorRgb;
219
+ static fromObject(obj: ColorRgbObject): ColorRgb;
220
+ }
221
+
222
+ interface ColorRgbObject {
223
+ r: number;
224
+ g: number;
225
+ b: number;
226
+ }
227
+ ```
228
+
229
+ ### ColorTemperature
230
+
231
+ Represents color temperature in Kelvin (2000-9000K).
232
+
233
+ ```typescript
234
+ class ColorTemperature {
235
+ readonly kelvin: number; // 2000-9000
236
+
237
+ constructor(kelvin: number);
238
+ equals(other: ColorTemperature): boolean;
239
+ toString(): string;
240
+ isWarm(): boolean; // < 4000K
241
+ isCool(): boolean; // > 5000K
242
+ toObject(): ColorTemperatureObject;
243
+
244
+ static warmWhite(): ColorTemperature; // 2700K
245
+ static coolWhite(): ColorTemperature; // 6500K
246
+ static daylight(): ColorTemperature; // 5600K
247
+ static fromObject(obj: ColorTemperatureObject): ColorTemperature;
248
+ }
249
+
250
+ interface ColorTemperatureObject {
251
+ kelvin: number;
252
+ }
253
+ ```
254
+
255
+ ### Brightness
256
+
257
+ Represents brightness level (0-100).
258
+
259
+ ```typescript
260
+ class Brightness {
261
+ readonly level: number; // 0-100
262
+
263
+ constructor(level: number);
264
+ equals(other: Brightness): boolean;
265
+ toString(): string;
266
+ asPercent(): number; // 0.0-1.0
267
+ isDim(): boolean; // < 30
268
+ isBright(): boolean; // > 70
269
+ toObject(): BrightnessObject;
270
+
271
+ static dim(): Brightness; // 25
272
+ static medium(): Brightness; // 50
273
+ static bright(): Brightness; // 75
274
+ static fromObject(obj: BrightnessObject): Brightness;
275
+ }
276
+
277
+ interface BrightnessObject {
278
+ level: number;
279
+ }
280
+ ```
281
+
282
+ ## Error Types
283
+
284
+ ### Error Hierarchy
285
+
286
+ Complete error class hierarchy with TypeScript types.
287
+
288
+ ```typescript
289
+ abstract class GoveeApiClientError extends Error {
290
+ abstract readonly errorType: string;
291
+ abstract isRetryable(): boolean;
292
+
293
+ constructor(message: string);
294
+ }
295
+
296
+ class GoveeApiError extends GoveeApiClientError {
297
+ readonly errorType = 'GoveeApiError';
298
+ readonly statusCode?: number;
299
+ readonly response?: unknown;
300
+
301
+ constructor(message: string, statusCode?: number, response?: unknown);
302
+ isRetryable(): boolean;
303
+ isDeviceOffline(): boolean;
304
+ getRecommendation(): string;
305
+ }
306
+
307
+ class InvalidApiKeyError extends GoveeApiClientError {
308
+ readonly errorType = 'InvalidApiKeyError';
309
+
310
+ constructor(message: string);
311
+ isRetryable(): false;
312
+ getRecommendation(): string;
313
+ }
314
+
315
+ class RateLimitError extends GoveeApiClientError {
316
+ readonly errorType = 'RateLimitError';
317
+ readonly retryAfterMs?: number;
318
+
319
+ constructor(message: string, retryAfterMs?: number);
320
+ isRetryable(): true;
321
+ getRetryAfterMs(): number;
322
+ }
323
+
324
+ class NetworkError extends GoveeApiClientError {
325
+ readonly errorType = 'NetworkError';
326
+ readonly cause?: Error;
327
+
328
+ constructor(message: string, cause?: Error);
329
+ isRetryable(): boolean;
330
+ }
331
+
332
+ class ValidationError extends GoveeApiClientError {
333
+ readonly code = 'VALIDATION_ERROR';
334
+ readonly zodError: ZodError;
335
+ readonly rawData: unknown;
336
+
337
+ constructor(message: string, zodError: ZodError, rawData: unknown);
338
+
339
+ static fromZodError(zodError: ZodError, rawData: unknown): ValidationError;
340
+ getValidationDetails(): Array<{ path: string; message: string; received: unknown }>;
341
+ getValidationSummary(): string;
342
+ }
343
+ ```
344
+
345
+ ### Error Type Guards
346
+
347
+ TypeScript type guards for error handling.
348
+
349
+ ```typescript
350
+ function isGoveeApiError(error: unknown): error is GoveeApiError;
351
+ function isInvalidApiKeyError(error: unknown): error is InvalidApiKeyError;
352
+ function isRateLimitError(error: unknown): error is RateLimitError;
353
+ function isNetworkError(error: unknown): error is NetworkError;
354
+ function isValidationError(error: unknown): error is ValidationError;
355
+ ```
356
+
357
+ ## Validation Types
358
+
359
+ ### Zod Schemas
360
+
361
+ Exported Zod schemas for runtime API response validation.
362
+
363
+ ```typescript
364
+ import { z } from 'zod';
365
+
366
+ // Device capability schema
367
+ const GoveeCapabilitySchema: z.ZodType;
368
+
369
+ // Individual device response schema
370
+ const GoveeDeviceResponseSchema: z.ZodType;
371
+
372
+ // Full devices API response schema
373
+ const GoveeDevicesResponseSchema: z.ZodObject<{
374
+ code: z.ZodNumber;
375
+ message: z.ZodString;
376
+ data: z.ZodArray<typeof GoveeDeviceResponseSchema>;
377
+ }>;
378
+
379
+ // Device state capability schema
380
+ const GoveeStateCapabilitySchema: z.ZodObject<{
381
+ type: z.ZodString;
382
+ instance: z.ZodString;
383
+ state: z.ZodObject<{ value: z.ZodUnknown }>;
384
+ }>;
385
+
386
+ // Device state API response schema
387
+ const GoveeStateResponseSchema: z.ZodObject<{
388
+ code: z.ZodNumber;
389
+ message: z.ZodString;
390
+ data: z.ZodObject<{
391
+ device: z.ZodString;
392
+ sku: z.ZodString;
393
+ capabilities: z.ZodArray<typeof GoveeStateCapabilitySchema>;
394
+ }>;
395
+ }>;
396
+
397
+ // Command API response schema
398
+ const GoveeCommandResponseSchema: z.ZodObject<{
399
+ code: z.ZodNumber;
400
+ message: z.ZodString;
401
+ data: z.ZodOptional<z.ZodUnknown>;
402
+ }>;
403
+ ```
404
+
405
+ ### Response Types
406
+
407
+ TypeScript types inferred from Zod schemas.
408
+
409
+ ```typescript
410
+ // Type inferred from GoveeDevicesResponseSchema
411
+ type GoveeDevicesResponse = {
412
+ code: number;
413
+ message: string;
414
+ data: Array<{
415
+ device?: string | null;
416
+ sku?: string | null;
417
+ deviceName?: string | null;
418
+ capabilities?: Array<{
419
+ type?: string | null;
420
+ instance?: string | null;
421
+ parameters?: {
422
+ dataType: string;
423
+ options?: Array<{
424
+ name: string;
425
+ value: unknown;
426
+ }>;
427
+ };
428
+ }> | null;
429
+ }>;
430
+ };
431
+
432
+ // Type inferred from GoveeStateResponseSchema
433
+ type GoveeStateResponse = {
434
+ code: number;
435
+ message: string;
436
+ data: {
437
+ device: string;
438
+ sku: string;
439
+ capabilities: Array<{
440
+ type: string;
441
+ instance: string;
442
+ state: {
443
+ value: unknown;
444
+ };
445
+ }>;
446
+ };
447
+ };
448
+
449
+ // Type inferred from GoveeCommandResponseSchema
450
+ type GoveeCommandResponse = {
451
+ code: number;
452
+ message: string;
453
+ data?: unknown;
454
+ };
455
+ ```
456
+
457
+ ### Using Validation Schemas
458
+
459
+ Examples of using exported schemas for custom validation:
460
+
461
+ ```typescript
462
+ import {
463
+ GoveeDevicesResponseSchema,
464
+ GoveeStateResponseSchema,
465
+ type GoveeDevicesResponse,
466
+ } from '@felixgeelhaar/govee-api-client';
467
+
468
+ // Validate unknown data
469
+ function validateDevicesResponse(data: unknown): GoveeDevicesResponse {
470
+ return GoveeDevicesResponseSchema.parse(data); // Throws on invalid data
471
+ }
472
+
473
+ // Safe validation without throwing
474
+ function safeValidate(data: unknown) {
475
+ const result = GoveeDevicesResponseSchema.safeParse(data);
476
+
477
+ if (result.success) {
478
+ const validData: GoveeDevicesResponse = result.data;
479
+ return validData;
480
+ } else {
481
+ console.error('Validation failed:', result.error);
482
+ return null;
483
+ }
484
+ }
485
+
486
+ // Custom schema composition
487
+ import { z } from 'zod';
488
+
489
+ const ExtendedDeviceSchema = GoveeDevicesResponseSchema.extend({
490
+ metadata: z.object({
491
+ fetchedAt: z.date(),
492
+ cacheKey: z.string(),
493
+ }),
494
+ });
495
+ ```
496
+
497
+ ### ValidationError Details
498
+
499
+ Structure of validation error details returned by `getValidationDetails()`:
500
+
501
+ ```typescript
502
+ interface ValidationDetail {
503
+ path: string; // JSON path to the field that failed (e.g., "data.0.deviceName")
504
+ message: string; // Human-readable error message
505
+ received: unknown; // The actual value that failed validation
506
+ }
507
+
508
+ // Example usage
509
+ try {
510
+ await client.getDevices();
511
+ } catch (error) {
512
+ if (error instanceof ValidationError) {
513
+ const details: ValidationDetail[] = error.getValidationDetails();
514
+
515
+ details.forEach(({ path, message, received }) => {
516
+ console.log(`Field "${path}" is invalid`);
517
+ console.log(`Error: ${message}`);
518
+ console.log(`Got: ${JSON.stringify(received)}`);
519
+ });
520
+ }
521
+ }
522
+ ```
523
+
524
+ ## Retry & Rate Limiting Types
525
+
526
+ ### RetryPolicy
527
+
528
+ Configuration for retry behavior.
529
+
530
+ ```typescript
531
+ class RetryPolicy {
532
+ constructor(config: RetryPolicyConfig);
533
+ }
534
+
535
+ interface RetryPolicyConfig {
536
+ backoff: BackoffStrategy;
537
+ jitter: JitterConfig;
538
+ condition: RetryCondition;
539
+ circuitBreaker: CircuitBreakerConfig;
540
+ enableMetrics: boolean;
541
+ }
542
+
543
+ interface BackoffStrategy {
544
+ type: 'exponential' | 'linear' | 'constant';
545
+ initialDelayMs: number;
546
+ maxDelayMs: number;
547
+ multiplier?: number; // For exponential backoff
548
+ increment?: number; // For linear backoff
549
+ }
550
+
551
+ interface JitterConfig {
552
+ type: 'none' | 'full' | 'equal' | 'decorrelated';
553
+ factor?: number; // 0.0-1.0, randomization factor
554
+ }
555
+
556
+ interface RetryCondition {
557
+ maxAttempts: number;
558
+ maxTotalTimeMs: number;
559
+ retryableStatusCodes: number[];
560
+ retryableErrorTypes: (new (...args: any[]) => Error)[];
561
+ }
562
+
563
+ interface CircuitBreakerConfig {
564
+ enabled: boolean;
565
+ failureThreshold: number; // Failures before opening
566
+ recoveryTimeoutMs: number; // Time before trying half-open
567
+ halfOpenSuccessThreshold: number; // Successes needed to close
568
+ }
569
+ ```
570
+
571
+ ### RetryMetrics
572
+
573
+ Metrics for monitoring retry behavior.
574
+
575
+ ```typescript
576
+ interface RetryMetrics {
577
+ totalAttempts: number;
578
+ successfulRetries: number;
579
+ failedRetries: number;
580
+ totalRetryTimeMs: number;
581
+ averageRetryDelayMs: number;
582
+ circuitBreakerState: CircuitBreakerState;
583
+ lastError?: Error;
584
+ lastRetryTimestamp?: Date;
585
+ }
586
+
587
+ type CircuitBreakerState = 'closed' | 'open' | 'half-open';
588
+ ```
589
+
590
+ ### Rate Limiter Types
591
+
592
+ Types for rate limiting functionality.
593
+
594
+ ```typescript
595
+ interface RateLimiterStats {
596
+ currentRequests: number;
597
+ maxRequests: number;
598
+ utilizationPercent: number;
599
+ queueSize: number;
600
+ canExecuteImmediately: boolean;
601
+ nextAvailableSlot: Date | null;
602
+ }
603
+
604
+ interface ServiceStats {
605
+ rateLimiter: RateLimiterStats;
606
+ retries?: RetryMetrics;
607
+ configuration: ServiceConfiguration;
608
+ }
609
+
610
+ interface ServiceConfiguration {
611
+ rateLimit: number;
612
+ timeout: number;
613
+ retriesEnabled: boolean;
614
+ retryPolicy?: string;
615
+ }
616
+ ```
617
+
618
+ ## Repository Types
619
+
620
+ ### IGoveeDeviceRepository
621
+
622
+ Interface for device repository implementations.
623
+
624
+ ```typescript
625
+ interface IGoveeDeviceRepository {
626
+ findAll(): Promise<GoveeDevice[]>;
627
+ findState(deviceId: string, model: string): Promise<DeviceState>;
628
+ sendCommand(deviceId: string, model: string, command: Command): Promise<void>;
629
+ }
630
+ ```
631
+
632
+ ### API Response Types
633
+
634
+ Internal types for API responses (used by repository).
635
+
636
+ ```typescript
637
+ interface DevicesResponse {
638
+ code: number;
639
+ message: string;
640
+ data: {
641
+ devices: DeviceData[];
642
+ };
643
+ }
644
+
645
+ interface DeviceData {
646
+ device: string; // deviceId
647
+ sku: string; // model
648
+ deviceName: string;
649
+ capabilities: GoveeCapability[];
650
+ }
651
+
652
+ interface StateResponse {
653
+ code: number;
654
+ message: string;
655
+ data: {
656
+ device: string;
657
+ sku: string;
658
+ capabilities: StateCapability[];
659
+ };
660
+ }
661
+
662
+ interface StateCapability {
663
+ type: string;
664
+ instance: string;
665
+ state: {
666
+ value: unknown;
667
+ };
668
+ }
669
+
670
+ interface CommandResponse {
671
+ code: number;
672
+ message: string;
673
+ data: Record<string, unknown>;
674
+ }
675
+
676
+ interface ApiErrorResponse {
677
+ code: number;
678
+ message: string;
679
+ data?: unknown;
680
+ }
681
+ ```
682
+
683
+ ## Utility Types
684
+
685
+ ### Generic Utility Types
686
+
687
+ Helpful TypeScript utility types.
688
+
689
+ ```typescript
690
+ // Extract device ID type
691
+ type DeviceId = GoveeDevice['deviceId'];
692
+
693
+ // Extract model type
694
+ type DeviceModel = GoveeDevice['model'];
695
+
696
+ // Extract supported command types
697
+ type SupportedCommand = GoveeDevice['supportedCmds'][number];
698
+
699
+ // Extract power state union
700
+ type PowerState = ReturnType<DeviceState['getPowerState']>;
701
+
702
+ // Extract color object type
703
+ type ColorObject = NonNullable<ReturnType<DeviceState['getColor']>>;
704
+
705
+ // Configuration with required API key
706
+ type RequiredApiKeyConfig = Required<Pick<GoveeClientConfig, 'apiKey'>> &
707
+ Partial<Omit<GoveeClientConfig, 'apiKey'>>;
708
+
709
+ // Partial device for updates
710
+ type PartialDevice = Partial<Pick<GoveeDevice, 'deviceName' | 'controllable' | 'retrievable'>>;
711
+
712
+ // Command name union type
713
+ type CommandName = Command['name'];
714
+
715
+ // Command value type
716
+ type CommandValue = Command['value'];
717
+ ```
718
+
719
+ ### Async Return Types
720
+
721
+ Types for async method return values.
722
+
723
+ ```typescript
724
+ // Device list operations
725
+ type DeviceListResult = Promise<GoveeDevice[]>;
726
+ type DeviceSearchResult = Promise<GoveeDevice | undefined>;
727
+ type DeviceFilterResult = Promise<GoveeDevice[]>;
728
+
729
+ // Device control operations
730
+ type ControlResult = Promise<void>;
731
+ type StateResult = Promise<DeviceState>;
732
+ type StatusResult = Promise<boolean>;
733
+
734
+ // Monitoring operations
735
+ type StatsResult = RateLimiterStats;
736
+ type MetricsResult = RetryMetrics | undefined;
737
+ type ServiceStatsResult = ServiceStats;
738
+ ```
739
+
740
+ ### Event Types
741
+
742
+ Types for potential event handling (future extension).
743
+
744
+ ```typescript
745
+ interface DeviceEvent {
746
+ type: 'state-changed' | 'offline' | 'online' | 'error';
747
+ deviceId: string;
748
+ model: string;
749
+ timestamp: Date;
750
+ data?: unknown;
751
+ }
752
+
753
+ interface RateLimitEvent {
754
+ type: 'limit-reached' | 'limit-warning' | 'queue-full';
755
+ timestamp: Date;
756
+ stats: RateLimiterStats;
757
+ }
758
+
759
+ interface RetryEvent {
760
+ type: 'retry-attempt' | 'retry-success' | 'retry-failure' | 'circuit-breaker';
761
+ timestamp: Date;
762
+ attempt: number;
763
+ delay: number;
764
+ error?: Error;
765
+ }
766
+ ```
767
+
768
+ ### Type Predicates
769
+
770
+ Type guard functions for runtime type checking.
771
+
772
+ ```typescript
773
+ // Device type guards
774
+ function isGoveeDevice(obj: unknown): obj is GoveeDevice;
775
+ function isDeviceState(obj: unknown): obj is DeviceState;
776
+ function isCommand(obj: unknown): obj is Command;
777
+
778
+ // Value object type guards
779
+ function isColorRgb(obj: unknown): obj is ColorRgb;
780
+ function isColorTemperature(obj: unknown): obj is ColorTemperature;
781
+ function isBrightness(obj: unknown): obj is Brightness;
782
+
783
+ // Configuration type guards
784
+ function isValidClientConfig(obj: unknown): obj is GoveeClientConfig;
785
+ function isValidRetryPolicy(obj: unknown): obj is RetryPolicy;
786
+
787
+ // State property type guards
788
+ function isPowerProperty(prop: StateProperty): prop is StateProperty & { value: 0 | 1 };
789
+ function isBrightnessProperty(prop: StateProperty): prop is StateProperty & { value: number };
790
+ function isColorProperty(prop: StateProperty): prop is StateProperty & { value: ColorState };
791
+ ```
792
+
793
+ ### Branded Types
794
+
795
+ Branded types for additional type safety.
796
+
797
+ ```typescript
798
+ // Branded string types for IDs
799
+ type DeviceId = string & { readonly __brand: 'DeviceId' };
800
+ type ModelId = string & { readonly __brand: 'ModelId' };
801
+ type ApiKey = string & { readonly __brand: 'ApiKey' };
802
+
803
+ // Branded number types for values
804
+ type KelvinValue = number & { readonly __brand: 'Kelvin' };
805
+ type BrightnessValue = number & { readonly __brand: 'Brightness' };
806
+ type RgbValue = number & { readonly __brand: 'RgbComponent' };
807
+
808
+ // Type constructors
809
+ function createDeviceId(id: string): DeviceId;
810
+ function createModelId(model: string): ModelId;
811
+ function createApiKey(key: string): ApiKey;
812
+ function createKelvinValue(kelvin: number): KelvinValue;
813
+ function createBrightnessValue(brightness: number): BrightnessValue;
814
+ function createRgbValue(rgb: number): RgbValue;
815
+ ```
816
+
817
+ ### Template Literal Types
818
+
819
+ Template literal types for command names and property types.
820
+
821
+ ```typescript
822
+ // Command name templates
823
+ type PowerCommand = `turn_${string}`;
824
+ type ColorCommand = `color_${string}`;
825
+ type BrightnessCommand = `brightness_${string}`;
826
+
827
+ // Property type templates
828
+ type OnOffProperty = `devices.capabilities.on_off.${string}`;
829
+ type RangeProperty = `devices.capabilities.range.${string}`;
830
+ type ColorProperty = `devices.capabilities.color_setting.${string}`;
831
+
832
+ // Instance name templates
833
+ type PowerInstance = 'powerSwitch';
834
+ type BrightnessInstance = 'brightness';
835
+ type ColorRgbInstance = 'colorRgb';
836
+ type ColorTemperatureInstance = 'colorTemperatureK';
837
+ ```
838
+
839
+ ### Conditional Types
840
+
841
+ Conditional types for advanced type manipulation.
842
+
843
+ ```typescript
844
+ // Extract command type based on name
845
+ type CommandByName<T extends string> = T extends 'turn'
846
+ ? PowerOnCommand | PowerOffCommand
847
+ : T extends 'brightness'
848
+ ? BrightnessCommand
849
+ : T extends 'color'
850
+ ? ColorCommand
851
+ : T extends 'colorTem'
852
+ ? ColorTemperatureCommand
853
+ : never;
854
+
855
+ // Extract value type based on command
856
+ type ValueByCommand<T extends Command> = T extends PowerOnCommand | PowerOffCommand
857
+ ? number
858
+ : T extends BrightnessCommand
859
+ ? number
860
+ : T extends ColorCommand
861
+ ? ColorState
862
+ : T extends ColorTemperatureCommand
863
+ ? number
864
+ : never;
865
+
866
+ // Device with specific capabilities
867
+ type DeviceWithCapability<T extends string> = GoveeDevice & {
868
+ supportedCmds: readonly T[];
869
+ };
870
+
871
+ // Controllable device
872
+ type ControllableDevice = DeviceWithCapability<'turn'>;
873
+
874
+ // Color-capable device
875
+ type ColorDevice = DeviceWithCapability<'color'>;
876
+ ```
877
+
878
+ ### Mapped Types
879
+
880
+ Mapped types for transforming interfaces.
881
+
882
+ ```typescript
883
+ // Optional device properties
884
+ type OptionalDevice = {
885
+ [K in keyof GoveeDevice]?: GoveeDevice[K];
886
+ };
887
+
888
+ // Required configuration
889
+ type RequiredConfig = {
890
+ [K in keyof GoveeClientConfig]-?: GoveeClientConfig[K];
891
+ };
892
+
893
+ // Serializable versions (without methods)
894
+ type SerializableDevice = Pick<
895
+ GoveeDevice,
896
+ 'deviceId' | 'model' | 'deviceName' | 'controllable' | 'retrievable' | 'supportedCmds'
897
+ >;
898
+
899
+ type SerializableState = Pick<DeviceState, 'deviceId' | 'model'> & {
900
+ properties: StateProperty[];
901
+ powerState?: PowerState;
902
+ brightness?: number;
903
+ color?: ColorState;
904
+ colorTemperature?: number;
905
+ online: boolean;
906
+ };
907
+ ```
908
+
909
+ ## Type Validation
910
+
911
+ ### Runtime Type Validation with Zod
912
+
913
+ Schema definitions for runtime validation.
914
+
915
+ ```typescript
916
+ import { z } from 'zod';
917
+
918
+ // Configuration schemas
919
+ const GoveeClientConfigSchema = z.object({
920
+ apiKey: z.string().min(1),
921
+ timeout: z.number().int().positive().optional(),
922
+ rateLimit: z.number().int().positive().optional(),
923
+ logger: z.any().optional(),
924
+ enableRetries: z.boolean().optional(),
925
+ retryPolicy: z
926
+ .union([
927
+ z.literal('development'),
928
+ z.literal('testing'),
929
+ z.literal('production'),
930
+ z.literal('custom'),
931
+ z.any(), // RetryPolicy instance
932
+ ])
933
+ .optional(),
934
+ });
935
+
936
+ // Value object schemas
937
+ const ColorRgbSchema = z.object({
938
+ r: z.number().int().min(0).max(255),
939
+ g: z.number().int().min(0).max(255),
940
+ b: z.number().int().min(0).max(255),
941
+ });
942
+
943
+ const ColorTemperatureSchema = z.object({
944
+ kelvin: z.number().int().min(2000).max(9000),
945
+ });
946
+
947
+ const BrightnessSchema = z.object({
948
+ level: z.number().int().min(0).max(100),
949
+ });
950
+
951
+ // Device schemas
952
+ const GoveeDeviceSchema = z.object({
953
+ deviceId: z.string().min(1),
954
+ model: z.string().min(1),
955
+ deviceName: z.string().min(1),
956
+ controllable: z.boolean(),
957
+ retrievable: z.boolean(),
958
+ supportedCmds: z.array(z.string()),
959
+ });
960
+
961
+ // API response schemas
962
+ const ApiErrorSchema = z.object({
963
+ code: z.number(),
964
+ message: z.string(),
965
+ data: z.unknown().optional(),
966
+ });
967
+
968
+ // Type extraction from schemas
969
+ type ValidatedClientConfig = z.infer<typeof GoveeClientConfigSchema>;
970
+ type ValidatedColorRgb = z.infer<typeof ColorRgbSchema>;
971
+ type ValidatedDevice = z.infer<typeof GoveeDeviceSchema>;
972
+ ```
973
+
974
+ This comprehensive type reference provides LLMs with complete type information for generating accurate, type-safe code when working with the Govee API Client library.