@oneuptime/common 10.0.65 → 10.0.67

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 (276) hide show
  1. package/Models/DatabaseModels/DockerHostOwnerTeam.ts +464 -0
  2. package/Models/DatabaseModels/DockerHostOwnerUser.ts +463 -0
  3. package/Models/DatabaseModels/GlobalConfig.ts +56 -0
  4. package/Models/DatabaseModels/Index.ts +28 -0
  5. package/Models/DatabaseModels/KubernetesClusterOwnerTeam.ts +464 -0
  6. package/Models/DatabaseModels/KubernetesClusterOwnerUser.ts +463 -0
  7. package/Models/DatabaseModels/KubernetesResource.ts +548 -0
  8. package/Models/DatabaseModels/MetricPipelineRule.ts +804 -0
  9. package/Models/DatabaseModels/MetricRecordingRule.ts +470 -0
  10. package/Models/DatabaseModels/Monitor.ts +2 -0
  11. package/Models/DatabaseModels/Project.ts +83 -0
  12. package/Models/DatabaseModels/Service.ts +79 -0
  13. package/Models/DatabaseModels/TelegramLog.ts +1025 -0
  14. package/Models/DatabaseModels/TraceDropFilter.ts +508 -0
  15. package/Models/DatabaseModels/TracePipeline.ts +436 -0
  16. package/Models/DatabaseModels/TracePipelineProcessor.ts +454 -0
  17. package/Models/DatabaseModels/TraceRecordingRule.ts +470 -0
  18. package/Models/DatabaseModels/TraceScrubRule.ts +546 -0
  19. package/Models/DatabaseModels/UserNotificationRule.ts +49 -0
  20. package/Models/DatabaseModels/UserNotificationSetting.ts +17 -0
  21. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +48 -0
  22. package/Models/DatabaseModels/UserTelegram.ts +312 -0
  23. package/Server/API/KubernetesResourceAPI.ts +129 -0
  24. package/Server/API/UserTelegramAPI.ts +167 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1776504277320-MigrationName.ts +399 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1776505976155-AddTracePipelineTables.ts +205 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1776509413763-MigrationName.ts +335 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1776541018853-MigrationName.ts +29 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1776544084793-MigrationName.ts +53 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1776761171349-MigrationName.ts +325 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -1
  32. package/Server/Services/DockerHostOwnerTeamService.ts +10 -0
  33. package/Server/Services/DockerHostOwnerUserService.ts +10 -0
  34. package/Server/Services/Index.ts +6 -0
  35. package/Server/Services/KubernetesClusterOwnerTeamService.ts +10 -0
  36. package/Server/Services/KubernetesClusterOwnerUserService.ts +10 -0
  37. package/Server/Services/KubernetesResourceService.ts +351 -0
  38. package/Server/Services/MetricPipelineRuleService.ts +10 -0
  39. package/Server/Services/MetricRecordingRuleService.ts +10 -0
  40. package/Server/Services/TelegramLogService.ts +15 -0
  41. package/Server/Services/TelegramService.ts +139 -0
  42. package/Server/Services/TraceDropFilterService.ts +10 -0
  43. package/Server/Services/TracePipelineProcessorService.ts +10 -0
  44. package/Server/Services/TracePipelineService.ts +10 -0
  45. package/Server/Services/TraceRecordingRuleService.ts +10 -0
  46. package/Server/Services/TraceScrubRuleService.ts +10 -0
  47. package/Server/Services/UserNotificationRuleService.ts +350 -1
  48. package/Server/Services/UserNotificationSettingService.ts +114 -0
  49. package/Server/Services/UserTelegramService.ts +140 -0
  50. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +71 -9
  51. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +483 -75
  52. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +379 -6
  53. package/Server/Utils/Monitor/MonitorResource.ts +29 -15
  54. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -16
  55. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +502 -0
  56. package/Tests/Types/Date.test.ts +158 -0
  57. package/Tests/Utils/MetricUnitUtil.test.ts +216 -0
  58. package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +269 -0
  59. package/Tests/Utils/Metrics/MetricResultUnitConverter.test.ts +231 -0
  60. package/Tests/Utils/RecordingRuleExpression.test.ts +177 -0
  61. package/Types/Date.ts +12 -3
  62. package/Types/Icon/IconProp.ts +1 -0
  63. package/Types/Kubernetes/KubernetesInventoryExtractor.ts +327 -0
  64. package/Types/Kubernetes/KubernetesObjectParser.ts +1949 -0
  65. package/Types/Metrics/MetricDownsamplingRetentionDays.ts +49 -0
  66. package/Types/Metrics/MetricFormulaConfigData.ts +4 -0
  67. package/Types/Metrics/MetricPipelineRuleFilterCondition.ts +136 -0
  68. package/Types/Metrics/MetricPipelineRuleType.ts +27 -0
  69. package/Types/Metrics/RecordingRuleDefinition.ts +180 -0
  70. package/Types/Monitor/CriteriaFilter.ts +43 -0
  71. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +70 -0
  72. package/Types/Permission.ts +531 -0
  73. package/Types/Telegram/TelegramMessage.ts +9 -0
  74. package/Types/TelegramStatus.ts +14 -0
  75. package/Types/Trace/TraceAggregationType.ts +17 -0
  76. package/Types/Trace/TraceDropFilterAction.ts +6 -0
  77. package/Types/Trace/TracePipelineProcessorType.ts +56 -0
  78. package/Types/Trace/TraceRecordingRuleDefinition.ts +218 -0
  79. package/Types/Trace/TraceScrubAction.ts +7 -0
  80. package/Types/Trace/TraceScrubField.ts +8 -0
  81. package/Types/Trace/TraceScrubPatternType.ts +10 -0
  82. package/UI/Components/CardSelect/CardSelect.tsx +9 -1
  83. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +6 -10
  84. package/UI/Components/Forms/Fields/FormField.tsx +1 -0
  85. package/UI/Components/Forms/Types/Field.ts +1 -0
  86. package/UI/Components/Icon/Icon.tsx +15 -0
  87. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +57 -0
  88. package/UI/Components/Page/Page.tsx +6 -0
  89. package/Utils/MetricUnitUtil.ts +289 -0
  90. package/Utils/Metrics/MetricFormulaEvaluator.ts +610 -0
  91. package/Utils/Metrics/MetricResultUnitConverter.ts +91 -0
  92. package/Utils/Metrics/RecordingRuleExpression.ts +359 -0
  93. package/Utils/ValueFormatter.ts +137 -13
  94. package/build/dist/Models/DatabaseModels/DockerHostOwnerTeam.js +480 -0
  95. package/build/dist/Models/DatabaseModels/DockerHostOwnerTeam.js.map +1 -0
  96. package/build/dist/Models/DatabaseModels/DockerHostOwnerUser.js +479 -0
  97. package/build/dist/Models/DatabaseModels/DockerHostOwnerUser.js.map +1 -0
  98. package/build/dist/Models/DatabaseModels/GlobalConfig.js +59 -0
  99. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  100. package/build/dist/Models/DatabaseModels/Index.js +28 -0
  101. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  102. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerTeam.js +480 -0
  103. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerTeam.js.map +1 -0
  104. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerUser.js +479 -0
  105. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerUser.js.map +1 -0
  106. package/build/dist/Models/DatabaseModels/KubernetesResource.js +590 -0
  107. package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -0
  108. package/build/dist/Models/DatabaseModels/MetricPipelineRule.js +836 -0
  109. package/build/dist/Models/DatabaseModels/MetricPipelineRule.js.map +1 -0
  110. package/build/dist/Models/DatabaseModels/MetricRecordingRule.js +497 -0
  111. package/build/dist/Models/DatabaseModels/MetricRecordingRule.js.map +1 -0
  112. package/build/dist/Models/DatabaseModels/Monitor.js +2 -0
  113. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  114. package/build/dist/Models/DatabaseModels/Project.js +85 -0
  115. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  116. package/build/dist/Models/DatabaseModels/Service.js +79 -0
  117. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  118. package/build/dist/Models/DatabaseModels/TelegramLog.js +1056 -0
  119. package/build/dist/Models/DatabaseModels/TelegramLog.js.map +1 -0
  120. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +536 -0
  121. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -0
  122. package/build/dist/Models/DatabaseModels/TracePipeline.js +462 -0
  123. package/build/dist/Models/DatabaseModels/TracePipeline.js.map +1 -0
  124. package/build/dist/Models/DatabaseModels/TracePipelineProcessor.js +476 -0
  125. package/build/dist/Models/DatabaseModels/TracePipelineProcessor.js.map +1 -0
  126. package/build/dist/Models/DatabaseModels/TraceRecordingRule.js +497 -0
  127. package/build/dist/Models/DatabaseModels/TraceRecordingRule.js.map +1 -0
  128. package/build/dist/Models/DatabaseModels/TraceScrubRule.js +575 -0
  129. package/build/dist/Models/DatabaseModels/TraceScrubRule.js.map +1 -0
  130. package/build/dist/Models/DatabaseModels/UserNotificationRule.js +49 -0
  131. package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
  132. package/build/dist/Models/DatabaseModels/UserNotificationSetting.js +19 -0
  133. package/build/dist/Models/DatabaseModels/UserNotificationSetting.js.map +1 -1
  134. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +48 -0
  135. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  136. package/build/dist/Models/DatabaseModels/UserTelegram.js +331 -0
  137. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -0
  138. package/build/dist/Server/API/KubernetesResourceAPI.js +98 -0
  139. package/build/dist/Server/API/KubernetesResourceAPI.js.map +1 -0
  140. package/build/dist/Server/API/UserTelegramAPI.js +99 -0
  141. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -0
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776504277320-MigrationName.js +144 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776504277320-MigrationName.js.map +1 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776505976155-AddTracePipelineTables.js +82 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776505976155-AddTracePipelineTables.js.map +1 -0
  146. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776509413763-MigrationName.js +118 -0
  147. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776509413763-MigrationName.js.map +1 -0
  148. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776541018853-MigrationName.js +16 -0
  149. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776541018853-MigrationName.js.map +1 -0
  150. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776544084793-MigrationName.js +24 -0
  151. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776544084793-MigrationName.js.map +1 -0
  152. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776761171349-MigrationName.js +116 -0
  153. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776761171349-MigrationName.js.map +1 -0
  154. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  155. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  156. package/build/dist/Server/Services/DockerHostOwnerTeamService.js +9 -0
  157. package/build/dist/Server/Services/DockerHostOwnerTeamService.js.map +1 -0
  158. package/build/dist/Server/Services/DockerHostOwnerUserService.js +9 -0
  159. package/build/dist/Server/Services/DockerHostOwnerUserService.js.map +1 -0
  160. package/build/dist/Server/Services/Index.js +6 -0
  161. package/build/dist/Server/Services/Index.js.map +1 -1
  162. package/build/dist/Server/Services/KubernetesClusterOwnerTeamService.js +9 -0
  163. package/build/dist/Server/Services/KubernetesClusterOwnerTeamService.js.map +1 -0
  164. package/build/dist/Server/Services/KubernetesClusterOwnerUserService.js +9 -0
  165. package/build/dist/Server/Services/KubernetesClusterOwnerUserService.js.map +1 -0
  166. package/build/dist/Server/Services/KubernetesResourceService.js +237 -0
  167. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -0
  168. package/build/dist/Server/Services/MetricPipelineRuleService.js +9 -0
  169. package/build/dist/Server/Services/MetricPipelineRuleService.js.map +1 -0
  170. package/build/dist/Server/Services/MetricRecordingRuleService.js +9 -0
  171. package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -0
  172. package/build/dist/Server/Services/TelegramLogService.js +13 -0
  173. package/build/dist/Server/Services/TelegramLogService.js.map +1 -0
  174. package/build/dist/Server/Services/TelegramService.js +100 -0
  175. package/build/dist/Server/Services/TelegramService.js.map +1 -0
  176. package/build/dist/Server/Services/TraceDropFilterService.js +9 -0
  177. package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -0
  178. package/build/dist/Server/Services/TracePipelineProcessorService.js +9 -0
  179. package/build/dist/Server/Services/TracePipelineProcessorService.js.map +1 -0
  180. package/build/dist/Server/Services/TracePipelineService.js +9 -0
  181. package/build/dist/Server/Services/TracePipelineService.js.map +1 -0
  182. package/build/dist/Server/Services/TraceRecordingRuleService.js +9 -0
  183. package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -0
  184. package/build/dist/Server/Services/TraceScrubRuleService.js +9 -0
  185. package/build/dist/Server/Services/TraceScrubRuleService.js.map +1 -0
  186. package/build/dist/Server/Services/UserNotificationRuleService.js +272 -21
  187. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  188. package/build/dist/Server/Services/UserNotificationSettingService.js +94 -0
  189. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  190. package/build/dist/Server/Services/UserTelegramService.js +133 -0
  191. package/build/dist/Server/Services/UserTelegramService.js.map +1 -0
  192. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +56 -9
  193. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  194. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +335 -53
  195. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  196. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +277 -5
  197. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  198. package/build/dist/Server/Utils/Monitor/MonitorResource.js +25 -12
  199. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  200. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +24 -12
  201. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  202. package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js +407 -0
  203. package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js.map +1 -0
  204. package/build/dist/Tests/Types/Date.test.js +96 -0
  205. package/build/dist/Tests/Types/Date.test.js.map +1 -1
  206. package/build/dist/Tests/Utils/MetricUnitUtil.test.js +159 -0
  207. package/build/dist/Tests/Utils/MetricUnitUtil.test.js.map +1 -0
  208. package/build/dist/Tests/Utils/Metrics/MetricFormulaEvaluator.test.js +224 -0
  209. package/build/dist/Tests/Utils/Metrics/MetricFormulaEvaluator.test.js.map +1 -0
  210. package/build/dist/Tests/Utils/Metrics/MetricResultUnitConverter.test.js +180 -0
  211. package/build/dist/Tests/Utils/Metrics/MetricResultUnitConverter.test.js.map +1 -0
  212. package/build/dist/Tests/Utils/RecordingRuleExpression.test.js +142 -0
  213. package/build/dist/Tests/Utils/RecordingRuleExpression.test.js.map +1 -0
  214. package/build/dist/Types/Date.js +9 -3
  215. package/build/dist/Types/Date.js.map +1 -1
  216. package/build/dist/Types/Icon/IconProp.js +1 -0
  217. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  218. package/build/dist/Types/Kubernetes/KubernetesInventoryExtractor.js +200 -0
  219. package/build/dist/Types/Kubernetes/KubernetesInventoryExtractor.js.map +1 -0
  220. package/build/dist/Types/Kubernetes/KubernetesObjectParser.js +1205 -0
  221. package/build/dist/Types/Kubernetes/KubernetesObjectParser.js.map +1 -0
  222. package/build/dist/Types/Metrics/MetricDownsamplingRetentionDays.js +32 -0
  223. package/build/dist/Types/Metrics/MetricDownsamplingRetentionDays.js.map +1 -0
  224. package/build/dist/Types/Metrics/MetricPipelineRuleFilterCondition.js +103 -0
  225. package/build/dist/Types/Metrics/MetricPipelineRuleFilterCondition.js.map +1 -0
  226. package/build/dist/Types/Metrics/MetricPipelineRuleType.js +27 -0
  227. package/build/dist/Types/Metrics/MetricPipelineRuleType.js.map +1 -0
  228. package/build/dist/Types/Metrics/RecordingRuleDefinition.js +110 -0
  229. package/build/dist/Types/Metrics/RecordingRuleDefinition.js.map +1 -0
  230. package/build/dist/Types/Monitor/CriteriaFilter.js +22 -0
  231. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  232. package/build/dist/Types/Monitor/MetricMonitor/MetricCriteriaContext.js +2 -0
  233. package/build/dist/Types/Monitor/MetricMonitor/MetricCriteriaContext.js.map +1 -0
  234. package/build/dist/Types/Permission.js +464 -0
  235. package/build/dist/Types/Permission.js.map +1 -1
  236. package/build/dist/Types/Telegram/TelegramMessage.js +2 -0
  237. package/build/dist/Types/Telegram/TelegramMessage.js.map +1 -0
  238. package/build/dist/Types/TelegramStatus.js +15 -0
  239. package/build/dist/Types/TelegramStatus.js.map +1 -0
  240. package/build/dist/Types/Trace/TraceAggregationType.js +18 -0
  241. package/build/dist/Types/Trace/TraceAggregationType.js.map +1 -0
  242. package/build/dist/Types/Trace/TraceDropFilterAction.js +7 -0
  243. package/build/dist/Types/Trace/TraceDropFilterAction.js.map +1 -0
  244. package/build/dist/Types/Trace/TracePipelineProcessorType.js +10 -0
  245. package/build/dist/Types/Trace/TracePipelineProcessorType.js.map +1 -0
  246. package/build/dist/Types/Trace/TraceRecordingRuleDefinition.js +145 -0
  247. package/build/dist/Types/Trace/TraceRecordingRuleDefinition.js.map +1 -0
  248. package/build/dist/Types/Trace/TraceScrubAction.js +8 -0
  249. package/build/dist/Types/Trace/TraceScrubAction.js.map +1 -0
  250. package/build/dist/Types/Trace/TraceScrubField.js +9 -0
  251. package/build/dist/Types/Trace/TraceScrubField.js.map +1 -0
  252. package/build/dist/Types/Trace/TraceScrubPatternType.js +11 -0
  253. package/build/dist/Types/Trace/TraceScrubPatternType.js.map +1 -0
  254. package/build/dist/UI/Components/CardSelect/CardSelect.js +3 -1
  255. package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
  256. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +6 -9
  257. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  258. package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
  259. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  260. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  261. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  262. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +30 -0
  263. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  264. package/build/dist/UI/Components/Page/Page.js +1 -0
  265. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  266. package/build/dist/Utils/MetricUnitUtil.js +232 -0
  267. package/build/dist/Utils/MetricUnitUtil.js.map +1 -0
  268. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +453 -0
  269. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -0
  270. package/build/dist/Utils/Metrics/MetricResultUnitConverter.js +61 -0
  271. package/build/dist/Utils/Metrics/MetricResultUnitConverter.js.map +1 -0
  272. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +298 -0
  273. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -0
  274. package/build/dist/Utils/ValueFormatter.js +123 -13
  275. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  276. package/package.json +2 -2
@@ -0,0 +1,502 @@
1
+ import MetricMonitorCriteria from "../../../../../Server/Utils/Monitor/Criteria/MetricMonitorCriteria";
2
+ import AggregateModel from "../../../../../Types/BaseDatabase/AggregatedModel";
3
+ import AggregatedResult from "../../../../../Types/BaseDatabase/AggregatedResult";
4
+ import {
5
+ CheckOn,
6
+ CriteriaFilter,
7
+ EvaluateOverTimeType,
8
+ FilterType,
9
+ NoDataPolicy,
10
+ } from "../../../../../Types/Monitor/CriteriaFilter";
11
+ import MetricAliasData from "../../../../../Types/Metrics/MetricAliasData";
12
+ import MetricFormulaConfigData from "../../../../../Types/Metrics/MetricFormulaConfigData";
13
+ import MetricQueryConfigData from "../../../../../Types/Metrics/MetricQueryConfigData";
14
+ import MetricQueryData from "../../../../../Types/Metrics/MetricQueryData";
15
+ import MetricsViewConfig from "../../../../../Types/Metrics/MetricsViewConfig";
16
+ import MetricMonitorResponse from "../../../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
17
+ import MetricFormulaEvaluator from "../../../../../Utils/Metrics/MetricFormulaEvaluator";
18
+ import MonitorStep from "../../../../../Types/Monitor/MonitorStep";
19
+ import RollingTime from "../../../../../Types/RollingTime/RollingTime";
20
+ import ObjectID from "../../../../../Types/ObjectID";
21
+
22
+ /*
23
+ * Light helper that assembles a MonitorStep + MetricMonitorResponse pair
24
+ * for a single metric alias "a" with the supplied native unit, so each
25
+ * test can just tweak the criteria filter + sample values.
26
+ */
27
+ function buildInputs(input: {
28
+ metricNativeUnit: string;
29
+ sampleValues: Array<number>;
30
+ criteriaFilter: CriteriaFilter;
31
+ }): {
32
+ criteriaFilter: CriteriaFilter;
33
+ monitorStep: MonitorStep;
34
+ dataToProcess: MetricMonitorResponse;
35
+ } {
36
+ const aliasData: MetricAliasData = {
37
+ metricVariable: "a",
38
+ title: "Response Time",
39
+ description: undefined,
40
+ legend: undefined,
41
+ legendUnit: input.metricNativeUnit,
42
+ };
43
+
44
+ const queryConfig: MetricQueryConfigData = {
45
+ metricAliasData: aliasData,
46
+ metricQueryData: {
47
+ filterData: {
48
+ metricName: "response_time",
49
+ },
50
+ } as unknown as MetricQueryData,
51
+ };
52
+
53
+ const metricViewConfig: MetricsViewConfig = {
54
+ queryConfigs: [queryConfig],
55
+ formulaConfigs: [],
56
+ };
57
+
58
+ const monitorStep: MonitorStep = new MonitorStep();
59
+ monitorStep.data = {
60
+ id: ObjectID.generate().toString(),
61
+ monitorCriteria: { data: undefined } as never,
62
+ } as unknown as MonitorStep["data"];
63
+ monitorStep.data!.metricMonitor = {
64
+ metricViewConfig,
65
+ rollingTime: RollingTime.Past1Minute,
66
+ };
67
+
68
+ const aggregated: AggregatedResult = {
69
+ data: input.sampleValues.map((v: number) => {
70
+ return {
71
+ timestamp: new Date(),
72
+ value: v,
73
+ } as AggregateModel;
74
+ }),
75
+ };
76
+
77
+ const dataToProcess: MetricMonitorResponse = {
78
+ projectId: ObjectID.generate(),
79
+ metricResult: [aggregated],
80
+ metricViewConfig,
81
+ monitorId: ObjectID.generate(),
82
+ };
83
+
84
+ return {
85
+ criteriaFilter: input.criteriaFilter,
86
+ monitorStep,
87
+ dataToProcess,
88
+ };
89
+ }
90
+
91
+ describe("MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet", () => {
92
+ test("no thresholdUnit → threshold evaluated in metric's native unit (backward compatible)", async () => {
93
+ const criteriaFilter: CriteriaFilter = {
94
+ checkOn: CheckOn.MetricValue,
95
+ filterType: FilterType.GreaterThan,
96
+ value: "2000",
97
+ metricMonitorOptions: {
98
+ metricAlias: "a",
99
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
100
+ },
101
+ };
102
+
103
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
104
+ metricNativeUnit: "ms",
105
+ sampleValues: [2500],
106
+ criteriaFilter,
107
+ });
108
+
109
+ const message: string | null =
110
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
111
+
112
+ expect(message).toBeTruthy();
113
+ expect(message).toContain("greater than 2000 ms");
114
+ expect(message).toContain("2500 ms");
115
+ expect(criteriaFilter.metricCriteriaContext?.unit).toBe("ms");
116
+ expect(criteriaFilter.metricCriteriaContext?.breachingSample?.value).toBe(
117
+ 2500,
118
+ );
119
+ });
120
+
121
+ test("thresholdUnit 'sec' with metric in 'ms' converts samples to sec for the comparison + message", async () => {
122
+ const criteriaFilter: CriteriaFilter = {
123
+ checkOn: CheckOn.MetricValue,
124
+ filterType: FilterType.GreaterThan,
125
+ value: "2",
126
+ metricMonitorOptions: {
127
+ metricAlias: "a",
128
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
129
+ thresholdUnit: "sec",
130
+ },
131
+ };
132
+
133
+ // 2500 ms == 2.5 sec — should breach "greater than 2 sec"
134
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
135
+ metricNativeUnit: "ms",
136
+ sampleValues: [2500],
137
+ criteriaFilter,
138
+ });
139
+
140
+ const message: string | null =
141
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
142
+
143
+ expect(message).toBeTruthy();
144
+ expect(message).toContain("greater than 2 sec");
145
+ expect(message).toContain("2.5 sec");
146
+ expect(criteriaFilter.metricCriteriaContext?.unit).toBe("sec");
147
+ expect(criteriaFilter.metricCriteriaContext?.breachingSample?.value).toBe(
148
+ 2.5,
149
+ );
150
+ });
151
+
152
+ test("thresholdUnit 'GB' with metric in 'bytes' breaches on 2.5 GB > 2 GB", async () => {
153
+ const criteriaFilter: CriteriaFilter = {
154
+ checkOn: CheckOn.MetricValue,
155
+ filterType: FilterType.GreaterThan,
156
+ value: "2",
157
+ metricMonitorOptions: {
158
+ metricAlias: "a",
159
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
160
+ thresholdUnit: "GB",
161
+ },
162
+ };
163
+
164
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
165
+ metricNativeUnit: "bytes",
166
+ sampleValues: [2.5e9],
167
+ criteriaFilter,
168
+ });
169
+
170
+ const message: string | null =
171
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
172
+
173
+ expect(message).toBeTruthy();
174
+ expect(message).toContain("greater than 2 GB");
175
+ expect(message).toContain("2.5 GB");
176
+ expect(criteriaFilter.metricCriteriaContext?.unit).toBe("GB");
177
+ });
178
+
179
+ test("thresholdUnit 'GB' — under-threshold samples do not trigger", async () => {
180
+ const criteriaFilter: CriteriaFilter = {
181
+ checkOn: CheckOn.MetricValue,
182
+ filterType: FilterType.GreaterThan,
183
+ value: "2",
184
+ metricMonitorOptions: {
185
+ metricAlias: "a",
186
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
187
+ thresholdUnit: "GB",
188
+ },
189
+ };
190
+
191
+ // 1.5 GB = 1.5e9 bytes — under 2 GB, should NOT breach.
192
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
193
+ metricNativeUnit: "bytes",
194
+ sampleValues: [1.5e9],
195
+ criteriaFilter,
196
+ });
197
+
198
+ const message: string | null =
199
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
200
+
201
+ expect(message).toBeNull();
202
+ });
203
+
204
+ test("thresholdUnit in an incompatible family falls back gracefully (no conversion)", async () => {
205
+ /*
206
+ * User incorrectly picked 'MB' but metric is in ms. Conversion should
207
+ * no-op and comparison proceeds in the user's raw unit.
208
+ */
209
+ const criteriaFilter: CriteriaFilter = {
210
+ checkOn: CheckOn.MetricValue,
211
+ filterType: FilterType.GreaterThan,
212
+ value: "1000",
213
+ metricMonitorOptions: {
214
+ metricAlias: "a",
215
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
216
+ thresholdUnit: "MB",
217
+ },
218
+ };
219
+
220
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
221
+ metricNativeUnit: "ms",
222
+ sampleValues: [5000],
223
+ criteriaFilter,
224
+ });
225
+
226
+ const message: string | null =
227
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
228
+
229
+ /*
230
+ * No conversion possible, so the displayed unit/values use user's MB
231
+ * label but values are passed through.
232
+ */
233
+ expect(message).toBeTruthy();
234
+ expect(message).toContain("MB");
235
+ });
236
+
237
+ test("no data + NoDataPolicy.Trigger triggers regardless of threshold", async () => {
238
+ const criteriaFilter: CriteriaFilter = {
239
+ checkOn: CheckOn.MetricValue,
240
+ filterType: FilterType.GreaterThan,
241
+ value: "2",
242
+ metricMonitorOptions: {
243
+ metricAlias: "a",
244
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
245
+ thresholdUnit: "GB",
246
+ onNoDataPolicy: NoDataPolicy.Trigger,
247
+ },
248
+ };
249
+
250
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
251
+ metricNativeUnit: "bytes",
252
+ sampleValues: [],
253
+ criteriaFilter,
254
+ });
255
+
256
+ const message: string | null =
257
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
258
+
259
+ expect(message).toBeTruthy();
260
+ expect(message).toContain("No data received");
261
+ });
262
+
263
+ test("breaching sample value is recorded in the user's chosen display unit", async () => {
264
+ const criteriaFilter: CriteriaFilter = {
265
+ checkOn: CheckOn.MetricValue,
266
+ filterType: FilterType.GreaterThan,
267
+ value: "1",
268
+ metricMonitorOptions: {
269
+ metricAlias: "a",
270
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
271
+ thresholdUnit: "sec",
272
+ },
273
+ };
274
+
275
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
276
+ metricNativeUnit: "ms",
277
+ sampleValues: [500, 3000, 800],
278
+ criteriaFilter,
279
+ });
280
+
281
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
282
+
283
+ expect(criteriaFilter.metricCriteriaContext?.breachingSample?.value).toBe(
284
+ 3,
285
+ );
286
+ expect(criteriaFilter.metricCriteriaContext?.unit).toBe("sec");
287
+ });
288
+
289
+ test("collects every breaching sample and totalSamplesInWindow", async () => {
290
+ const criteriaFilter: CriteriaFilter = {
291
+ checkOn: CheckOn.MetricValue,
292
+ filterType: FilterType.GreaterThan,
293
+ value: "100",
294
+ metricMonitorOptions: {
295
+ metricAlias: "a",
296
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
297
+ },
298
+ };
299
+
300
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
301
+ metricNativeUnit: "ms",
302
+ // 4 breach (>100), 1 does not
303
+ sampleValues: [120, 150, 80, 200, 300],
304
+ criteriaFilter,
305
+ });
306
+
307
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
308
+
309
+ const ctx: NonNullable<CriteriaFilter["metricCriteriaContext"]> =
310
+ criteriaFilter.metricCriteriaContext!;
311
+
312
+ expect(ctx.totalSamplesInWindow).toBe(5);
313
+ expect(ctx.breachingSamples).toBeDefined();
314
+ expect(ctx.breachingSamples?.length).toBe(4);
315
+ expect(
316
+ ctx.breachingSamples?.map((s: { value: number }) => {
317
+ return s.value;
318
+ }),
319
+ ).toEqual([120, 150, 200, 300]);
320
+ });
321
+
322
+ test("formula criteria populates components and per-sample component values", async () => {
323
+ // Build two query configs (a: ms, b: ms) and a formula c = a + b (ms).
324
+ const sharedTimestamps: Array<Date> = [
325
+ new Date("2026-04-20T11:00:00.000Z"),
326
+ new Date("2026-04-20T11:01:00.000Z"),
327
+ ];
328
+
329
+ const queryA: MetricQueryConfigData = {
330
+ metricAliasData: {
331
+ metricVariable: "a",
332
+ title: "",
333
+ description: "",
334
+ legend: "",
335
+ legendUnit: "ms",
336
+ },
337
+ metricQueryData: {
338
+ filterData: {
339
+ metricName: "request_latency",
340
+ },
341
+ } as unknown as MetricQueryData,
342
+ };
343
+
344
+ const queryB: MetricQueryConfigData = {
345
+ metricAliasData: {
346
+ metricVariable: "b",
347
+ title: "",
348
+ description: "",
349
+ legend: "",
350
+ legendUnit: "ms",
351
+ },
352
+ metricQueryData: {
353
+ filterData: {
354
+ metricName: "db_latency",
355
+ },
356
+ } as unknown as MetricQueryData,
357
+ };
358
+
359
+ const formulaC: MetricFormulaConfigData = {
360
+ metricAliasData: {
361
+ metricVariable: "c",
362
+ title: "",
363
+ description: "",
364
+ legend: "",
365
+ legendUnit: "ms",
366
+ },
367
+ metricFormulaData: {
368
+ metricFormula: "a + b",
369
+ },
370
+ };
371
+
372
+ const queryAResult: AggregatedResult = {
373
+ data: [
374
+ { timestamp: sharedTimestamps[0], value: 40 } as AggregateModel,
375
+ { timestamp: sharedTimestamps[1], value: 60 } as AggregateModel,
376
+ ],
377
+ };
378
+ const queryBResult: AggregatedResult = {
379
+ data: [
380
+ { timestamp: sharedTimestamps[0], value: 70 } as AggregateModel,
381
+ { timestamp: sharedTimestamps[1], value: 80 } as AggregateModel,
382
+ ],
383
+ };
384
+
385
+ /*
386
+ * c = a + b, evaluated via the shared evaluator so the synthetic series
387
+ * matches the production code path exactly.
388
+ */
389
+ const formulaCResult: AggregatedResult =
390
+ MetricFormulaEvaluator.evaluateFormula({
391
+ formula: "a + b",
392
+ queryConfigs: [queryA, queryB],
393
+ formulaConfigs: [],
394
+ results: [queryAResult, queryBResult],
395
+ });
396
+
397
+ const metricViewConfig: MetricsViewConfig = {
398
+ queryConfigs: [queryA, queryB],
399
+ formulaConfigs: [formulaC],
400
+ };
401
+
402
+ const monitorStep: MonitorStep = new MonitorStep();
403
+ monitorStep.data = {
404
+ id: ObjectID.generate().toString(),
405
+ monitorCriteria: { data: undefined } as never,
406
+ } as unknown as MonitorStep["data"];
407
+ monitorStep.data!.metricMonitor = {
408
+ metricViewConfig,
409
+ rollingTime: RollingTime.Past1Minute,
410
+ };
411
+
412
+ const dataToProcess: MetricMonitorResponse = {
413
+ projectId: ObjectID.generate(),
414
+ metricResult: [queryAResult, queryBResult, formulaCResult],
415
+ metricViewConfig,
416
+ monitorId: ObjectID.generate(),
417
+ };
418
+
419
+ const criteriaFilter: CriteriaFilter = {
420
+ checkOn: CheckOn.MetricValue,
421
+ filterType: FilterType.GreaterThan,
422
+ value: "100",
423
+ metricMonitorOptions: {
424
+ metricAlias: "c",
425
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
426
+ },
427
+ };
428
+
429
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
430
+ criteriaFilter,
431
+ monitorStep,
432
+ dataToProcess,
433
+ });
434
+
435
+ const ctx: NonNullable<CriteriaFilter["metricCriteriaContext"]> =
436
+ criteriaFilter.metricCriteriaContext!;
437
+
438
+ expect(ctx.isFormula).toBe(true);
439
+ expect(ctx.formulaExpression).toBe("a + b");
440
+
441
+ // Components describe each formula variable with its source metric + unit.
442
+ expect(ctx.components).toBeDefined();
443
+ expect(ctx.components?.length).toBe(2);
444
+ expect(ctx.components?.[0]).toMatchObject({
445
+ alias: "a",
446
+ name: "request_latency",
447
+ unit: "ms",
448
+ isFormula: false,
449
+ });
450
+ expect(ctx.components?.[1]).toMatchObject({
451
+ alias: "b",
452
+ name: "db_latency",
453
+ unit: "ms",
454
+ });
455
+
456
+ // Both formula points breach > 100 (40+70=110, 60+80=140).
457
+ expect(ctx.breachingSamples?.length).toBe(2);
458
+ const first: NonNullable<typeof ctx.breachingSamples>[number] =
459
+ ctx.breachingSamples![0]!;
460
+ expect(first.value).toBe(110);
461
+ expect(first.componentValues).toBeDefined();
462
+ expect(first.componentValues).toEqual([
463
+ { alias: "a", value: 40 },
464
+ { alias: "b", value: 70 },
465
+ ]);
466
+
467
+ const second: NonNullable<typeof ctx.breachingSamples>[number] =
468
+ ctx.breachingSamples![1]!;
469
+ expect(second.value).toBe(140);
470
+ expect(second.componentValues).toEqual([
471
+ { alias: "a", value: 60 },
472
+ { alias: "b", value: 80 },
473
+ ]);
474
+ });
475
+
476
+ test("summarises Filter Conditions Met when more than 5 values breach", async () => {
477
+ const criteriaFilter: CriteriaFilter = {
478
+ checkOn: CheckOn.MetricValue,
479
+ filterType: FilterType.GreaterThan,
480
+ value: "100",
481
+ metricMonitorOptions: {
482
+ metricAlias: "a",
483
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
484
+ },
485
+ };
486
+
487
+ const inputs: ReturnType<typeof buildInputs> = buildInputs({
488
+ metricNativeUnit: "ms",
489
+ sampleValues: [110, 120, 130, 140, 150, 160, 170, 180, 190, 200],
490
+ criteriaFilter,
491
+ });
492
+
493
+ const message: string | null =
494
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet(inputs);
495
+
496
+ expect(message).toBeTruthy();
497
+ expect(message).toContain("10 samples between 110 and 200");
498
+ expect(message).toContain("greater than 100 ms");
499
+ // The raw comma-joined dump is no longer in the message
500
+ expect(message).not.toContain("110, 120, 130, 140, 150, 160");
501
+ });
502
+ });
@@ -1,5 +1,6 @@
1
1
  import OneUptimeDate from "../../Types/Date";
2
2
  import PositiveNumber from "../../Types/PositiveNumber";
3
+ import Timezone from "../../Types/Timezone";
3
4
  import moment, { isMoment } from "moment";
4
5
 
5
6
  describe("class OneUptimeDate", () => {
@@ -92,4 +93,161 @@ describe("class OneUptimeDate", () => {
92
93
  OneUptimeDate.fromString("2026-04-01 14:45:31.414000000").toISOString(),
93
94
  ).toBe("2026-04-01T14:45:31.414Z");
94
95
  });
96
+
97
+ describe("getZoneAbbrByTimezone (DST awareness)", () => {
98
+ test("returns EST for America/New_York on a winter date", () => {
99
+ const winterDate: Date = new Date("2026-01-15T12:00:00Z");
100
+ expect(
101
+ OneUptimeDate.getZoneAbbrByTimezone(
102
+ Timezone.AmericaNew_York,
103
+ winterDate,
104
+ ),
105
+ ).toBe("EST");
106
+ });
107
+
108
+ test("returns EDT for America/New_York on a summer date", () => {
109
+ const summerDate: Date = new Date("2026-07-15T12:00:00Z");
110
+ expect(
111
+ OneUptimeDate.getZoneAbbrByTimezone(
112
+ Timezone.AmericaNew_York,
113
+ summerDate,
114
+ ),
115
+ ).toBe("EDT");
116
+ });
117
+
118
+ test("returns PST for America/Los_Angeles on a winter date", () => {
119
+ const winterDate: Date = new Date("2026-01-15T12:00:00Z");
120
+ expect(
121
+ OneUptimeDate.getZoneAbbrByTimezone(
122
+ Timezone.AmericaLos_Angeles,
123
+ winterDate,
124
+ ),
125
+ ).toBe("PST");
126
+ });
127
+
128
+ test("returns PDT for America/Los_Angeles on a summer date", () => {
129
+ const summerDate: Date = new Date("2026-07-15T12:00:00Z");
130
+ expect(
131
+ OneUptimeDate.getZoneAbbrByTimezone(
132
+ Timezone.AmericaLos_Angeles,
133
+ summerDate,
134
+ ),
135
+ ).toBe("PDT");
136
+ });
137
+
138
+ test("returns UTC for UTC regardless of date", () => {
139
+ const winterDate: Date = new Date("2026-01-15T12:00:00Z");
140
+ const summerDate: Date = new Date("2026-07-15T12:00:00Z");
141
+ expect(
142
+ OneUptimeDate.getZoneAbbrByTimezone(Timezone.UTC, winterDate),
143
+ ).toBe("UTC");
144
+ expect(
145
+ OneUptimeDate.getZoneAbbrByTimezone(Timezone.UTC, summerDate),
146
+ ).toBe("UTC");
147
+ });
148
+
149
+ test("returns IST for Asia/Kolkata year-round (no DST)", () => {
150
+ const winterDate: Date = new Date("2026-01-15T12:00:00Z");
151
+ const summerDate: Date = new Date("2026-07-15T12:00:00Z");
152
+ expect(
153
+ OneUptimeDate.getZoneAbbrByTimezone(Timezone.AsiaKolkata, winterDate),
154
+ ).toBe("IST");
155
+ expect(
156
+ OneUptimeDate.getZoneAbbrByTimezone(Timezone.AsiaKolkata, summerDate),
157
+ ).toBe("IST");
158
+ });
159
+
160
+ test("returns correct abbreviation right after US DST spring-forward", () => {
161
+ // US DST begins 2026-03-08 at 02:00 local -> springs to 03:00 EDT.
162
+ const beforeDst: Date = new Date("2026-03-08T06:00:00Z"); // 01:00 EST
163
+ const afterDst: Date = new Date("2026-03-08T08:00:00Z"); // 04:00 EDT
164
+ expect(
165
+ OneUptimeDate.getZoneAbbrByTimezone(
166
+ Timezone.AmericaNew_York,
167
+ beforeDst,
168
+ ),
169
+ ).toBe("EST");
170
+ expect(
171
+ OneUptimeDate.getZoneAbbrByTimezone(Timezone.AmericaNew_York, afterDst),
172
+ ).toBe("EDT");
173
+ });
174
+
175
+ test("accepts an ISO date string", () => {
176
+ expect(
177
+ OneUptimeDate.getZoneAbbrByTimezone(
178
+ Timezone.AmericaNew_York,
179
+ "2026-01-15T12:00:00Z",
180
+ ),
181
+ ).toBe("EST");
182
+ expect(
183
+ OneUptimeDate.getZoneAbbrByTimezone(
184
+ Timezone.AmericaNew_York,
185
+ "2026-07-15T12:00:00Z",
186
+ ),
187
+ ).toBe("EDT");
188
+ });
189
+
190
+ test("falls back to current date when no date is passed (backward compat)", () => {
191
+ const abbr: string = OneUptimeDate.getZoneAbbrByTimezone(Timezone.UTC);
192
+ expect(abbr).toBe("UTC");
193
+ });
194
+ });
195
+
196
+ describe("getDateAsFormattedArrayInMultipleTimezones (DST awareness)", () => {
197
+ test("shows EST for a winter event in America/New_York", () => {
198
+ const result: Array<string> =
199
+ OneUptimeDate.getDateAsFormattedArrayInMultipleTimezones({
200
+ date: new Date("2026-01-15T17:00:00Z"),
201
+ timezones: [Timezone.AmericaNew_York],
202
+ use12HourFormat: true,
203
+ });
204
+ expect(result).toHaveLength(1);
205
+ expect(result[0]).toContain("EST");
206
+ expect(result[0]).not.toContain("EDT");
207
+ // 17:00 UTC in winter EST (UTC-5) = 12:00 PM
208
+ expect(result[0]).toContain("12:00 PM");
209
+ });
210
+
211
+ test("shows EDT for a summer event in America/New_York", () => {
212
+ const result: Array<string> =
213
+ OneUptimeDate.getDateAsFormattedArrayInMultipleTimezones({
214
+ date: new Date("2026-07-15T17:00:00Z"),
215
+ timezones: [Timezone.AmericaNew_York],
216
+ use12HourFormat: true,
217
+ });
218
+ expect(result).toHaveLength(1);
219
+ expect(result[0]).toContain("EDT");
220
+ expect(result[0]).not.toContain("EST");
221
+ // 17:00 UTC in summer EDT (UTC-4) = 01:00 PM
222
+ expect(result[0]).toContain("01:00 PM");
223
+ });
224
+
225
+ test("picks the correct abbreviation per-timezone for the same event", () => {
226
+ // A winter event in multiple zones: NY should say EST, LA should say PST, UTC stays UTC.
227
+ const result: Array<string> =
228
+ OneUptimeDate.getDateAsFormattedArrayInMultipleTimezones({
229
+ date: new Date("2026-01-15T17:00:00Z"),
230
+ timezones: [
231
+ Timezone.UTC,
232
+ Timezone.AmericaNew_York,
233
+ Timezone.AmericaLos_Angeles,
234
+ ],
235
+ use12HourFormat: true,
236
+ });
237
+ expect(result[0]).toContain("UTC");
238
+ expect(result[1]).toContain("EST");
239
+ expect(result[2]).toContain("PST");
240
+ });
241
+
242
+ test("omits the abbreviation when onlyShowDate is true", () => {
243
+ const result: Array<string> =
244
+ OneUptimeDate.getDateAsFormattedArrayInMultipleTimezones({
245
+ date: new Date("2026-07-15T17:00:00Z"),
246
+ timezones: [Timezone.AmericaNew_York],
247
+ onlyShowDate: true,
248
+ });
249
+ expect(result[0]).not.toContain("EDT");
250
+ expect(result[0]).not.toContain("EST");
251
+ });
252
+ });
95
253
  });