@oneuptime/common 14.0.6 → 14.0.8

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 (556) hide show
  1. package/Models/DatabaseModels/Incident.ts +267 -1
  2. package/Models/DatabaseModels/IncidentCustomField.ts +202 -0
  3. package/Models/DatabaseModels/IncidentEpisode.ts +30 -0
  4. package/Models/DatabaseModels/IncidentTemplate.ts +126 -1
  5. package/Models/DatabaseModels/InventoryItem.ts +23 -12
  6. package/Models/DatabaseModels/StatusPage.ts +55 -0
  7. package/Models/DatabaseModels/StatusPageSubscriber.ts +128 -0
  8. package/Server/API/IncidentAPI.ts +162 -0
  9. package/Server/API/StatusPageAPI.ts +487 -171
  10. package/Server/API/StatusPageSubscriberAPI.ts +63 -15
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.ts +217 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.ts +49 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.ts +108 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.ts +33 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.ts +51 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.ts +33 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.ts +168 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.ts +44 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
  20. package/Server/Infrastructure/Semaphore.ts +10 -0
  21. package/Server/Middleware/IdentityRateLimit.ts +108 -3
  22. package/Server/Middleware/SubscriberNotificationPreviewRateLimit.ts +237 -0
  23. package/Server/Middleware/SubscriberNotificationTestSendRateLimit.ts +304 -0
  24. package/Server/Services/AlertService.ts +32 -36
  25. package/Server/Services/DatabaseService.ts +93 -10
  26. package/Server/Services/IncidentAlertService.ts +609 -2
  27. package/Server/Services/IncidentCustomFieldService.ts +276 -1
  28. package/Server/Services/IncidentEpisodePublicNoteService.ts +28 -0
  29. package/Server/Services/IncidentEpisodeService.ts +15 -0
  30. package/Server/Services/IncidentEpisodeStateTimelineService.ts +27 -1
  31. package/Server/Services/IncidentPublicNoteService.ts +30 -1
  32. package/Server/Services/IncidentService.ts +1663 -103
  33. package/Server/Services/IncidentStateTimelineService.ts +13 -0
  34. package/Server/Services/IncidentTemplateService.ts +109 -0
  35. package/Server/Services/InventoryItemService.ts +38 -0
  36. package/Server/Services/IoTDeviceCredentialService.ts +13 -4
  37. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +30 -1
  38. package/Server/Services/ScheduledMaintenanceService.ts +118 -64
  39. package/Server/Services/SmsService.ts +10 -0
  40. package/Server/Services/StatusPageService.ts +65 -8
  41. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +299 -37
  42. package/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.ts +129 -0
  43. package/Server/Services/StatusPageSubscriberService.ts +1161 -64
  44. package/Server/Services/UserNotificationRuleService.ts +55 -53
  45. package/Server/Services/WorkspaceNotificationSummaryService.ts +38 -20
  46. package/Server/Types/Markdown.ts +153 -6
  47. package/Server/Types/Workflow/Components/Email.ts +61 -2
  48. package/Server/Utils/AffectedResources/LinkedAffectedResources.ts +576 -0
  49. package/Server/Utils/Alert/AlertStateChangeAuthorization.ts +129 -0
  50. package/Server/Utils/CustomField/CustomFieldRename.ts +378 -0
  51. package/Server/Utils/DataSource/EgressGuard.ts +66 -21
  52. package/Server/Utils/Inventory/InventoryOverviewAggregation.ts +111 -0
  53. package/Server/Utils/Mail/PinnedSmtpSocket.ts +130 -0
  54. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +10 -0
  55. package/Server/Utils/Response.ts +31 -0
  56. package/Server/Utils/SSRFProtection.ts +76 -16
  57. package/Server/Utils/StatusPage/IncidentStatusPageScope.ts +948 -0
  58. package/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.ts +656 -0
  59. package/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.ts +805 -0
  60. package/Server/Utils/StatusPage/StatusPageExclusion.ts +18 -0
  61. package/Server/Utils/StatusPage/StatusPageReadAccess.ts +125 -0
  62. package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.ts +151 -0
  63. package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.ts +70 -0
  64. package/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.ts +421 -0
  65. package/Server/Utils/StatusPage/SubscriberNotificationClaim.ts +107 -0
  66. package/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.ts +1049 -0
  67. package/Server/Utils/StatusPage/SubscriberNotificationFanOut.ts +180 -0
  68. package/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.ts +839 -0
  69. package/Server/Utils/StatusPage/SubscriberNotificationResendAccess.ts +393 -0
  70. package/Server/Utils/StatusPage/SubscriberNotificationRunLimit.ts +246 -0
  71. package/Server/Utils/StatusPage/SubscriberNotificationTiming.ts +133 -0
  72. package/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.ts +215 -0
  73. package/Server/Utils/StatusPageResource.ts +51 -20
  74. package/Server/Utils/Topology/TopologyConcurrencyLimiter.ts +229 -0
  75. package/Server/Utils/Topology/TopologyQueries.ts +1350 -0
  76. package/Server/Utils/Topology/TopologyRequest.ts +463 -0
  77. package/Server/Utils/Topology/TopologyResponseCache.ts +183 -0
  78. package/Server/Utils/Topology/TopologySql.ts +1024 -0
  79. package/Server/Utils/VM/VMAPI.ts +1 -0
  80. package/Server/Utils/VM/VMRunner.ts +10 -0
  81. package/Server/Utils/Workflow/OAuth2TokenClient.ts +10 -0
  82. package/Server/Views/Partials/SensitiveUrlToken.ejs +8 -5
  83. package/Tests/App/Accounts/RegisterVerifyEmail.test.tsx +748 -0
  84. package/Tests/App/Accounts/ResendVerificationEmail.test.tsx +1222 -0
  85. package/Tests/App/Accounts/VerificationEmailResendUtils.test.ts +797 -0
  86. package/Tests/App/Accounts/VerifyEmailPending.test.tsx +538 -0
  87. package/Tests/App/Accounts/VerifyEmailResend.test.tsx +779 -0
  88. package/Tests/App/Dashboard/AcknowledgeAlertsOnDeclare.test.ts +369 -0
  89. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +1 -1
  90. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +510 -123
  91. package/Tests/App/Dashboard/AlertsTableAffectedResources.test.tsx +490 -0
  92. package/Tests/App/Dashboard/ChangeAlertStateDeclareIncident.test.tsx +886 -0
  93. package/Tests/App/Dashboard/CreateReviewStepRoleSummary.test.tsx +1250 -0
  94. package/Tests/App/Dashboard/CreateReviewStepSelectionSummary.test.tsx +738 -0
  95. package/Tests/App/Dashboard/CustomFieldsSettingsIncidentOptions.test.tsx +357 -0
  96. package/Tests/App/Dashboard/DeclareIncidentFromAlert.test.ts +417 -0
  97. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +1948 -229
  98. package/Tests/App/Dashboard/EntityDetailPanelLifecycle.test.tsx +493 -0
  99. package/Tests/App/Dashboard/EntityDetailPanelNavigation.test.tsx +439 -0
  100. package/Tests/App/Dashboard/EventNotes.test.tsx +776 -0
  101. package/Tests/App/Dashboard/EventNotesPages.test.tsx +119 -0
  102. package/Tests/App/Dashboard/EventNotesUtil.test.ts +116 -17
  103. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +534 -6
  104. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +798 -2
  105. package/Tests/App/Dashboard/FetchStateAndSeverityElements.test.tsx +669 -0
  106. package/Tests/App/Dashboard/FetchUsers.test.tsx +230 -0
  107. package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +91 -1
  108. package/Tests/App/Dashboard/IncidentCreateAcknowledgeAlerts.test.tsx +1611 -0
  109. package/Tests/App/Dashboard/IncidentCreateDetailsStep.test.tsx +643 -0
  110. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +8 -1
  111. package/Tests/App/Dashboard/IncidentCreateStatusPageScope.test.tsx +601 -0
  112. package/Tests/App/Dashboard/IncidentCustomFieldTemplateVariables.test.tsx +386 -0
  113. package/Tests/App/Dashboard/IncidentNoteTemplatePlaceholders.test.tsx +124 -0
  114. package/Tests/App/Dashboard/IncidentNoteTemplateVariablesLoader.test.ts +305 -0
  115. package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +112 -0
  116. package/Tests/App/Dashboard/IncidentSettingsRenotifyOnPublish.test.tsx +674 -0
  117. package/Tests/App/Dashboard/IncidentSettingsStatusPageScope.test.tsx +1051 -0
  118. package/Tests/App/Dashboard/IncidentTemplateCustomFields.test.tsx +384 -0
  119. package/Tests/App/Dashboard/IncidentTemplateStatusPageScopeCard.test.tsx +215 -0
  120. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +1365 -57
  121. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +964 -23
  122. package/Tests/App/Dashboard/InventoryRelationships.test.tsx +885 -0
  123. package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +113 -1
  124. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +201 -15
  125. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +508 -36
  126. package/Tests/App/Dashboard/SubscriberAudienceSummary.test.tsx +512 -0
  127. package/Tests/App/Dashboard/SubscriberNotificationPreviewModal.test.tsx +837 -0
  128. package/Tests/App/Dashboard/SubscriberNotificationStatusLabel.test.tsx +88 -0
  129. package/Tests/App/Dashboard/SubscriberNotificationStatusResend.test.tsx +473 -0
  130. package/Tests/App/Dashboard/SubscriberTemplateLivePreview.test.tsx +196 -0
  131. package/Tests/App/Dashboard/TeamAddedSubscribersUnsubscribedNotice.test.tsx +248 -0
  132. package/Tests/App/Dashboard/TopologyDataLifecycle.test.tsx +583 -0
  133. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +982 -218
  134. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +818 -114
  135. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +64 -3
  136. package/Tests/App/StatusPage/StatusPageUnsubscribePage.test.tsx +412 -0
  137. package/Tests/Models/IncidentCustomFieldApiSchemaContract.test.ts +217 -0
  138. package/Tests/Models/IncidentCustomFieldCreateSettingsColumns.test.ts +252 -0
  139. package/Tests/Models/StatusPageSubscriberUnsubscribeColumns.test.ts +218 -0
  140. package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +7 -0
  141. package/Tests/Server/API/IncidentSubscriberAudienceAPI.test.ts +1408 -0
  142. package/Tests/Server/API/StatusPageIncidentScope.test.ts +1868 -0
  143. package/Tests/Server/API/StatusPageIncidentScopePostgres.test.ts +790 -0
  144. package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +10 -1
  145. package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +206 -18
  146. package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +14 -2
  147. package/Tests/Server/API/StatusPageSubscriberCreateResponse.test.ts +217 -0
  148. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +103 -2
  149. package/Tests/Server/API/StatusPageUnsubscribeAPI.test.ts +396 -0
  150. package/Tests/Server/Infrastructure/Postgres/AddIncidentStatusPageScopeMigration.test.ts +395 -0
  151. package/Tests/Server/Infrastructure/Postgres/AddIncidentTemplateStatusPageScopeFlagMigration.test.ts +150 -0
  152. package/Tests/Server/Infrastructure/Postgres/AddSubscriberNotificationClaimedAtMigration.test.ts +156 -0
  153. package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +90 -21
  154. package/Tests/Server/Infrastructure/Postgres/SkipHiddenIncidentCreatedNotificationsMigration.test.ts +410 -0
  155. package/Tests/Server/Middleware/IdentityRateLimit.test.ts +551 -1
  156. package/Tests/Server/Middleware/SubscriberNotificationPreviewRateLimit.test.ts +238 -0
  157. package/Tests/Server/Middleware/SubscriberNotificationTestSendRateLimit.test.ts +245 -0
  158. package/Tests/Server/Services/AddStatusPageSubscriberUnsubscribeTokenMigration.test.ts +152 -0
  159. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +221 -36
  160. package/Tests/Server/Services/DatabaseServiceCompareAndSetColumns.test.ts +191 -0
  161. package/Tests/Server/Services/DomainService.test.ts +525 -0
  162. package/Tests/Server/Services/IncidentAlertAcknowledgeOnDeclare.test.ts +2630 -0
  163. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +1625 -1
  164. package/Tests/Server/Services/IncidentCreatedRenotifyOnPublish.test.ts +681 -0
  165. package/Tests/Server/Services/IncidentCreatedResend.test.ts +775 -0
  166. package/Tests/Server/Services/IncidentCustomFieldRenamePostgres.test.ts +713 -0
  167. package/Tests/Server/Services/IncidentCustomFieldService.test.ts +751 -0
  168. package/Tests/Server/Services/IncidentCustomFieldValueValidation.test.ts +556 -0
  169. package/Tests/Server/Services/IncidentDeclareAcknowledgeAlerts.test.ts +2189 -0
  170. package/Tests/Server/Services/IncidentStatusPageScope.test.ts +2971 -0
  171. package/Tests/Server/Services/IncidentStatusPageScopeFeed.test.ts +131 -0
  172. package/Tests/Server/Services/IncidentStatusPageScopePostgres.test.ts +625 -0
  173. package/Tests/Server/Services/IncidentTemplateCustomFieldsCopy.test.ts +311 -0
  174. package/Tests/Server/Services/IncidentTemplateStatusPageScope.test.ts +363 -0
  175. package/Tests/Server/Services/InventoryItemServiceOverviewCounts.test.ts +345 -0
  176. package/Tests/Server/Services/InventoryOverviewPostgres.test.ts +254 -0
  177. package/Tests/Server/Services/IoTDeviceCredentialService.test.ts +819 -0
  178. package/Tests/Server/Services/LinkedAffectedResourcesCreatedFeed.test.ts +420 -0
  179. package/Tests/Server/Services/PublicNoteEditFeedEventType.test.ts +213 -0
  180. package/Tests/Server/Services/PublicNoteResendAccess.test.ts +994 -0
  181. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +289 -9
  182. package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +92 -36
  183. package/Tests/Server/Services/SmsServiceFailIfNotSent.test.ts +67 -0
  184. package/Tests/Server/Services/StatusPageReportIncidentCounts.test.ts +610 -0
  185. package/Tests/Server/Services/StatusPageSubscriberAudienceCounts.test.ts +201 -0
  186. package/Tests/Server/Services/StatusPageSubscriberAudienceCountsPostgres.test.ts +271 -0
  187. package/Tests/Server/Services/StatusPageSubscriberConfirmationTemplateEscaping.test.ts +200 -0
  188. package/Tests/Server/Services/StatusPageSubscriberNotificationLogRedaction.test.ts +54 -0
  189. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +37 -0
  190. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateIncidentRecordAccess.test.ts +772 -0
  191. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookup.test.ts +506 -0
  192. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookupPostgres.test.ts +261 -0
  193. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +21 -5
  194. package/Tests/Server/Services/StatusPageSubscriberUnsubscribe.test.ts +1618 -0
  195. package/Tests/Server/Services/StatusPageSubscriberUnsubscribeLinkSenders.test.ts +373 -0
  196. package/Tests/Server/Services/StatusPageSubscriberUnsubscribePostgres.test.ts +388 -0
  197. package/Tests/Server/Services/SubscriberNotificationInFlightRequeue.test.ts +500 -0
  198. package/Tests/Server/Types/MarkdownEmailLinks.test.ts +320 -0
  199. package/Tests/Server/Types/Workflow/Components/Email.test.ts +491 -1
  200. package/Tests/Server/Types/Workflow/Components/EmailSmtpPinning.test.ts +398 -0
  201. package/Tests/Server/Utils/AffectedResources/LinkedAffectedResources.test.ts +858 -0
  202. package/Tests/Server/Utils/Alert/AlertStateChangeAuthorization.test.ts +1172 -0
  203. package/Tests/Server/Utils/CustomField/CustomFieldRename.test.ts +586 -0
  204. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +246 -10
  205. package/Tests/Server/Utils/DataSource/EgressGuardDeploymentConfig.test.ts +226 -0
  206. package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +131 -0
  207. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +4 -0
  208. package/Tests/Server/Utils/EgressPolicyEnvironment.ts +45 -0
  209. package/Tests/Server/Utils/Mail/PinnedSmtpSocket.test.ts +409 -0
  210. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +23 -0
  211. package/Tests/Server/Utils/SSRFProtection.test.ts +4 -0
  212. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +4 -0
  213. package/Tests/Server/Utils/SSRFProtectionPrivateNetwork.test.ts +4 -0
  214. package/Tests/Server/Utils/SSRFProtectionResolutionDetail.test.ts +314 -0
  215. package/Tests/Server/Utils/StatusPage/IncidentStatusPageScope.test.ts +1699 -0
  216. package/Tests/Server/Utils/StatusPage/IncidentStatusPageScopeQueriesPostgres.test.ts +508 -0
  217. package/Tests/Server/Utils/StatusPage/IncidentSubscriberAudienceCallerPermission.test.ts +246 -0
  218. package/Tests/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.test.ts +1348 -0
  219. package/Tests/Server/Utils/StatusPage/StatusPageReadAccess.test.ts +221 -0
  220. package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.test.ts +132 -0
  221. package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.test.ts +155 -0
  222. package/Tests/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.test.ts +708 -0
  223. package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaim.test.ts +255 -0
  224. package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaimPostgres.test.ts +528 -0
  225. package/Tests/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.test.ts +1238 -0
  226. package/Tests/Server/Utils/StatusPage/SubscriberNotificationFanOut.test.ts +472 -0
  227. package/Tests/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.test.ts +1168 -0
  228. package/Tests/Server/Utils/StatusPage/SubscriberNotificationRunLimit.test.ts +275 -0
  229. package/Tests/Server/Utils/StatusPage/SubscriberNotificationTiming.test.ts +131 -0
  230. package/Tests/Server/Utils/StatusPageResource.test.ts +98 -0
  231. package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigration.test.ts +386 -0
  232. package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigrationPostgres.test.ts +430 -0
  233. package/Tests/Server/Utils/Topology/TopologyActivityParityPostgres.test.ts +279 -0
  234. package/Tests/Server/Utils/Topology/TopologyConcurrencyLimiter.test.ts +534 -0
  235. package/Tests/Server/Utils/Topology/TopologyEstateGenerator.ts +624 -0
  236. package/Tests/Server/Utils/Topology/TopologyJsonResponse.test.ts +90 -0
  237. package/Tests/Server/Utils/Topology/TopologyQueries.test.ts +1634 -0
  238. package/Tests/Server/Utils/Topology/TopologyQueriesDifferentialPostgres.test.ts +683 -0
  239. package/Tests/Server/Utils/Topology/TopologyQueriesPostgres.test.ts +2624 -0
  240. package/Tests/Server/Utils/Topology/TopologyReference.ts +1018 -0
  241. package/Tests/Server/Utils/Topology/TopologyRequest.test.ts +643 -0
  242. package/Tests/Server/Utils/Topology/TopologyResponseCache.test.ts +305 -0
  243. package/Tests/Server/Utils/Topology/TopologySql.test.ts +973 -0
  244. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +17 -0
  245. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +75 -0
  246. package/Tests/Types/CustomField/CustomFieldSavedViews.test.ts +247 -0
  247. package/Tests/Types/CustomField/CustomFieldTemplateValues.test.ts +186 -0
  248. package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +48 -0
  249. package/Tests/Types/CustomField/CustomFieldValueFormat.test.ts +215 -0
  250. package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +343 -0
  251. package/Tests/Types/CustomField/CustomFieldVariableKey.test.ts +364 -0
  252. package/Tests/Types/SafeHtml.test.ts +102 -0
  253. package/Tests/Types/StatusPage/IncidentCreatedRenotify.test.ts +419 -0
  254. package/Tests/Types/StatusPage/IncidentCreatedResend.test.ts +118 -0
  255. package/Tests/Types/StatusPage/IncidentScopeAddedPagesNotification.test.ts +558 -0
  256. package/Tests/Types/StatusPage/IncidentSubscriberAudience.test.ts +284 -0
  257. package/Tests/Types/StatusPage/StatusPageSubscriberUnsubscribe.test.ts +341 -0
  258. package/Tests/Types/StatusPage/SubscriberNotificationPreview.test.ts +196 -0
  259. package/Tests/Types/StatusPage/SubscriberNotificationResend.test.ts +201 -0
  260. package/Tests/Types/StatusPage/SubscriberNotificationTemplateCompiler.test.ts +277 -0
  261. package/Tests/Types/StatusPage/SubscriberNotificationTemplatePreview.test.ts +179 -0
  262. package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +324 -0
  263. package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +60 -13
  264. package/Tests/Types/Topology/TopologyTypeRules.test.ts +176 -0
  265. package/Tests/UI/Components/CustomFields/CustomFieldFormFields.test.ts +432 -0
  266. package/Tests/UI/Components/CustomFields/CustomFieldModelFormFields.test.tsx +685 -0
  267. package/Tests/UI/Components/CustomFields/CustomFieldsDetailOrder.test.tsx +469 -0
  268. package/Tests/UI/Components/Forms/ModelFormCustomFieldInputs.test.tsx +325 -0
  269. package/Tests/UI/Components/Forms/ModelFormDropdownOptionsRefused.test.tsx +358 -0
  270. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +22 -0
  271. package/Tests/UI/Monitor/NetworkPathView.test.tsx +289 -0
  272. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +302 -0
  273. package/Tests/Utils/Incident/IncidentNoteTemplateVariables.test.ts +623 -0
  274. package/Tests/Utils/Markdown/MarkdownEscape.test.ts +89 -0
  275. package/Tests/Utils/ProbeNetworkFailureUtil.test.ts +992 -0
  276. package/Tests/Utils/RequestFailedDetails.test.ts +575 -0
  277. package/Types/CustomField/CustomFieldOrder.ts +55 -0
  278. package/Types/CustomField/CustomFieldSavedViews.ts +225 -0
  279. package/Types/CustomField/CustomFieldTemplateMerge.ts +71 -0
  280. package/Types/CustomField/CustomFieldType.ts +14 -0
  281. package/Types/CustomField/CustomFieldValueFormat.ts +161 -0
  282. package/Types/CustomField/CustomFieldValueValidator.ts +488 -0
  283. package/Types/CustomField/CustomFieldVariableKey.ts +211 -0
  284. package/Types/Incident/IncidentAlertLink.ts +19 -0
  285. package/Types/SafeHtml.ts +93 -0
  286. package/Types/StatusPage/IncidentCreatedRenotify.ts +224 -0
  287. package/Types/StatusPage/IncidentCreatedResend.ts +108 -0
  288. package/Types/StatusPage/IncidentScopeAddedPagesNotification.ts +343 -0
  289. package/Types/StatusPage/IncidentSubscriberAudience.ts +332 -0
  290. package/Types/StatusPage/StatusPageSubscriberUnsubscribe.ts +405 -0
  291. package/Types/StatusPage/SubscriberNotificationInterruption.ts +32 -0
  292. package/Types/StatusPage/SubscriberNotificationPreview.ts +322 -0
  293. package/Types/StatusPage/SubscriberNotificationResend.ts +132 -0
  294. package/Types/StatusPage/SubscriberNotificationTemplateCompiler.ts +180 -0
  295. package/Types/StatusPage/SubscriberNotificationTemplatePreview.ts +301 -0
  296. package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +217 -4
  297. package/Types/StatusPage/SubscriberUpdateNotification.ts +32 -11
  298. package/Types/Telemetry/InventoryLiveness.ts +26 -0
  299. package/Types/Topology/TopologyApi.ts +428 -0
  300. package/Types/Topology/TopologyTypeRules.ts +191 -0
  301. package/UI/Components/CustomFields/CustomFieldFormFields.ts +317 -0
  302. package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +395 -0
  303. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +95 -55
  304. package/UI/Components/Forms/ModelForm.tsx +70 -8
  305. package/UI/Components/Forms/Validation.ts +1 -1
  306. package/UI/Components/ModelFormModal/ModelFormModal.tsx +2 -4
  307. package/UI/Components/ModelTable/AnalyticsModelTable.tsx +2 -6
  308. package/UI/Components/ModelTable/BaseModelTable.tsx +9 -8
  309. package/UI/Components/ModelTable/CustomFieldColumns.tsx +14 -1
  310. package/UI/Components/ModelTable/ModelTable.tsx +6 -7
  311. package/UI/Utils/SensitiveUrlToken.ts +10 -5
  312. package/Utils/API.ts +247 -2
  313. package/Utils/Incident/IncidentFromAlerts.ts +78 -0
  314. package/Utils/Incident/IncidentNoteTemplateVariables.ts +304 -0
  315. package/Utils/Markdown/MarkdownEscape.ts +65 -0
  316. package/Utils/ProbeNetworkFailureUtil.ts +673 -0
  317. package/build/dist/Models/DatabaseModels/Incident.js +267 -1
  318. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  319. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +207 -1
  320. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  321. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +31 -0
  322. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  323. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +124 -1
  324. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  325. package/build/dist/Models/DatabaseModels/InventoryItem.js +20 -11
  326. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
  327. package/build/dist/Models/DatabaseModels/StatusPage.js +56 -0
  328. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  329. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +131 -0
  330. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
  331. package/build/dist/Server/API/IncidentAPI.js +100 -1
  332. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  333. package/build/dist/Server/API/StatusPageAPI.js +417 -176
  334. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  335. package/build/dist/Server/API/StatusPageSubscriberAPI.js +52 -13
  336. package/build/dist/Server/API/StatusPageSubscriberAPI.js.map +1 -1
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js +165 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js +41 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js.map +1 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js +57 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js.map +1 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js +23 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js.map +1 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js +40 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js.map +1 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js +26 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js.map +1 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js +89 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js.map +1 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js +29 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js.map +1 -0
  353. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
  354. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  355. package/build/dist/Server/Infrastructure/Semaphore.js +3 -0
  356. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  357. package/build/dist/Server/Middleware/IdentityRateLimit.js +89 -3
  358. package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
  359. package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js +149 -0
  360. package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js.map +1 -0
  361. package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js +190 -0
  362. package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js.map +1 -0
  363. package/build/dist/Server/Services/AlertService.js +21 -33
  364. package/build/dist/Server/Services/AlertService.js.map +1 -1
  365. package/build/dist/Server/Services/DatabaseService.js +56 -7
  366. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  367. package/build/dist/Server/Services/IncidentAlertService.js +457 -3
  368. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -1
  369. package/build/dist/Server/Services/IncidentCustomFieldService.js +204 -8
  370. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  371. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
  372. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  373. package/build/dist/Server/Services/IncidentEpisodeService.js +14 -0
  374. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  375. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +26 -0
  376. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  377. package/build/dist/Server/Services/IncidentPublicNoteService.js +26 -1
  378. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  379. package/build/dist/Server/Services/IncidentService.js +1148 -42
  380. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  381. package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
  382. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  383. package/build/dist/Server/Services/IncidentTemplateService.js +83 -0
  384. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  385. package/build/dist/Server/Services/InventoryItemService.js +31 -0
  386. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  387. package/build/dist/Server/Services/IoTDeviceCredentialService.js +12 -5
  388. package/build/dist/Server/Services/IoTDeviceCredentialService.js.map +1 -1
  389. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +26 -1
  390. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  391. package/build/dist/Server/Services/ScheduledMaintenanceService.js +84 -57
  392. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  393. package/build/dist/Server/Services/SmsService.js +2 -22
  394. package/build/dist/Server/Services/SmsService.js.map +1 -1
  395. package/build/dist/Server/Services/StatusPageService.js +47 -9
  396. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  397. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +237 -32
  398. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  399. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js +109 -0
  400. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js.map +1 -1
  401. package/build/dist/Server/Services/StatusPageSubscriberService.js +925 -99
  402. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  403. package/build/dist/Server/Services/UserNotificationRuleService.js +55 -51
  404. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  405. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +42 -25
  406. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
  407. package/build/dist/Server/Types/Markdown.js +110 -6
  408. package/build/dist/Server/Types/Markdown.js.map +1 -1
  409. package/build/dist/Server/Types/Workflow/Components/Email.js +55 -6
  410. package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
  411. package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js +405 -0
  412. package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js.map +1 -0
  413. package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js +112 -0
  414. package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js.map +1 -0
  415. package/build/dist/Server/Utils/CustomField/CustomFieldRename.js +211 -0
  416. package/build/dist/Server/Utils/CustomField/CustomFieldRename.js.map +1 -0
  417. package/build/dist/Server/Utils/DataSource/EgressGuard.js +41 -12
  418. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  419. package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js +81 -0
  420. package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js.map +1 -0
  421. package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js +101 -0
  422. package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js.map +1 -0
  423. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
  424. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  425. package/build/dist/Server/Utils/Response.js +30 -0
  426. package/build/dist/Server/Utils/Response.js.map +1 -1
  427. package/build/dist/Server/Utils/SSRFProtection.js +48 -6
  428. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  429. package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js +631 -0
  430. package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js.map +1 -0
  431. package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js +403 -0
  432. package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js.map +1 -0
  433. package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js +451 -0
  434. package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js.map +1 -0
  435. package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js +13 -0
  436. package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js.map +1 -0
  437. package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js +91 -0
  438. package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js.map +1 -0
  439. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js +101 -0
  440. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js.map +1 -0
  441. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js +47 -0
  442. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js.map +1 -0
  443. package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js +273 -0
  444. package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js.map +1 -0
  445. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js +73 -0
  446. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js.map +1 -0
  447. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js +722 -0
  448. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js.map +1 -0
  449. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js +102 -0
  450. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js.map +1 -0
  451. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js +527 -0
  452. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js.map +1 -0
  453. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js +278 -0
  454. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js.map +1 -0
  455. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js +137 -0
  456. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js.map +1 -0
  457. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js +103 -0
  458. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js.map +1 -0
  459. package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js +114 -0
  460. package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js.map +1 -0
  461. package/build/dist/Server/Utils/StatusPageResource.js +39 -7
  462. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
  463. package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js +178 -0
  464. package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js.map +1 -0
  465. package/build/dist/Server/Utils/Topology/TopologyQueries.js +884 -0
  466. package/build/dist/Server/Utils/Topology/TopologyQueries.js.map +1 -0
  467. package/build/dist/Server/Utils/Topology/TopologyRequest.js +275 -0
  468. package/build/dist/Server/Utils/Topology/TopologyRequest.js.map +1 -0
  469. package/build/dist/Server/Utils/Topology/TopologyResponseCache.js +146 -0
  470. package/build/dist/Server/Utils/Topology/TopologyResponseCache.js.map +1 -0
  471. package/build/dist/Server/Utils/Topology/TopologySql.js +688 -0
  472. package/build/dist/Server/Utils/Topology/TopologySql.js.map +1 -0
  473. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  474. package/build/dist/Server/Utils/VM/VMRunner.js +1 -0
  475. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  476. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +3 -0
  477. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -1
  478. package/build/dist/Types/CustomField/CustomFieldOrder.js +36 -0
  479. package/build/dist/Types/CustomField/CustomFieldOrder.js.map +1 -0
  480. package/build/dist/Types/CustomField/CustomFieldSavedViews.js +135 -0
  481. package/build/dist/Types/CustomField/CustomFieldSavedViews.js.map +1 -0
  482. package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js +27 -0
  483. package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js.map +1 -0
  484. package/build/dist/Types/CustomField/CustomFieldType.js +12 -0
  485. package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
  486. package/build/dist/Types/CustomField/CustomFieldValueFormat.js +126 -0
  487. package/build/dist/Types/CustomField/CustomFieldValueFormat.js.map +1 -0
  488. package/build/dist/Types/CustomField/CustomFieldValueValidator.js +280 -0
  489. package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -0
  490. package/build/dist/Types/CustomField/CustomFieldVariableKey.js +150 -0
  491. package/build/dist/Types/CustomField/CustomFieldVariableKey.js.map +1 -0
  492. package/build/dist/Types/Incident/IncidentAlertLink.js +17 -0
  493. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -1
  494. package/build/dist/Types/SafeHtml.js +84 -0
  495. package/build/dist/Types/SafeHtml.js.map +1 -0
  496. package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js +117 -0
  497. package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js.map +1 -0
  498. package/build/dist/Types/StatusPage/IncidentCreatedResend.js +86 -0
  499. package/build/dist/Types/StatusPage/IncidentCreatedResend.js.map +1 -0
  500. package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js +246 -0
  501. package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js.map +1 -0
  502. package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js +183 -0
  503. package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js.map +1 -0
  504. package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js +277 -0
  505. package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js.map +1 -0
  506. package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js +27 -0
  507. package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js.map +1 -0
  508. package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js +190 -0
  509. package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js.map +1 -0
  510. package/build/dist/Types/StatusPage/SubscriberNotificationResend.js +102 -0
  511. package/build/dist/Types/StatusPage/SubscriberNotificationResend.js.map +1 -0
  512. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js +97 -0
  513. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js.map +1 -0
  514. package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js +175 -0
  515. package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js.map +1 -0
  516. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +144 -4
  517. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -1
  518. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +29 -9
  519. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -1
  520. package/build/dist/Types/Telemetry/InventoryLiveness.js +23 -0
  521. package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -1
  522. package/build/dist/Types/Topology/TopologyApi.js +55 -0
  523. package/build/dist/Types/Topology/TopologyApi.js.map +1 -0
  524. package/build/dist/Types/Topology/TopologyTypeRules.js +165 -0
  525. package/build/dist/Types/Topology/TopologyTypeRules.js.map +1 -0
  526. package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js +169 -0
  527. package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js.map +1 -0
  528. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +212 -0
  529. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -0
  530. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +64 -49
  531. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  532. package/build/dist/UI/Components/Forms/ModelForm.js +39 -5
  533. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  534. package/build/dist/UI/Components/Forms/Validation.js +1 -1
  535. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  536. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  537. package/build/dist/UI/Components/ModelTable/AnalyticsModelTable.js.map +1 -1
  538. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +2 -2
  539. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  540. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +13 -1
  541. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  542. package/build/dist/UI/Components/ModelTable/ModelTable.js +1 -1
  543. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  544. package/build/dist/UI/Utils/SensitiveUrlToken.js +10 -5
  545. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -1
  546. package/build/dist/Utils/API.js +177 -1
  547. package/build/dist/Utils/API.js.map +1 -1
  548. package/build/dist/Utils/Incident/IncidentFromAlerts.js +38 -0
  549. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -1
  550. package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js +155 -0
  551. package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js.map +1 -0
  552. package/build/dist/Utils/Markdown/MarkdownEscape.js +48 -0
  553. package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -1
  554. package/build/dist/Utils/ProbeNetworkFailureUtil.js +460 -0
  555. package/build/dist/Utils/ProbeNetworkFailureUtil.js.map +1 -0
  556. package/package.json +1 -1
@@ -0,0 +1,343 @@
1
+ import { JSONObject } from "../JSON";
2
+ import StatusPageSubscriberNotificationStatus from "./StatusPageSubscriberNotificationStatus";
3
+
4
+ /*
5
+ * An incident can be limited to some status pages (Incident.statusPages), and
6
+ * the pages it is limited to often change while it is open: a site turns out
7
+ * to be affected after all, or an incident a monitor created on its own gets
8
+ * scoped once someone works out who is affected. Subscribers of a page hear
9
+ * about an incident once, when it is created, so without a way back a page
10
+ * added later never got the 'created' notification at all.
11
+ *
12
+ * Whether a newly added page should hear about it now is the editor's call,
13
+ * so it is asked when pages are added (the dashboard ticks it by default)
14
+ * rather than decided automatically, and the answer travels with that update
15
+ * as a misc data prop - like SubscriberUpdateNotification and
16
+ * IncidentCreatedRenotify, it is not a column. IncidentService turns it into a
17
+ * Pending 'created' notification, and the Incident:SendNotificationToSubscribers
18
+ * job sends it to the pages in the scope that are not yet listed in
19
+ * Incident.statusPagesNotifiedOnCreation. That record is what keeps the pages
20
+ * that were already told from hearing it twice: the request re-queues the
21
+ * notification, and the record decides who it goes to.
22
+ *
23
+ * The record only exists once the job has settled a send, so two cases have
24
+ * none, and each is handled so that only the pages the edit adds are told:
25
+ *
26
+ * - the notification went out before the record existed (an incident from an
27
+ * earlier release, Success or Failed with no record). It reached every page
28
+ * that listed the incident's monitors back then, so there is no way to tell
29
+ * an added page from one that was told, and nothing is queued. An empty
30
+ * record would otherwise read as "nobody was told" and announce the incident
31
+ * a second time;
32
+ * - the notification was Skipped and never sent (published without
33
+ * announcing it, or declared without monitors). The pages the incident was
34
+ * limited to before the edit were deliberately not told, so the update
35
+ * writes them in as the record when it queues the notification (see
36
+ * getRecordToSeedOnQueue): the job then tells the added pages only, not the
37
+ * pages the editor chose not to announce it on.
38
+ *
39
+ * Everything here is shared by the dashboard, which offers the checkbox, and
40
+ * the server, which acts on it, so the two cannot drift apart: the dashboard
41
+ * offers the checkbox exactly when getAction would queue.
42
+ */
43
+
44
+ // What an update that adds status pages does to the 'created' notification.
45
+ export enum IncidentScopeAddedPagesNotificationAction {
46
+ /*
47
+ * Nothing to do: no page was added, every added page was told already, or
48
+ * the incident is not to be announced.
49
+ */
50
+ None = "None",
51
+ // Put the 'created' notification back to Pending.
52
+ Queue = "Queue",
53
+ /*
54
+ * It is Pending, or being sent right now. A queued send reads the scope
55
+ * when it goes out, and a send that is running reads it again once it has
56
+ * finished and queues itself once more for any page added meanwhile, so the
57
+ * added pages are reached without any change here. IncidentService checks
58
+ * once the update is written, in case the send finished in between.
59
+ */
60
+ AlreadyQueued = "AlreadyQueued",
61
+ }
62
+
63
+ export interface IncidentScopeAddedPagesNotificationState {
64
+ subscriberNotificationStatusOnIncidentCreated?:
65
+ | StatusPageSubscriberNotificationStatus
66
+ | undefined
67
+ | null;
68
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated?:
69
+ | boolean
70
+ | undefined
71
+ | null;
72
+ // Both as they will be once the update is written.
73
+ isVisibleOnStatusPage?: boolean | undefined | null;
74
+ isPrivate?: boolean | undefined | null;
75
+ /*
76
+ * Incident.statusPagesNotifiedOnCreation as stored: the pages the job has a
77
+ * record of telling. Null or undefined when it has none (see the header).
78
+ */
79
+ statusPagesNotifiedOnCreation?: unknown;
80
+ }
81
+
82
+ export interface StatusPageScopeChange {
83
+ addedStatusPageIds: Array<string>;
84
+ removedStatusPageIds: Array<string>;
85
+ }
86
+
87
+ export default class IncidentScopeAddedPagesNotification {
88
+ // The misc data prop an update request carries to ask for the notification.
89
+ public static readonly miscDataKey: string =
90
+ "notifyAddedStatusPagesOfIncidentCreated";
91
+
92
+ public static readonly queuedMessage: string =
93
+ "Status pages were added to this incident. Their subscribers will be sent the notification that this incident was created.";
94
+
95
+ /*
96
+ * The status the job leaves when pages were added to the scope while it was
97
+ * sending: queued again, for the pages it had not reached.
98
+ */
99
+ public static readonly addedWhileSendingMessage: string =
100
+ "Status pages were added to this incident while its subscribers were being sent the notification that it was created. The added pages will be sent it next.";
101
+
102
+ public static readonly formFieldTitle: string =
103
+ "Send the incident-created notification to newly added pages";
104
+
105
+ public static readonly formFieldDescription: string =
106
+ "Subscribers of the status pages you add are sent the notification that this incident was created. Pages that were already told are not sent it again.";
107
+
108
+ /*
109
+ * Only a real yes counts. The flag arrives over JSON, so accept the string
110
+ * form a hand-written API request might send, and nothing looser: a stray
111
+ * "false" or 1 must never email every subscriber of a status page.
112
+ */
113
+ public static isRequested(
114
+ miscDataProps: JSONObject | undefined | null,
115
+ ): boolean {
116
+ if (!miscDataProps || typeof miscDataProps !== "object") {
117
+ return false;
118
+ }
119
+
120
+ const value: unknown = miscDataProps[this.miscDataKey];
121
+
122
+ return value === true || value === "true";
123
+ }
124
+
125
+ public static getMiscDataProps(): JSONObject {
126
+ return {
127
+ [this.miscDataKey]: true,
128
+ };
129
+ }
130
+
131
+ /*
132
+ * The status page ids in any shape a status page list arrives in - a model,
133
+ * a {_id} or {id} object, an ObjectID or a bare string - lower-cased (the
134
+ * database reads uuids back lower-cased) and without duplicates, in the
135
+ * order first seen.
136
+ */
137
+ public static normalizeStatusPageIds(value: unknown): Array<string> {
138
+ if (value === undefined || value === null) {
139
+ return [];
140
+ }
141
+
142
+ const entries: Array<unknown> = Array.isArray(value) ? value : [value];
143
+ const ids: Array<string> = [];
144
+
145
+ for (const entry of entries) {
146
+ const id: string | undefined = this.getStatusPageId(entry);
147
+
148
+ if (id && !ids.includes(id)) {
149
+ ids.push(id);
150
+ }
151
+ }
152
+
153
+ return ids;
154
+ }
155
+
156
+ // Which pages a change of the scope from `before` to `after` adds and removes.
157
+ public static getScopeChange(data: {
158
+ before: unknown;
159
+ after: unknown;
160
+ }): StatusPageScopeChange {
161
+ const before: Array<string> = this.normalizeStatusPageIds(data.before);
162
+ const after: Array<string> = this.normalizeStatusPageIds(data.after);
163
+
164
+ return {
165
+ addedStatusPageIds: after.filter((id: string) => {
166
+ return !before.includes(id);
167
+ }),
168
+ removedStatusPageIds: before.filter((id: string) => {
169
+ return !after.includes(id);
170
+ }),
171
+ };
172
+ }
173
+
174
+ /*
175
+ * The pages Incident.statusPagesNotifiedOnCreation lists, or null when there
176
+ * is no record: never written (the job has not settled a send since the
177
+ * record was introduced), or not a list.
178
+ */
179
+ public static getRecordedStatusPageIds(value: unknown): Array<string> | null {
180
+ if (!Array.isArray(value)) {
181
+ return null;
182
+ }
183
+
184
+ return this.normalizeStatusPageIds(value);
185
+ }
186
+
187
+ /*
188
+ * What adding `addedStatusPageIds` to an incident's scope does to its
189
+ * 'created' notification, given where that notification is:
190
+ *
191
+ * - no page added: nothing, whatever else the update does;
192
+ * - notifying on creation is off: nothing. An incident declared with
193
+ * notifications off was deliberately kept quiet, and scoping it does not
194
+ * change that;
195
+ * - hidden from status pages or private once the update is written:
196
+ * nothing. The job would only skip it again. Publishing the incident
197
+ * offers to announce it to the pages that were not told
198
+ * (IncidentCreatedRenotify.canRenotifyOnPublish), including pages added
199
+ * while it was hidden;
200
+ * - every added page is in the record: nothing, they were told already
201
+ * (a page removed earlier and added back, or an unscoped incident being
202
+ * narrowed to pages it reached);
203
+ * - Success or Failed with no record: nothing. It went out before the
204
+ * record existed, to every page that listed the monitors then (see the
205
+ * header);
206
+ * - Success, Skipped or Failed otherwise: queue it again. The job then
207
+ * sends it to the pages in the scope it has no record of telling - the
208
+ * added pages, plus, after a failure, the pages the failed send did not
209
+ * reach;
210
+ * - Pending or InProgress: already on its way, and it reaches the added
211
+ * pages (see AlreadyQueued).
212
+ */
213
+ public static getAction(data: {
214
+ addedStatusPageIds: Array<string>;
215
+ incident: IncidentScopeAddedPagesNotificationState;
216
+ }): IncidentScopeAddedPagesNotificationAction {
217
+ const addedStatusPageIds: Array<string> = this.normalizeStatusPageIds(
218
+ data.addedStatusPageIds,
219
+ );
220
+
221
+ if (addedStatusPageIds.length === 0) {
222
+ return IncidentScopeAddedPagesNotificationAction.None;
223
+ }
224
+
225
+ const incident: IncidentScopeAddedPagesNotificationState = data.incident;
226
+
227
+ if (
228
+ incident.shouldStatusPageSubscribersBeNotifiedOnIncidentCreated !== true
229
+ ) {
230
+ return IncidentScopeAddedPagesNotificationAction.None;
231
+ }
232
+
233
+ // A null visibility is hidden to the job, so it is here too.
234
+ if (
235
+ incident.isVisibleOnStatusPage !== true ||
236
+ incident.isPrivate === true
237
+ ) {
238
+ return IncidentScopeAddedPagesNotificationAction.None;
239
+ }
240
+
241
+ const status: StatusPageSubscriberNotificationStatus | undefined | null =
242
+ incident.subscriberNotificationStatusOnIncidentCreated;
243
+
244
+ const recorded: Array<string> | null = this.getRecordedStatusPageIds(
245
+ incident.statusPagesNotifiedOnCreation,
246
+ );
247
+
248
+ if (recorded === null) {
249
+ if (
250
+ status === StatusPageSubscriberNotificationStatus.Success ||
251
+ status === StatusPageSubscriberNotificationStatus.Failed
252
+ ) {
253
+ return IncidentScopeAddedPagesNotificationAction.None;
254
+ }
255
+ } else if (
256
+ addedStatusPageIds.every((id: string): boolean => {
257
+ return recorded.includes(id);
258
+ })
259
+ ) {
260
+ return IncidentScopeAddedPagesNotificationAction.None;
261
+ }
262
+
263
+ switch (status) {
264
+ case StatusPageSubscriberNotificationStatus.Pending:
265
+ case StatusPageSubscriberNotificationStatus.InProgress:
266
+ return IncidentScopeAddedPagesNotificationAction.AlreadyQueued;
267
+ default:
268
+ /*
269
+ * Success, Skipped and Failed - and a missing status, which the
270
+ * column's Pending default makes impossible but which would otherwise
271
+ * never be sent.
272
+ */
273
+ return IncidentScopeAddedPagesNotificationAction.Queue;
274
+ }
275
+ }
276
+
277
+ /*
278
+ * The record an update that queues the notification (action Queue) has to
279
+ * write along with it, or undefined when the stored record stands.
280
+ *
281
+ * With a record, the job already knows who was told. Without one the
282
+ * notification was never sent (getAction does not queue a Success or
283
+ * Failed one without a record), so the pages the incident was limited to
284
+ * before the update were deliberately not told - it was published without
285
+ * announcing it, or declared without monitors. They are written in as the
286
+ * record, so the job tells only the pages the update adds. An incident
287
+ * that was not limited to any page before has nothing to leave out: every
288
+ * page it is now limited to is one the update adds.
289
+ */
290
+ public static getRecordToSeedOnQueue(data: {
291
+ statusPagesNotifiedOnCreation: unknown;
292
+ statusPageIdsBeforeUpdate: unknown;
293
+ }): Array<string> | undefined {
294
+ if (this.getRecordedStatusPageIds(data.statusPagesNotifiedOnCreation)) {
295
+ return undefined;
296
+ }
297
+
298
+ return this.normalizeStatusPageIds(data.statusPageIdsBeforeUpdate);
299
+ }
300
+
301
+ private static getStatusPageId(entry: unknown): string | undefined {
302
+ if (!entry) {
303
+ return undefined;
304
+ }
305
+
306
+ let id: unknown = entry;
307
+
308
+ if (typeof entry === "object") {
309
+ const relation: {
310
+ _id?: unknown;
311
+ id?: unknown;
312
+ _type?: unknown;
313
+ value?: unknown;
314
+ } = entry as {
315
+ _id?: unknown;
316
+ id?: unknown;
317
+ _type?: unknown;
318
+ value?: unknown;
319
+ };
320
+
321
+ // A model, an ObjectID, a {_id}/{id} object or a serialized ObjectID.
322
+ if (relation._id !== undefined && relation._id !== null) {
323
+ id = relation._id;
324
+ } else if (relation.id !== undefined && relation.id !== null) {
325
+ id = relation.id;
326
+ } else if (relation._type === "ObjectID" && relation.value) {
327
+ id = relation.value;
328
+ }
329
+ }
330
+
331
+ if (typeof id !== "string" && typeof id !== "object") {
332
+ return undefined;
333
+ }
334
+
335
+ const text: string = String(id).trim().toLowerCase();
336
+
337
+ if (!text || text === "[object object]") {
338
+ return undefined;
339
+ }
340
+
341
+ return text;
342
+ }
343
+ }
@@ -0,0 +1,332 @@
1
+ import { JSONObject } from "../JSON";
2
+
3
+ /*
4
+ * Who an incident's status page notifications reach, shown before anything is
5
+ * sent: on the last step of declaring an incident, and above a public note
6
+ * while it is being written. "Will notify: Site 03 (up to 41 email), Site 07
7
+ * (up to 18 email)".
8
+ *
9
+ * POST /incident/subscriber-audience (IncidentAPI) answers it, from the same
10
+ * helper the subscriber jobs send through (IncidentStatusPageScope), so the
11
+ * preview and the send cannot disagree about which pages an incident reaches.
12
+ * It takes either an incident that is being declared - the monitors and the
13
+ * status pages picked on the form - or one that exists.
14
+ *
15
+ * The counts are "up to": they count the confirmed subscribers of each page
16
+ * who have not unsubscribed, per channel. A subscriber who picked only some
17
+ * of a page's resources, or only some event types, is filtered out at send
18
+ * time; and for an incident limited to specific pages an email address or
19
+ * phone number on two of them gets one message, not two. Addresses themselves
20
+ * never leave the server - only counts do.
21
+ *
22
+ * Everything here is shared by the server, which builds the answer, and the
23
+ * dashboard, which reads it, so the two cannot drift apart.
24
+ */
25
+
26
+ // Why a status page that lists the incident's monitors is not notified.
27
+ export enum IncidentSubscriberAudienceExclusionReason {
28
+ // The incident is limited to other status pages.
29
+ OutsideIncidentScope = "OutsideIncidentScope",
30
+ // The page only shows incidents limited to it, and this one is not.
31
+ OnlyShowsScopedIncidents = "OnlyShowsScopedIncidents",
32
+ // The page does not show incidents at all (Show Incidents is off).
33
+ HidesIncidents = "HidesIncidents",
34
+ /*
35
+ * Asked for a Retry of the incident's 'created' notification only: the
36
+ * page was already sent it in full (Incident.statusPagesNotifiedOnCreation),
37
+ * and Retry resumes after it.
38
+ */
39
+ AlreadyNotified = "AlreadyNotified",
40
+ }
41
+
42
+ // How many subscribers of one status page each channel reaches, at most.
43
+ export interface IncidentSubscriberAudienceCounts {
44
+ email: number;
45
+ sms: number;
46
+ slack: number;
47
+ microsoftTeams: number;
48
+ webhook: number;
49
+ }
50
+
51
+ export type IncidentSubscriberAudienceChannel =
52
+ keyof IncidentSubscriberAudienceCounts;
53
+
54
+ export interface IncidentSubscriberAudienceNamedStatusPage {
55
+ statusPageId: string;
56
+ name: string;
57
+ }
58
+
59
+ // A status page that will be notified.
60
+ export interface IncidentSubscriberAudienceStatusPage
61
+ extends IncidentSubscriberAudienceNamedStatusPage {
62
+ subscriberCounts: IncidentSubscriberAudienceCounts;
63
+ }
64
+
65
+ // A status page that lists the incident's monitors but will not be notified.
66
+ export interface IncidentSubscriberAudienceExcludedStatusPage
67
+ extends IncidentSubscriberAudienceNamedStatusPage {
68
+ reason: IncidentSubscriberAudienceExclusionReason;
69
+ }
70
+
71
+ export interface IncidentSubscriberAudienceResult {
72
+ /*
73
+ * Whether the incident is on any monitor. Status page subscribers hear
74
+ * about an incident through its monitors, so one on none notifies nobody.
75
+ */
76
+ hasMonitors: boolean;
77
+ /*
78
+ * Whether it is limited to specific status pages. Only then are email and
79
+ * SMS sent once per address across pages.
80
+ */
81
+ isScoped: boolean;
82
+ /*
83
+ * For an incident that exists: it is hidden from status pages (not
84
+ * visible, or private), so nothing is sent whatever pages it reaches.
85
+ */
86
+ isHiddenFromStatusPages: boolean;
87
+ // The status pages that will be notified that the caller can see, by name.
88
+ statusPages: Array<IncidentSubscriberAudienceStatusPage>;
89
+ /*
90
+ * How many more status pages will be notified that the caller cannot see.
91
+ * Status pages are label-scoped, and a page the caller may not read is not
92
+ * named in this answer, nor are its subscribers counted. (The names of the
93
+ * pages an incident is limited to are part of the incident itself, and
94
+ * readable by anyone who can read it.)
95
+ */
96
+ hiddenStatusPageCount: number;
97
+ /*
98
+ * Status pages the caller can see that list the monitors but will not be
99
+ * notified, with why. Pages the caller cannot see are left out.
100
+ */
101
+ excludedStatusPages: Array<IncidentSubscriberAudienceExcludedStatusPage>;
102
+ /*
103
+ * Status pages the incident is limited to that list none of its monitors.
104
+ * The scope only narrows where the monitors already reach, so the incident
105
+ * does not show on, or notify, these. Only pages the caller can see.
106
+ */
107
+ selectedStatusPagesNotListingMonitors: Array<IncidentSubscriberAudienceNamedStatusPage>;
108
+ }
109
+
110
+ // The order channels are listed in, and what each is called on screen.
111
+ export const INCIDENT_SUBSCRIBER_AUDIENCE_CHANNELS: ReadonlyArray<{
112
+ channel: IncidentSubscriberAudienceChannel;
113
+ label: string;
114
+ }> = [
115
+ { channel: "email", label: "email" },
116
+ { channel: "sms", label: "SMS" },
117
+ { channel: "slack", label: "Slack" },
118
+ { channel: "microsoftTeams", label: "Microsoft Teams" },
119
+ { channel: "webhook", label: "webhook" },
120
+ ];
121
+
122
+ export default class IncidentSubscriberAudience {
123
+ // The route, under the API's base URL.
124
+ public static readonly apiPath: string = "/incident/subscriber-audience";
125
+
126
+ // How many monitors or status pages one request may name.
127
+ public static readonly maxIdsPerRequest: number = 1000;
128
+
129
+ public static getEmptyCounts(): IncidentSubscriberAudienceCounts {
130
+ return {
131
+ email: 0,
132
+ sms: 0,
133
+ slack: 0,
134
+ microsoftTeams: 0,
135
+ webhook: 0,
136
+ };
137
+ }
138
+
139
+ public static getTotal(counts: IncidentSubscriberAudienceCounts): number {
140
+ return INCIDENT_SUBSCRIBER_AUDIENCE_CHANNELS.reduce(
141
+ (
142
+ total: number,
143
+ entry: { channel: IncidentSubscriberAudienceChannel },
144
+ ): number => {
145
+ return total + (counts[entry.channel] || 0);
146
+ },
147
+ 0,
148
+ );
149
+ }
150
+
151
+ /*
152
+ * The channels of one page that reach anyone, in display order, with their
153
+ * counts: [{channel: "email", label: "email", count: 41}, ...].
154
+ */
155
+ public static getNonEmptyChannels(
156
+ counts: IncidentSubscriberAudienceCounts,
157
+ ): Array<{
158
+ channel: IncidentSubscriberAudienceChannel;
159
+ label: string;
160
+ count: number;
161
+ }> {
162
+ return INCIDENT_SUBSCRIBER_AUDIENCE_CHANNELS.map(
163
+ (entry: {
164
+ channel: IncidentSubscriberAudienceChannel;
165
+ label: string;
166
+ }) => {
167
+ return {
168
+ channel: entry.channel,
169
+ label: entry.label,
170
+ count: counts[entry.channel] || 0,
171
+ };
172
+ },
173
+ ).filter((entry: { count: number }): boolean => {
174
+ return entry.count > 0;
175
+ });
176
+ }
177
+
178
+ // Whether anyone at all will be sent anything.
179
+ public static reachesAnyone(
180
+ audience: IncidentSubscriberAudienceResult,
181
+ ): boolean {
182
+ if (audience.isHiddenFromStatusPages || !audience.hasMonitors) {
183
+ return false;
184
+ }
185
+
186
+ return (
187
+ audience.hiddenStatusPageCount > 0 ||
188
+ audience.statusPages.some(
189
+ (statusPage: IncidentSubscriberAudienceStatusPage): boolean => {
190
+ return this.getTotal(statusPage.subscriberCounts) > 0;
191
+ },
192
+ )
193
+ );
194
+ }
195
+
196
+ /*
197
+ * The server's answer as the dashboard receives it. Read defensively: the
198
+ * summary is advisory, and a field that is missing or of the wrong type
199
+ * must read as "nothing" rather than break the form it sits on.
200
+ */
201
+ public static fromJSON(json: JSONObject): IncidentSubscriberAudienceResult {
202
+ const toArray: (value: unknown) => Array<JSONObject> = (
203
+ value: unknown,
204
+ ): Array<JSONObject> => {
205
+ return Array.isArray(value)
206
+ ? (value.filter((item: unknown): boolean => {
207
+ return Boolean(item) && typeof item === "object";
208
+ }) as Array<JSONObject>)
209
+ : [];
210
+ };
211
+
212
+ const toCount: (value: unknown) => number = (value: unknown): number => {
213
+ const count: number = Number(value);
214
+ return Number.isFinite(count) && count > 0 ? Math.floor(count) : 0;
215
+ };
216
+
217
+ const toNamed: (
218
+ item: JSONObject,
219
+ ) => IncidentSubscriberAudienceNamedStatusPage = (
220
+ item: JSONObject,
221
+ ): IncidentSubscriberAudienceNamedStatusPage => {
222
+ return {
223
+ statusPageId: String(item["statusPageId"] || ""),
224
+ name: String(item["name"] || ""),
225
+ };
226
+ };
227
+
228
+ const reasons: Array<string> = Object.values(
229
+ IncidentSubscriberAudienceExclusionReason,
230
+ );
231
+
232
+ return {
233
+ hasMonitors: json["hasMonitors"] === true,
234
+ isScoped: json["isScoped"] === true,
235
+ isHiddenFromStatusPages: json["isHiddenFromStatusPages"] === true,
236
+ statusPages: toArray(json["statusPages"]).map(
237
+ (item: JSONObject): IncidentSubscriberAudienceStatusPage => {
238
+ return {
239
+ ...toNamed(item),
240
+ subscriberCounts: this.countsFromJSON(item["subscriberCounts"]),
241
+ };
242
+ },
243
+ ),
244
+ hiddenStatusPageCount: toCount(json["hiddenStatusPageCount"]),
245
+ excludedStatusPages: toArray(json["excludedStatusPages"])
246
+ .filter((item: JSONObject): boolean => {
247
+ return reasons.includes(String(item["reason"]));
248
+ })
249
+ .map(
250
+ (item: JSONObject): IncidentSubscriberAudienceExcludedStatusPage => {
251
+ return {
252
+ ...toNamed(item),
253
+ reason: item[
254
+ "reason"
255
+ ] as IncidentSubscriberAudienceExclusionReason,
256
+ };
257
+ },
258
+ ),
259
+ selectedStatusPagesNotListingMonitors: toArray(
260
+ json["selectedStatusPagesNotListingMonitors"],
261
+ ).map(toNamed),
262
+ };
263
+ }
264
+
265
+ /*
266
+ * One page's counts as they arrive, each a whole number of at least 0: a
267
+ * count that is missing or not a number reads as 0.
268
+ */
269
+ public static countsFromJSON(
270
+ value: unknown,
271
+ ): IncidentSubscriberAudienceCounts {
272
+ const counts: JSONObject =
273
+ value && typeof value === "object" && !Array.isArray(value)
274
+ ? (value as JSONObject)
275
+ : {};
276
+
277
+ const toCount: (count: unknown) => number = (count: unknown): number => {
278
+ const number: number = Number(count);
279
+ return Number.isFinite(number) && number > 0 ? Math.floor(number) : 0;
280
+ };
281
+
282
+ return {
283
+ email: toCount(counts["email"]),
284
+ sms: toCount(counts["sms"]),
285
+ slack: toCount(counts["slack"]),
286
+ microsoftTeams: toCount(counts["microsoftTeams"]),
287
+ webhook: toCount(counts["webhook"]),
288
+ };
289
+ }
290
+
291
+ public static toJSON(audience: IncidentSubscriberAudienceResult): JSONObject {
292
+ return {
293
+ hasMonitors: audience.hasMonitors,
294
+ isScoped: audience.isScoped,
295
+ isHiddenFromStatusPages: audience.isHiddenFromStatusPages,
296
+ statusPages: audience.statusPages.map(
297
+ (statusPage: IncidentSubscriberAudienceStatusPage): JSONObject => {
298
+ return {
299
+ statusPageId: statusPage.statusPageId,
300
+ name: statusPage.name,
301
+ subscriberCounts: {
302
+ ...statusPage.subscriberCounts,
303
+ },
304
+ };
305
+ },
306
+ ),
307
+ hiddenStatusPageCount: audience.hiddenStatusPageCount,
308
+ excludedStatusPages: audience.excludedStatusPages.map(
309
+ (
310
+ statusPage: IncidentSubscriberAudienceExcludedStatusPage,
311
+ ): JSONObject => {
312
+ return {
313
+ statusPageId: statusPage.statusPageId,
314
+ name: statusPage.name,
315
+ reason: statusPage.reason,
316
+ };
317
+ },
318
+ ),
319
+ selectedStatusPagesNotListingMonitors:
320
+ audience.selectedStatusPagesNotListingMonitors.map(
321
+ (
322
+ statusPage: IncidentSubscriberAudienceNamedStatusPage,
323
+ ): JSONObject => {
324
+ return {
325
+ statusPageId: statusPage.statusPageId,
326
+ name: statusPage.name,
327
+ };
328
+ },
329
+ ),
330
+ };
331
+ }
332
+ }