@oneuptime/common 11.6.1 → 11.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. package/Models/AnalyticsModels/Index.ts +4 -0
  2. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  3. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  4. package/Models/AnalyticsModels/SloHistory.ts +243 -0
  5. package/Models/DatabaseModels/Index.ts +20 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  8. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  9. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  10. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  11. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  13. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  14. package/Models/DatabaseModels/ServiceLevelObjective.ts +1115 -0
  15. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  16. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  17. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.ts +30 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  25. package/Server/Services/AnalyticsDatabaseService.ts +25 -9
  26. package/Server/Services/Index.ts +24 -0
  27. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  28. package/Server/Services/MetricService.ts +21 -2
  29. package/Server/Services/MonitorService.ts +22 -0
  30. package/Server/Services/NetworkDeviceService.ts +438 -2
  31. package/Server/Services/NetworkEndpointService.ts +414 -0
  32. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  33. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  34. package/Server/Services/NetworkSiteService.ts +1254 -0
  35. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  36. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  37. package/Server/Services/ProjectService.ts +122 -2
  38. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  39. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  40. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  41. package/Server/Services/ServiceLevelObjectiveService.ts +685 -0
  42. package/Server/Services/SloHistoryService.ts +101 -0
  43. package/Server/Services/UserNotificationSettingService.ts +37 -0
  44. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  45. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  46. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  47. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
  48. package/Server/Utils/Memory.ts +9 -1
  49. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  50. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  51. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  52. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  53. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  54. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  55. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  56. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  57. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  58. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  59. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  60. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  61. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  62. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  63. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  64. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  65. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  66. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  67. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  68. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  69. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  70. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  72. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
  73. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  74. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  75. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  76. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  77. package/Tests/Server/Utils/Memory.test.ts +213 -0
  78. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  79. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  80. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  81. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  82. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  83. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  84. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  85. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  86. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  87. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  88. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  89. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  90. package/Tests/Server/Utils/Stream.test.ts +87 -0
  91. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  92. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  93. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  94. package/Tests/Types/Email.test.ts +198 -0
  95. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  96. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  97. package/Tests/Types/Monitor/MonitorCriteria.test.ts +155 -0
  98. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +465 -0
  99. package/Tests/Types/Monitor/MonitorStep.test.ts +183 -0
  100. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  101. package/Tests/Types/Monitor/MonitorSteps.test.ts +183 -0
  102. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  103. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  104. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  105. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  106. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  107. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  108. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  109. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  110. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  111. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  112. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  113. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  114. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  115. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  116. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  117. package/Tests/Utils/Base64.test.ts +51 -0
  118. package/Tests/Utils/Boolean.test.ts +76 -0
  119. package/Tests/Utils/Crypto.test.ts +48 -0
  120. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  121. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  122. package/Tests/Utils/Enum.test.ts +54 -0
  123. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  124. package/Tests/Utils/Memory.test.ts +44 -0
  125. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  126. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  127. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  128. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  129. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  130. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  131. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  132. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  133. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  134. package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +124 -0
  135. package/Tests/Utils/Slo/SloDuration.test.ts +148 -0
  136. package/Tests/Utils/Slo/SloHealth.test.ts +334 -0
  137. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  138. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  139. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  140. package/Tests/Utils/TechStack.test.ts +50 -0
  141. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  142. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  143. package/Types/BaseDatabase/EqualTo.ts +9 -1
  144. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  145. package/Types/BaseDatabase/NotEqual.ts +9 -1
  146. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  147. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  148. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  149. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  150. package/Types/Email/EmailTemplateType.ts +2 -0
  151. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  152. package/Types/Monitor/CriteriaFilter.ts +9 -0
  153. package/Types/Monitor/MonitorStep.ts +5 -8
  154. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  155. package/Types/Monitor/MonitorType.ts +15 -5
  156. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  157. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  158. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  159. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  160. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  161. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  162. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  163. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  164. package/Types/Permission.ts +449 -0
  165. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  166. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  167. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  168. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  169. package/Types/Telemetry/ServiceType.ts +1 -0
  170. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  171. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  172. package/UI/Components/List/List.tsx +8 -0
  173. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  174. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  175. package/UI/Components/Navbar/NavBar.tsx +16 -2
  176. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  177. package/UI/Utils/Navigation.ts +10 -0
  178. package/UI/Utils/TableFilterUrlState.ts +204 -17
  179. package/UI/Utils/TableViewUrlState.ts +165 -0
  180. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  181. package/Utils/Dashboard/Components/Index.ts +7 -0
  182. package/Utils/IpCanonicalUtil.ts +134 -0
  183. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  184. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  185. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  186. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  187. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  188. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  189. package/Utils/Slo/SloBurnRateRuleState.ts +91 -0
  190. package/Utils/Slo/SloDuration.ts +165 -0
  191. package/Utils/Slo/SloEvaluation.ts +22 -0
  192. package/Utils/Slo/SloHealth.ts +302 -0
  193. package/Utils/Slo/SloStatusColor.ts +54 -0
  194. package/Utils/Slo/SloUtil.ts +637 -0
  195. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  196. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  197. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  198. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  199. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  200. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  201. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  202. package/build/dist/Models/AnalyticsModels/SloHistory.js +218 -0
  203. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  204. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  205. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  207. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  209. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  211. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  212. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  213. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  214. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  215. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  216. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  217. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  218. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  219. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  220. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  221. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  222. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1134 -0
  223. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  224. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  225. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  226. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  227. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  228. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  229. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js +21 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js.map +1 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  244. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
  245. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  246. package/build/dist/Server/Services/Index.js +24 -0
  247. package/build/dist/Server/Services/Index.js.map +1 -1
  248. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  249. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  250. package/build/dist/Server/Services/MetricService.js +21 -3
  251. package/build/dist/Server/Services/MetricService.js.map +1 -1
  252. package/build/dist/Server/Services/MonitorService.js +19 -0
  253. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  254. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  255. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  256. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  257. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  258. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  259. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  260. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  261. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  262. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  263. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  264. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  265. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  266. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  267. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  268. package/build/dist/Server/Services/ProjectService.js +98 -2
  269. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  270. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  271. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  272. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  273. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  274. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  275. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  276. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +588 -0
  277. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  278. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  279. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  280. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  281. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  282. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  283. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  284. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  285. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  286. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  287. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  288. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
  289. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  290. package/build/dist/Server/Utils/Memory.js +9 -1
  291. package/build/dist/Server/Utils/Memory.js.map +1 -1
  292. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  293. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  294. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  295. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  296. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  297. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  298. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  299. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  300. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  301. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  302. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  303. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  304. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  305. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  306. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  307. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  308. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  309. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  310. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  311. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  312. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  313. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  314. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  315. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  316. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  317. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  318. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  319. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  320. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  321. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  322. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  323. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  324. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  325. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  326. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  327. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  328. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  329. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  330. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  331. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  332. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  333. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  334. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  335. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  336. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  337. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  338. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  339. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  340. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  341. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  342. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  343. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  344. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  345. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  346. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  347. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  348. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  349. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  350. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  351. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  352. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  353. package/build/dist/Types/Permission.js +409 -0
  354. package/build/dist/Types/Permission.js.map +1 -1
  355. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  356. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  357. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  358. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  359. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  360. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  361. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  362. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  363. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  364. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  365. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  366. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  367. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  368. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  369. package/build/dist/UI/Components/List/List.js +1 -1
  370. package/build/dist/UI/Components/List/List.js.map +1 -1
  371. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  372. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  373. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  374. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  375. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  376. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  377. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  378. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  379. package/build/dist/UI/Utils/Navigation.js +9 -0
  380. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  381. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  382. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  383. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  384. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  385. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  386. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  387. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  388. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  389. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  390. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  391. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  392. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  393. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  394. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  395. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  396. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  397. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  398. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  399. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  400. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  401. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  402. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  403. package/build/dist/Utils/Slo/SloBurnRateRuleState.js +35 -0
  404. package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -0
  405. package/build/dist/Utils/Slo/SloDuration.js +87 -0
  406. package/build/dist/Utils/Slo/SloDuration.js.map +1 -0
  407. package/build/dist/Utils/Slo/SloEvaluation.js +21 -0
  408. package/build/dist/Utils/Slo/SloEvaluation.js.map +1 -0
  409. package/build/dist/Utils/Slo/SloHealth.js +179 -0
  410. package/build/dist/Utils/Slo/SloHealth.js.map +1 -0
  411. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  412. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  413. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  414. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  415. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  416. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  417. package/package.json +2 -2
  418. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  419. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  420. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -0,0 +1,370 @@
1
+ import StackTraceParser, {
2
+ ParsedStackTrace,
3
+ StackFrame,
4
+ } from "../../../Server/Utils/Telemetry/StackTraceParser";
5
+ import { describe, expect, test } from "@jest/globals";
6
+
7
+ /*
8
+ * StackTraceParser auto-detects the language of a raw stack trace by running
9
+ * every language parser and keeping whichever produces the most frames. These
10
+ * tests lock down:
11
+ *
12
+ * 1. Each language parser recognizes its canonical format.
13
+ * 2. The inApp classification (user code vs library/framework code) matches
14
+ * the LIBRARY_PATTERNS heuristics — this drives which frames get
15
+ * highlighted in the UI, so a regression here silently mislabels frames.
16
+ * 3. The auto-detect "most frames wins" tie-break picks the right parser
17
+ * when a trace could be partially matched by more than one parser.
18
+ */
19
+
20
+ describe("StackTraceParser.parse - guard clauses", () => {
21
+ test("returns empty frames for empty string", () => {
22
+ const result: ParsedStackTrace = StackTraceParser.parse("");
23
+ expect(result.frames).toEqual([]);
24
+ expect(result.raw).toBe("");
25
+ });
26
+
27
+ test("returns empty frames for whitespace-only string", () => {
28
+ const result: ParsedStackTrace = StackTraceParser.parse(" \n \t \n ");
29
+ expect(result.frames).toEqual([]);
30
+ });
31
+
32
+ test("preserves the raw string unchanged", () => {
33
+ const raw: string = "at foo (/app/index.js:1:1)";
34
+ const result: ParsedStackTrace = StackTraceParser.parse(raw);
35
+ expect(result.raw).toBe(raw);
36
+ });
37
+
38
+ test("handles null/undefined gracefully via falsy guard", () => {
39
+ // parse() guards with `!rawStackTrace` before using it.
40
+ const result: ParsedStackTrace = StackTraceParser.parse(
41
+ undefined as unknown as string,
42
+ );
43
+ expect(result.frames).toEqual([]);
44
+ expect(result.raw).toBe("");
45
+ });
46
+
47
+ test("returns empty frames for unparseable garbage", () => {
48
+ const result: ParsedStackTrace = StackTraceParser.parse(
49
+ "this is not a stack trace at all\njust some random text",
50
+ );
51
+ expect(result.frames).toEqual([]);
52
+ });
53
+ });
54
+
55
+ describe("StackTraceParser.parse - JavaScript/Node.js", () => {
56
+ test("parses `at functionName (file:line:col)`", () => {
57
+ const trace: string = [
58
+ "Error: boom",
59
+ " at doWork (/app/src/worker.js:42:15)",
60
+ " at main (/app/src/index.js:10:3)",
61
+ ].join("\n");
62
+
63
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
64
+
65
+ expect(result.frames).toHaveLength(2);
66
+ expect(result.frames[0]).toEqual({
67
+ functionName: "doWork",
68
+ fileName: "/app/src/worker.js",
69
+ lineNumber: 42,
70
+ columnNumber: 15,
71
+ inApp: true,
72
+ });
73
+ expect(result.frames[1]!.functionName).toBe("main");
74
+ expect(result.frames[1]!.lineNumber).toBe(10);
75
+ });
76
+
77
+ test("parses anonymous `at file:line:col` frames", () => {
78
+ const trace: string = " at /app/src/index.js:10:3";
79
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
80
+
81
+ expect(result.frames).toHaveLength(1);
82
+ expect(result.frames[0]).toEqual({
83
+ functionName: "<anonymous>",
84
+ fileName: "/app/src/index.js",
85
+ lineNumber: 10,
86
+ columnNumber: 3,
87
+ inApp: true,
88
+ });
89
+ });
90
+
91
+ test("parses `at functionName (file:line)` without a column", () => {
92
+ const trace: string = " at render (/app/component.js:7)";
93
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
94
+
95
+ expect(result.frames).toHaveLength(1);
96
+ expect(result.frames[0]!.lineNumber).toBe(7);
97
+ expect(result.frames[0]!.columnNumber).toBeUndefined();
98
+ expect(result.frames[0]!.functionName).toBe("render");
99
+ });
100
+
101
+ test("parses eval frames", () => {
102
+ const trace: string =
103
+ " at eval (eval at compile (/app/vm.js:5:10), <anonymous>:1:1)";
104
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
105
+
106
+ expect(result.frames).toHaveLength(1);
107
+ expect(result.frames[0]!.functionName).toBe("eval at compile");
108
+ expect(result.frames[0]!.fileName).toBe("/app/vm.js");
109
+ expect(result.frames[0]!.lineNumber).toBe(5);
110
+ expect(result.frames[0]!.columnNumber).toBe(10);
111
+ });
112
+
113
+ test("marks node_modules and node: internals as not inApp", () => {
114
+ const trace: string = [
115
+ " at userCode (/app/src/handler.js:1:1)",
116
+ " at libCode (/app/node_modules/express/lib/router.js:2:2)",
117
+ " at process (node:internal/process/task_queues:3:3)",
118
+ ].join("\n");
119
+
120
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
121
+
122
+ expect(result.frames).toHaveLength(3);
123
+ expect(result.frames[0]!.inApp).toBe(true);
124
+ expect(result.frames[1]!.inApp).toBe(false);
125
+ expect(result.frames[2]!.inApp).toBe(false);
126
+ });
127
+ });
128
+
129
+ describe("StackTraceParser.parse - Python", () => {
130
+ test('parses `File "path", line N, in function`', () => {
131
+ const trace: string = [
132
+ "Traceback (most recent call last):",
133
+ ' File "/app/main.py", line 22, in run',
134
+ " do_thing()",
135
+ ' File "/app/service.py", line 5, in do_thing',
136
+ " raise ValueError()",
137
+ ].join("\n");
138
+
139
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
140
+
141
+ expect(result.frames).toHaveLength(2);
142
+ expect(result.frames[0]).toEqual({
143
+ functionName: "run",
144
+ fileName: "/app/main.py",
145
+ lineNumber: 22,
146
+ inApp: true,
147
+ });
148
+ expect(result.frames[1]!.functionName).toBe("do_thing");
149
+ });
150
+
151
+ test("uses <module> when the `in function` suffix is absent", () => {
152
+ const trace: string = ' File "/app/main.py", line 1';
153
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
154
+
155
+ expect(result.frames).toHaveLength(1);
156
+ expect(result.frames[0]!.functionName).toBe("<module>");
157
+ });
158
+
159
+ test("marks site-packages as not inApp", () => {
160
+ const trace: string = [
161
+ ' File "/app/main.py", line 1, in run',
162
+ ' File "/usr/lib/python3.11/site-packages/requests/api.py", line 9, in get',
163
+ ].join("\n");
164
+
165
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
166
+
167
+ expect(result.frames).toHaveLength(2);
168
+ expect(result.frames[0]!.inApp).toBe(true);
169
+ expect(result.frames[1]!.inApp).toBe(false);
170
+ });
171
+ });
172
+
173
+ describe("StackTraceParser.parse - Java", () => {
174
+ test("parses `at package.Class.method(File.java:line)`", () => {
175
+ const trace: string = [
176
+ "java.lang.NullPointerException",
177
+ " at com.example.Service.process(Service.java:42)",
178
+ " at com.example.Main.main(Main.java:10)",
179
+ ].join("\n");
180
+
181
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
182
+
183
+ expect(result.frames).toHaveLength(2);
184
+ expect(result.frames[0]!.functionName).toBe("com.example.Service.process");
185
+ expect(result.frames[0]!.fileName).toBe("Service.java");
186
+ expect(result.frames[0]!.lineNumber).toBe(42);
187
+ });
188
+
189
+ test("parses native and unknown-source frames", () => {
190
+ const trace: string = [
191
+ " at com.example.Service.process(Service.java:42)",
192
+ " at sun.reflect.NativeMethod.invoke(Native Method)",
193
+ " at com.example.App.run(Unknown Source)",
194
+ ].join("\n");
195
+
196
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
197
+
198
+ expect(result.frames).toHaveLength(3);
199
+ expect(result.frames[1]!.fileName).toBe("Native Method");
200
+ expect(result.frames[1]!.lineNumber).toBe(0);
201
+ expect(result.frames[1]!.inApp).toBe(false);
202
+ expect(result.frames[2]!.fileName).toBe("Unknown Source");
203
+ expect(result.frames[2]!.lineNumber).toBe(0);
204
+ });
205
+
206
+ test("marks java.* / org.springframework.* as not inApp", () => {
207
+ const trace: string = [
208
+ " at com.example.Service.process(Service.java:42)",
209
+ " at org.springframework.web.Dispatcher.doDispatch(Dispatcher.java:1)",
210
+ ].join("\n");
211
+
212
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
213
+
214
+ expect(result.frames[0]!.inApp).toBe(true);
215
+ expect(result.frames[1]!.inApp).toBe(false);
216
+ });
217
+ });
218
+
219
+ describe("StackTraceParser.parse - Go", () => {
220
+ test("pairs the function line with the following file:line", () => {
221
+ const trace: string = [
222
+ "goroutine 1 [running]:",
223
+ "main.doWork(0x1, 0x2)",
224
+ "\t/app/main.go:25 +0x1a",
225
+ "main.main()",
226
+ "\t/app/main.go:10 +0x2b",
227
+ ].join("\n");
228
+
229
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
230
+
231
+ expect(result.frames).toHaveLength(2);
232
+ expect(result.frames[0]!.functionName).toBe("main.doWork");
233
+ expect(result.frames[0]!.fileName).toBe("/app/main.go");
234
+ expect(result.frames[0]!.lineNumber).toBe(25);
235
+ expect(result.frames[1]!.functionName).toBe("main.main");
236
+ });
237
+
238
+ test("marks vendor / pkg/mod paths as not inApp", () => {
239
+ const trace: string = [
240
+ "main.doWork()",
241
+ "\t/app/main.go:25 +0x1a",
242
+ "github.com/lib/pq.Query()",
243
+ "\t/app/vendor/github.com/lib/pq/conn.go:5 +0x3c",
244
+ ].join("\n");
245
+
246
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
247
+
248
+ expect(result.frames).toHaveLength(2);
249
+ expect(result.frames[0]!.inApp).toBe(true);
250
+ expect(result.frames[1]!.inApp).toBe(false);
251
+ });
252
+ });
253
+
254
+ describe("StackTraceParser.parse - Ruby", () => {
255
+ test("parses `file:line:in 'method'`", () => {
256
+ const trace: string = [
257
+ "/app/service.rb:12:in `process'",
258
+ "/app/main.rb:3:in `<main>'",
259
+ ].join("\n");
260
+
261
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
262
+
263
+ expect(result.frames).toHaveLength(2);
264
+ expect(result.frames[0]!.functionName).toBe("process");
265
+ expect(result.frames[0]!.fileName).toBe("/app/service.rb");
266
+ expect(result.frames[0]!.lineNumber).toBe(12);
267
+ expect(result.frames[1]!.functionName).toBe("<main>");
268
+ });
269
+
270
+ test("marks gems paths as not inApp", () => {
271
+ const trace: string = [
272
+ "/app/service.rb:12:in `process'",
273
+ "/usr/local/gems/activerecord/lib/query.rb:8:in `execute'",
274
+ ].join("\n");
275
+
276
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
277
+
278
+ expect(result.frames[0]!.inApp).toBe(true);
279
+ expect(result.frames[1]!.inApp).toBe(false);
280
+ });
281
+ });
282
+
283
+ describe("StackTraceParser.parse - C#/.NET", () => {
284
+ test("parses `at Namespace.Class.Method(params) in file:line N`", () => {
285
+ const trace: string = [
286
+ "System.NullReferenceException: boom",
287
+ " at MyApp.Service.Process(String id) in /app/Service.cs:line 42",
288
+ " at MyApp.Program.Main() in /app/Program.cs:line 10",
289
+ ].join("\n");
290
+
291
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
292
+
293
+ expect(result.frames).toHaveLength(2);
294
+ expect(result.frames[0]!.functionName).toBe(
295
+ "MyApp.Service.Process(String id)",
296
+ );
297
+ expect(result.frames[0]!.fileName).toBe("/app/Service.cs");
298
+ expect(result.frames[0]!.lineNumber).toBe(42);
299
+ });
300
+
301
+ test("parses frames without file info", () => {
302
+ const trace: string = [
303
+ " at MyApp.Service.Process(String id) in /app/Service.cs:line 42",
304
+ " at MyApp.Internal.Helper.Run()",
305
+ ].join("\n");
306
+
307
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
308
+
309
+ expect(result.frames).toHaveLength(2);
310
+ expect(result.frames[1]!.fileName).toBe("");
311
+ expect(result.frames[1]!.lineNumber).toBe(0);
312
+ expect(result.frames[1]!.functionName).toBe("MyApp.Internal.Helper.Run()");
313
+ });
314
+ });
315
+
316
+ describe("StackTraceParser.parse - PHP", () => {
317
+ test("parses `#N /path/file.php(line): Class->method()`", () => {
318
+ const trace: string = [
319
+ "#0 /app/service.php(42): Service->process()",
320
+ "#1 /app/index.php(10): Service->run()",
321
+ "#2 {main}",
322
+ ].join("\n");
323
+
324
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
325
+
326
+ expect(result.frames).toHaveLength(3);
327
+ expect(result.frames[0]!.functionName).toBe("Service->process");
328
+ expect(result.frames[0]!.fileName).toBe("/app/service.php");
329
+ expect(result.frames[0]!.lineNumber).toBe(42);
330
+ expect(result.frames[2]!.functionName).toBe("{main}");
331
+ expect(result.frames[2]!.inApp).toBe(true);
332
+ });
333
+
334
+ test("strips trailing () from method names", () => {
335
+ const trace: string = "#0 /app/service.php(42): MyClass->doThing()";
336
+ const result: ParsedStackTrace = StackTraceParser.parse(trace);
337
+
338
+ expect(result.frames[0]!.functionName).toBe("MyClass->doThing");
339
+ });
340
+ });
341
+
342
+ describe("StackTraceParser.parse - auto-detection", () => {
343
+ test("picks the parser that yields the most frames", () => {
344
+ /*
345
+ * A pure Python trace should be attributed entirely to the Python parser,
346
+ * not partially matched by another language.
347
+ */
348
+ const python: string = [
349
+ ' File "/app/a.py", line 1, in a',
350
+ ' File "/app/b.py", line 2, in b',
351
+ ' File "/app/c.py", line 3, in c',
352
+ ].join("\n");
353
+
354
+ const result: ParsedStackTrace = StackTraceParser.parse(python);
355
+ expect(result.frames).toHaveLength(3);
356
+ expect(
357
+ result.frames.every((f: StackFrame) => {
358
+ return f.fileName.endsWith(".py");
359
+ }),
360
+ ).toBe(true);
361
+ });
362
+
363
+ test("a single JS frame beats zero frames from other parsers", () => {
364
+ const result: ParsedStackTrace = StackTraceParser.parse(
365
+ " at solo (/app/only.js:1:1)",
366
+ );
367
+ expect(result.frames).toHaveLength(1);
368
+ expect(result.frames[0]!.fileName).toBe("/app/only.js");
369
+ });
370
+ });
@@ -0,0 +1,87 @@
1
+ import StreamUtil from "../../../Server/Utils/Stream";
2
+ import { PassThrough, Readable } from "stream";
3
+
4
+ describe("StreamUtil", () => {
5
+ describe("convertStreamToText", () => {
6
+ test("should concatenate chunks in order", async () => {
7
+ const stream: Readable = Readable.from(["hello ", "world"]);
8
+
9
+ expect(await StreamUtil.convertStreamToText(stream)).toEqual(
10
+ "hello world",
11
+ );
12
+ });
13
+
14
+ test("should return an empty string for an empty stream", async () => {
15
+ expect(await StreamUtil.convertStreamToText(Readable.from([]))).toEqual(
16
+ "",
17
+ );
18
+ });
19
+
20
+ test("should handle buffer chunks", async () => {
21
+ const stream: Readable = Readable.from([
22
+ Buffer.from("abc"),
23
+ Buffer.from("def"),
24
+ ]);
25
+
26
+ expect(await StreamUtil.convertStreamToText(stream)).toEqual("abcdef");
27
+ });
28
+
29
+ test("should decode multi-byte characters split across chunks", async () => {
30
+ /*
31
+ * Chunks are collected as buffers and only decoded once at the end, so a
32
+ * character whose bytes straddle a chunk boundary must still come out
33
+ * intact.
34
+ */
35
+ const euro: Buffer = Buffer.from("€", "utf8");
36
+ const stream: Readable = Readable.from([
37
+ euro.subarray(0, 1),
38
+ euro.subarray(1),
39
+ ]);
40
+
41
+ expect(await StreamUtil.convertStreamToText(stream)).toEqual("€");
42
+ });
43
+
44
+ test("should reject when the stream errors", async () => {
45
+ const stream: PassThrough = new PassThrough();
46
+
47
+ const result: Promise<string> = StreamUtil.convertStreamToText(stream);
48
+
49
+ stream.emit("error", new Error("stream blew up"));
50
+
51
+ await expect(result).rejects.toThrow("stream blew up");
52
+ });
53
+ });
54
+
55
+ describe("toStringArray", () => {
56
+ test("should split the stream on newlines", async () => {
57
+ const stream: Readable = Readable.from(["first\nsecond\nthird"]);
58
+
59
+ expect(await StreamUtil.toStringArray(stream)).toEqual([
60
+ "first",
61
+ "second",
62
+ "third",
63
+ ]);
64
+ });
65
+
66
+ test("should keep the trailing empty entry from a trailing newline", async () => {
67
+ // split() on a trailing separator yields a final empty string.
68
+ expect(await StreamUtil.toStringArray(Readable.from(["a\n"]))).toEqual([
69
+ "a",
70
+ "",
71
+ ]);
72
+ });
73
+
74
+ test("should return a single empty entry for an empty stream", async () => {
75
+ expect(await StreamUtil.toStringArray(Readable.from([]))).toEqual([""]);
76
+ });
77
+
78
+ test("should not split lines that span chunk boundaries", async () => {
79
+ const stream: Readable = Readable.from(["fir", "st\nsec", "ond"]);
80
+
81
+ expect(await StreamUtil.toStringArray(stream)).toEqual([
82
+ "first",
83
+ "second",
84
+ ]);
85
+ });
86
+ });
87
+ });
@@ -0,0 +1,221 @@
1
+ import BadDataException from "../../../Types/Exception/BadDataException";
2
+ import ObjectID from "../../../Types/ObjectID";
3
+ import Project from "../../../Models/DatabaseModels/Project";
4
+ import Team from "../../../Models/DatabaseModels/Team";
5
+
6
+ /*
7
+ * TeamService reaches Postgres, so it is replaced with a fake whose only job
8
+ * is to answer "which teams exist and which project does each belong to".
9
+ * The mock must be declared before the module under test is imported.
10
+ */
11
+ const findByMock: jest.Mock = jest.fn();
12
+
13
+ jest.mock("../../../Server/Services/TeamService", () => {
14
+ return {
15
+ __esModule: true,
16
+ default: {
17
+ findBy: (...args: Array<unknown>) => {
18
+ return findByMock(...args);
19
+ },
20
+ },
21
+ };
22
+ });
23
+
24
+ import validateGlobalProviderProjectTeams, {
25
+ resolveAttachmentProjectId,
26
+ } from "../../../Server/Utils/ValidateGlobalProviderProjectTeams";
27
+
28
+ type MakeTeamFunction = (data: { id: string; projectId?: string }) => Team;
29
+
30
+ const makeTeam: MakeTeamFunction = (data: {
31
+ id: string;
32
+ projectId?: string;
33
+ }): Team => {
34
+ const team: Team = new Team();
35
+ team.id = new ObjectID(data.id);
36
+
37
+ if (data.projectId) {
38
+ team.projectId = new ObjectID(data.projectId);
39
+ }
40
+
41
+ return team;
42
+ };
43
+
44
+ describe("resolveAttachmentProjectId", () => {
45
+ const projectId: ObjectID = ObjectID.generate();
46
+
47
+ test("should prefer an explicit projectId", () => {
48
+ const other: Project = new Project();
49
+ other.id = ObjectID.generate();
50
+
51
+ expect(
52
+ resolveAttachmentProjectId({ projectId, project: other })?.toString(),
53
+ ).toEqual(projectId.toString());
54
+ });
55
+
56
+ test("should fall back to the project relation's id", () => {
57
+ const project: Project = new Project();
58
+ project.id = projectId;
59
+
60
+ expect(resolveAttachmentProjectId({ project })?.toString()).toEqual(
61
+ projectId.toString(),
62
+ );
63
+ });
64
+
65
+ test("should fall back to a bare _id on the project relation", () => {
66
+ /*
67
+ * The Admin Dashboard entity dropdown submits the related Project as a
68
+ * plain object carrying only `_id`, which is the shape this branch exists
69
+ * for.
70
+ */
71
+ const project: Project = {
72
+ _id: projectId.toString(),
73
+ } as unknown as Project;
74
+
75
+ expect(resolveAttachmentProjectId({ project })?.toString()).toEqual(
76
+ projectId.toString(),
77
+ );
78
+ });
79
+
80
+ test("should return undefined when neither is present", () => {
81
+ expect(resolveAttachmentProjectId({})).toBeUndefined();
82
+ expect(
83
+ resolveAttachmentProjectId({ project: new Project() }),
84
+ ).toBeUndefined();
85
+ });
86
+ });
87
+
88
+ describe("validateGlobalProviderProjectTeams", () => {
89
+ const projectId: ObjectID = ObjectID.generate();
90
+ const otherProjectId: ObjectID = ObjectID.generate();
91
+
92
+ beforeEach(() => {
93
+ findByMock.mockReset();
94
+ });
95
+
96
+ test("should do nothing when no teams are selected", async () => {
97
+ await expect(
98
+ validateGlobalProviderProjectTeams({ teams: undefined, projectId }),
99
+ ).resolves.toBeUndefined();
100
+
101
+ await expect(
102
+ validateGlobalProviderProjectTeams({ teams: [], projectId }),
103
+ ).resolves.toBeUndefined();
104
+
105
+ // No teams means no reason to hit the database at all.
106
+ expect(findByMock).not.toHaveBeenCalled();
107
+ });
108
+
109
+ test("should reject teams selected without a project", async () => {
110
+ const team: Team = makeTeam({ id: ObjectID.generate().toString() });
111
+
112
+ await expect(
113
+ validateGlobalProviderProjectTeams({
114
+ teams: [team],
115
+ projectId: undefined,
116
+ }),
117
+ ).rejects.toThrow(BadDataException);
118
+
119
+ expect(findByMock).not.toHaveBeenCalled();
120
+ });
121
+
122
+ test("should pass when every team belongs to the target project", async () => {
123
+ const first: string = ObjectID.generate().toString();
124
+ const second: string = ObjectID.generate().toString();
125
+
126
+ findByMock.mockResolvedValue([
127
+ makeTeam({ id: first, projectId: projectId.toString() }),
128
+ makeTeam({ id: second, projectId: projectId.toString() }),
129
+ ]);
130
+
131
+ await expect(
132
+ validateGlobalProviderProjectTeams({
133
+ teams: [makeTeam({ id: first }), makeTeam({ id: second })],
134
+ projectId,
135
+ }),
136
+ ).resolves.toBeUndefined();
137
+
138
+ expect(findByMock).toHaveBeenCalledTimes(1);
139
+ });
140
+
141
+ test("should reject a team that belongs to a different project", async () => {
142
+ /*
143
+ * This is the guard's whole reason to exist: the SSO login fan-out
144
+ * provisions a TeamMember with the attachment's projectId and the team's
145
+ * id, and runs with ignoreHooks, so a cross-project team here would
146
+ * produce a corrupt membership row that nothing else would catch.
147
+ */
148
+ const mine: string = ObjectID.generate().toString();
149
+ const theirs: string = ObjectID.generate().toString();
150
+
151
+ findByMock.mockResolvedValue([
152
+ makeTeam({ id: mine, projectId: projectId.toString() }),
153
+ makeTeam({ id: theirs, projectId: otherProjectId.toString() }),
154
+ ]);
155
+
156
+ await expect(
157
+ validateGlobalProviderProjectTeams({
158
+ teams: [makeTeam({ id: mine }), makeTeam({ id: theirs })],
159
+ projectId,
160
+ }),
161
+ ).rejects.toThrow(
162
+ "All selected teams must belong to the project this provider is attached to.",
163
+ );
164
+ });
165
+
166
+ test("should reject when a selected team does not exist", async () => {
167
+ const present: string = ObjectID.generate().toString();
168
+ const missing: string = ObjectID.generate().toString();
169
+
170
+ findByMock.mockResolvedValue([
171
+ makeTeam({ id: present, projectId: projectId.toString() }),
172
+ ]);
173
+
174
+ await expect(
175
+ validateGlobalProviderProjectTeams({
176
+ teams: [makeTeam({ id: present }), makeTeam({ id: missing })],
177
+ projectId,
178
+ }),
179
+ ).rejects.toThrow("One or more selected teams could not be found.");
180
+ });
181
+
182
+ test("should reject a team with no project at all", async () => {
183
+ const teamId: string = ObjectID.generate().toString();
184
+
185
+ findByMock.mockResolvedValue([makeTeam({ id: teamId })]);
186
+
187
+ await expect(
188
+ validateGlobalProviderProjectTeams({
189
+ teams: [makeTeam({ id: teamId })],
190
+ projectId,
191
+ }),
192
+ ).rejects.toThrow(BadDataException);
193
+ });
194
+
195
+ test("should accept teams submitted as bare _id objects", async () => {
196
+ const teamId: string = ObjectID.generate().toString();
197
+
198
+ findByMock.mockResolvedValue([
199
+ makeTeam({ id: teamId, projectId: projectId.toString() }),
200
+ ]);
201
+
202
+ await expect(
203
+ validateGlobalProviderProjectTeams({
204
+ teams: [{ _id: teamId } as unknown as Team],
205
+ projectId,
206
+ }),
207
+ ).resolves.toBeUndefined();
208
+ });
209
+
210
+ test("should skip the lookup when no team carries an id", async () => {
211
+ // Nothing identifiable to validate, so there is nothing to query for.
212
+ await expect(
213
+ validateGlobalProviderProjectTeams({
214
+ teams: [new Team()],
215
+ projectId,
216
+ }),
217
+ ).resolves.toBeUndefined();
218
+
219
+ expect(findByMock).not.toHaveBeenCalled();
220
+ });
221
+ });