@oneuptime/common 12.0.12 → 12.0.14

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 (596) hide show
  1. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
  2. package/Models/DatabaseModels/NetworkDevice.ts +64 -0
  3. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  4. package/Models/DatabaseModels/StatusPage.ts +59 -0
  5. package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
  6. package/Models/DatabaseModels/UserCall.ts +94 -3
  7. package/Models/DatabaseModels/UserEmail.ts +94 -3
  8. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  9. package/Models/DatabaseModels/UserPush.ts +37 -0
  10. package/Models/DatabaseModels/UserSMS.ts +94 -3
  11. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  12. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
  13. package/Server/API/AIChatAPI.ts +55 -56
  14. package/Server/API/BaseAPI.ts +79 -14
  15. package/Server/API/CommonAPI.ts +89 -0
  16. package/Server/API/MicrosoftTeamsAPI.ts +20 -9
  17. package/Server/API/SlackAPI.ts +13 -10
  18. package/Server/API/StatusPageAPI.ts +2197 -2128
  19. package/Server/API/TelemetryAPI.ts +72 -3
  20. package/Server/API/UserCallAPI.ts +53 -45
  21. package/Server/API/UserEmailAPI.ts +53 -44
  22. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  23. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  24. package/Server/API/UserPushAPI.ts +126 -2
  25. package/Server/API/UserSmsAPI.ts +53 -44
  26. package/Server/API/UserWhatsAppAPI.ts +53 -50
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  33. package/Server/Middleware/UserAuthorization.ts +11 -2
  34. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  35. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  36. package/Server/Services/ApiKeyPermissionService.ts +116 -2
  37. package/Server/Services/DatabaseService.ts +118 -6
  38. package/Server/Services/LogAggregationService.ts +39 -0
  39. package/Server/Services/LogService.ts +21 -0
  40. package/Server/Services/NetworkSiteService.ts +12 -0
  41. package/Server/Services/PushNotificationService.ts +127 -12
  42. package/Server/Services/SpanService.ts +21 -0
  43. package/Server/Services/TeamMemberService.ts +53 -13
  44. package/Server/Services/TraceAggregationService.ts +15 -0
  45. package/Server/Services/UserCallService.ts +55 -24
  46. package/Server/Services/UserEmailService.ts +83 -17
  47. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  48. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  49. package/Server/Services/UserNotificationRuleService.ts +26 -0
  50. package/Server/Services/UserPushService.ts +89 -0
  51. package/Server/Services/UserSmsService.ts +50 -17
  52. package/Server/Services/UserWhatsAppService.ts +48 -15
  53. package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
  54. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
  55. package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
  56. package/Server/Types/Database/QueryHelper.ts +30 -0
  57. package/Server/Utils/APIKey/AccessPermission.ts +16 -40
  58. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  59. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
  60. package/Server/Utils/ChannelVerification.ts +510 -0
  61. package/Server/Utils/LogRedaction.ts +576 -0
  62. package/Server/Utils/Logger.ts +123 -46
  63. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  64. package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
  65. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  66. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  67. package/Server/Utils/Monitor/MonitorResource.ts +29 -9
  68. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  69. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  70. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
  71. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  72. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  73. package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
  74. package/Server/Utils/StartServer.ts +30 -9
  75. package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
  76. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
  77. package/Server/Utils/TotpAuth.ts +137 -9
  78. package/Server/Utils/UserRegistrationToken.ts +182 -0
  79. package/Server/Utils/VerificationCode.ts +134 -0
  80. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
  81. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  82. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  83. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  84. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  85. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  86. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +328 -0
  87. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
  88. package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
  89. package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
  90. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  91. package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
  92. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
  93. package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
  94. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  95. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
  96. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
  97. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  98. package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
  99. package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
  100. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  101. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  102. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  103. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  104. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  105. package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
  106. package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
  107. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  108. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
  109. package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
  110. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  111. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +280 -0
  112. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  113. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  114. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
  115. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  116. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  117. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  118. package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
  119. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  120. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  121. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  122. package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
  123. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  124. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  125. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  126. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  127. package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
  128. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  129. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  130. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  131. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  132. package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
  133. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  134. package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
  135. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  136. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  137. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  138. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  139. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  140. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
  141. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
  142. package/Tests/Server/Utils/Browser.test.ts +162 -0
  143. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  144. package/Tests/Server/Utils/Express.test.ts +371 -0
  145. package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
  146. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
  147. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  148. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  149. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  150. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  151. package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
  152. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  153. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  154. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  155. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  156. package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
  157. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  158. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  159. package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
  160. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
  161. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  162. package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
  163. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  164. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
  165. package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
  166. package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
  167. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  168. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
  169. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  170. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  171. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  172. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
  173. package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
  174. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
  175. package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
  176. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  177. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  178. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  179. package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
  180. package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
  181. package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
  182. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  183. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  184. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  185. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  186. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  187. package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
  188. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
  189. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  190. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  191. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  192. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  193. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  194. package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
  195. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
  196. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  197. package/Tests/UI/Components/Button.test.tsx +175 -1
  198. package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
  199. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  200. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  201. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  202. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  203. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  204. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  205. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  206. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  207. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  208. package/Tests/UI/Components/List.test.tsx +9 -2
  209. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  210. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  211. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  212. package/Tests/UI/Components/MasterPage.test.tsx +36 -1
  213. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  214. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  215. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  216. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  217. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  218. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  219. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  220. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  221. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  222. package/Tests/UI/Components/Toast.test.tsx +130 -7
  223. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  224. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  225. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  226. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  227. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  228. package/Tests/Utils/API.test.ts +16 -2
  229. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  230. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  231. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  232. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
  233. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
  234. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
  235. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
  236. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  237. package/Types/API/Hostname.ts +79 -0
  238. package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
  239. package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
  240. package/Types/Database/DatabaseProperty.ts +38 -0
  241. package/Types/Database/TableColumn.ts +34 -7
  242. package/Types/Email/EmailTemplateType.ts +1 -0
  243. package/Types/Events/Recurring.ts +16 -1
  244. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  245. package/Types/Monitor/MonitorStep.ts +13 -1
  246. package/Types/Monitor/MonitorType.ts +345 -40
  247. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  248. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  249. package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
  250. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  251. package/Types/Permission.ts +35 -0
  252. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  253. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  254. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  255. package/Types/Service/ServiceLanguage.ts +144 -0
  256. package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
  257. package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
  258. package/Types/Text.ts +111 -19
  259. package/UI/Components/Button/Button.tsx +27 -14
  260. package/UI/Components/CardSelect/CardSelect.tsx +714 -105
  261. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  262. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  263. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  264. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  265. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  266. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  267. package/UI/Components/CommandPalette/Types.ts +49 -0
  268. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  269. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  270. package/UI/Components/EmptyState/EmptyState.tsx +8 -1
  271. package/UI/Components/Feed/FeedItem.tsx +1 -1
  272. package/UI/Components/Footer/Footer.tsx +32 -6
  273. package/UI/Components/Forms/Fields/FormField.tsx +3 -0
  274. package/UI/Components/Forms/Types/Field.ts +8 -0
  275. package/UI/Components/List/List.tsx +37 -5
  276. package/UI/Components/List/ListSkeleton.tsx +54 -0
  277. package/UI/Components/Loader/PageLoader.tsx +29 -8
  278. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
  279. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +23 -2
  280. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  281. package/UI/Components/MasterPage/MasterPage.tsx +24 -11
  282. package/UI/Components/Modal/Modal.tsx +2 -2
  283. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  284. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  285. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  286. package/UI/Components/Navbar/NavBar.tsx +14 -1
  287. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  288. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  289. package/UI/Components/SideOver/SideOver.tsx +37 -2
  290. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  291. package/UI/Components/Table/Table.tsx +74 -44
  292. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  293. package/UI/Components/Tabs/Tab.tsx +1 -1
  294. package/UI/Components/Toast/Toast.tsx +118 -53
  295. package/UI/Components/Toast/ToastInit.tsx +82 -32
  296. package/UI/Styles/Theme.css +40 -0
  297. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  298. package/UI/Utils/ModelListCache.ts +188 -0
  299. package/UI/Utils/Project.ts +29 -0
  300. package/Utils/API.ts +6 -1
  301. package/Utils/Monitor/MonitorMetricType.ts +16 -1
  302. package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
  303. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
  304. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
  305. package/Utils/Telemetry/CrossSignalScope.ts +75 -4
  306. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
  307. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
  309. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  311. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
  313. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
  315. package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
  316. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  317. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  318. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  319. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  320. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  321. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  322. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  323. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  324. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  325. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  326. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  327. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  328. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  329. package/build/dist/Server/API/AIChatAPI.js +48 -35
  330. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  331. package/build/dist/Server/API/BaseAPI.js +69 -13
  332. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  333. package/build/dist/Server/API/CommonAPI.js +59 -0
  334. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  335. package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
  336. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  337. package/build/dist/Server/API/SlackAPI.js +13 -10
  338. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  339. package/build/dist/Server/API/StatusPageAPI.js +745 -673
  340. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  341. package/build/dist/Server/API/TelemetryAPI.js +34 -3
  342. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  343. package/build/dist/Server/API/UserCallAPI.js +42 -38
  344. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  345. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  346. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  347. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  348. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  349. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  350. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  351. package/build/dist/Server/API/UserPushAPI.js +95 -2
  352. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  353. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  354. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  355. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  356. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  357. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  358. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  359. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  360. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  361. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
  362. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
  363. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
  364. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
  365. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  366. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  367. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  368. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  369. package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
  370. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  371. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  372. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  373. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  374. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  375. package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
  376. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  377. package/build/dist/Server/Services/DatabaseService.js +89 -6
  378. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  379. package/build/dist/Server/Services/LogAggregationService.js +7 -0
  380. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  381. package/build/dist/Server/Services/LogService.js +16 -0
  382. package/build/dist/Server/Services/LogService.js.map +1 -1
  383. package/build/dist/Server/Services/NetworkSiteService.js +12 -0
  384. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  385. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  386. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  387. package/build/dist/Server/Services/SpanService.js +16 -0
  388. package/build/dist/Server/Services/SpanService.js.map +1 -1
  389. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  390. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  391. package/build/dist/Server/Services/TraceAggregationService.js +2 -0
  392. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  393. package/build/dist/Server/Services/UserCallService.js +54 -22
  394. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  395. package/build/dist/Server/Services/UserEmailService.js +78 -17
  396. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  397. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  398. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  399. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  400. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  401. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  402. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  403. package/build/dist/Server/Services/UserPushService.js +77 -0
  404. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  405. package/build/dist/Server/Services/UserSmsService.js +50 -17
  406. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  407. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  408. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  409. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
  410. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  411. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
  412. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  413. package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
  414. package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
  415. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  416. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  417. package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
  418. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  419. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  420. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  421. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
  422. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  423. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  424. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  425. package/build/dist/Server/Utils/LogRedaction.js +449 -0
  426. package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
  427. package/build/dist/Server/Utils/Logger.js +98 -45
  428. package/build/dist/Server/Utils/Logger.js.map +1 -1
  429. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  430. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  431. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
  432. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
  433. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  434. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  435. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  436. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  437. package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
  438. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  439. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  440. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  441. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  442. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  443. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
  444. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  445. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  446. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  447. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  448. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
  449. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
  450. package/build/dist/Server/Utils/StartServer.js +10 -7
  451. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  452. package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
  453. package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
  454. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
  455. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
  456. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  457. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  458. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  459. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  460. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  461. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  462. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
  463. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  464. package/build/dist/Types/API/Hostname.js +63 -0
  465. package/build/dist/Types/API/Hostname.js.map +1 -1
  466. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
  467. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
  468. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
  469. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
  470. package/build/dist/Types/Database/DatabaseProperty.js +38 -0
  471. package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
  472. package/build/dist/Types/Database/TableColumn.js +24 -6
  473. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  474. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  475. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  476. package/build/dist/Types/Events/Recurring.js +13 -1
  477. package/build/dist/Types/Events/Recurring.js.map +1 -1
  478. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  479. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  480. package/build/dist/Types/Monitor/MonitorStep.js +9 -1
  481. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  482. package/build/dist/Types/Monitor/MonitorType.js +330 -31
  483. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  484. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  485. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  486. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  487. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  488. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  489. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  490. package/build/dist/Types/Permission.js +33 -0
  491. package/build/dist/Types/Permission.js.map +1 -1
  492. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  493. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  494. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  495. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  496. package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
  497. package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
  498. package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
  499. package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
  500. package/build/dist/Types/Text.js +82 -17
  501. package/build/dist/Types/Text.js.map +1 -1
  502. package/build/dist/UI/Components/Button/Button.js +22 -14
  503. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  504. package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
  505. package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
  506. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  507. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  508. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  509. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  510. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  511. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  512. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  513. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  514. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  515. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  516. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  517. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  518. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  519. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  520. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  521. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  522. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  523. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  524. package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
  525. package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
  526. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  527. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  528. package/build/dist/UI/Components/Footer/Footer.js +7 -4
  529. package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
  530. package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
  531. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  532. package/build/dist/UI/Components/List/List.js +19 -5
  533. package/build/dist/UI/Components/List/List.js.map +1 -1
  534. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  535. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  536. package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
  537. package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
  538. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
  539. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  540. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
  541. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  542. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  543. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  544. package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
  545. package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
  546. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  547. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  548. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  549. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  550. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  551. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  552. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  553. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  554. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  555. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  556. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  557. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  558. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  559. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  560. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  561. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  562. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  563. package/build/dist/UI/Components/Table/Table.js +35 -24
  564. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  565. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  566. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  567. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  568. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  569. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  570. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  571. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  572. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  573. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  574. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  575. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  576. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  577. package/build/dist/UI/Utils/Project.js +24 -1
  578. package/build/dist/UI/Utils/Project.js.map +1 -1
  579. package/build/dist/Utils/API.js +6 -1
  580. package/build/dist/Utils/API.js.map +1 -1
  581. package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
  582. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  583. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
  584. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  585. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
  586. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
  587. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
  588. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  589. package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
  590. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  591. package/jest.config.json +1 -1
  592. package/package.json +2 -3
  593. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  594. package/Tests/__mocks__/otpauth.js +0 -30
  595. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  596. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -0,0 +1,226 @@
1
+ import DefaultDashboardSize, {
2
+ GetDashboardComponentWidthInDashboardUnits,
3
+ SpaceBetweenUnitsInPx,
4
+ } from "../../../Types/Dashboard/DashboardSize";
5
+ import { describe, expect, test } from "@jest/globals";
6
+
7
+ /*
8
+ * GetDashboardComponentWidthInDashboardUnits converts a pixel width into a
9
+ * count of dashboard grid units. The internal math is:
10
+ *
11
+ * eachUnitSizeInPx = currentTotalDashboardWidthInPx / widthInDashboardUnits
12
+ * units = Math.ceil(componentWidthInPx / eachUnitSizeInPx)
13
+ * return units < 1 ? 1 : units
14
+ *
15
+ * where widthInDashboardUnits comes from DefaultDashboardSize. The tests below
16
+ * pin down the ceiling rounding, the floor-to-1 clamp, the absence of any
17
+ * upper clamp, and the degenerate divide-by-zero behaviour.
18
+ */
19
+
20
+ describe("GetDashboardComponentWidthInDashboardUnits", () => {
21
+ /*
22
+ * The whole module is calibrated around a 12-unit-wide grid. If that default
23
+ * ever changes, the hand-computed expectations below would silently drift, so
24
+ * assert the assumption explicitly and fail loudly here instead.
25
+ */
26
+ const GRID_UNITS: number = DefaultDashboardSize.widthInDashboardUnits;
27
+
28
+ test("assumes the default grid is 12 units wide", () => {
29
+ expect(GRID_UNITS).toBe(12);
30
+ });
31
+
32
+ describe("basic conversion", () => {
33
+ test("returns 1 when the component spans exactly one unit", () => {
34
+ /*
35
+ * total 1200px over 12 units => 100px per unit. A 100px component is
36
+ * exactly one unit and must round to 1 (not 2).
37
+ */
38
+ const units: number = GetDashboardComponentWidthInDashboardUnits(
39
+ 1200,
40
+ 100,
41
+ );
42
+ expect(units).toBe(1);
43
+ });
44
+
45
+ test("returns 2 when the component spans exactly two units", () => {
46
+ const units: number = GetDashboardComponentWidthInDashboardUnits(
47
+ 1200,
48
+ 200,
49
+ );
50
+ expect(units).toBe(2);
51
+ });
52
+
53
+ test("returns the full grid width when the component fills the dashboard", () => {
54
+ const units: number = GetDashboardComponentWidthInDashboardUnits(
55
+ 1200,
56
+ 1200,
57
+ );
58
+ expect(units).toBe(GRID_UNITS);
59
+ });
60
+
61
+ test("scales the unit size with the total dashboard width", () => {
62
+ /*
63
+ * total 600px over 12 units => 50px per unit. A 50px component is one
64
+ * unit and a 150px component is three units. The unit size is derived
65
+ * from the total width, so a different total yields a different mapping.
66
+ */
67
+ expect(GetDashboardComponentWidthInDashboardUnits(600, 50)).toBe(1);
68
+ expect(GetDashboardComponentWidthInDashboardUnits(600, 150)).toBe(3);
69
+ });
70
+ });
71
+
72
+ describe("ceiling / round-up behaviour", () => {
73
+ test("rounds a partial unit up to the next whole unit", () => {
74
+ /*
75
+ * 100px per unit. 150px is 1.5 units and must round up to 2. 250px is
76
+ * 2.5 units and must round up to 3.
77
+ */
78
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 150)).toBe(2);
79
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 250)).toBe(3);
80
+ });
81
+
82
+ test("rounds up even a single pixel over a unit boundary", () => {
83
+ /*
84
+ * 101px is 1.01 units; the ceiling makes it consume 2 whole units so the
85
+ * component is never visually clipped.
86
+ */
87
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 101)).toBe(2);
88
+ });
89
+
90
+ test("does not round up when the width lands exactly on a boundary", () => {
91
+ /*
92
+ * ceil(2.0) is 2, not 3. Exact multiples of the unit size stay put.
93
+ */
94
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 200)).toBe(2);
95
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 300)).toBe(3);
96
+ });
97
+
98
+ test("rounds a sub-unit width up to a single unit", () => {
99
+ /*
100
+ * 50px is half a unit; ceil(0.5) is 1, so a component narrower than one
101
+ * unit still occupies a whole unit.
102
+ */
103
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 50)).toBe(1);
104
+ });
105
+ });
106
+
107
+ describe("floor-to-1 clamp", () => {
108
+ test("returns 1 for a zero-width component", () => {
109
+ /*
110
+ * ceil(0) is 0, which is below the minimum, so the clamp forces 1. A
111
+ * component always occupies at least one grid unit.
112
+ */
113
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 0)).toBe(1);
114
+ });
115
+
116
+ test("returns 1 for a negative component width", () => {
117
+ /*
118
+ * ceil(-0.5) is -0, which is below the minimum and clamps to 1 rather
119
+ * than returning a negative or zero unit count.
120
+ */
121
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, -50)).toBe(1);
122
+ });
123
+
124
+ test("returns 1 when the total dashboard width is negative", () => {
125
+ /*
126
+ * A negative total flips the sign of the unit size, so a positive
127
+ * component yields a negative raw unit count that clamps to 1.
128
+ */
129
+ expect(GetDashboardComponentWidthInDashboardUnits(-1200, 100)).toBe(1);
130
+ });
131
+ });
132
+
133
+ describe("no upper clamp", () => {
134
+ test("returns more than the grid width when the component overflows the dashboard", () => {
135
+ /*
136
+ * A 2400px component on a 1200px dashboard is 24 units. The function does
137
+ * not cap the result at the 12-unit grid width.
138
+ */
139
+ const units: number = GetDashboardComponentWidthInDashboardUnits(
140
+ 1200,
141
+ 2400,
142
+ );
143
+ expect(units).toBe(24);
144
+ expect(units).toBeGreaterThan(GRID_UNITS);
145
+ });
146
+ });
147
+
148
+ describe("degenerate totals (divide by zero)", () => {
149
+ test("returns Infinity when the total is zero but the component is positive", () => {
150
+ /*
151
+ * A zero total makes the per-unit size zero, so a positive component
152
+ * divides by zero to Infinity. ceil(Infinity) is Infinity, which is above
153
+ * the minimum and is returned as-is rather than clamped.
154
+ */
155
+ const units: number = GetDashboardComponentWidthInDashboardUnits(0, 100);
156
+ expect(units).toBe(Infinity);
157
+ expect(Number.isFinite(units)).toBe(false);
158
+ });
159
+
160
+ test("returns NaN when both the total and the component are zero", () => {
161
+ /*
162
+ * 0 / 0 is NaN, ceil(NaN) is NaN, and NaN < 1 is false, so NaN passes the
163
+ * clamp untouched.
164
+ */
165
+ const units: number = GetDashboardComponentWidthInDashboardUnits(0, 0);
166
+ expect(Number.isNaN(units)).toBe(true);
167
+ });
168
+ });
169
+
170
+ describe("independence from inter-unit spacing", () => {
171
+ test("ignores SpaceBetweenUnitsInPx when computing the unit count", () => {
172
+ /*
173
+ * Unlike GetWidthOfDashboardComponent, this function divides the raw total
174
+ * width by the unit count and never subtracts SpaceBetweenUnitsInPx. Prove
175
+ * that by showing the result depends only on total and component width: a
176
+ * 100px component on a 1200px dashboard is exactly one unit regardless of
177
+ * the spacing constant's value.
178
+ */
179
+ expect(SpaceBetweenUnitsInPx).toBeGreaterThan(0);
180
+ expect(GetDashboardComponentWidthInDashboardUnits(1200, 100)).toBe(1);
181
+ });
182
+ });
183
+
184
+ describe("monotonicity", () => {
185
+ test("never decreases as the component width grows", () => {
186
+ /*
187
+ * For a fixed dashboard width, a wider component can only ever require the
188
+ * same number of units or more. Sweep a range of widths and assert the
189
+ * unit count is non-decreasing.
190
+ */
191
+ const total: number = 1200;
192
+ let previous: number = GetDashboardComponentWidthInDashboardUnits(
193
+ total,
194
+ 0,
195
+ );
196
+
197
+ for (
198
+ let componentWidth: number = 0;
199
+ componentWidth <= 2400;
200
+ componentWidth += 37
201
+ ) {
202
+ const current: number = GetDashboardComponentWidthInDashboardUnits(
203
+ total,
204
+ componentWidth,
205
+ );
206
+ expect(current).toBeGreaterThanOrEqual(previous);
207
+ previous = current;
208
+ }
209
+ });
210
+ });
211
+
212
+ describe("output shape", () => {
213
+ test("always returns a whole number for finite positive inputs", () => {
214
+ const widths: Array<number> = [1, 49, 50, 99, 100, 101, 599, 1200, 5000];
215
+
216
+ for (const componentWidth of widths) {
217
+ const units: number = GetDashboardComponentWidthInDashboardUnits(
218
+ 1200,
219
+ componentWidth,
220
+ );
221
+ expect(Number.isInteger(units)).toBe(true);
222
+ expect(units).toBeGreaterThanOrEqual(1);
223
+ }
224
+ });
225
+ });
226
+ });
@@ -0,0 +1,344 @@
1
+ import DatabaseBaseModel from "../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
2
+ import Incident from "../../../../Models/DatabaseModels/Incident";
3
+ import Monitor from "../../../../Models/DatabaseModels/Monitor";
4
+ import Project from "../../../../Models/DatabaseModels/Project";
5
+ import StatusPage from "../../../../Models/DatabaseModels/StatusPage";
6
+ import { ColumnAccessControl } from "../../../../Types/BaseDatabase/AccessControl";
7
+ import ColumnBillingAccessControl from "../../../../Types/BaseDatabase/ColumnBillingAccessControl";
8
+ import { getColumnAccessControlForAllColumns } from "../../../../Types/Database/AccessControl/ColumnAccessControl";
9
+ import { getColumnBillingAccessControlForAllColumns } from "../../../../Types/Database/AccessControl/ColumnBillingAccessControl";
10
+ import Dictionary from "../../../../Types/Dictionary";
11
+ import "reflect-metadata";
12
+
13
+ type ModelCtor = new () => DatabaseBaseModel;
14
+
15
+ const MODELS: Array<[string, ModelCtor]> = [
16
+ ["Monitor", Monitor],
17
+ ["Incident", Incident],
18
+ ["Project", Project],
19
+ ];
20
+
21
+ // Monitor and Incident have no billing-decorated columns; StatusPage does.
22
+ const BILLING_MODELS: Array<[string, ModelCtor]> = [["StatusPage", StatusPage]];
23
+
24
+ const DEFAULT_COLUMNS: Array<string> = [
25
+ "_id",
26
+ "createdAt",
27
+ "deletedAt",
28
+ "updatedAt",
29
+ ];
30
+
31
+ /*
32
+ * Locate the module-private metadata symbol (e.g. Symbol(ColumnAccessControl))
33
+ * by scanning the metadata keys of every instance property, so the tests can
34
+ * rebuild the dictionary from scratch exactly the way the pre-cache
35
+ * implementation did — without importing any private state.
36
+ */
37
+ function findMetadataSymbol(
38
+ model: DatabaseBaseModel,
39
+ symbolName: string,
40
+ ): symbol | null {
41
+ for (const key of Object.keys(model)) {
42
+ const metadataKeys: Array<unknown> = Reflect.getMetadataKeys(
43
+ model,
44
+ key,
45
+ ) as Array<unknown>;
46
+ for (const metadataKey of metadataKeys) {
47
+ if (
48
+ typeof metadataKey === "symbol" &&
49
+ metadataKey.toString() === `Symbol(${symbolName})`
50
+ ) {
51
+ return metadataKey;
52
+ }
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ // The exact algorithm both helpers used before caching was introduced.
59
+ function rebuildFromReflect<T>(
60
+ model: DatabaseBaseModel,
61
+ symbolName: string,
62
+ ): Dictionary<T> {
63
+ const metadataSymbol: symbol | null = findMetadataSymbol(model, symbolName);
64
+ const dictionary: Dictionary<T> = {};
65
+
66
+ if (!metadataSymbol) {
67
+ return dictionary;
68
+ }
69
+
70
+ for (const key of Object.keys(model)) {
71
+ const metadata: T | undefined = Reflect.getMetadata(
72
+ metadataSymbol,
73
+ model,
74
+ key,
75
+ ) as T | undefined;
76
+ if (metadata) {
77
+ dictionary[key] = metadata;
78
+ }
79
+ }
80
+
81
+ return dictionary;
82
+ }
83
+
84
+ function rebuildAccessControl(
85
+ model: DatabaseBaseModel,
86
+ ): Dictionary<ColumnAccessControl> {
87
+ return rebuildFromReflect<ColumnAccessControl>(model, "ColumnAccessControl");
88
+ }
89
+
90
+ function rebuildBillingAccessControl(
91
+ model: DatabaseBaseModel,
92
+ ): Dictionary<ColumnBillingAccessControl> {
93
+ return rebuildFromReflect<ColumnBillingAccessControl>(
94
+ model,
95
+ "ColumnBillingAccessControl",
96
+ );
97
+ }
98
+
99
+ describe("getColumnAccessControlForAllColumns helper caching", () => {
100
+ for (const [name, ModelClass] of MODELS) {
101
+ test(`matches a from-scratch Reflect rebuild for ${name} — keys, order, and value identity`, () => {
102
+ const model: DatabaseBaseModel = new ModelClass();
103
+ const expected: Dictionary<ColumnAccessControl> =
104
+ rebuildAccessControl(model);
105
+ const actual: Dictionary<ColumnAccessControl> =
106
+ getColumnAccessControlForAllColumns(model);
107
+
108
+ // Sanity: real models have plenty of decorated columns.
109
+ expect(Object.keys(expected).length).toBeGreaterThan(5);
110
+
111
+ expect(Object.keys(actual)).toEqual(Object.keys(expected));
112
+ for (const key of Object.keys(expected)) {
113
+ expect(actual[key]).toBe(expected[key]);
114
+ }
115
+ });
116
+ }
117
+
118
+ test("repeated calls return the same dictionary object", () => {
119
+ const monitor: Monitor = new Monitor();
120
+ const first: Dictionary<ColumnAccessControl> =
121
+ getColumnAccessControlForAllColumns(monitor);
122
+ const second: Dictionary<ColumnAccessControl> =
123
+ getColumnAccessControlForAllColumns(monitor);
124
+
125
+ expect(second).toBe(first);
126
+ });
127
+
128
+ test("different instances of the same class share the cached dictionary", () => {
129
+ const first: Dictionary<ColumnAccessControl> =
130
+ getColumnAccessControlForAllColumns(new Monitor());
131
+ const second: Dictionary<ColumnAccessControl> =
132
+ getColumnAccessControlForAllColumns(new Monitor());
133
+
134
+ expect(second).toBe(first);
135
+ });
136
+
137
+ test("second call performs zero Reflect metadata reads", () => {
138
+ const incident: Incident = new Incident();
139
+ getColumnAccessControlForAllColumns(incident); // warm the cache
140
+
141
+ const spy: jest.SpyInstance = jest.spyOn(Reflect, "getMetadata");
142
+ try {
143
+ getColumnAccessControlForAllColumns(incident);
144
+ expect(spy).not.toHaveBeenCalled();
145
+ } finally {
146
+ spy.mockRestore();
147
+ }
148
+ });
149
+
150
+ test("different classes get distinct dictionaries", () => {
151
+ const monitorAccessControl: Dictionary<ColumnAccessControl> =
152
+ getColumnAccessControlForAllColumns(new Monitor());
153
+ const incidentAccessControl: Dictionary<ColumnAccessControl> =
154
+ getColumnAccessControlForAllColumns(new Incident());
155
+ const projectAccessControl: Dictionary<ColumnAccessControl> =
156
+ getColumnAccessControlForAllColumns(new Project());
157
+
158
+ expect(monitorAccessControl).not.toBe(incidentAccessControl);
159
+ expect(monitorAccessControl).not.toBe(projectAccessControl);
160
+ expect(incidentAccessControl).not.toBe(projectAccessControl);
161
+
162
+ expect(monitorAccessControl["monitorType"]).toBeDefined();
163
+ expect(incidentAccessControl["monitorType"]).toBeUndefined();
164
+ });
165
+ });
166
+
167
+ describe("DatabaseBaseModel.getColumnAccessControlForAllColumns override", () => {
168
+ test("adds default columns with record-level permissions, exactly as before", () => {
169
+ const monitor: Monitor = new Monitor();
170
+ const raw: Dictionary<ColumnAccessControl> = rebuildAccessControl(monitor);
171
+ const merged: Dictionary<ColumnAccessControl> =
172
+ monitor.getColumnAccessControlForAllColumns();
173
+
174
+ for (const key of DEFAULT_COLUMNS) {
175
+ expect(merged[key]).toEqual({
176
+ read: monitor.readRecordPermissions,
177
+ create: monitor.createRecordPermissions,
178
+ update: monitor.updateRecordPermissions,
179
+ });
180
+ }
181
+
182
+ // Decorated columns flow through as the exact same Reflect singletons.
183
+ for (const key of Object.keys(raw)) {
184
+ if (!DEFAULT_COLUMNS.includes(key)) {
185
+ expect(merged[key]).toBe(raw[key]);
186
+ }
187
+ }
188
+
189
+ expect(Object.keys(merged).sort()).toEqual(
190
+ [...Object.keys(raw), ...DEFAULT_COLUMNS].sort(),
191
+ );
192
+ });
193
+
194
+ test("never pollutes the raw helper dictionary with default columns", () => {
195
+ const monitor: Monitor = new Monitor();
196
+
197
+ const rawKeysBefore: Array<string> = Object.keys(
198
+ getColumnAccessControlForAllColumns(monitor),
199
+ );
200
+ for (const key of DEFAULT_COLUMNS) {
201
+ expect(rawKeysBefore).not.toContain(key);
202
+ }
203
+
204
+ monitor.getColumnAccessControlForAllColumns();
205
+ monitor.getColumnAccessControlForAllColumns();
206
+
207
+ /*
208
+ * AuditLogService.getRedactedFields consumes the raw helper result and
209
+ * must never see the record-level defaults the model override adds.
210
+ */
211
+ const rawAfter: Dictionary<ColumnAccessControl> =
212
+ getColumnAccessControlForAllColumns(new Monitor());
213
+ expect(Object.keys(rawAfter)).toEqual(rawKeysBefore);
214
+ for (const key of DEFAULT_COLUMNS) {
215
+ expect(rawAfter[key]).toBeUndefined();
216
+ }
217
+ });
218
+
219
+ test("mutating one override result does not affect the next call", () => {
220
+ const monitor: Monitor = new Monitor();
221
+
222
+ const first: Dictionary<ColumnAccessControl> =
223
+ monitor.getColumnAccessControlForAllColumns();
224
+ const originalName: ColumnAccessControl = first[
225
+ "name"
226
+ ] as ColumnAccessControl;
227
+ expect(originalName).toBeDefined();
228
+
229
+ delete first["name"];
230
+ first["_id"] = { read: [], create: [], update: [] };
231
+ first["injected"] = { read: [], create: [], update: [] };
232
+
233
+ const second: Dictionary<ColumnAccessControl> =
234
+ monitor.getColumnAccessControlForAllColumns();
235
+
236
+ expect(second).not.toBe(first);
237
+ expect(second["name"]).toBe(originalName);
238
+ expect(second["injected"]).toBeUndefined();
239
+ expect(second["_id"]).toEqual({
240
+ read: monitor.readRecordPermissions,
241
+ create: monitor.createRecordPermissions,
242
+ update: monitor.updateRecordPermissions,
243
+ });
244
+ });
245
+
246
+ test("getColumnAccessControlFor still resolves decorated, default, and unknown columns", () => {
247
+ const monitor: Monitor = new Monitor();
248
+ const raw: Dictionary<ColumnAccessControl> = rebuildAccessControl(monitor);
249
+
250
+ expect(monitor.getColumnAccessControlFor("name")).toBe(raw["name"]);
251
+ expect(monitor.getColumnAccessControlFor("_id")).toEqual({
252
+ read: monitor.readRecordPermissions,
253
+ create: monitor.createRecordPermissions,
254
+ update: monitor.updateRecordPermissions,
255
+ });
256
+ expect(monitor.getColumnAccessControlFor("doesNotExist")).toBeNull();
257
+ });
258
+ });
259
+
260
+ describe("getColumnBillingAccessControlForAllColumns helper caching", () => {
261
+ for (const [name, ModelClass] of [...MODELS, ...BILLING_MODELS]) {
262
+ test(`matches a from-scratch Reflect rebuild for ${name} — keys, order, and value identity`, () => {
263
+ const model: DatabaseBaseModel = new ModelClass();
264
+ const expected: Dictionary<ColumnBillingAccessControl> =
265
+ rebuildBillingAccessControl(model);
266
+ const actual: Dictionary<ColumnBillingAccessControl> =
267
+ getColumnBillingAccessControlForAllColumns(model);
268
+
269
+ expect(Object.keys(actual)).toEqual(Object.keys(expected));
270
+ for (const key of Object.keys(expected)) {
271
+ expect(actual[key]).toBe(expected[key]);
272
+ }
273
+ });
274
+ }
275
+
276
+ test("Project and StatusPage carry billing-decorated columns; Monitor's dictionary is empty", () => {
277
+ expect(
278
+ Object.keys(getColumnBillingAccessControlForAllColumns(new Project()))
279
+ .length,
280
+ ).toBeGreaterThan(0);
281
+ expect(
282
+ Object.keys(getColumnBillingAccessControlForAllColumns(new StatusPage()))
283
+ .length,
284
+ ).toBeGreaterThan(0);
285
+ expect(getColumnBillingAccessControlForAllColumns(new Monitor())).toEqual(
286
+ {},
287
+ );
288
+ });
289
+
290
+ test("repeated calls return the same dictionary object", () => {
291
+ const project: Project = new Project();
292
+ const first: Dictionary<ColumnBillingAccessControl> =
293
+ getColumnBillingAccessControlForAllColumns(project);
294
+ const second: Dictionary<ColumnBillingAccessControl> =
295
+ getColumnBillingAccessControlForAllColumns(new Project());
296
+
297
+ expect(second).toBe(first);
298
+ });
299
+
300
+ test("second call performs zero Reflect metadata reads", () => {
301
+ const project: Project = new Project();
302
+ getColumnBillingAccessControlForAllColumns(project); // warm the cache
303
+
304
+ const spy: jest.SpyInstance = jest.spyOn(Reflect, "getMetadata");
305
+ try {
306
+ getColumnBillingAccessControlForAllColumns(project);
307
+ expect(spy).not.toHaveBeenCalled();
308
+ } finally {
309
+ spy.mockRestore();
310
+ }
311
+ });
312
+
313
+ test("different classes get distinct dictionaries", () => {
314
+ const statusPageBilling: Dictionary<ColumnBillingAccessControl> =
315
+ getColumnBillingAccessControlForAllColumns(new StatusPage());
316
+ const projectBilling: Dictionary<ColumnBillingAccessControl> =
317
+ getColumnBillingAccessControlForAllColumns(new Project());
318
+
319
+ expect(statusPageBilling).not.toBe(projectBilling);
320
+ expect(Object.keys(statusPageBilling)).not.toEqual(
321
+ Object.keys(projectBilling),
322
+ );
323
+ });
324
+
325
+ test("model getColumnBillingAccessControl reads without mutating the cached dictionary", () => {
326
+ const project: Project = new Project();
327
+ const expected: Dictionary<ColumnBillingAccessControl> =
328
+ rebuildBillingAccessControl(project);
329
+ const keysBefore: Array<string> = Object.keys(
330
+ getColumnBillingAccessControlForAllColumns(project),
331
+ );
332
+
333
+ for (const key of keysBefore) {
334
+ expect(project.getColumnBillingAccessControl(key)).toBe(expected[key]);
335
+ }
336
+ expect(project.getColumnBillingAccessControl("doesNotExist")).toBe(
337
+ undefined,
338
+ );
339
+
340
+ expect(
341
+ Object.keys(getColumnBillingAccessControlForAllColumns(new Project())),
342
+ ).toEqual(keysBefore);
343
+ });
344
+ });