@oneuptime/common 12.0.28 → 12.0.30

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 (367) hide show
  1. package/Models/DatabaseModels/DashboardDomain.ts +43 -0
  2. package/Models/DatabaseModels/Index.ts +11 -0
  3. package/Models/DatabaseModels/MonitorTemplate.ts +15 -3
  4. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +43 -0
  5. package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +662 -0
  6. package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +584 -0
  7. package/Models/DatabaseModels/StatusPageDomain.ts +43 -0
  8. package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +546 -0
  9. package/Models/DatabaseModels/UserOnCallShiftReminder.ts +231 -0
  10. package/Models/DatabaseModels/UserOnCallShiftReminderLog.ts +331 -0
  11. package/Server/API/DashboardDomainAPI.ts +74 -0
  12. package/Server/API/MicrosoftTeamsAPI.ts +81 -180
  13. package/Server/API/OnCallCalendarAPI.ts +2194 -0
  14. package/Server/API/StatusPageDomainAPI.ts +74 -0
  15. package/Server/EnvironmentConfig.ts +138 -0
  16. package/Server/Infrastructure/OnCallCalendarFeedCache.ts +1050 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.ts +43 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.ts +40 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.ts +253 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  21. package/Server/Middleware/OnCallCalendarFeedRateLimit.ts +487 -0
  22. package/Server/Middleware/ProjectAuthorization.ts +6 -1
  23. package/Server/Services/DashboardDomainService.ts +131 -0
  24. package/Server/Services/Index.ts +12 -0
  25. package/Server/Services/LogPipelineProcessorService.ts +88 -0
  26. package/Server/Services/MonitorTemplateService.ts +70 -11
  27. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +32 -0
  28. package/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.ts +260 -0
  29. package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +70 -3
  30. package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +138 -3
  31. package/Server/Services/OnCallDutyPolicyScheduleService.ts +1465 -134
  32. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +167 -31
  33. package/Server/Services/ProjectOnCallCalendarFeedService.ts +192 -0
  34. package/Server/Services/StatusPageDomainService.ts +163 -3
  35. package/Server/Services/StatusPagePrivateUserSessionService.ts +197 -56
  36. package/Server/Services/TeamMemberService.ts +489 -1
  37. package/Server/Services/TeamService.ts +50 -0
  38. package/Server/Services/UserNotificationSettingService.ts +44 -1
  39. package/Server/Services/UserOnCallCalendarFeedService.ts +159 -0
  40. package/Server/Services/UserOnCallShiftReminderLogService.ts +151 -0
  41. package/Server/Services/UserOnCallShiftReminderService.ts +112 -0
  42. package/Server/Types/Domain.ts +17 -0
  43. package/Server/Utils/APIKey/AccessPermission.ts +24 -0
  44. package/Server/Utils/Greenlock/Greenlock.ts +156 -58
  45. package/Server/Utils/LogPipelineProcessorValidation.ts +112 -0
  46. package/Server/Utils/OnCall/CalendarFeedToken.ts +241 -0
  47. package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1488 -0
  48. package/Server/Utils/OnCall/OnCallCalendarFeedUrls.ts +230 -0
  49. package/Server/Utils/OnCall/OnCallShiftChangeListeners.ts +227 -0
  50. package/Server/Utils/OnCall/OnCallShiftMaterializer.ts +1127 -0
  51. package/Server/Utils/OnCall/OnCallShiftReminderListener.ts +174 -0
  52. package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +2584 -0
  53. package/Server/Utils/Response.ts +134 -0
  54. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +1094 -45
  55. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +153 -17
  56. package/Server/Utils/StartServer.ts +10 -0
  57. package/Server/Utils/Telemetry/AppMetrics.ts +51 -0
  58. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +23 -11
  59. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +0 -170
  60. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.ts +158 -0
  61. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +23 -11
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +35 -13
  63. package/Tests/App/Dashboard/MonitorTemplateColumnAndFacet.test.tsx +505 -0
  64. package/Tests/App/Dashboard/OnCallCalendarFeedLinks.test.tsx +229 -0
  65. package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +489 -0
  66. package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +149 -0
  67. package/Tests/App/Dashboard/OnCallCalendarFeedUtil.test.ts +855 -0
  68. package/Tests/App/Dashboard/OnCallPersonalCalendarFeed.test.tsx +1209 -0
  69. package/Tests/App/Dashboard/OnCallSharedCalendarFeedCard.test.tsx +1019 -0
  70. package/Tests/App/Dashboard/OnCallShiftRemindersAndUpcomingShifts.test.tsx +655 -0
  71. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +73 -0
  72. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +106 -0
  73. package/Tests/App/StatusPage/StatusPageLoginCodeUtil.test.ts +84 -0
  74. package/Tests/App/StatusPage/StatusPageRedirectSafety.test.ts +119 -0
  75. package/Tests/Models/MonitorTemplateMonitorNameColumn.test.ts +258 -0
  76. package/Tests/Models/OnCallCalendarFeedModels.test.ts +642 -0
  77. package/Tests/Models/OnCallDutyPolicyScheduleCalendarFeed.test.ts +288 -0
  78. package/Tests/Models/OnCallDutyPolicyScheduleShiftConfigVersion.test.ts +88 -0
  79. package/Tests/Models/UserOnCallShiftReminderModels.test.ts +368 -0
  80. package/Tests/Server/API/CustomDomainReissueSslAPI.test.ts +469 -0
  81. package/Tests/Server/API/Helpers.ts +8 -0
  82. package/Tests/Server/API/MicrosoftTeamsBotMessagesEndpoint.test.ts +729 -0
  83. package/Tests/Server/API/MicrosoftTeamsBotTestEndpoint.test.ts +26 -0
  84. package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +402 -0
  85. package/Tests/Server/API/OnCallCalendarAPI.test.ts +4461 -0
  86. package/Tests/Server/EnvironmentConfigOnCallCalendarFeed.test.ts +357 -0
  87. package/Tests/Server/Infrastructure/OnCallCalendarFeedCache.test.ts +1589 -0
  88. package/Tests/Server/Infrastructure/Postgres/AddOnCallCalendarFeedsMigration.test.ts +369 -0
  89. package/Tests/Server/Middleware/OnCallCalendarFeedRateLimit.test.ts +1365 -0
  90. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -0
  91. package/Tests/Server/Services/AddCertificateReissueRequestedAtToDomainsMigration.test.ts +287 -0
  92. package/Tests/Server/Services/CustomDomainCertificateReissue.test.ts +477 -0
  93. package/Tests/Server/Services/FeedRetentionConsistency.test.ts +70 -0
  94. package/Tests/Server/Services/LogPipelineProcessorSaveValidation.test.ts +249 -0
  95. package/Tests/Server/Services/MonitorTemplateServiceBulkSync.test.ts +549 -0
  96. package/Tests/Server/Services/MonitorTemplateServiceNetworkDeviceSync.test.ts +16 -3
  97. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +57 -0
  98. package/Tests/Server/Services/OnCallCalendarFeedServices.test.ts +1103 -0
  99. package/Tests/Server/Services/OnCallDutyPolicyScheduleResolver.test.ts +1037 -0
  100. package/Tests/Server/Services/OnCallShiftConfigPropagation.test.ts +1270 -0
  101. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +151 -15
  102. package/Tests/Server/Services/StatusPagePrivateUserSessionService.test.ts +587 -0
  103. package/Tests/Server/Services/TeamDeleteMemberCleanup.test.ts +156 -0
  104. package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +755 -0
  105. package/Tests/Server/Services/UserNotificationSettingShiftReminderDefaults.test.ts +267 -0
  106. package/Tests/Server/Services/UserOnCallShiftReminderServices.test.ts +583 -0
  107. package/Tests/Server/Types/Database/Permissions/ApiKeyFileAccess.test.ts +286 -0
  108. package/Tests/Server/Types/Database/Permissions/MonitorTemplateColumnAccess.test.ts +328 -0
  109. package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +254 -0
  110. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAndIsNull.test.ts +83 -0
  111. package/Tests/Server/Utils/AI/SRE/ConfidenceSignal.test.ts +377 -0
  112. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +16 -1
  113. package/Tests/Server/Utils/Greenlock/CertificateRenewalSchedule.test.ts +250 -0
  114. package/Tests/Server/Utils/LogPipelineProcessorValidation.test.ts +198 -0
  115. package/Tests/Server/Utils/OnCall/CalendarFeedToken.test.ts +467 -0
  116. package/Tests/Server/Utils/OnCall/OnCallCalendarFeedRenderer.test.ts +2142 -0
  117. package/Tests/Server/Utils/OnCall/OnCallCalendarFeedUrls.test.ts +278 -0
  118. package/Tests/Server/Utils/OnCall/OnCallResolverTestHarness.ts +440 -0
  119. package/Tests/Server/Utils/OnCall/OnCallShiftChangeListeners.test.ts +314 -0
  120. package/Tests/Server/Utils/OnCall/OnCallShiftMaterializer.test.ts +1502 -0
  121. package/Tests/Server/Utils/OnCall/OnCallShiftReminderListener.test.ts +491 -0
  122. package/Tests/Server/Utils/OnCall/OnCallShiftReminderRunner.test.ts +3088 -0
  123. package/Tests/Server/Utils/OnCall/OnCallShiftReminderTestHarness.ts +910 -0
  124. package/Tests/Server/Utils/ResponseSendCalendarResponse.test.ts +561 -0
  125. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +48 -9
  126. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsAuth.test.ts +726 -0
  127. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +74 -11
  128. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsErrorHandling.test.ts +1107 -0
  129. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +20 -3
  130. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +51 -11
  131. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +1246 -0
  132. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsRequestContract.test.ts +961 -0
  133. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsResponseParsing.test.ts +653 -0
  134. package/Tests/Server/Utils/StartServerEncryptionSecretWarning.test.ts +64 -0
  135. package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +29 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +880 -0
  137. package/Tests/Types/API/HTTPResponse.test.ts +175 -0
  138. package/Tests/Types/API/Route.test.ts +36 -4
  139. package/Tests/Types/Calendar/ICalendar.test.ts +488 -0
  140. package/Tests/Types/Database/DatabaseProperty.test.ts +171 -0
  141. package/Tests/Types/DateLocalShortDateTimeString.test.ts +518 -0
  142. package/Tests/Types/DateLocalTimeString.test.ts +259 -0
  143. package/Tests/Types/DateUserPrefers12HourFormat.test.ts +316 -0
  144. package/Tests/Types/NotificationSetting/NotificationSettingEventType.test.ts +53 -0
  145. package/Tests/Types/OnCallDutyPolicy/CalendarFeedTestFixtures.ts +310 -0
  146. package/Tests/Types/OnCallDutyPolicy/CalendarFeedWindow.test.ts +205 -0
  147. package/Tests/Types/OnCallDutyPolicy/LayerUtilLayerMetaAndIterationCap.test.ts +458 -0
  148. package/Tests/Types/OnCallDutyPolicy/MaterializedShift.test.ts +197 -0
  149. package/Tests/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.test.ts +1986 -0
  150. package/Tests/Types/OnCallDutyPolicy/ScheduleShiftUtilGroupKey.test.ts +678 -0
  151. package/Tests/Types/OnCallDutyPolicy/ShiftSeamUtil.test.ts +417 -0
  152. package/Tests/UI/Components/LogsHistogram.test.tsx +41 -2
  153. package/Tests/UI/Components/LogsViewerEmptyStateTimeRange.test.tsx +212 -0
  154. package/Tests/UI/Components/TelemetryChartClockFormat.test.tsx +359 -0
  155. package/Tests/UI/Components/TimeRangePickerClockFormat.test.tsx +422 -0
  156. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +146 -8
  157. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsMessagingEndpointGuidance.test.tsx +520 -0
  158. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  159. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  160. package/Tests/UI/Utils/Navigation.test.ts +82 -0
  161. package/Tests/Utils/Array.test.ts +100 -0
  162. package/Tests/Utils/CertificateReissue.test.ts +225 -0
  163. package/Tests/Utils/Grok/Grok.test.ts +492 -0
  164. package/Tests/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.test.ts +181 -13
  165. package/Types/API/Route.ts +20 -5
  166. package/Types/Calendar/ICalendar.ts +442 -0
  167. package/Types/Date.ts +143 -13
  168. package/Types/Email/EmailTemplateType.ts +2 -0
  169. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  170. package/Types/OnCallDutyPolicy/CalendarFeedWindow.ts +140 -0
  171. package/Types/OnCallDutyPolicy/Layer.ts +190 -35
  172. package/Types/OnCallDutyPolicy/MaterializedShift.ts +274 -0
  173. package/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.ts +1415 -0
  174. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +159 -4
  175. package/Types/OnCallDutyPolicy/ShiftSeamUtil.ts +106 -0
  176. package/Types/Rum/SessionReplay.ts +62 -1
  177. package/UI/Components/Date/TimeRangePickerDropdown.tsx +9 -5
  178. package/UI/Components/LogsViewer/LogsViewer.tsx +12 -7
  179. package/UI/Components/LogsViewer/components/HistogramTooltip.tsx +18 -17
  180. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +21 -28
  181. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +2 -4
  182. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +2 -4
  183. package/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.tsx +17 -16
  184. package/UI/Utils/Navigation.ts +42 -0
  185. package/Utils/Array.ts +37 -0
  186. package/Utils/CertificateReissue.ts +128 -0
  187. package/Utils/Grok/Grok.ts +461 -0
  188. package/Utils/Grok/GrokPatterns.ts +118 -0
  189. package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +58 -6
  190. package/build/dist/Models/DatabaseModels/DashboardDomain.js +44 -0
  191. package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/Index.js +11 -0
  193. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +17 -4
  195. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +44 -0
  197. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +699 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -0
  200. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +620 -0
  201. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -0
  202. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +44 -0
  203. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +585 -0
  205. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -0
  206. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminder.js +247 -0
  207. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminder.js.map +1 -0
  208. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminderLog.js +355 -0
  209. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminderLog.js.map +1 -0
  210. package/build/dist/Server/API/DashboardDomainAPI.js +43 -1
  211. package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -1
  212. package/build/dist/Server/API/MicrosoftTeamsAPI.js +74 -118
  213. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  214. package/build/dist/Server/API/OnCallCalendarAPI.js +1371 -0
  215. package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -0
  216. package/build/dist/Server/API/StatusPageDomainAPI.js +43 -1
  217. package/build/dist/Server/API/StatusPageDomainAPI.js.map +1 -1
  218. package/build/dist/Server/EnvironmentConfig.js +102 -0
  219. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  220. package/build/dist/Server/Infrastructure/OnCallCalendarFeedCache.js +663 -0
  221. package/build/dist/Server/Infrastructure/OnCallCalendarFeedCache.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.js +34 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.js.map +1 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.js +28 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.js.map +1 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.js +103 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.js.map +1 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  230. package/build/dist/Server/Middleware/OnCallCalendarFeedRateLimit.js +342 -0
  231. package/build/dist/Server/Middleware/OnCallCalendarFeedRateLimit.js.map +1 -0
  232. package/build/dist/Server/Middleware/ProjectAuthorization.js +6 -1
  233. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  234. package/build/dist/Server/Services/DashboardDomainService.js +104 -0
  235. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  236. package/build/dist/Server/Services/Index.js +12 -0
  237. package/build/dist/Server/Services/Index.js.map +1 -1
  238. package/build/dist/Server/Services/LogPipelineProcessorService.js +65 -0
  239. package/build/dist/Server/Services/LogPipelineProcessorService.js.map +1 -1
  240. package/build/dist/Server/Services/MonitorTemplateService.js +57 -11
  241. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  242. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +20 -0
  243. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  244. package/build/dist/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.js +219 -0
  245. package/build/dist/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.js.map +1 -0
  246. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +47 -3
  247. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
  248. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +112 -3
  249. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
  250. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +955 -9
  251. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  252. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +93 -6
  253. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  254. package/build/dist/Server/Services/ProjectOnCallCalendarFeedService.js +157 -0
  255. package/build/dist/Server/Services/ProjectOnCallCalendarFeedService.js.map +1 -0
  256. package/build/dist/Server/Services/StatusPageDomainService.js +132 -3
  257. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  258. package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js +112 -32
  259. package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js.map +1 -1
  260. package/build/dist/Server/Services/TeamMemberService.js +396 -1
  261. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  262. package/build/dist/Server/Services/TeamService.js +43 -0
  263. package/build/dist/Server/Services/TeamService.js.map +1 -1
  264. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -1
  265. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  266. package/build/dist/Server/Services/UserOnCallCalendarFeedService.js +140 -0
  267. package/build/dist/Server/Services/UserOnCallCalendarFeedService.js.map +1 -0
  268. package/build/dist/Server/Services/UserOnCallShiftReminderLogService.js +116 -0
  269. package/build/dist/Server/Services/UserOnCallShiftReminderLogService.js.map +1 -0
  270. package/build/dist/Server/Services/UserOnCallShiftReminderService.js +92 -0
  271. package/build/dist/Server/Services/UserOnCallShiftReminderService.js.map +1 -0
  272. package/build/dist/Server/Types/Domain.js +16 -0
  273. package/build/dist/Server/Types/Domain.js.map +1 -1
  274. package/build/dist/Server/Utils/APIKey/AccessPermission.js +24 -0
  275. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  276. package/build/dist/Server/Utils/Greenlock/Greenlock.js +110 -35
  277. package/build/dist/Server/Utils/Greenlock/Greenlock.js.map +1 -1
  278. package/build/dist/Server/Utils/LogPipelineProcessorValidation.js +77 -0
  279. package/build/dist/Server/Utils/LogPipelineProcessorValidation.js.map +1 -0
  280. package/build/dist/Server/Utils/OnCall/CalendarFeedToken.js +161 -0
  281. package/build/dist/Server/Utils/OnCall/CalendarFeedToken.js.map +1 -0
  282. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedRenderer.js +983 -0
  283. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedRenderer.js.map +1 -0
  284. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedUrls.js +155 -0
  285. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedUrls.js.map +1 -0
  286. package/build/dist/Server/Utils/OnCall/OnCallShiftChangeListeners.js +145 -0
  287. package/build/dist/Server/Utils/OnCall/OnCallShiftChangeListeners.js.map +1 -0
  288. package/build/dist/Server/Utils/OnCall/OnCallShiftMaterializer.js +752 -0
  289. package/build/dist/Server/Utils/OnCall/OnCallShiftMaterializer.js.map +1 -0
  290. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderListener.js +92 -0
  291. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderListener.js.map +1 -0
  292. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1786 -0
  293. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -0
  294. package/build/dist/Server/Utils/Response.js +97 -0
  295. package/build/dist/Server/Utils/Response.js.map +1 -1
  296. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +777 -36
  297. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
  298. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +108 -17
  299. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
  300. package/build/dist/Server/Utils/StartServer.js +9 -1
  301. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  302. package/build/dist/Server/Utils/Telemetry/AppMetrics.js +41 -0
  303. package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
  304. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +17 -6
  305. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  306. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +0 -159
  307. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  308. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.js +128 -0
  309. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.js.map +1 -0
  310. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +17 -6
  311. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  312. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -13
  313. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  314. package/build/dist/Types/API/Route.js +16 -5
  315. package/build/dist/Types/API/Route.js.map +1 -1
  316. package/build/dist/Types/Calendar/ICalendar.js +290 -0
  317. package/build/dist/Types/Calendar/ICalendar.js.map +1 -0
  318. package/build/dist/Types/Date.js +115 -13
  319. package/build/dist/Types/Date.js.map +1 -1
  320. package/build/dist/Types/Email/EmailTemplateType.js +2 -0
  321. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  322. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  323. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  324. package/build/dist/Types/OnCallDutyPolicy/CalendarFeedWindow.js +97 -0
  325. package/build/dist/Types/OnCallDutyPolicy/CalendarFeedWindow.js.map +1 -0
  326. package/build/dist/Types/OnCallDutyPolicy/Layer.js +113 -19
  327. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  328. package/build/dist/Types/OnCallDutyPolicy/MaterializedShift.js +134 -0
  329. package/build/dist/Types/OnCallDutyPolicy/MaterializedShift.js.map +1 -0
  330. package/build/dist/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.js +800 -0
  331. package/build/dist/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.js.map +1 -0
  332. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +97 -3
  333. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
  334. package/build/dist/Types/OnCallDutyPolicy/ShiftSeamUtil.js +77 -0
  335. package/build/dist/Types/OnCallDutyPolicy/ShiftSeamUtil.js.map +1 -0
  336. package/build/dist/Types/Rum/SessionReplay.js +38 -0
  337. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  338. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +9 -5
  339. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -1
  340. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +12 -7
  341. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  342. package/build/dist/UI/Components/LogsViewer/components/HistogramTooltip.js +15 -14
  343. package/build/dist/UI/Components/LogsViewer/components/HistogramTooltip.js.map +1 -1
  344. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +17 -22
  345. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  346. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +2 -4
  347. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  348. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +2 -4
  349. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  350. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js +15 -14
  351. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js.map +1 -1
  352. package/build/dist/UI/Utils/Navigation.js +30 -0
  353. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  354. package/build/dist/Utils/Array.js +25 -0
  355. package/build/dist/Utils/Array.js.map +1 -1
  356. package/build/dist/Utils/CertificateReissue.js +97 -0
  357. package/build/dist/Utils/CertificateReissue.js.map +1 -0
  358. package/build/dist/Utils/Grok/Grok.js +324 -0
  359. package/build/dist/Utils/Grok/Grok.js.map +1 -0
  360. package/build/dist/Utils/Grok/GrokPatterns.js +112 -0
  361. package/build/dist/Utils/Grok/GrokPatterns.js.map +1 -0
  362. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +63 -3
  363. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
  364. package/package.json +1 -1
  365. package/UI/Utils/JsonWebToken.ts +0 -14
  366. package/build/dist/UI/Utils/JsonWebToken.js +0 -10
  367. package/build/dist/UI/Utils/JsonWebToken.js.map +0 -1
@@ -0,0 +1,310 @@
1
+ import moment from "moment-timezone";
2
+ import User from "../../../Models/DatabaseModels/User";
3
+ import OneUptimeDate from "../../../Types/Date";
4
+ import EventInterval from "../../../Types/Events/EventInterval";
5
+ import Recurring from "../../../Types/Events/Recurring";
6
+ import MaterializedShiftUtil, {
7
+ MaterializedShift,
8
+ MaterializedShiftPolicy,
9
+ } from "../../../Types/OnCallDutyPolicy/MaterializedShift";
10
+ import RestrictionTimes, {
11
+ RestrictionType,
12
+ WeeklyResctriction,
13
+ } from "../../../Types/OnCallDutyPolicy/RestrictionTimes";
14
+ import { OnCallShift } from "../../../Types/OnCallDutyPolicy/ScheduleShiftUtil";
15
+
16
+ /*
17
+ * Shared fixtures for the on-call calendar feed suites. Everything is built
18
+ * from explicit IANA zones and fixed ISO instants (the tzInstant / hhmm idiom
19
+ * from LayerUtilTimezone.test.ts) so the results do not depend on the zone
20
+ * the test process happens to run in.
21
+ */
22
+
23
+ export function user(id: string): User {
24
+ return {
25
+ id: {
26
+ toString: (): string => {
27
+ return id;
28
+ },
29
+ } as any,
30
+ } as User;
31
+ }
32
+
33
+ export function rotation(
34
+ intervalType: EventInterval,
35
+ intervalCount: number,
36
+ ): Recurring {
37
+ return Recurring.fromJSON({
38
+ _type: "Recurring",
39
+ value: {
40
+ intervalType: intervalType,
41
+ intervalCount: { _type: "PositiveNumber", value: intervalCount },
42
+ },
43
+ } as any);
44
+ }
45
+
46
+ export function noRestriction(): RestrictionTimes {
47
+ const restrictionTimes: RestrictionTimes = new RestrictionTimes();
48
+ restrictionTimes.restictionType = RestrictionType.None;
49
+ restrictionTimes.dayRestrictionTimes = null;
50
+ return restrictionTimes;
51
+ }
52
+
53
+ // An absolute instant that is `iso` ("YYYY-MM-DD HH:mm") wall-clock in `tz`.
54
+ export function tzInstant(iso: string, tz: string): Date {
55
+ return moment.tz(iso, tz).toDate();
56
+ }
57
+
58
+ // Wall-clock "HH:mm" of an instant AS SEEN IN `tz`.
59
+ export function hhmm(date: Date, tz: string): string {
60
+ return moment.tz(date, tz).format("HH:mm");
61
+ }
62
+
63
+ export function at(iso: string): Date {
64
+ return OneUptimeDate.fromString(iso);
65
+ }
66
+
67
+ /*
68
+ * Daily HH:mm-HH:mm restriction authored in `tz`. LayerUtil only reads the
69
+ * wall-clock time of the two instants (keepTimeButMoveDay), so the date part
70
+ * is irrelevant.
71
+ */
72
+ export function dailyRestriction(
73
+ startHHmm: string,
74
+ endHHmm: string,
75
+ tz: string,
76
+ ): RestrictionTimes {
77
+ const restrictionTimes: RestrictionTimes = new RestrictionTimes();
78
+ restrictionTimes.restictionType = RestrictionType.Daily;
79
+ restrictionTimes.dayRestrictionTimes = {
80
+ startTime: tzInstant(`2026-01-05 ${startHHmm}`, tz),
81
+ endTime: tzInstant(`2026-01-05 ${endHHmm}`, tz),
82
+ };
83
+ return restrictionTimes;
84
+ }
85
+
86
+ /*
87
+ * Office hours, Mon-Fri 09:00-17:00 in `tz`, authored as five weekday windows
88
+ * on the week of Monday 2026-01-05. The engine derives the enforced weekday
89
+ * from each instant's weekday in `tz`.
90
+ */
91
+ export function businessHoursRestriction(tz: string): RestrictionTimes {
92
+ const restrictionTimes: RestrictionTimes = new RestrictionTimes();
93
+ restrictionTimes.restictionType = RestrictionType.Weekly;
94
+ restrictionTimes.weeklyRestrictionTimes = [
95
+ "2026-01-05",
96
+ "2026-01-06",
97
+ "2026-01-07",
98
+ "2026-01-08",
99
+ "2026-01-09",
100
+ ].map((day: string): WeeklyResctriction => {
101
+ const startTime: Date = tzInstant(`${day} 09:00`, tz);
102
+ const endTime: Date = tzInstant(`${day} 17:00`, tz);
103
+ return {
104
+ startDay: OneUptimeDate.getDayOfWeek(startTime, tz),
105
+ endDay: OneUptimeDate.getDayOfWeek(endTime, tz),
106
+ startTime,
107
+ endTime,
108
+ };
109
+ });
110
+ return restrictionTimes;
111
+ }
112
+
113
+ export const DEFAULT_POLICY: MaterializedShiftPolicy = {
114
+ policyId: "pol-1",
115
+ policyName: "Payments Policy",
116
+ ruleId: "rule-1",
117
+ ruleName: "Primary",
118
+ ruleOrder: 1,
119
+ };
120
+
121
+ export const DEFAULT_LAST_MODIFIED: Date = at("2026-08-01T10:00:00Z");
122
+
123
+ export const DASHBOARD_URL: string = "https://oneuptime.example.com/dashboard";
124
+
125
+ export type ShiftOverrides = Omit<
126
+ Partial<MaterializedShift>,
127
+ "scheduleTimezone"
128
+ > & {
129
+ start: Date;
130
+ end: Date;
131
+ // Pass an explicit undefined to build a legacy shift with no timezone.
132
+ scheduleTimezone?: string | undefined;
133
+ };
134
+
135
+ /*
136
+ * A MaterializedShift with sensible defaults: Alice on the "Payments"
137
+ * schedule (Europe/Stockholm) attached to one policy. Optional fields are only
138
+ * added when the caller supplies them, so key presence matches what the
139
+ * materializer would produce.
140
+ */
141
+ export function shift(overrides: ShiftOverrides): MaterializedShift {
142
+ const scheduleId: string = overrides.scheduleId ?? "sched-1";
143
+ const policyVariantOf: MaterializedShift["policyVariantOf"] =
144
+ overrides.policyVariantOf;
145
+
146
+ const base: MaterializedShift = {
147
+ shiftKey:
148
+ overrides.shiftKey ??
149
+ MaterializedShiftUtil.buildShiftKey({
150
+ scheduleId,
151
+ start: overrides.start,
152
+ policyId: policyVariantOf?.policyId,
153
+ }),
154
+ contentHash: overrides.contentHash ?? "hash",
155
+ projectId: overrides.projectId ?? "proj-1",
156
+ scheduleId,
157
+ scheduleName: overrides.scheduleName ?? "Payments",
158
+ userId: overrides.userId ?? "user-a",
159
+ userName: overrides.userName ?? "Alice Andersson",
160
+ start: overrides.start,
161
+ end: overrides.end,
162
+ coverageSeconds:
163
+ overrides.coverageSeconds ??
164
+ Math.round((overrides.end.getTime() - overrides.start.getTime()) / 1000),
165
+ policies: overrides.policies ?? [{ ...DEFAULT_POLICY }],
166
+ isPast: overrides.isPast ?? false,
167
+ lastModifiedAt: overrides.lastModifiedAt ?? DEFAULT_LAST_MODIFIED,
168
+ shiftConfigVersion: overrides.shiftConfigVersion ?? 3,
169
+ };
170
+
171
+ if ("scheduleTimezone" in overrides) {
172
+ if (overrides.scheduleTimezone !== undefined) {
173
+ base.scheduleTimezone = overrides.scheduleTimezone;
174
+ }
175
+ } else {
176
+ base.scheduleTimezone = "Europe/Stockholm";
177
+ }
178
+
179
+ if (overrides.projectName !== undefined) {
180
+ base.projectName = overrides.projectName;
181
+ }
182
+
183
+ if (overrides.layerId !== undefined) {
184
+ base.layerId = overrides.layerId;
185
+ }
186
+
187
+ if (overrides.layerName !== undefined) {
188
+ base.layerName = overrides.layerName;
189
+ }
190
+
191
+ if (overrides.override !== undefined) {
192
+ base.override = overrides.override;
193
+ }
194
+
195
+ if (policyVariantOf !== undefined) {
196
+ base.policyVariantOf = policyVariantOf;
197
+ }
198
+
199
+ return base;
200
+ }
201
+
202
+ // Turn engine-derived OnCallShifts into MaterializedShifts on one schedule.
203
+ export function materialize(
204
+ shifts: Array<OnCallShift>,
205
+ overrides?: Partial<MaterializedShift> | undefined,
206
+ ): Array<MaterializedShift> {
207
+ return shifts.map((onCallShift: OnCallShift) => {
208
+ const extra: Partial<MaterializedShift> = { ...(overrides ?? {}) };
209
+
210
+ if (onCallShift.override) {
211
+ extra.override = {
212
+ originalUserId: onCallShift.override.originalUserId,
213
+ originalUserName: `Name of ${onCallShift.override.originalUserId}`,
214
+ overrideStartsAt: onCallShift.override.overrideStartsAt,
215
+ overrideEndsAt: onCallShift.override.overrideEndsAt,
216
+ };
217
+ }
218
+
219
+ if (onCallShift.layerId !== undefined) {
220
+ extra.layerId = onCallShift.layerId;
221
+ }
222
+
223
+ if (onCallShift.layerName !== undefined) {
224
+ extra.layerName = onCallShift.layerName;
225
+ }
226
+
227
+ return shift({
228
+ ...extra,
229
+ start: onCallShift.start,
230
+ end: onCallShift.end,
231
+ userId: onCallShift.userId,
232
+ userName: `Name of ${onCallShift.userId}`,
233
+ coverageSeconds: onCallShift.coverageSeconds,
234
+ });
235
+ });
236
+ }
237
+
238
+ // Physical lines of a serialized calendar (CRLF separated, no folding undone).
239
+ export function physicalLines(body: string): Array<string> {
240
+ const lines: Array<string> = body.split("\r\n");
241
+ // A well-formed body ends with CRLF, leaving one empty trailing element.
242
+ if (lines[lines.length - 1] === "") {
243
+ lines.pop();
244
+ }
245
+ return lines;
246
+ }
247
+
248
+ // Logical (unfolded) lines of a serialized calendar.
249
+ export function logicalLines(body: string): Array<string> {
250
+ return physicalLines(body.replace(/\r\n[ \t]/g, ""));
251
+ }
252
+
253
+ // The value of the first logical line starting with `NAME:` / `NAME;`.
254
+ export function property(body: string, name: string): string | undefined {
255
+ const line: string | undefined = logicalLines(body).find((entry: string) => {
256
+ return entry.startsWith(`${name}:`) || entry.startsWith(`${name};`);
257
+ });
258
+
259
+ if (line === undefined) {
260
+ return undefined;
261
+ }
262
+
263
+ return line.slice(line.indexOf(":") + 1);
264
+ }
265
+
266
+ // Every value of a repeated property (e.g. every UID in the body).
267
+ export function properties(body: string, name: string): Array<string> {
268
+ return logicalLines(body)
269
+ .filter((entry: string) => {
270
+ return entry.startsWith(`${name}:`) || entry.startsWith(`${name};`);
271
+ })
272
+ .map((entry: string) => {
273
+ return entry.slice(entry.indexOf(":") + 1);
274
+ });
275
+ }
276
+
277
+ // The logical lines of each VEVENT block, in document order.
278
+ export function eventBlocks(body: string): Array<Array<string>> {
279
+ const blocks: Array<Array<string>> = [];
280
+ let current: Array<string> | null = null;
281
+
282
+ for (const line of logicalLines(body)) {
283
+ if (line === "BEGIN:VEVENT") {
284
+ current = [];
285
+ continue;
286
+ }
287
+ if (line === "END:VEVENT") {
288
+ if (current) {
289
+ blocks.push(current);
290
+ }
291
+ current = null;
292
+ continue;
293
+ }
294
+ if (current) {
295
+ current.push(line);
296
+ }
297
+ }
298
+
299
+ return blocks;
300
+ }
301
+
302
+ export function blockProperty(
303
+ block: Array<string>,
304
+ name: string,
305
+ ): string | undefined {
306
+ const line: string | undefined = block.find((entry: string) => {
307
+ return entry.startsWith(`${name}:`) || entry.startsWith(`${name};`);
308
+ });
309
+ return line === undefined ? undefined : line.slice(line.indexOf(":") + 1);
310
+ }
@@ -0,0 +1,205 @@
1
+ import CalendarFeedWindow, {
2
+ BODY_CACHE_TTL_SECONDS,
3
+ DEFAULT_FUTURE_DAYS,
4
+ DEFAULT_PAST_DAYS,
5
+ FEED_SIMULATION_ITERATION_CAP,
6
+ FeedWindow,
7
+ MAX_EVENTS,
8
+ MAX_FUTURE_DAYS,
9
+ MAX_GAP_EVENTS,
10
+ MAX_PAST_DAYS,
11
+ MIN_FUTURE_DAYS,
12
+ PREVIOUS_TOKEN_GRACE_DAYS,
13
+ RENDER_CONCURRENCY,
14
+ SCHEDULE_CACHE_TTL_SECONDS,
15
+ } from "../../../Types/OnCallDutyPolicy/CalendarFeedWindow";
16
+ import { at } from "./CalendarFeedTestFixtures";
17
+
18
+ describe("CalendarFeedWindow constants", () => {
19
+ test("hold the values the design fixes", () => {
20
+ expect(MAX_FUTURE_DAYS).toBe(180);
21
+ expect(MIN_FUTURE_DAYS).toBe(7);
22
+ expect(DEFAULT_FUTURE_DAYS).toBe(90);
23
+ expect(MAX_PAST_DAYS).toBe(60);
24
+ expect(DEFAULT_PAST_DAYS).toBe(2);
25
+ expect(MAX_EVENTS).toBe(5000);
26
+ expect(MAX_GAP_EVENTS).toBe(100);
27
+ expect(PREVIOUS_TOKEN_GRACE_DAYS).toBe(30);
28
+ expect(BODY_CACHE_TTL_SECONDS).toBe(300);
29
+ expect(SCHEDULE_CACHE_TTL_SECONDS).toBe(3600);
30
+ expect(RENDER_CONCURRENCY).toBe(4);
31
+ expect(FEED_SIMULATION_ITERATION_CAP).toBe(200000);
32
+ });
33
+
34
+ test("are internally consistent", () => {
35
+ expect(MIN_FUTURE_DAYS).toBeLessThanOrEqual(DEFAULT_FUTURE_DAYS);
36
+ expect(DEFAULT_FUTURE_DAYS).toBeLessThanOrEqual(MAX_FUTURE_DAYS);
37
+ expect(DEFAULT_PAST_DAYS).toBeLessThanOrEqual(MAX_PAST_DAYS);
38
+ expect(MAX_GAP_EVENTS).toBeLessThan(MAX_EVENTS);
39
+ });
40
+ });
41
+
42
+ describe("CalendarFeedWindow.clampPastDays", () => {
43
+ test("keeps values inside 0..MAX_PAST_DAYS and clamps the rest", () => {
44
+ expect(CalendarFeedWindow.clampPastDays(0)).toBe(0);
45
+ expect(CalendarFeedWindow.clampPastDays(2)).toBe(2);
46
+ expect(CalendarFeedWindow.clampPastDays(60)).toBe(60);
47
+ expect(CalendarFeedWindow.clampPastDays(61)).toBe(60);
48
+ expect(CalendarFeedWindow.clampPastDays(999)).toBe(60);
49
+ expect(CalendarFeedWindow.clampPastDays(-5)).toBe(0);
50
+ });
51
+
52
+ test("floors fractions and parses numeric strings (as stored Number columns arrive)", () => {
53
+ expect(CalendarFeedWindow.clampPastDays(2.9)).toBe(2);
54
+ expect(CalendarFeedWindow.clampPastDays("7")).toBe(7);
55
+ expect(CalendarFeedWindow.clampPastDays(" 90 ")).toBe(60);
56
+ });
57
+
58
+ test("falls back to the default for anything that is not a number", () => {
59
+ expect(CalendarFeedWindow.clampPastDays(undefined)).toBe(DEFAULT_PAST_DAYS);
60
+ expect(CalendarFeedWindow.clampPastDays(null)).toBe(DEFAULT_PAST_DAYS);
61
+ expect(CalendarFeedWindow.clampPastDays(Number.NaN)).toBe(
62
+ DEFAULT_PAST_DAYS,
63
+ );
64
+ expect(CalendarFeedWindow.clampPastDays("abc")).toBe(DEFAULT_PAST_DAYS);
65
+ expect(CalendarFeedWindow.clampPastDays("")).toBe(DEFAULT_PAST_DAYS);
66
+ expect(CalendarFeedWindow.clampPastDays(Number.POSITIVE_INFINITY)).toBe(
67
+ DEFAULT_PAST_DAYS,
68
+ );
69
+ expect(CalendarFeedWindow.clampPastDays({})).toBe(DEFAULT_PAST_DAYS);
70
+ });
71
+ });
72
+
73
+ describe("CalendarFeedWindow.clampFutureDays", () => {
74
+ test("keeps values inside MIN..MAX and clamps the rest", () => {
75
+ expect(CalendarFeedWindow.clampFutureDays(7)).toBe(7);
76
+ expect(CalendarFeedWindow.clampFutureDays(90)).toBe(90);
77
+ expect(CalendarFeedWindow.clampFutureDays(180)).toBe(180);
78
+ expect(CalendarFeedWindow.clampFutureDays(181)).toBe(180);
79
+ expect(CalendarFeedWindow.clampFutureDays(6)).toBe(7);
80
+ expect(CalendarFeedWindow.clampFutureDays(0)).toBe(7);
81
+ expect(CalendarFeedWindow.clampFutureDays(-1)).toBe(7);
82
+ });
83
+
84
+ test("falls back to the default for anything that is not a number", () => {
85
+ expect(CalendarFeedWindow.clampFutureDays(undefined)).toBe(
86
+ DEFAULT_FUTURE_DAYS,
87
+ );
88
+ expect(CalendarFeedWindow.clampFutureDays(null)).toBe(DEFAULT_FUTURE_DAYS);
89
+ expect(CalendarFeedWindow.clampFutureDays("x")).toBe(DEFAULT_FUTURE_DAYS);
90
+ expect(CalendarFeedWindow.clampFutureDays("30")).toBe(30);
91
+ });
92
+ });
93
+
94
+ describe("CalendarFeedWindow.computeFeedWindow", () => {
95
+ test("puts both edges on UTC midnights around a mid-day instant", () => {
96
+ const window: FeedWindow = CalendarFeedWindow.computeFeedWindow({
97
+ now: at("2026-08-31T14:37:12Z"),
98
+ pastDays: 2,
99
+ futureDays: 90,
100
+ });
101
+
102
+ expect(window.feedStart.toISOString()).toBe("2026-08-29T00:00:00.000Z");
103
+ // 90 days ahead is 2026-11-29; the exclusive end is the following midnight.
104
+ expect(window.feedEnd.toISOString()).toBe("2026-11-30T00:00:00.000Z");
105
+ });
106
+
107
+ test("is identical for every instant inside the same UTC day", () => {
108
+ const first: FeedWindow = CalendarFeedWindow.computeFeedWindow({
109
+ now: at("2026-08-31T00:00:00Z"),
110
+ pastDays: 2,
111
+ futureDays: 30,
112
+ });
113
+ const last: FeedWindow = CalendarFeedWindow.computeFeedWindow({
114
+ now: at("2026-08-31T23:59:59.999Z"),
115
+ pastDays: 2,
116
+ futureDays: 30,
117
+ });
118
+
119
+ expect(first.feedStart.getTime()).toBe(last.feedStart.getTime());
120
+ expect(first.feedEnd.getTime()).toBe(last.feedEnd.getTime());
121
+ });
122
+
123
+ test("changes at the UTC day boundary, not the local one", () => {
124
+ const before: FeedWindow = CalendarFeedWindow.computeFeedWindow({
125
+ now: at("2026-08-31T23:59:59Z"),
126
+ pastDays: 0,
127
+ futureDays: 7,
128
+ });
129
+ const after: FeedWindow = CalendarFeedWindow.computeFeedWindow({
130
+ now: at("2026-09-01T00:00:00Z"),
131
+ pastDays: 0,
132
+ futureDays: 7,
133
+ });
134
+
135
+ expect(before.feedStart.toISOString()).toBe("2026-08-31T00:00:00.000Z");
136
+ expect(after.feedStart.toISOString()).toBe("2026-09-01T00:00:00.000Z");
137
+ expect(after.feedEnd.getTime() - before.feedEnd.getTime()).toBe(
138
+ 24 * 3600 * 1000,
139
+ );
140
+ });
141
+
142
+ test("clamps the day counts before applying them", () => {
143
+ const window: FeedWindow = CalendarFeedWindow.computeFeedWindow({
144
+ now: at("2026-08-31T12:00:00Z"),
145
+ pastDays: 500,
146
+ futureDays: 1,
147
+ });
148
+
149
+ expect(window.feedStart.toISOString()).toBe("2026-07-02T00:00:00.000Z"); // 60 days back
150
+ expect(window.feedEnd.toISOString()).toBe("2026-09-08T00:00:00.000Z"); // MIN 7 days + 1
151
+ });
152
+
153
+ test("pastDays 0 starts today; the window always spans at least MIN_FUTURE_DAYS + 1 days", () => {
154
+ const window: FeedWindow = CalendarFeedWindow.computeFeedWindow({
155
+ now: at("2026-02-28T09:00:00Z"),
156
+ pastDays: 0,
157
+ futureDays: 7,
158
+ });
159
+
160
+ expect(window.feedStart.toISOString()).toBe("2026-02-28T00:00:00.000Z");
161
+ expect(window.feedEnd.toISOString()).toBe("2026-03-08T00:00:00.000Z");
162
+ expect(
163
+ (window.feedEnd.getTime() - window.feedStart.getTime()) / 86400000,
164
+ ).toBe(8);
165
+ });
166
+
167
+ test("survives leap days and year boundaries", () => {
168
+ const window: FeedWindow = CalendarFeedWindow.computeFeedWindow({
169
+ now: at("2028-02-29T12:00:00Z"),
170
+ pastDays: 1,
171
+ futureDays: 7,
172
+ });
173
+
174
+ expect(window.feedStart.toISOString()).toBe("2028-02-28T00:00:00.000Z");
175
+ expect(window.feedEnd.toISOString()).toBe("2028-03-08T00:00:00.000Z");
176
+
177
+ const newYear: FeedWindow = CalendarFeedWindow.computeFeedWindow({
178
+ now: at("2026-12-31T23:00:00Z"),
179
+ pastDays: 2,
180
+ futureDays: 7,
181
+ });
182
+
183
+ expect(newYear.feedStart.toISOString()).toBe("2026-12-29T00:00:00.000Z");
184
+ expect(newYear.feedEnd.toISOString()).toBe("2027-01-08T00:00:00.000Z");
185
+ });
186
+ });
187
+
188
+ describe("CalendarFeedWindow.startOfUtcDay / getUtcDayBucket", () => {
189
+ test("startOfUtcDay truncates to 00:00:00.000 UTC", () => {
190
+ expect(
191
+ new Date(
192
+ CalendarFeedWindow.startOfUtcDay(at("2026-08-31T23:59:59.999Z")),
193
+ ).toISOString(),
194
+ ).toBe("2026-08-31T00:00:00.000Z");
195
+ });
196
+
197
+ test("getUtcDayBucket is the UTC calendar date", () => {
198
+ expect(CalendarFeedWindow.getUtcDayBucket(at("2026-08-31T23:59:59Z"))).toBe(
199
+ "2026-08-31",
200
+ );
201
+ expect(CalendarFeedWindow.getUtcDayBucket(at("2026-09-01T00:00:00Z"))).toBe(
202
+ "2026-09-01",
203
+ );
204
+ });
205
+ });