@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
@@ -87,9 +87,20 @@ const FOREIGN_KEY_COLUMNS: Array<Array<string>> = [
87
87
  ["deletedByUserId"],
88
88
  ];
89
89
 
90
- type DeclaredIndexColumnsFunction = (
91
- modelType: ModelClass,
92
- ) => Array<Array<string>>;
90
+ interface DeclaredIndex {
91
+ columns: Array<string>;
92
+ /*
93
+ * The name the model pins with `@Index("NAME", [...])`, when it pins one.
94
+ *
95
+ * Only TypeORM's derived names contain the table name and so had to be
96
+ * renamed. A pinned name reads the same before and after the rename, so the
97
+ * rename has nothing to do for it - and must not claim to, or it would try
98
+ * to rename a name that never existed.
99
+ */
100
+ name: string | undefined;
101
+ }
102
+
103
+ type DeclaredIndexesFunction = (modelType: ModelClass) => Array<DeclaredIndex>;
93
104
 
94
105
  /*
95
106
  * The indexes a model actually declares, read out of TypeORM's decorator
@@ -97,19 +108,19 @@ type DeclaredIndexColumnsFunction = (
97
108
  * `@Index([...])` carries its columns; a column-level `@Index()` records the
98
109
  * property it decorates instead.
99
110
  */
100
- const getDeclaredIndexColumns: DeclaredIndexColumnsFunction = (
111
+ const getDeclaredIndexes: DeclaredIndexesFunction = (
101
112
  modelType: ModelClass,
102
- ): Array<Array<string>> => {
113
+ ): Array<DeclaredIndex> => {
103
114
  return getMetadataArgsStorage()
104
115
  .indices.filter((index: IndexMetadataArgs): boolean => {
105
116
  return index.target === modelType;
106
117
  })
107
- .map((index: IndexMetadataArgs): Array<string> => {
108
- if (Array.isArray(index.columns)) {
109
- return index.columns as Array<string>;
110
- }
118
+ .map((index: IndexMetadataArgs): DeclaredIndex => {
119
+ const columns: Array<string> = Array.isArray(index.columns)
120
+ ? (index.columns as Array<string>)
121
+ : [String((index as { propertyName?: string }).propertyName)];
111
122
 
112
- return [String((index as { propertyName?: string }).propertyName)];
123
+ return { columns: columns, name: index.name };
113
124
  });
114
125
  };
115
126
 
@@ -145,9 +156,10 @@ const MIGRATION_TIMESTAMP: number = 1786800000000;
145
156
  * yet. Read out of the migration directory rather than hand-listed, so a
146
157
  * future migration adding an index does not require editing this test.
147
158
  */
148
- function getIndexesCreatedAfterTheRename(): Set<string> {
159
+ /** The source of every migration that runs after the rename. */
160
+ function getMigrationSourcesAfterTheRename(): Array<string> {
149
161
  const directory: string = path.dirname(MIGRATION_PATH);
150
- const created: Set<string> = new Set<string>();
162
+ const sources: Array<string> = [];
151
163
 
152
164
  for (const file of fs.readdirSync(directory)) {
153
165
  const timestamp: number = Number(file.split("-")[0]);
@@ -156,11 +168,27 @@ function getIndexesCreatedAfterTheRename(): Set<string> {
156
168
  continue;
157
169
  }
158
170
 
159
- const source: string = fs.readFileSync(path.join(directory, file), "utf8");
171
+ sources.push(fs.readFileSync(path.join(directory, file), "utf8"));
172
+ }
173
+
174
+ return sources;
175
+ }
176
+
177
+ const MIGRATIONS_AFTER_THE_RENAME: Array<string> =
178
+ getMigrationSourcesAfterTheRename();
179
+
180
+ function getIndexesCreatedAfterTheRename(): Set<string> {
181
+ const created: Set<string> = new Set<string>();
160
182
 
183
+ for (const source of MIGRATIONS_AFTER_THE_RENAME) {
161
184
  for (const table of ["InventoryItem", "InventoryItemRelationship"]) {
185
+ /*
186
+ * `IF NOT EXISTS` is allowed for: a migration that has to be safe to
187
+ * re-run still creates the index, and skipping it here would demand a
188
+ * rename pair for an index that did not exist when the rename ran.
189
+ */
162
190
  const pattern: RegExp = new RegExp(
163
- `CREATE (?:UNIQUE )?INDEX "(IDX_[a-f0-9]+)" ON "${table}"`,
191
+ `CREATE (?:UNIQUE )?INDEX (?:IF NOT EXISTS )?"(IDX_[a-f0-9]+)" ON "${table}"`,
164
192
  "g",
165
193
  );
166
194
 
@@ -178,6 +206,23 @@ function getIndexesCreatedAfterTheRename(): Set<string> {
178
206
 
179
207
  const INDEXES_ADDED_LATER: Set<string> = getIndexesCreatedAfterTheRename();
180
208
 
209
+ type PinnedIndexCreatedFunction = (indexName: string) => boolean;
210
+
211
+ /*
212
+ * Whether some migration after the rename creates the index a model pins by
213
+ * name. Matched by the name appearing anywhere in that migration rather than
214
+ * by a CREATE INDEX pattern: a pinned name is normally held in an exported
215
+ * constant and interpolated into the statement, so the statement itself
216
+ * carries `${THE_CONSTANT}` and only the declaration carries the literal.
217
+ */
218
+ const isPinnedIndexCreatedAfterTheRename: PinnedIndexCreatedFunction = (
219
+ indexName: string,
220
+ ): boolean => {
221
+ return MIGRATIONS_AFTER_THE_RENAME.some((source: string): boolean => {
222
+ return source.includes(indexName);
223
+ });
224
+ };
225
+
181
226
  type PairMapFunction = (prefix: string) => Map<string, string>;
182
227
 
183
228
  const pairsWithPrefix: PairMapFunction = (
@@ -228,15 +273,34 @@ describe("the data survives", () => {
228
273
 
229
274
  describe("index names match TypeORM's naming strategy", () => {
230
275
  for (const table of TABLES) {
231
- const declared: Array<Array<string>> = getDeclaredIndexColumns(
232
- table.modelType,
233
- );
276
+ const declared: Array<DeclaredIndex> = getDeclaredIndexes(table.modelType);
234
277
 
235
278
  test(`${table.newTable} declares indexes to rename`, () => {
236
279
  expect(declared.length).toBeGreaterThan(0);
237
280
  });
238
281
 
239
- for (const columns of declared) {
282
+ for (const index of declared) {
283
+ const columns: Array<string> = index.columns;
284
+ const pinnedName: string | undefined = index.name;
285
+
286
+ if (pinnedName) {
287
+ /*
288
+ * A pinned name carries no table name, so the rename had nothing to
289
+ * change and must not claim otherwise. What still has to hold is that
290
+ * a migration creates it - otherwise the model declares an index that
291
+ * only ever exists on a schema the builder synchronizes, and these are
292
+ * declared `synchronize: false` precisely so it does not.
293
+ */
294
+ test(`${table.newTable} (${columns.join(", ")}) is pinned by name, so the rename leaves it alone`, () => {
295
+ const indexPairs: Map<string, string> = pairsWithPrefix("IDX_");
296
+
297
+ expect(indexPairs.has(pinnedName)).toBe(false);
298
+ expect(Array.from(indexPairs.values())).not.toContain(pinnedName);
299
+ expect(isPinnedIndexCreatedAfterTheRename(pinnedName)).toBe(true);
300
+ });
301
+ continue;
302
+ }
303
+
240
304
  const oldName: string = namingStrategy.indexName(table.oldTable, columns);
241
305
  const newName: string = namingStrategy.indexName(table.newTable, columns);
242
306
 
@@ -263,16 +327,21 @@ describe("index names match TypeORM's naming strategy", () => {
263
327
  const expected: Set<string> = new Set<string>();
264
328
 
265
329
  for (const table of TABLES) {
266
- for (const columns of getDeclaredIndexColumns(table.modelType)) {
330
+ for (const index of getDeclaredIndexes(table.modelType)) {
331
+ if (index.name) {
332
+ // Pinned name: table-independent, so the rename never touched it.
333
+ continue;
334
+ }
335
+
267
336
  if (
268
337
  INDEXES_ADDED_LATER.has(
269
- namingStrategy.indexName(table.newTable, columns),
338
+ namingStrategy.indexName(table.newTable, index.columns),
270
339
  )
271
340
  ) {
272
341
  continue;
273
342
  }
274
343
 
275
- expected.add(namingStrategy.indexName(table.oldTable, columns));
344
+ expected.add(namingStrategy.indexName(table.oldTable, index.columns));
276
345
  }
277
346
  }
278
347
 
@@ -0,0 +1,410 @@
1
+ import Incident from "../../../../Models/DatabaseModels/Incident";
2
+ import {
3
+ HIDDEN_FROM_STATUS_PAGES_MESSAGE,
4
+ SkipHiddenIncidentCreatedNotifications1795300000000,
5
+ } from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications";
6
+ import SchemaMigrations from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/Index";
7
+ import ObjectID from "../../../../Types/ObjectID";
8
+ import IncidentCreatedRenotify from "../../../../Types/StatusPage/IncidentCreatedRenotify";
9
+ import StatusPageSubscriberNotificationStatus from "../../../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
10
+ import {
11
+ afterAll,
12
+ afterEach,
13
+ beforeAll,
14
+ beforeEach,
15
+ describe,
16
+ expect,
17
+ test,
18
+ } from "@jest/globals";
19
+ import {
20
+ DataSource,
21
+ MigrationInterface,
22
+ QueryRunner,
23
+ getMetadataArgsStorage,
24
+ } from "typeorm";
25
+ import type { ColumnMetadataArgs } from "typeorm/metadata-args/ColumnMetadataArgs";
26
+
27
+ /*
28
+ * SkipHiddenIncidentCreatedNotifications1795300000000 settles the 'incident
29
+ * created' subscriber notification of hidden incidents that the old worker
30
+ * marked InProgress and then abandoned. The worker only picks up Pending
31
+ * rows, so those rows could never move again; Skipped is what the fixed
32
+ * worker writes for a hidden incident, and what lets publishing the incident
33
+ * re-queue the notification.
34
+ */
35
+
36
+ interface Statement {
37
+ sql: string;
38
+ parameters: Array<unknown> | undefined;
39
+ }
40
+
41
+ async function statementsFor(
42
+ direction: "up" | "down",
43
+ ): Promise<Array<Statement>> {
44
+ const statements: Array<Statement> = [];
45
+ const runner: QueryRunner = {
46
+ query: async (sql: string, parameters?: Array<unknown>): Promise<void> => {
47
+ statements.push({ sql, parameters });
48
+ },
49
+ } as unknown as QueryRunner;
50
+
51
+ await new SkipHiddenIncidentCreatedNotifications1795300000000()[direction](
52
+ runner,
53
+ );
54
+ return statements;
55
+ }
56
+
57
+ function incidentColumn(property: string): ColumnMetadataArgs {
58
+ const column: ColumnMetadataArgs | undefined = getMetadataArgsStorage()
59
+ .columns.filter((args: ColumnMetadataArgs) => {
60
+ return args.target === Incident && args.propertyName === property;
61
+ })
62
+ .pop();
63
+
64
+ expect(column).toBeDefined();
65
+ return column!;
66
+ }
67
+
68
+ describe("SkipHiddenIncidentCreatedNotifications1795300000000 SQL contract", () => {
69
+ test("up() runs a single UPDATE of Incident and no schema change", async () => {
70
+ const statements: Array<Statement> = await statementsFor("up");
71
+
72
+ expect(statements).toHaveLength(1);
73
+ expect(statements[0]!.sql).toMatch(/^UPDATE "Incident" SET /);
74
+ // Keywords only: the status column's own name contains "Created".
75
+ expect(statements[0]!.sql).not.toMatch(
76
+ /\b(ALTER|CREATE|DROP|DELETE|INSERT|TRUNCATE)\b/,
77
+ );
78
+ });
79
+
80
+ test("sets the status to Skipped and the message to the worker's hidden-incident reason", async () => {
81
+ const statement: Statement = (await statementsFor("up"))[0]!;
82
+
83
+ expect(statement.sql).toContain(
84
+ `SET "subscriberNotificationStatusOnIncidentCreated" = '${StatusPageSubscriberNotificationStatus.Skipped}', "subscriberNotificationStatusMessage" = $1 `,
85
+ );
86
+ expect(statement.parameters).toEqual([
87
+ IncidentCreatedRenotify.hiddenFromStatusPagesMessage,
88
+ ]);
89
+ });
90
+
91
+ test("touches only InProgress rows of incidents that are not visible, counting NULL as hidden", async () => {
92
+ const statement: Statement = (await statementsFor("up"))[0]!;
93
+
94
+ expect(statement.sql).toContain(
95
+ `WHERE "subscriberNotificationStatusOnIncidentCreated" = '${StatusPageSubscriberNotificationStatus.InProgress}' AND "isVisibleOnStatusPage" IS NOT TRUE`,
96
+ );
97
+ // Nothing else narrows or widens it.
98
+ expect(statement.sql.split("WHERE")).toHaveLength(2);
99
+ expect(statement.sql).not.toMatch(/ OR /i);
100
+ });
101
+
102
+ test("migrated rows read exactly like rows the fixed worker skips", () => {
103
+ /*
104
+ * The migration keeps its own copy of the text so it never changes after
105
+ * it ships; the dashboard recognises the reason by this text.
106
+ */
107
+ expect(HIDDEN_FROM_STATUS_PAGES_MESSAGE).toBe(
108
+ IncidentCreatedRenotify.hiddenFromStatusPagesMessage,
109
+ );
110
+ expect(
111
+ IncidentCreatedRenotify.isHiddenFromStatusPagesSkip({
112
+ status: StatusPageSubscriberNotificationStatus.Skipped,
113
+ message: HIDDEN_FROM_STATUS_PAGES_MESSAGE,
114
+ }),
115
+ ).toBe(true);
116
+ });
117
+
118
+ test("names real Incident columns", () => {
119
+ expect(
120
+ incidentColumn("subscriberNotificationStatusOnIncidentCreated").options
121
+ .type,
122
+ ).toBeDefined();
123
+ expect(
124
+ incidentColumn("subscriberNotificationStatusMessage").options.nullable,
125
+ ).toBe(true);
126
+ // The worker reads a NULL visibility as hidden; the column allows it.
127
+ expect(incidentColumn("isVisibleOnStatusPage").options.nullable).toBe(true);
128
+ });
129
+
130
+ test("down() restores nothing", async () => {
131
+ expect(await statementsFor("down")).toEqual([]);
132
+ });
133
+
134
+ test("is registered exactly once, after the migrations before it, so it runs on boot", () => {
135
+ const registered: Array<new () => MigrationInterface> =
136
+ SchemaMigrations.filter(
137
+ (migration: new () => MigrationInterface): boolean => {
138
+ return (
139
+ migration === SkipHiddenIncidentCreatedNotifications1795300000000
140
+ );
141
+ },
142
+ );
143
+
144
+ expect(registered).toHaveLength(1);
145
+ expect(new SkipHiddenIncidentCreatedNotifications1795300000000().name).toBe(
146
+ "SkipHiddenIncidentCreatedNotifications1795300000000",
147
+ );
148
+ expect(
149
+ SchemaMigrations.indexOf(
150
+ SkipHiddenIncidentCreatedNotifications1795300000000,
151
+ ),
152
+ ).toBeGreaterThan(
153
+ SchemaMigrations.findIndex(
154
+ (migration: new () => MigrationInterface): boolean => {
155
+ return (
156
+ new migration().name === "AddUserProjectSsoConsent1795100000000"
157
+ );
158
+ },
159
+ ),
160
+ );
161
+ });
162
+ });
163
+
164
+ /*
165
+ * Opt in with RUN_POSTGRES_HIDDEN_INCIDENT_NOTIFICATION_MIGRATION_TESTS=true
166
+ * and the normal database credentials (the Common test job does). The table
167
+ * is a minimal stand-in for Incident with the columns the migration reads and
168
+ * writes, typed as the entity declares them, in a uniquely named schema whose
169
+ * search_path excludes public - so no application row is ever touched.
170
+ */
171
+ const describePostgres: typeof describe.skip =
172
+ process.env["RUN_POSTGRES_HIDDEN_INCIDENT_NOTIFICATION_MIGRATION_TESTS"] ===
173
+ "true"
174
+ ? describe
175
+ : describe.skip;
176
+
177
+ interface StoredIncident {
178
+ _id: string;
179
+ isVisibleOnStatusPage: boolean | null;
180
+ status: string;
181
+ message: string | null;
182
+ postmortemStatus: string;
183
+ }
184
+
185
+ describePostgres(
186
+ "SkipHiddenIncidentCreatedNotifications against Postgres",
187
+ () => {
188
+ const schema: string = `hidden_incident_notifications_${ObjectID.generate()
189
+ .toString()
190
+ .replace(/-/g, "")}`;
191
+ const migration: SkipHiddenIncidentCreatedNotifications1795300000000 =
192
+ new SkipHiddenIncidentCreatedNotifications1795300000000();
193
+
194
+ let database: DataSource;
195
+ let runner: QueryRunner;
196
+
197
+ async function insert(row: {
198
+ isVisibleOnStatusPage: boolean | null;
199
+ status: StatusPageSubscriberNotificationStatus;
200
+ message?: string | null;
201
+ }): Promise<string> {
202
+ const id: string = ObjectID.generate().toString();
203
+ await runner.query(
204
+ `INSERT INTO "Incident" ("_id", "isVisibleOnStatusPage", "subscriberNotificationStatusOnIncidentCreated", "subscriberNotificationStatusMessage") VALUES ($1, $2, $3, $4)`,
205
+ [id, row.isVisibleOnStatusPage, row.status, row.message ?? null],
206
+ );
207
+ return id;
208
+ }
209
+
210
+ async function read(id: string): Promise<StoredIncident> {
211
+ const rows: Array<StoredIncident> = await runner.query(
212
+ `SELECT "_id", "isVisibleOnStatusPage", "subscriberNotificationStatusOnIncidentCreated" AS status, "subscriberNotificationStatusMessage" AS message, "subscriberNotificationStatusOnPostmortemPublished" AS "postmortemStatus" FROM "Incident" WHERE "_id" = $1`,
213
+ [id],
214
+ );
215
+ expect(rows).toHaveLength(1);
216
+ return rows[0]!;
217
+ }
218
+
219
+ beforeAll(async () => {
220
+ database = new DataSource({
221
+ type: "postgres",
222
+ host:
223
+ process.env[
224
+ "HIDDEN_INCIDENT_NOTIFICATION_MIGRATION_TEST_DATABASE_HOST"
225
+ ] || "localhost",
226
+ port: Number(
227
+ process.env[
228
+ "HIDDEN_INCIDENT_NOTIFICATION_MIGRATION_TEST_DATABASE_PORT"
229
+ ] || "5400",
230
+ ),
231
+ username: process.env["DATABASE_USERNAME"] || "postgres",
232
+ password: process.env["DATABASE_PASSWORD"] || "password",
233
+ database: process.env["DATABASE_NAME"] || "oneuptimedb",
234
+ entities: [],
235
+ schema,
236
+ synchronize: false,
237
+ extra: { options: `-c search_path=${schema}` },
238
+ });
239
+ await database.initialize();
240
+ await database.query(`CREATE SCHEMA "${schema}"`);
241
+ runner = database.createQueryRunner();
242
+ await runner.connect();
243
+
244
+ const currentSchema: Array<{ current_schema: string }> =
245
+ await runner.query("SELECT current_schema()");
246
+ expect(currentSchema[0]?.current_schema).toBe(schema);
247
+ });
248
+
249
+ beforeEach(async () => {
250
+ await runner.startTransaction();
251
+ // The columns as the migrated Incident table declares them.
252
+ await runner.query(
253
+ `CREATE TABLE "Incident" ("_id" uuid PRIMARY KEY, "isVisibleOnStatusPage" boolean DEFAULT true, "subscriberNotificationStatusOnIncidentCreated" character varying NOT NULL DEFAULT 'Pending', "subscriberNotificationStatusMessage" text, "subscriberNotificationStatusOnPostmortemPublished" character varying NOT NULL DEFAULT 'Pending')`,
254
+ );
255
+ });
256
+
257
+ afterEach(async () => {
258
+ if (runner?.isTransactionActive) {
259
+ await runner.rollbackTransaction();
260
+ }
261
+ });
262
+
263
+ afterAll(async () => {
264
+ if (runner) {
265
+ await runner.release();
266
+ }
267
+ if (database?.isInitialized) {
268
+ await database.query(`DROP SCHEMA IF EXISTS "${schema}" CASCADE`);
269
+ await database.destroy();
270
+ }
271
+ });
272
+
273
+ test("moves a hidden incident stuck InProgress to Skipped, with the reason", async () => {
274
+ const id: string = await insert({
275
+ isVisibleOnStatusPage: false,
276
+ status: StatusPageSubscriberNotificationStatus.InProgress,
277
+ });
278
+
279
+ await migration.up(runner);
280
+
281
+ expect(await read(id)).toEqual({
282
+ _id: id,
283
+ isVisibleOnStatusPage: false,
284
+ status: StatusPageSubscriberNotificationStatus.Skipped,
285
+ message: IncidentCreatedRenotify.hiddenFromStatusPagesMessage,
286
+ postmortemStatus: StatusPageSubscriberNotificationStatus.Pending,
287
+ });
288
+ });
289
+
290
+ test("treats a NULL visibility as hidden, as the worker did", async () => {
291
+ const id: string = await insert({
292
+ isVisibleOnStatusPage: null,
293
+ status: StatusPageSubscriberNotificationStatus.InProgress,
294
+ });
295
+
296
+ await migration.up(runner);
297
+
298
+ expect((await read(id)).status).toBe(
299
+ StatusPageSubscriberNotificationStatus.Skipped,
300
+ );
301
+ });
302
+
303
+ test("overwrites a stale message on the rows it settles", async () => {
304
+ const id: string = await insert({
305
+ isVisibleOnStatusPage: false,
306
+ status: StatusPageSubscriberNotificationStatus.InProgress,
307
+ message: "Notification queued for resending",
308
+ });
309
+
310
+ await migration.up(runner);
311
+
312
+ expect((await read(id)).message).toBe(
313
+ IncidentCreatedRenotify.hiddenFromStatusPagesMessage,
314
+ );
315
+ });
316
+
317
+ test("leaves a visible incident that is InProgress alone: it may be sending right now", async () => {
318
+ const id: string = await insert({
319
+ isVisibleOnStatusPage: true,
320
+ status: StatusPageSubscriberNotificationStatus.InProgress,
321
+ });
322
+
323
+ await migration.up(runner);
324
+
325
+ expect(await read(id)).toEqual(
326
+ expect.objectContaining({
327
+ status: StatusPageSubscriberNotificationStatus.InProgress,
328
+ message: null,
329
+ }),
330
+ );
331
+ });
332
+
333
+ test.each([
334
+ StatusPageSubscriberNotificationStatus.Pending,
335
+ StatusPageSubscriberNotificationStatus.Success,
336
+ StatusPageSubscriberNotificationStatus.Failed,
337
+ StatusPageSubscriberNotificationStatus.Skipped,
338
+ ])(
339
+ "leaves a hidden incident whose notification is %s alone",
340
+ async (status: StatusPageSubscriberNotificationStatus) => {
341
+ const id: string = await insert({
342
+ isVisibleOnStatusPage: false,
343
+ status,
344
+ message: "original message",
345
+ });
346
+
347
+ await migration.up(runner);
348
+
349
+ expect(await read(id)).toEqual(
350
+ expect.objectContaining({ status, message: "original message" }),
351
+ );
352
+ },
353
+ );
354
+
355
+ test("settles every stuck row in one pass and nothing else", async () => {
356
+ const stuck: Array<string> = [];
357
+ for (let i: number = 0; i < 5; i++) {
358
+ stuck.push(
359
+ await insert({
360
+ isVisibleOnStatusPage: false,
361
+ status: StatusPageSubscriberNotificationStatus.InProgress,
362
+ }),
363
+ );
364
+ }
365
+ const untouched: string = await insert({
366
+ isVisibleOnStatusPage: true,
367
+ status: StatusPageSubscriberNotificationStatus.Success,
368
+ });
369
+
370
+ await migration.up(runner);
371
+
372
+ for (const id of stuck) {
373
+ expect((await read(id)).status).toBe(
374
+ StatusPageSubscriberNotificationStatus.Skipped,
375
+ );
376
+ }
377
+ expect((await read(untouched)).status).toBe(
378
+ StatusPageSubscriberNotificationStatus.Success,
379
+ );
380
+ });
381
+
382
+ test("is safe to run twice", async () => {
383
+ const id: string = await insert({
384
+ isVisibleOnStatusPage: false,
385
+ status: StatusPageSubscriberNotificationStatus.InProgress,
386
+ });
387
+
388
+ await migration.up(runner);
389
+ await migration.up(runner);
390
+
391
+ expect((await read(id)).status).toBe(
392
+ StatusPageSubscriberNotificationStatus.Skipped,
393
+ );
394
+ });
395
+
396
+ test("down() leaves the settled rows as they are", async () => {
397
+ const id: string = await insert({
398
+ isVisibleOnStatusPage: false,
399
+ status: StatusPageSubscriberNotificationStatus.InProgress,
400
+ });
401
+
402
+ await migration.up(runner);
403
+ await migration.down(runner);
404
+
405
+ expect((await read(id)).status).toBe(
406
+ StatusPageSubscriberNotificationStatus.Skipped,
407
+ );
408
+ });
409
+ },
410
+ );