@oneuptime/common 11.6.0 → 11.6.2

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 (427) hide show
  1. package/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.ts +41 -24
  2. package/Models/AnalyticsModels/Index.ts +4 -0
  3. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  4. package/Models/AnalyticsModels/MetricBaselineHourly.ts +2 -0
  5. package/Models/AnalyticsModels/MetricItemAggMV1m.ts +5 -2
  6. package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +5 -2
  7. package/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.ts +5 -2
  8. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +5 -2
  9. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +5 -2
  10. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  11. package/Models/AnalyticsModels/SloHistory.ts +240 -0
  12. package/Models/DatabaseModels/Index.ts +20 -0
  13. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  14. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  15. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  16. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  17. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  18. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  19. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  20. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  21. package/Models/DatabaseModels/ServiceLevelObjective.ts +1106 -0
  22. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  23. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  24. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  31. package/Server/Services/AnalyticsDatabaseService.ts +38 -10
  32. package/Server/Services/Index.ts +24 -0
  33. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  34. package/Server/Services/MetricService.ts +21 -2
  35. package/Server/Services/MonitorService.ts +22 -0
  36. package/Server/Services/NetworkDeviceService.ts +438 -2
  37. package/Server/Services/NetworkEndpointService.ts +414 -0
  38. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  39. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  40. package/Server/Services/NetworkSiteService.ts +1254 -0
  41. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  42. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  43. package/Server/Services/ProjectService.ts +122 -2
  44. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  45. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  46. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  47. package/Server/Services/ServiceLevelObjectiveService.ts +677 -0
  48. package/Server/Services/SloHistoryService.ts +101 -0
  49. package/Server/Services/UserNotificationSettingService.ts +37 -0
  50. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  51. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  52. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  53. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +128 -52
  54. package/Server/Utils/Memory.ts +9 -1
  55. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  56. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  57. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  58. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  59. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  60. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  61. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  62. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  63. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  64. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  65. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  66. package/Tests/Models/AnalyticsModels/AnalyticsBaseModel.test.ts +122 -0
  67. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  68. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  69. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  70. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  71. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  72. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  73. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  74. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  75. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  76. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  77. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  78. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +164 -3
  79. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  80. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +503 -0
  81. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  82. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  83. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  84. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  85. package/Tests/Server/Utils/Memory.test.ts +213 -0
  86. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  87. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  88. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  89. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  90. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  91. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  92. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  93. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  94. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  95. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  96. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  97. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  98. package/Tests/Server/Utils/Stream.test.ts +87 -0
  99. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  100. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  101. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  102. package/Tests/Types/Email.test.ts +198 -0
  103. package/Tests/Types/HashCode.test.ts +41 -0
  104. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  105. package/Tests/Types/Log/LogQueryParser.test.ts +186 -0
  106. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  107. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  108. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  109. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  110. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  111. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  112. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  113. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  114. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  115. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  116. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  117. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  118. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  119. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  120. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  121. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  122. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  123. package/Tests/Utils/Base64.test.ts +51 -0
  124. package/Tests/Utils/Boolean.test.ts +76 -0
  125. package/Tests/Utils/Crypto.test.ts +48 -0
  126. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  127. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  128. package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +197 -0
  129. package/Tests/Utils/Enum.test.ts +54 -0
  130. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  131. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  132. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  133. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  134. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  135. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  136. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  137. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  138. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  139. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  140. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  141. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  142. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  143. package/Tests/Utils/TechStack.test.ts +50 -0
  144. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  145. package/Tests/Utils/ValueFormatter.test.ts +305 -0
  146. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  147. package/Types/AnalyticsDatabase/TableColumn.ts +23 -0
  148. package/Types/BaseDatabase/EqualTo.ts +9 -1
  149. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  150. package/Types/BaseDatabase/NotEqual.ts +9 -1
  151. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  152. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  153. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  154. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  155. package/Types/Email/EmailTemplateType.ts +2 -0
  156. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  157. package/Types/Monitor/CriteriaFilter.ts +9 -0
  158. package/Types/Monitor/MonitorStep.ts +5 -8
  159. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  160. package/Types/Monitor/MonitorType.ts +15 -5
  161. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  162. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  163. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  164. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  165. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  166. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  167. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  168. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  169. package/Types/Permission.ts +449 -0
  170. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  171. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  172. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  173. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  174. package/Types/Telemetry/ServiceType.ts +1 -0
  175. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  176. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  177. package/UI/Components/List/List.tsx +8 -0
  178. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  179. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  180. package/UI/Components/Navbar/NavBar.tsx +16 -2
  181. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  182. package/UI/Utils/Navigation.ts +10 -0
  183. package/UI/Utils/TableFilterUrlState.ts +204 -17
  184. package/UI/Utils/TableViewUrlState.ts +165 -0
  185. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  186. package/Utils/Dashboard/Components/Index.ts +7 -0
  187. package/Utils/IpCanonicalUtil.ts +134 -0
  188. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  189. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  190. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  191. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  192. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  193. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  194. package/Utils/Slo/SloStatusColor.ts +54 -0
  195. package/Utils/Slo/SloUtil.ts +637 -0
  196. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  197. package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js +25 -20
  198. package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js.map +1 -1
  199. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  200. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  201. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  202. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  203. package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js +2 -0
  204. package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js.map +1 -1
  205. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js +5 -2
  206. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js.map +1 -1
  207. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +5 -2
  208. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -1
  209. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.js +5 -2
  210. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.js.map +1 -1
  211. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +5 -2
  212. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -1
  213. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +5 -2
  214. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -1
  215. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  216. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  217. package/build/dist/Models/AnalyticsModels/SloHistory.js +215 -0
  218. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  219. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  220. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  221. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  222. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  223. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  224. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  225. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  226. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  227. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  228. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  229. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  230. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  231. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  232. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  233. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  234. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  235. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  236. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  237. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1124 -0
  238. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  239. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  240. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  241. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  242. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  243. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  244. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  249. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  253. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  254. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  255. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  256. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  257. package/build/dist/Server/Services/AnalyticsDatabaseService.js +32 -7
  258. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  259. package/build/dist/Server/Services/Index.js +24 -0
  260. package/build/dist/Server/Services/Index.js.map +1 -1
  261. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  262. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  263. package/build/dist/Server/Services/MetricService.js +21 -3
  264. package/build/dist/Server/Services/MetricService.js.map +1 -1
  265. package/build/dist/Server/Services/MonitorService.js +19 -0
  266. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  267. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  268. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  269. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  270. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  271. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  272. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  273. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  274. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  275. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  276. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  277. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  278. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  279. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  280. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  281. package/build/dist/Server/Services/ProjectService.js +98 -2
  282. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  283. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  284. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  285. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  286. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  287. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  288. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  289. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +582 -0
  290. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  291. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  292. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  293. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  294. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  295. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  296. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  297. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  298. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  299. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  300. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  301. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +105 -52
  302. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  303. package/build/dist/Server/Utils/Memory.js +9 -1
  304. package/build/dist/Server/Utils/Memory.js.map +1 -1
  305. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  306. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  307. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  308. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  309. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  310. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  311. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  312. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  313. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  314. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  315. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  316. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  317. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  318. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  319. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  320. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  321. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  322. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  323. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  324. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  325. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  326. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  327. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  328. package/build/dist/Types/AnalyticsDatabase/TableColumn.js +7 -0
  329. package/build/dist/Types/AnalyticsDatabase/TableColumn.js.map +1 -1
  330. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  331. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  332. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  333. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  334. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  335. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  336. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  337. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  338. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  339. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  340. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  341. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  342. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  343. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  344. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  345. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  346. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  347. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  348. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  349. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  350. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  351. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  352. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  353. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  354. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  355. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  356. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  357. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  358. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  359. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  360. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  361. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  362. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  363. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  364. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  365. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  366. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  367. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  368. package/build/dist/Types/Permission.js +409 -0
  369. package/build/dist/Types/Permission.js.map +1 -1
  370. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  371. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  372. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  373. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  374. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  375. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  376. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  377. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  378. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  379. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  380. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  381. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  382. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  383. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  384. package/build/dist/UI/Components/List/List.js +1 -1
  385. package/build/dist/UI/Components/List/List.js.map +1 -1
  386. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  387. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  388. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  389. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  390. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  391. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  392. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  393. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  394. package/build/dist/UI/Utils/Navigation.js +9 -0
  395. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  396. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  397. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  398. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  399. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  400. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  401. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  402. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  403. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  404. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  405. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  406. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  407. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  408. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  409. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  410. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  411. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  412. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  413. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  414. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  415. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  416. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  417. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  418. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  419. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  420. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  421. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  422. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  423. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  424. package/package.json +2 -2
  425. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  426. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  427. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -0,0 +1,151 @@
1
+ import ArpEntry from "../../../Types/Monitor/SnmpMonitor/ArpEntry";
2
+ import FdbEntry from "../../../Types/Monitor/SnmpMonitor/FdbEntry";
3
+ import SnmpMonitorResponse from "../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
4
+ import NetworkTopology, {
5
+ NetworkTopologyEdge,
6
+ NetworkTopologyNode,
7
+ } from "../../../Types/Monitor/SnmpMonitor/NetworkTopology";
8
+
9
+ /*
10
+ * These types travel over the probe ingest wire and get stored in JSON
11
+ * columns, so a plain JSON round trip must preserve them exactly — no
12
+ * class instances, no Dates, no methods.
13
+ */
14
+ describe("SNMP endpoint discovery types", () => {
15
+ describe("SnmpMonitorResponse with endpoint data", () => {
16
+ test("arp and fdb entries survive a JSON wire round trip", () => {
17
+ const arpEntry: ArpEntry = {
18
+ ipAddress: "10.20.30.40",
19
+ macAddress: "aa:bb:cc:dd:ee:ff",
20
+ interfaceIndex: 3,
21
+ entryType: "dynamic",
22
+ };
23
+ const fdbEntry: FdbEntry = {
24
+ macAddress: "aa:bb:cc:dd:ee:ff",
25
+ bridgePort: 7,
26
+ interfaceIndex: 3,
27
+ vlanId: 120,
28
+ status: "learned",
29
+ };
30
+ const response: SnmpMonitorResponse = {
31
+ isOnline: true,
32
+ responseTimeInMs: 12,
33
+ failureCause: "",
34
+ oidResponses: [],
35
+ arpEntries: [arpEntry],
36
+ fdbEntries: [fdbEntry],
37
+ };
38
+
39
+ const roundTripped: SnmpMonitorResponse = JSON.parse(
40
+ JSON.stringify(response),
41
+ ) as SnmpMonitorResponse;
42
+
43
+ expect(roundTripped.arpEntries).toEqual([arpEntry]);
44
+ expect(roundTripped.fdbEntries).toEqual([fdbEntry]);
45
+ });
46
+
47
+ test("an older probe's payload carries no endpoint keys at all", () => {
48
+ const response: SnmpMonitorResponse = {
49
+ isOnline: false,
50
+ responseTimeInMs: 0,
51
+ failureCause: "Timed out",
52
+ oidResponses: [],
53
+ };
54
+
55
+ /*
56
+ * The server branches on presence, not emptiness (an absent array
57
+ * means "this probe does not collect endpoints", an empty one means
58
+ * "collected, found nothing"), so the wire form must not gain the
59
+ * keys — JSON.stringify has to drop them rather than emit [].
60
+ */
61
+ const roundTripped: SnmpMonitorResponse = JSON.parse(
62
+ JSON.stringify(response),
63
+ ) as SnmpMonitorResponse;
64
+
65
+ expect(Object.keys(roundTripped)).toEqual([
66
+ "isOnline",
67
+ "responseTimeInMs",
68
+ "failureCause",
69
+ "oidResponses",
70
+ ]);
71
+ expect("arpEntries" in roundTripped).toBe(false);
72
+ expect("fdbEntries" in roundTripped).toBe(false);
73
+ });
74
+
75
+ test("entries carry only their required fields over the wire", () => {
76
+ const arpEntry: ArpEntry = {
77
+ ipAddress: "10.0.0.1",
78
+ macAddress: "00:11:22:33:44:55",
79
+ interfaceIndex: 1,
80
+ };
81
+ const fdbEntry: FdbEntry = {
82
+ macAddress: "00:11:22:33:44:55",
83
+ bridgePort: 2,
84
+ };
85
+
86
+ expect(Object.keys(JSON.parse(JSON.stringify(arpEntry)))).toEqual([
87
+ "ipAddress",
88
+ "macAddress",
89
+ "interfaceIndex",
90
+ ]);
91
+ expect(Object.keys(JSON.parse(JSON.stringify(fdbEntry)))).toEqual([
92
+ "macAddress",
93
+ "bridgePort",
94
+ ]);
95
+ });
96
+ });
97
+
98
+ describe("NetworkTopology endpoint nodes and fdb links", () => {
99
+ test("an endpoint node attached via an fdb edge round-trips", () => {
100
+ const endpointNode: NetworkTopologyNode = {
101
+ id: "endpoint:aa:bb:cc:dd:ee:ff",
102
+ name: "POS Terminal 3",
103
+ isManaged: false,
104
+ status: "up",
105
+ kind: "endpoint",
106
+ macAddress: "aa:bb:cc:dd:ee:ff",
107
+ ipAddress: "10.20.30.40",
108
+ vendor: "Verifone",
109
+ classification: "pos-terminal",
110
+ };
111
+ const edge: NetworkTopologyEdge = {
112
+ fromNodeId: "device-1",
113
+ toNodeId: endpointNode.id,
114
+ protocols: ["fdb"],
115
+ };
116
+ const topology: NetworkTopology = {
117
+ nodes: [endpointNode],
118
+ edges: [edge],
119
+ };
120
+
121
+ const roundTripped: NetworkTopology = JSON.parse(
122
+ JSON.stringify(topology),
123
+ ) as NetworkTopology;
124
+
125
+ expect(roundTripped).toEqual(topology);
126
+ expect(roundTripped.nodes[0]!.kind).toBe("endpoint");
127
+ expect(roundTripped.edges[0]!.protocols).toEqual(["fdb"]);
128
+ });
129
+
130
+ test("a legacy node round-trips without gaining endpoint keys", () => {
131
+ const legacyNode: NetworkTopologyNode = {
132
+ id: "device-1",
133
+ name: "core-switch",
134
+ isManaged: true,
135
+ status: "up",
136
+ };
137
+
138
+ const roundTripped: NetworkTopologyNode = JSON.parse(
139
+ JSON.stringify(legacyNode),
140
+ ) as NetworkTopologyNode;
141
+
142
+ expect(Object.keys(roundTripped)).toEqual([
143
+ "id",
144
+ "name",
145
+ "isManaged",
146
+ "status",
147
+ ]);
148
+ expect(roundTripped).toEqual(legacyNode);
149
+ });
150
+ });
151
+ });
@@ -18,6 +18,15 @@ const CISCO_SYS_OBJECT_ID: string = "1.3.6.1.4.1.9.1.1208"; // Catalyst 2960X
18
18
  const MIKROTIK_SYS_OBJECT_ID: string = "1.3.6.1.4.1.14988.1";
19
19
  const UBIQUITI_SYS_OBJECT_ID: string = "1.3.6.1.4.1.41112.1.4";
20
20
  const JUNIPER_SYS_OBJECT_ID: string = "1.3.6.1.4.1.2636.1.1.1.2.29"; // EX2200
21
+ const ARISTA_SYS_OBJECT_ID: string = "1.3.6.1.4.1.30065.1.3011.7048";
22
+ const HPE_SYS_OBJECT_ID: string = "1.3.6.1.4.1.11.2.3.7.11.87"; // ProCurve
23
+ const FORTINET_SYS_OBJECT_ID: string = "1.3.6.1.4.1.12356.101.1.60";
24
+ const PALO_ALTO_SYS_OBJECT_ID: string = "1.3.6.1.4.1.25461.2.3.36";
25
+ const HUAWEI_SYS_OBJECT_ID: string = "1.3.6.1.4.1.2011.2.23.92";
26
+ const FORCE10_SYS_OBJECT_ID: string = "1.3.6.1.4.1.6027.1.3.4"; // S-series
27
+ // Ubiquiti EdgeSwitch firmware reports Broadcom's FASTPATH arc, not 41112.
28
+ const EDGESWITCH_SYS_OBJECT_ID: string = "1.3.6.1.4.1.4413";
29
+ const DELL_SYS_OBJECT_ID: string = "1.3.6.1.4.1.674.10895.3031"; // PowerConnect
21
30
 
22
31
  describe("SnmpVendorTemplateUtil.getEnterpriseNumber", () => {
23
32
  test("extracts the enterprise number from a Cisco sysObjectID", () => {
@@ -82,6 +91,14 @@ describe("SnmpVendorTemplateUtil.getVendorNameBySysObjectId", () => {
82
91
  [MIKROTIK_SYS_OBJECT_ID, "MikroTik"],
83
92
  [UBIQUITI_SYS_OBJECT_ID, "Ubiquiti"],
84
93
  [JUNIPER_SYS_OBJECT_ID, "Juniper"],
94
+ [ARISTA_SYS_OBJECT_ID, "Arista"],
95
+ [HPE_SYS_OBJECT_ID, "HPE"],
96
+ [FORTINET_SYS_OBJECT_ID, "Fortinet"],
97
+ [PALO_ALTO_SYS_OBJECT_ID, "Palo Alto Networks"],
98
+ [HUAWEI_SYS_OBJECT_ID, "Huawei"],
99
+ [FORCE10_SYS_OBJECT_ID, "Force10"],
100
+ [EDGESWITCH_SYS_OBJECT_ID, "Broadcom"],
101
+ [DELL_SYS_OBJECT_ID, "Dell"],
85
102
  ])("%s resolves to vendor %s", (sysObjectId: string, vendor: string) => {
86
103
  expect(SnmpVendorTemplateUtil.getVendorNameBySysObjectId(sysObjectId)).toBe(
87
104
  vendor,
@@ -130,17 +147,42 @@ describe("SnmpVendorTemplateUtil.matchBySysObjectId", () => {
130
147
  ).toBe("ubiquiti-edgeos");
131
148
  });
132
149
 
150
+ test.each([
151
+ [JUNIPER_SYS_OBJECT_ID, "juniper-junos"],
152
+ [ARISTA_SYS_OBJECT_ID, "arista-eos"],
153
+ [HPE_SYS_OBJECT_ID, "hpe-procurve"],
154
+ [FORTINET_SYS_OBJECT_ID, "fortinet-fortigate"],
155
+ [PALO_ALTO_SYS_OBJECT_ID, "paloalto-panos"],
156
+ [HUAWEI_SYS_OBJECT_ID, "huawei-vrp"],
157
+ [FORCE10_SYS_OBJECT_ID, "dell-force10"],
158
+ /*
159
+ * EdgeSwitch reports Broadcom's FASTPATH arc but still gets the
160
+ * standard-MIB Ubiquiti template.
161
+ */
162
+ [EDGESWITCH_SYS_OBJECT_ID, "ubiquiti-edgeos"],
163
+ ])(
164
+ "%s is routed to the %s template",
165
+ (sysObjectId: string, templateId: string) => {
166
+ const template: SnmpVendorTemplate | undefined =
167
+ SnmpVendorTemplateUtil.matchBySysObjectId(sysObjectId);
168
+
169
+ expect(template?.id).toBe(templateId);
170
+ expect(template).toBe(SnmpVendorTemplateUtil.getById(templateId));
171
+ },
172
+ );
173
+
133
174
  /*
134
- * Juniper has a vendor name in the enterprise map but no vendor-specific
135
- * template the match must come back empty so callers fall back to the
175
+ * Dell enterprise 674 (PowerConnect and friends) has a vendor name in the
176
+ * enterprise map but no vendor-specific template only Force10 (6027) is
177
+ * routed. The match must come back empty so callers fall back to the
136
178
  * generic Host Resources template rather than mislabeling the device.
137
179
  */
138
- test("a Juniper device has a vendor name but no template", () => {
180
+ test("a Dell PowerConnect device has a vendor name but no template", () => {
139
181
  expect(
140
- SnmpVendorTemplateUtil.getVendorNameBySysObjectId(JUNIPER_SYS_OBJECT_ID),
141
- ).toBe("Juniper");
182
+ SnmpVendorTemplateUtil.getVendorNameBySysObjectId(DELL_SYS_OBJECT_ID),
183
+ ).toBe("Dell");
142
184
  expect(
143
- SnmpVendorTemplateUtil.matchBySysObjectId(JUNIPER_SYS_OBJECT_ID),
185
+ SnmpVendorTemplateUtil.matchBySysObjectId(DELL_SYS_OBJECT_ID),
144
186
  ).toBeUndefined();
145
187
  });
146
188
 
@@ -169,6 +211,68 @@ describe("SnmpVendorTemplateUtil.getAll / getById", () => {
169
211
  });
170
212
  });
171
213
 
214
+ /*
215
+ * Catalog hygiene: every shipped template must contain OIDs a poller can
216
+ * actually GET (dotted-numeric instance OIDs, no symbolic names or trailing
217
+ * dots) and enough metadata for the dashboard to render a useful row.
218
+ */
219
+ describe("SnmpVendorTemplates catalog", () => {
220
+ // Absolute numeric OID: digits separated by single dots, at least two arcs.
221
+ const OID_REGEX: RegExp = /^[0-9]+(\.[0-9]+)+$/;
222
+
223
+ test("template ids are unique", () => {
224
+ const ids: Array<string> = SnmpVendorTemplates.map(
225
+ (template: SnmpVendorTemplate) => {
226
+ return template.id;
227
+ },
228
+ );
229
+
230
+ expect(new Set(ids).size).toBe(ids.length);
231
+ });
232
+
233
+ test.each(
234
+ SnmpVendorTemplates.map((template: SnmpVendorTemplate) => {
235
+ return [template.id, template] as [string, SnmpVendorTemplate];
236
+ }),
237
+ )(
238
+ "%s has valid OIDs and non-empty metadata",
239
+ (_id: string, template: SnmpVendorTemplate) => {
240
+ expect(template.label.trim()).not.toHaveLength(0);
241
+ expect(template.description.trim()).not.toHaveLength(0);
242
+ expect(template.oids.length).toBeGreaterThan(0);
243
+
244
+ for (const oid of template.oids) {
245
+ expect(oid.oid).toMatch(OID_REGEX);
246
+ expect(oid.name?.trim()).toBeTruthy();
247
+ expect(oid.description?.trim()).toBeTruthy();
248
+ }
249
+
250
+ // No template should list the same OID twice.
251
+ const values: Array<string> = template.oids.map((oid: SnmpOid) => {
252
+ return oid.oid;
253
+ });
254
+ expect(new Set(values).size).toBe(values.length);
255
+ },
256
+ );
257
+
258
+ /*
259
+ * The Cisco env-mon states are enums where 1 = normal — users build
260
+ * "not equal to 1" alert criteria on them, so the template must keep
261
+ * shipping these exact instance OIDs.
262
+ */
263
+ test("the Cisco template includes fan and PSU state OIDs", () => {
264
+ const cisco: SnmpVendorTemplate | undefined =
265
+ SnmpVendorTemplateUtil.getById("cisco-ios");
266
+
267
+ const oidValues: Array<string> = (cisco?.oids || []).map((oid: SnmpOid) => {
268
+ return oid.oid;
269
+ });
270
+
271
+ expect(oidValues).toContain("1.3.6.1.4.1.9.9.13.1.4.1.3.1"); // fan state
272
+ expect(oidValues).toContain("1.3.6.1.4.1.9.9.13.1.5.1.3.1"); // PSU state
273
+ });
274
+ });
275
+
172
276
  describe("SnmpVendorTemplateUtil.mergeOids", () => {
173
277
  function oidValues(oids: Array<SnmpOid>): Array<string> {
174
278
  return oids.map((oid: SnmpOid) => {
@@ -0,0 +1,129 @@
1
+ import DefaultNetworkSiteType from "../../../Types/NetworkSite/DefaultNetworkSiteType";
2
+ import Permission, {
3
+ PermissionHelper,
4
+ PermissionProps,
5
+ } from "../../../Types/Permission";
6
+
7
+ describe("DefaultNetworkSiteType", () => {
8
+ /*
9
+ * These values are the names seeded into every project's NetworkSiteType
10
+ * table (and the names the backfill migration matches legacy site type
11
+ * strings against), so they are data, not just labels - renaming a member
12
+ * value here would leave existing sites pointing at a type that no longer
13
+ * gets seeded.
14
+ */
15
+ test("contains every hierarchy level with its display value", () => {
16
+ expect(DefaultNetworkSiteType.AccountType).toBe("Account Type");
17
+ expect(DefaultNetworkSiteType.Region).toBe("Region");
18
+ expect(DefaultNetworkSiteType.Franchisee).toBe("Franchisee");
19
+ expect(DefaultNetworkSiteType.Market).toBe("Market");
20
+ expect(DefaultNetworkSiteType.Unit).toBe("Unit");
21
+ expect(DefaultNetworkSiteType.DataCenter).toBe("Data Center");
22
+ expect(DefaultNetworkSiteType.Other).toBe("Other");
23
+ });
24
+
25
+ test("has exactly the expected members", () => {
26
+ expect(Object.keys(DefaultNetworkSiteType).sort()).toEqual(
27
+ [
28
+ "AccountType",
29
+ "DataCenter",
30
+ "Franchisee",
31
+ "Market",
32
+ "Other",
33
+ "Region",
34
+ "Unit",
35
+ ].sort(),
36
+ );
37
+ });
38
+ });
39
+
40
+ describe("NetworkSite permissions", () => {
41
+ /*
42
+ * Keyed by the enum member name on purpose: the VALUE is what gets
43
+ * persisted in team/API-key permission rows and compared as a raw string
44
+ * across services, so a value that drifts from its key is a silent
45
+ * authorization break. Referencing the members by symbol also keeps this
46
+ * a compile error if one is ever removed.
47
+ */
48
+ const permissionsByName: Record<string, Permission> = {
49
+ CreateNetworkSite: Permission.CreateNetworkSite,
50
+ DeleteNetworkSite: Permission.DeleteNetworkSite,
51
+ EditNetworkSite: Permission.EditNetworkSite,
52
+ ReadNetworkSite: Permission.ReadNetworkSite,
53
+ CreateNetworkEndpoint: Permission.CreateNetworkEndpoint,
54
+ DeleteNetworkEndpoint: Permission.DeleteNetworkEndpoint,
55
+ EditNetworkEndpoint: Permission.EditNetworkEndpoint,
56
+ ReadNetworkEndpoint: Permission.ReadNetworkEndpoint,
57
+ CreateNetworkSiteStatusTimeline: Permission.CreateNetworkSiteStatusTimeline,
58
+ DeleteNetworkSiteStatusTimeline: Permission.DeleteNetworkSiteStatusTimeline,
59
+ EditNetworkSiteStatusTimeline: Permission.EditNetworkSiteStatusTimeline,
60
+ ReadNetworkSiteStatusTimeline: Permission.ReadNetworkSiteStatusTimeline,
61
+ CreateNetworkSiteLink: Permission.CreateNetworkSiteLink,
62
+ DeleteNetworkSiteLink: Permission.DeleteNetworkSiteLink,
63
+ EditNetworkSiteLink: Permission.EditNetworkSiteLink,
64
+ ReadNetworkSiteLink: Permission.ReadNetworkSiteLink,
65
+ CreateNetworkSiteAssignmentRule: Permission.CreateNetworkSiteAssignmentRule,
66
+ DeleteNetworkSiteAssignmentRule: Permission.DeleteNetworkSiteAssignmentRule,
67
+ EditNetworkSiteAssignmentRule: Permission.EditNetworkSiteAssignmentRule,
68
+ ReadNetworkSiteAssignmentRule: Permission.ReadNetworkSiteAssignmentRule,
69
+ CreateNetworkSiteType: Permission.CreateNetworkSiteType,
70
+ DeleteNetworkSiteType: Permission.DeleteNetworkSiteType,
71
+ EditNetworkSiteType: Permission.EditNetworkSiteType,
72
+ ReadNetworkSiteType: Permission.ReadNetworkSiteType,
73
+ };
74
+
75
+ const permissions: Array<Permission> = Object.values(permissionsByName);
76
+
77
+ test.each(Object.keys(permissionsByName))(
78
+ "%s has an enum value identical to its key",
79
+ (name: string) => {
80
+ expect(permissionsByName[name]).toBe(name);
81
+ },
82
+ );
83
+
84
+ test("the enum values are exactly the twenty four expected strings", () => {
85
+ expect(permissions).toEqual([
86
+ "CreateNetworkSite",
87
+ "DeleteNetworkSite",
88
+ "EditNetworkSite",
89
+ "ReadNetworkSite",
90
+ "CreateNetworkEndpoint",
91
+ "DeleteNetworkEndpoint",
92
+ "EditNetworkEndpoint",
93
+ "ReadNetworkEndpoint",
94
+ "CreateNetworkSiteStatusTimeline",
95
+ "DeleteNetworkSiteStatusTimeline",
96
+ "EditNetworkSiteStatusTimeline",
97
+ "ReadNetworkSiteStatusTimeline",
98
+ "CreateNetworkSiteLink",
99
+ "DeleteNetworkSiteLink",
100
+ "EditNetworkSiteLink",
101
+ "ReadNetworkSiteLink",
102
+ "CreateNetworkSiteAssignmentRule",
103
+ "DeleteNetworkSiteAssignmentRule",
104
+ "EditNetworkSiteAssignmentRule",
105
+ "ReadNetworkSiteAssignmentRule",
106
+ "CreateNetworkSiteType",
107
+ "DeleteNetworkSiteType",
108
+ "EditNetworkSiteType",
109
+ "ReadNetworkSiteType",
110
+ ]);
111
+ });
112
+
113
+ test.each(permissions)(
114
+ "%s has permission props with a title and description",
115
+ (permission: Permission) => {
116
+ const props: PermissionProps | undefined =
117
+ PermissionHelper.getAllPermissionProps().find(
118
+ (item: PermissionProps) => {
119
+ return item.permission === permission;
120
+ },
121
+ );
122
+
123
+ expect(props).toBeDefined();
124
+ expect(props?.title.length).toBeGreaterThan(0);
125
+ expect(props?.description.length).toBeGreaterThan(0);
126
+ expect(props?.isAssignableToTenant).toBe(true);
127
+ },
128
+ );
129
+ });
@@ -0,0 +1,166 @@
1
+ import SerializableObjectDictionary from "../../Types/SerializableObjectDictionary";
2
+ import Color from "../../Types/Color";
3
+ import Email from "../../Types/Email";
4
+ import { JSONValue, ObjectType } from "../../Types/JSON";
5
+ import JSONFunctions from "../../Types/JSONFunctions";
6
+ import ObjectID from "../../Types/ObjectID";
7
+ import Phone from "../../Types/Phone";
8
+ import Port from "../../Types/Port";
9
+ import Version from "../../Types/Version";
10
+
11
+ /*
12
+ * SerializableObjectDictionary is the registry JSONFunctions.deserializeValue
13
+ * looks a `_type` up in. A missing or wrong entry does not throw — the value
14
+ * just silently stays a plain `{ _type, value }` object and surfaces much
15
+ * later as a "x.toString is not a function" somewhere else entirely. These
16
+ * tests make that failure mode loud.
17
+ */
18
+
19
+ /*
20
+ * ObjectTypes that deliberately have no registry entry, with the reason.
21
+ * Adding a new ObjectType without deciding which side of this line it falls
22
+ * on will fail the completeness test below.
23
+ */
24
+ const INTENTIONALLY_UNREGISTERED: Array<ObjectType> = [
25
+ // Handled by its own branch in deserializeValue, before the registry lookup.
26
+ ObjectType.Buffer,
27
+ // Plain numeric wrappers that serialize as bare values.
28
+ ObjectType.Decimal,
29
+ ObjectType.PositiveNumber,
30
+ // Not a database property: permissions serialize as plain enum strings.
31
+ ObjectType.Permission,
32
+ // Nested inside Recurring / dashboard configs, never deserialized standalone.
33
+ ObjectType.RestrictionTimes,
34
+ ObjectType.DashboardComponent,
35
+ ObjectType.DashboardViewConfig,
36
+ ];
37
+
38
+ describe("SerializableObjectDictionary", () => {
39
+ test("every key should be a known ObjectType", () => {
40
+ const objectTypes: Array<string> = Object.values(ObjectType);
41
+
42
+ for (const key of Object.keys(SerializableObjectDictionary)) {
43
+ expect(objectTypes).toContain(key);
44
+ }
45
+ });
46
+
47
+ test("every registered class should expose a static fromJSON", () => {
48
+ const withoutFromJson: Array<string> = Object.entries(
49
+ SerializableObjectDictionary,
50
+ )
51
+ .filter(([, value]: [string, any]) => {
52
+ return !value || typeof value.fromJSON !== "function";
53
+ })
54
+ .map(([key]: [string, any]) => {
55
+ return key;
56
+ });
57
+
58
+ // Listing the offenders makes a failure name the broken entry directly.
59
+ expect(withoutFromJson).toEqual([]);
60
+ });
61
+
62
+ test("every ObjectType should be registered or explicitly exempt", () => {
63
+ const registered: Array<string> = Object.keys(SerializableObjectDictionary);
64
+ const exempt: Array<string> = INTENTIONALLY_UNREGISTERED.map(
65
+ (type: ObjectType) => {
66
+ return type.toString();
67
+ },
68
+ );
69
+
70
+ const unaccounted: Array<string> = Object.values(ObjectType).filter(
71
+ (type: string) => {
72
+ return !registered.includes(type) && !exempt.includes(type);
73
+ },
74
+ );
75
+
76
+ /*
77
+ * A non-empty list here means a new ObjectType was added without deciding
78
+ * whether it needs a registry entry: either add it to
79
+ * SerializableObjectDictionary or list it in INTENTIONALLY_UNREGISTERED
80
+ * with the reason.
81
+ */
82
+ expect(unaccounted).toEqual([]);
83
+ });
84
+
85
+ test("no exempt ObjectType should also be registered", () => {
86
+ // Keeps the exemption list honest as entries get added to the registry.
87
+ const exemptButRegistered: Array<string> =
88
+ INTENTIONALLY_UNREGISTERED.filter((type: ObjectType) => {
89
+ return Boolean(SerializableObjectDictionary[type.toString()]);
90
+ }).map((type: ObjectType) => {
91
+ return type.toString();
92
+ });
93
+
94
+ expect(exemptButRegistered).toEqual([]);
95
+ });
96
+
97
+ describe("deserializeValue should hydrate registered types", () => {
98
+ test("should hydrate an ObjectID", () => {
99
+ const id: ObjectID = ObjectID.generate();
100
+ const hydrated: JSONValue = JSONFunctions.deserializeValue(id.toJSON());
101
+
102
+ expect(hydrated).toBeInstanceOf(ObjectID);
103
+ expect((hydrated as ObjectID).toString()).toEqual(id.toString());
104
+ });
105
+
106
+ test("should hydrate an Email", () => {
107
+ const email: Email = new Email("registry@example.com");
108
+ const hydrated: JSONValue = JSONFunctions.deserializeValue(
109
+ email.toJSON(),
110
+ );
111
+
112
+ expect(hydrated).toBeInstanceOf(Email);
113
+ expect((hydrated as Email).toString()).toEqual("registry@example.com");
114
+ });
115
+
116
+ test("should hydrate a Color", () => {
117
+ const color: Color = new Color("#ab12cd");
118
+ const hydrated: JSONValue = JSONFunctions.deserializeValue(
119
+ color.toJSON(),
120
+ );
121
+
122
+ expect(hydrated).toBeInstanceOf(Color);
123
+ expect((hydrated as Color).toString()).toEqual("#ab12cd");
124
+ });
125
+
126
+ test("should hydrate a Port", () => {
127
+ const port: Port = new Port(8080);
128
+ const hydrated: JSONValue = JSONFunctions.deserializeValue(port.toJSON());
129
+
130
+ expect(hydrated).toBeInstanceOf(Port);
131
+ expect((hydrated as Port).toNumber()).toEqual(8080);
132
+ });
133
+
134
+ test("should hydrate a Version", () => {
135
+ const version: Version = new Version("1.2.3");
136
+ const hydrated: JSONValue = JSONFunctions.deserializeValue(
137
+ version.toJSON(),
138
+ );
139
+
140
+ expect(hydrated).toBeInstanceOf(Version);
141
+ expect((hydrated as Version).toString()).toEqual("1.2.3");
142
+ });
143
+
144
+ test("should hydrate a Phone", () => {
145
+ const phone: Phone = new Phone("+15551234567");
146
+ const hydrated: JSONValue = JSONFunctions.deserializeValue(
147
+ phone.toJSON(),
148
+ );
149
+
150
+ expect(hydrated).toBeInstanceOf(Phone);
151
+ expect((hydrated as Phone).toString()).toEqual("+15551234567");
152
+ });
153
+
154
+ test("should leave an unknown _type as a plain object", () => {
155
+ const unknown: JSONValue = JSONFunctions.deserializeValue({
156
+ _type: "NotARegisteredType",
157
+ value: "whatever",
158
+ });
159
+
160
+ expect(unknown).toEqual({
161
+ _type: "NotARegisteredType",
162
+ value: "whatever",
163
+ });
164
+ });
165
+ });
166
+ });
@@ -0,0 +1,98 @@
1
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
2
+ import OneUptimeDate from "../../../Types/Date";
3
+ import { RangeStartAndEndDateTimeUtil } from "../../../Types/Time/RangeStartAndEndDateTime";
4
+ import TimeRange from "../../../Types/Time/TimeRange";
5
+ import { describe, expect, test } from "@jest/globals";
6
+
7
+ /*
8
+ * RangeStartAndEndDateTimeUtil turns a relative TimeRange (last 5 mins, last
9
+ * hour, ...) into a concrete [start, end] window ending "now". Because both
10
+ * bounds are captured from the same `now`, the window's *width* is
11
+ * deterministic even though its absolute position moves — so these tests assert
12
+ * the exact width for the fixed-duration ranges without freezing the clock, and
13
+ * a sane ordering/magnitude for the calendar-variable month ranges.
14
+ */
15
+
16
+ function widthMs(range: TimeRange): number {
17
+ const between: InBetween<Date> =
18
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate({ range });
19
+ return between.endValue.getTime() - between.startValue.getTime();
20
+ }
21
+
22
+ const MIN: number = 60 * 1000;
23
+ const HOUR: number = 60 * MIN;
24
+ const DAY: number = 24 * HOUR;
25
+
26
+ describe("RangeStartAndEndDateTimeUtil.getStartAndEndDate - fixed durations", () => {
27
+ const cases: Array<[TimeRange, number]> = [
28
+ [TimeRange.PAST_FIVE_MINS, 5 * MIN],
29
+ [TimeRange.PAST_FIFTEEN_MINS, 15 * MIN],
30
+ [TimeRange.PAST_THIRTY_MINS, 30 * MIN],
31
+ [TimeRange.PAST_ONE_HOUR, HOUR],
32
+ [TimeRange.PAST_TWO_HOURS, 2 * HOUR],
33
+ [TimeRange.PAST_THREE_HOURS, 3 * HOUR],
34
+ [TimeRange.PAST_ONE_DAY, DAY],
35
+ [TimeRange.PAST_TWO_DAYS, 2 * DAY],
36
+ [TimeRange.PAST_ONE_WEEK, 7 * DAY],
37
+ [TimeRange.PAST_TWO_WEEKS, 14 * DAY],
38
+ ];
39
+
40
+ for (const [range, expectedWidth] of cases) {
41
+ test(`${range} spans exactly ${expectedWidth / MIN} minutes`, () => {
42
+ // Allow a tiny tolerance for the two now() reads inside the util.
43
+ expect(Math.abs(widthMs(range) - expectedWidth)).toBeLessThan(2000);
44
+ });
45
+ }
46
+
47
+ test("end bound is at (or a hair before) now, start is earlier", () => {
48
+ const between: InBetween<Date> =
49
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate({
50
+ range: TimeRange.PAST_ONE_HOUR,
51
+ });
52
+ expect(between.startValue.getTime()).toBeLessThan(
53
+ between.endValue.getTime(),
54
+ );
55
+ expect(between.endValue.getTime()).toBeLessThanOrEqual(Date.now() + 2000);
56
+ });
57
+ });
58
+
59
+ describe("RangeStartAndEndDateTimeUtil.getStartAndEndDate - calendar ranges", () => {
60
+ test("one month is between 27 and 32 days wide", () => {
61
+ const width: number = widthMs(TimeRange.PAST_ONE_MONTH);
62
+ expect(width).toBeGreaterThan(27 * DAY);
63
+ expect(width).toBeLessThan(32 * DAY);
64
+ });
65
+
66
+ test("three months is wider than one month", () => {
67
+ expect(widthMs(TimeRange.PAST_THREE_MONTHS)).toBeGreaterThan(
68
+ widthMs(TimeRange.PAST_ONE_MONTH),
69
+ );
70
+ });
71
+ });
72
+
73
+ describe("RangeStartAndEndDateTimeUtil.getStartAndEndDate - custom", () => {
74
+ test("returns the caller-supplied window for CUSTOM", () => {
75
+ const start: Date = OneUptimeDate.fromString("2026-01-01T00:00:00.000Z");
76
+ const end: Date = OneUptimeDate.fromString("2026-01-02T00:00:00.000Z");
77
+ const custom: InBetween<Date> = new InBetween<Date>(start, end);
78
+
79
+ const result: InBetween<Date> =
80
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate({
81
+ range: TimeRange.CUSTOM,
82
+ startAndEndDate: custom,
83
+ });
84
+
85
+ expect(result).toBe(custom);
86
+ });
87
+
88
+ test("falls back to a zero-width now window when CUSTOM has no dates", () => {
89
+ const result: InBetween<Date> =
90
+ RangeStartAndEndDateTimeUtil.getStartAndEndDate({
91
+ range: TimeRange.CUSTOM,
92
+ });
93
+ // start === end within tolerance -> effectively zero width.
94
+ expect(
95
+ Math.abs(result.endValue.getTime() - result.startValue.getTime()),
96
+ ).toBeLessThan(2000);
97
+ });
98
+ });