dt-common-device 2.0.7 → 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 (186) hide show
  1. package/README.md +321 -99
  2. package/dist/alerts/Alert.model.d.ts +28 -0
  3. package/dist/alerts/Alert.model.js +222 -0
  4. package/dist/alerts/Alert.repository.d.ts +106 -0
  5. package/dist/alerts/Alert.repository.js +374 -0
  6. package/dist/alerts/Alert.service.d.ts +137 -0
  7. package/dist/alerts/Alert.service.js +476 -0
  8. package/dist/alerts/AlertBuilder.d.ts +87 -0
  9. package/dist/alerts/AlertBuilder.example.d.ts +11 -0
  10. package/dist/alerts/AlertBuilder.example.js +117 -0
  11. package/dist/alerts/AlertBuilder.js +185 -0
  12. package/dist/alerts/AlertService.example.d.ts +55 -0
  13. package/dist/alerts/AlertService.example.js +148 -0
  14. package/dist/alerts/alert.types.d.ts +57 -0
  15. package/dist/alerts/alert.types.js +22 -0
  16. package/dist/alerts/index.d.ts +3 -0
  17. package/dist/alerts/index.js +19 -0
  18. package/dist/config/config.d.ts +4 -4
  19. package/dist/config/config.js +3 -3
  20. package/dist/config/config.types.d.ts +19 -0
  21. package/dist/config/config.types.js +2 -0
  22. package/dist/connection/Connection.repository.d.ts +8 -0
  23. package/dist/connection/Connection.repository.js +92 -0
  24. package/dist/connection/Connection.service.d.ts +8 -0
  25. package/dist/connection/Connection.service.js +32 -0
  26. package/dist/connection/IConnection.d.ts +26 -0
  27. package/dist/connection/IConnection.js +14 -0
  28. package/dist/connection/index.d.ts +2 -0
  29. package/dist/connection/index.js +18 -0
  30. package/dist/device/cloud/entities/CloudDevice.d.ts +2 -2
  31. package/dist/device/cloud/entities/CloudDeviceService.d.ts +1 -1
  32. package/dist/device/cloud/entities/DeviceFactory.d.ts +1 -1
  33. package/dist/device/cloud/entities/DeviceFactory.js +1 -1
  34. package/dist/device/cloud/interfaces/ICloudDeviceService.d.ts +1 -1
  35. package/dist/device/cloud/interfaces/IRawDevice.d.ts +1 -1
  36. package/dist/device/local/interfaces/index.d.ts +2 -3
  37. package/dist/device/local/interfaces/index.js +2 -3
  38. package/dist/device/local/repository/Device.repository.js +3 -3
  39. package/dist/device/local/repository/Hub.repository.js +4 -4
  40. package/dist/device/local/repository/Schedule.repository.js +2 -2
  41. package/dist/device/local/services/Device.service.d.ts +2 -2
  42. package/dist/device/local/services/Device.service.js +1 -1
  43. package/dist/device/local/services/index.d.ts +0 -4
  44. package/dist/device/local/services/index.js +0 -4
  45. package/dist/events/BaseEventHandler.d.ts +2 -2
  46. package/dist/events/BaseEventHandler.js +2 -2
  47. package/dist/events/BaseEventTransformer.d.ts +1 -1
  48. package/dist/events/BaseEventTransformer.js +1 -1
  49. package/dist/events/DeviceEventHandler.d.ts +1 -1
  50. package/dist/events/DeviceEventHandler.js +2 -2
  51. package/dist/events/EventHandler.js +1 -1
  52. package/dist/events/EventHandlerOrchestrator.js +1 -1
  53. package/dist/events/EventProcessingService.js +1 -1
  54. package/dist/events/InternalEventSubscription.js +1 -1
  55. package/dist/index.d.ts +7 -5
  56. package/dist/index.js +16 -13
  57. package/dist/issues/Issue.model.d.ts +28 -0
  58. package/dist/issues/Issue.model.js +260 -0
  59. package/dist/issues/Issue.repository.d.ts +113 -0
  60. package/dist/issues/Issue.repository.js +401 -0
  61. package/dist/issues/Issue.service.d.ts +168 -0
  62. package/dist/issues/Issue.service.js +642 -0
  63. package/dist/issues/IssueBuilder.d.ts +109 -0
  64. package/dist/issues/IssueBuilder.example.d.ts +16 -0
  65. package/dist/issues/IssueBuilder.example.js +196 -0
  66. package/dist/issues/IssueBuilder.js +237 -0
  67. package/dist/issues/IssueService.example.d.ts +68 -0
  68. package/dist/issues/IssueService.example.js +177 -0
  69. package/dist/issues/index.d.ts +2 -0
  70. package/dist/issues/index.js +18 -0
  71. package/dist/issues/issue.types.d.ts +90 -0
  72. package/dist/issues/issue.types.js +40 -0
  73. package/dist/property/IProperty.d.ts +29 -0
  74. package/dist/property/IProperty.js +2 -0
  75. package/dist/property/Property.repository.d.ts +8 -0
  76. package/dist/property/Property.repository.js +95 -0
  77. package/dist/property/Property.service.d.ts +8 -0
  78. package/dist/property/Property.service.js +36 -0
  79. package/dist/property/index.d.ts +2 -0
  80. package/dist/property/index.js +18 -0
  81. package/dist/queue/entities/HybridHttpQueue.d.ts +23 -0
  82. package/dist/queue/entities/HybridHttpQueue.js +189 -0
  83. package/dist/queue/entities/index.d.ts +1 -0
  84. package/dist/queue/entities/index.js +17 -0
  85. package/dist/queue/index.d.ts +5 -0
  86. package/dist/queue/index.js +22 -0
  87. package/dist/queue/interfaces/IHttpRequestJob.d.ts +9 -0
  88. package/dist/queue/interfaces/IHttpRequestJob.js +2 -0
  89. package/dist/queue/interfaces/IHybridHttpQueue.d.ts +16 -0
  90. package/dist/queue/interfaces/IHybridHttpQueue.js +2 -0
  91. package/dist/queue/interfaces/IJobResult.d.ts +6 -0
  92. package/dist/queue/interfaces/IJobResult.js +2 -0
  93. package/dist/queue/interfaces/IRateLimitConfig.d.ts +5 -0
  94. package/dist/queue/interfaces/IRateLimitConfig.js +2 -0
  95. package/dist/queue/interfaces/index.d.ts +4 -0
  96. package/dist/queue/interfaces/index.js +20 -0
  97. package/dist/queue/services/QueueService.d.ts +19 -0
  98. package/dist/queue/services/QueueService.js +73 -0
  99. package/dist/queue/services/index.d.ts +1 -0
  100. package/dist/queue/services/index.js +17 -0
  101. package/dist/queue/types/http.types.d.ts +21 -0
  102. package/dist/queue/types/http.types.js +2 -0
  103. package/dist/queue/types/index.d.ts +2 -0
  104. package/dist/queue/types/index.js +18 -0
  105. package/dist/queue/types/queue.types.d.ts +35 -0
  106. package/dist/queue/types/queue.types.js +2 -0
  107. package/dist/queue/utils/index.d.ts +3 -0
  108. package/dist/queue/utils/index.js +19 -0
  109. package/dist/queue/utils/jobUtils.d.ts +10 -0
  110. package/dist/queue/utils/jobUtils.js +64 -0
  111. package/dist/queue/utils/queueUtils.d.ts +5 -0
  112. package/dist/queue/utils/queueUtils.js +59 -0
  113. package/dist/queue/utils/rateLimit.utils.d.ts +6 -0
  114. package/dist/queue/utils/rateLimit.utils.js +44 -0
  115. package/package.json +2 -1
  116. package/src/{device/local/models → alerts}/Alert.model.ts +1 -1
  117. package/src/{device/local/repository → alerts}/Alert.repository.ts +2 -2
  118. package/src/{device/local/services → alerts}/Alert.service.ts +14 -7
  119. package/src/{device/local/entities → alerts}/AlertBuilder.example.ts +2 -2
  120. package/src/{device/local/entities → alerts}/AlertBuilder.ts +14 -8
  121. package/src/{device/local/services → alerts}/AlertService.example.ts +6 -5
  122. package/src/{types → alerts}/alert.types.ts +2 -2
  123. package/src/alerts/index.ts +3 -0
  124. package/src/config/config.ts +7 -7
  125. package/src/{types → config}/config.types.ts +1 -1
  126. package/src/{device/local/repository → connection}/Connection.repository.ts +2 -2
  127. package/src/{device/local/services → connection}/Connection.service.ts +2 -2
  128. package/src/connection/index.ts +3 -0
  129. package/src/device/cloud/entities/CloudDevice.ts +2 -2
  130. package/src/device/cloud/entities/CloudDeviceService.ts +1 -1
  131. package/src/device/cloud/entities/DeviceFactory.ts +2 -2
  132. package/src/device/cloud/interfaces/ICloudDeviceService.ts +1 -1
  133. package/src/device/cloud/interfaces/IRawDevice.ts +1 -1
  134. package/src/device/local/interfaces/index.ts +2 -3
  135. package/src/device/local/repository/Device.repository.ts +3 -3
  136. package/src/device/local/repository/Hub.repository.ts +4 -4
  137. package/src/device/local/repository/Schedule.repository.ts +2 -2
  138. package/src/device/local/services/Device.service.ts +1 -1
  139. package/src/device/local/services/index.ts +0 -4
  140. package/{TROUBLESHOOTING.md → src/docs/TROUBLESHOOTING.md} +2 -2
  141. package/src/events/BaseEventHandler.ts +3 -3
  142. package/src/events/BaseEventTransformer.ts +2 -2
  143. package/src/events/DeviceEventHandler.ts +3 -3
  144. package/src/events/EventHandler.ts +1 -1
  145. package/src/events/EventHandlerOrchestrator.ts +2 -2
  146. package/src/events/EventProcessingService.ts +2 -2
  147. package/src/events/InternalEventSubscription.ts +2 -2
  148. package/src/index.ts +19 -13
  149. package/src/{device/local/models → issues}/Issue.model.ts +1 -1
  150. package/src/{device/local/repository → issues}/Issue.repository.ts +2 -2
  151. package/src/{device/local/services → issues}/Issue.service.ts +4 -4
  152. package/src/{device/local/entities → issues}/IssueBuilder.example.ts +1 -1
  153. package/src/{device/local/entities → issues}/IssueBuilder.ts +1 -1
  154. package/src/{device/local/services → issues}/IssueService.example.ts +6 -5
  155. package/src/issues/index.ts +2 -0
  156. package/src/{device/local/repository → property}/Property.repository.ts +2 -2
  157. package/src/{device/local/services → property}/Property.service.ts +1 -1
  158. package/src/property/index.ts +2 -0
  159. package/src/queue/entities/HybridHttpQueue.ts +196 -0
  160. package/src/queue/entities/index.ts +1 -0
  161. package/src/queue/index.ts +6 -0
  162. package/src/queue/interfaces/IHttpRequestJob.ts +10 -0
  163. package/src/queue/interfaces/IHybridHttpQueue.ts +23 -0
  164. package/src/queue/interfaces/IJobResult.ts +6 -0
  165. package/src/queue/interfaces/IRateLimitConfig.ts +5 -0
  166. package/src/queue/interfaces/index.ts +4 -0
  167. package/src/queue/services/QueueService.ts +39 -0
  168. package/src/queue/services/index.ts +1 -0
  169. package/src/queue/types/http.types.ts +22 -0
  170. package/src/queue/types/index.ts +2 -0
  171. package/src/queue/types/queue.types.ts +22 -0
  172. package/src/queue/utils/index.ts +3 -0
  173. package/src/queue/utils/jobUtils.ts +80 -0
  174. package/src/queue/utils/queueUtils.ts +90 -0
  175. package/src/queue/utils/rateLimit.utils.ts +58 -0
  176. package/tsconfig.json +4 -0
  177. package/src/device/local/entities/README.md +0 -173
  178. package/src/device/local/entities/index.ts +0 -2
  179. package/src/types/index.ts +0 -3
  180. /package/src/{device/local/interfaces → connection}/IConnection.ts +0 -0
  181. /package/src/{device/local/models → docs}/Alert.model.md +0 -0
  182. /package/src/{device/local/models/README.md → docs/Alerts&IssuesModel.md} +0 -0
  183. /package/src/{device/local/models → docs}/Issue.model.md +0 -0
  184. /package/{SECURITY.md → src/docs/SECURITY.md} +0 -0
  185. /package/src/{types → issues}/issue.types.ts +0 -0
  186. /package/src/{device/local/interfaces → property}/IProperty.ts +0 -0
@@ -0,0 +1,90 @@
1
+ import { getConfig } from "../../config/config";
2
+
3
+ export class QueueUtils {
4
+ static getQueueKey(
5
+ microservice: string,
6
+ connectionId: string,
7
+ provider: string
8
+ ): string {
9
+ return `${microservice}_${provider}_${connectionId}`;
10
+ }
11
+
12
+ static getOrCreateQueue(queueKey: string, queues: Map<string, any>): any {
13
+ return (
14
+ queues.get(queueKey) ??
15
+ queues
16
+ .set(
17
+ queueKey,
18
+ new (require("bullmq").Queue)(queueKey, {
19
+ connection: require("../../db/redis").getRedisClient(),
20
+ })
21
+ )
22
+ .get(queueKey)!
23
+ );
24
+ }
25
+
26
+ static getOrCreateWorker(
27
+ queueKey: string,
28
+ workers: Map<string, any>,
29
+ processFunction: (job: any) => Promise<any>,
30
+ jobResults: Map<string, any>
31
+ ): void {
32
+ if (workers.has(queueKey)) return;
33
+
34
+ const { Worker } = require("bullmq");
35
+ const worker = new Worker(queueKey, processFunction, {
36
+ connection: require("../../db/redis").getRedisClient(),
37
+ concurrency: 1,
38
+ removeOnComplete: { age: 300, count: 1 },
39
+ removeOnFail: { age: 300, count: 1 },
40
+ lockDuration: 300000,
41
+ stalledInterval: 60000,
42
+ });
43
+
44
+ // Simplified event handlers
45
+ worker.on("completed", (job: any) => {
46
+ getConfig().LOGGER.info(
47
+ `HTTP request completed: ${job.id} [${queueKey}]`
48
+ );
49
+ job.returnvalue
50
+ .then((result: any) =>
51
+ jobResults.set(job.id!, {
52
+ result,
53
+ resolved: true,
54
+ timestamp: Date.now(),
55
+ })
56
+ )
57
+ .catch((error: any) =>
58
+ jobResults.set(job.id!, {
59
+ error: error.message,
60
+ resolved: true,
61
+ timestamp: Date.now(),
62
+ })
63
+ );
64
+ });
65
+
66
+ worker.on("failed", (job: any, err: any) => {
67
+ getConfig().LOGGER.error(
68
+ `HTTP request failed: ${job?.id} [${queueKey}], Error: ${err.message}`
69
+ );
70
+ jobResults.set(job!.id!, {
71
+ error: err.message,
72
+ resolved: true,
73
+ timestamp: Date.now(),
74
+ });
75
+ });
76
+
77
+ worker.on("error", (err: any) =>
78
+ getConfig().LOGGER.error(`Worker error for ${queueKey}: ${err.message}`)
79
+ );
80
+ worker.on("stalled", (jobId: string) =>
81
+ getConfig().LOGGER.warn(`Job ${jobId} stalled in worker ${queueKey}`)
82
+ );
83
+ worker.on("active", (job: any) =>
84
+ getConfig().LOGGER.info(`HTTP request started: ${job.id} [${queueKey}]`)
85
+ );
86
+
87
+ workers.set(queueKey, worker);
88
+ getConfig().LOGGER.info(`Worker initialized for queue: ${queueKey}`);
89
+ }
90
+ }
@@ -0,0 +1,58 @@
1
+ import { IRateLimitConfig } from "../interfaces";
2
+ import { getRedisClient } from "../../db/redis";
3
+ import { getConfig } from "../../config/config";
4
+
5
+ export class RateLimitUtils {
6
+ private static redisClient = getRedisClient();
7
+
8
+ static async checkRateLimit(
9
+ connectionId: string,
10
+ provider: string,
11
+ rateLimitConfigs: Map<string, IRateLimitConfig>
12
+ ): Promise<boolean> {
13
+ const config = rateLimitConfigs.get(provider);
14
+ if (!config) {
15
+ getConfig().LOGGER.warn(
16
+ `No rate limit config found for provider: ${provider}`
17
+ );
18
+ return true;
19
+ }
20
+
21
+ const key = `rate_limit:${provider}:${connectionId}`;
22
+ const now = Date.now();
23
+ const windowStart = now - config.windowMs;
24
+
25
+ try {
26
+ const data = await this.redisClient.get(key);
27
+ const requests = data
28
+ ? JSON.parse(data).filter((t: number) => t > windowStart)
29
+ : [];
30
+
31
+ if (requests.length >= config.maxRequests) return false;
32
+
33
+ requests.push(now);
34
+ await this.redisClient.setex(
35
+ key,
36
+ Math.ceil(config.windowMs / 1000),
37
+ JSON.stringify(requests)
38
+ );
39
+ return true;
40
+ } catch (error) {
41
+ getConfig().LOGGER.error(`Rate limit check error: ${error}`);
42
+ return true;
43
+ }
44
+ }
45
+
46
+ static initializeRateLimitConfigs(): Map<string, IRateLimitConfig> {
47
+ const configs = new Map<string, IRateLimitConfig>();
48
+
49
+ // Configure rate limits for different providers
50
+ configs.set("Sensibo", {
51
+ maxRequests: 40,
52
+ windowMs: 60000,
53
+ provider: "Sensibo",
54
+ });
55
+
56
+ return configs;
57
+ }
58
+ }
package/tsconfig.json CHANGED
@@ -6,6 +6,10 @@
6
6
  "declaration": true,
7
7
  "outDir": "./dist",
8
8
  "rootDir": "./src",
9
+ "baseUrl": ".",
10
+ "paths": {
11
+ "src/*": ["src/*"]
12
+ },
9
13
  "strict": true,
10
14
  "esModuleInterop": true,
11
15
  "skipLibCheck": true,
@@ -1,173 +0,0 @@
1
- # AlertBuilder - Builder Pattern Implementation
2
-
3
- ## Overview
4
-
5
- The `AlertBuilder` is a TypeScript implementation of the Builder design pattern, specifically designed to help construct `CreateAlertData` objects with a fluent interface. This is a standard and widely-used design pattern in TypeScript for creating complex objects with optional parameters.
6
-
7
- ## Why Use the Builder Pattern?
8
-
9
- The Builder pattern is particularly useful for:
10
-
11
- 1. **Complex Object Construction**: When creating objects with many optional parameters
12
- 2. **Fluent Interface**: Provides a readable, chainable API
13
- 3. **Validation**: Ensures required fields are provided before object creation
14
- 4. **Default Values**: Automatically sets sensible defaults
15
- 5. **Type Safety**: Provides compile-time type checking
16
-
17
- ## Usage Examples
18
-
19
- ### Basic Usage
20
-
21
- ```typescript
22
- import { AlertBuilder } from "./AlertBuilder";
23
- import { AlertCategory, AlertSeverity, EntityType } from "../../../types/alert.types";
24
-
25
- const alertData = new AlertBuilder()
26
- .setCategory(AlertCategory.OPERATIONS)
27
- .setPropertyId("prop123")
28
- .setTitle("Device Offline")
29
- .setDescription("Device has been offline for more than 5 minutes")
30
- .setEntityId("device456")
31
- .setEntityType(EntityType.DEVICE)
32
- .setSeverity(AlertSeverity.HIGH)
33
- .setCreatedBy("user789")
34
- .build();
35
- ```
36
-
37
- ### Using Static Factory Methods
38
-
39
- ```typescript
40
- // Create a device-specific alert
41
- const deviceAlert = AlertBuilder.createDeviceAlert("device123", "prop456")
42
- .setCategory(AlertCategory.READINESS)
43
- .setTitle("Device Maintenance Required")
44
- .setDescription("Device firmware update is available")
45
- .setSeverity(AlertSeverity.MEDIUM)
46
- .setCreatedBy("system")
47
- .build();
48
-
49
- // Create a hub-specific alert
50
- const hubAlert = AlertBuilder.createHubAlert("hub789", "prop202")
51
- .setCategory(AlertCategory.OPERATIONS)
52
- .setTitle("Hub Connection Lost")
53
- .setDescription("Hub has lost connection to the network")
54
- .setSeverity(AlertSeverity.CRITICAL)
55
- .setCreatedBy("network-monitor")
56
- .build();
57
- ```
58
-
59
- ### Using Predefined Alert Types
60
-
61
- ```typescript
62
- // Security alert with CRITICAL severity
63
- const securityAlert = AlertBuilder.createSecurityAlert()
64
- .setPropertyId("prop789")
65
- .setTitle("Unauthorized Access Attempt")
66
- .setDescription("Multiple failed login attempts detected")
67
- .setEntityId("user123")
68
- .setEntityType(EntityType.USER)
69
- .setCreatedBy("security-system")
70
- .build();
71
-
72
- // Energy alert with LOW severity
73
- const energyAlert = AlertBuilder.createEnergyAlert()
74
- .setPropertyId("prop101")
75
- .setTitle("High Energy Consumption")
76
- .setDescription("Energy usage is 20% above normal levels")
77
- .setEntityId("zone456")
78
- .setEntityType(EntityType.COLLECTION)
79
- .setCreatedBy("energy-monitor")
80
- .build();
81
- ```
82
-
83
- ### Reusing Builder Instances
84
-
85
- ```typescript
86
- const builder = new AlertBuilder()
87
- .setPropertyId("prop404")
88
- .setCreatedBy("system");
89
-
90
- const alert1 = builder
91
- .setCategory(AlertCategory.OPERATIONS)
92
- .setTitle("Device Temperature High")
93
- .setDescription("Device temperature exceeds normal operating range")
94
- .setEntityId("device789")
95
- .setEntityType(EntityType.DEVICE)
96
- .setSeverity(AlertSeverity.HIGH)
97
- .build();
98
-
99
- const alert2 = builder
100
- .reset()
101
- .setPropertyId("prop404")
102
- .setCategory(AlertCategory.ENERGY)
103
- .setTitle("Low Battery Warning")
104
- .setDescription("Device battery level is below 20%")
105
- .setEntityId("device789")
106
- .setEntityType(EntityType.DEVICE)
107
- .setSeverity(AlertSeverity.MEDIUM)
108
- .setCreatedBy("system")
109
- .build();
110
- ```
111
-
112
- ## Available Methods
113
-
114
- ### Instance Methods
115
-
116
- - `setCategory(category: AlertCategory)`: Sets the alert category
117
- - `setPropertyId(propertyId: string)`: Sets the property ID (required)
118
- - `setTitle(title: string)`: Sets the alert title (required)
119
- - `setDescription(description: string)`: Sets the alert description (required)
120
- - `setEntityId(entityId?: string)`: Sets the entity ID (optional)
121
- - `setEntityType(entityType: EntityType)`: Sets the entity type (required)
122
- - `setSeverity(severity?: AlertSeverity)`: Sets the alert severity (optional, defaults to MEDIUM)
123
- - `setCreatedBy(createdBy?: string)`: Sets the user who created the alert (optional)
124
- - `setSnoozeUntil(snoozeUntil?: Date)`: Sets the snooze until date (optional)
125
- - `build()`: Builds and returns the CreateAlertData object
126
- - `reset()`: Resets the builder to its initial state
127
-
128
- ### Static Factory Methods
129
-
130
- - `createReadinessAlert()`: Creates a builder with READINESS category and MEDIUM severity
131
- - `createOperationsAlert()`: Creates a builder with OPERATIONS category and HIGH severity
132
- - `createSecurityAlert()`: Creates a builder with SECURITY category and CRITICAL severity
133
- - `createEnergyAlert()`: Creates a builder with ENERGY category and LOW severity
134
- - `createDeviceAlert(deviceId: string, propertyId: string)`: Creates a device-specific alert builder
135
- - `createHubAlert(hubId: string, propertyId: string)`: Creates a hub-specific alert builder
136
-
137
- ## Validation
138
-
139
- The builder automatically validates that all required fields are present when `build()` is called. Required fields are:
140
-
141
- - `category`
142
- - `propertyId`
143
- - `title`
144
- - `description`
145
- - `entityType`
146
-
147
- If any required field is missing, an error will be thrown with details about which fields are missing.
148
-
149
- ## Default Values
150
-
151
- - `severity`: Defaults to `AlertSeverity.MEDIUM` if not specified
152
-
153
- ## Error Handling
154
-
155
- The builder includes comprehensive error handling:
156
-
157
- - Validates required fields before building
158
- - Trims whitespace from string inputs
159
- - Validates that propertyId and title are not empty strings
160
- - Provides clear error messages for missing or invalid data
161
-
162
- ## Design Pattern Benefits
163
-
164
- This implementation follows the Builder pattern which provides:
165
-
166
- 1. **Separation of Concerns**: Object construction is separated from object representation
167
- 2. **Fluent Interface**: Method chaining for better readability
168
- 3. **Immutability**: Each method returns a new builder instance
169
- 4. **Validation**: Built-in validation before object creation
170
- 5. **Flexibility**: Easy to add new fields or modify existing ones
171
- 6. **Type Safety**: Full TypeScript support with compile-time checking
172
-
173
- This is indeed a standard design pattern in TypeScript and is widely used in enterprise applications for constructing complex objects with many optional parameters.
@@ -1,2 +0,0 @@
1
- export { AlertBuilder } from "./AlertBuilder";
2
- export { IssueBuilder } from "./IssueBuilder";
@@ -1,3 +0,0 @@
1
- export * from "./config.types";
2
- export * from "./issue.types";
3
- export * from "./alert.types";
File without changes
File without changes