@oneuptime/common 12.0.13 → 12.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  2. package/Models/DatabaseModels/UserCall.ts +94 -3
  3. package/Models/DatabaseModels/UserEmail.ts +94 -3
  4. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  5. package/Models/DatabaseModels/UserPush.ts +37 -0
  6. package/Models/DatabaseModels/UserSMS.ts +94 -3
  7. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  8. package/Server/API/BaseAPI.ts +79 -14
  9. package/Server/API/UserCallAPI.ts +53 -45
  10. package/Server/API/UserEmailAPI.ts +53 -44
  11. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  12. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  13. package/Server/API/UserPushAPI.ts +126 -2
  14. package/Server/API/UserSmsAPI.ts +53 -44
  15. package/Server/API/UserWhatsAppAPI.ts +53 -50
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  21. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  22. package/Server/Services/DatabaseService.ts +101 -0
  23. package/Server/Services/LogAggregationService.ts +5 -0
  24. package/Server/Services/PushNotificationService.ts +127 -12
  25. package/Server/Services/TeamMemberService.ts +53 -13
  26. package/Server/Services/UserCallService.ts +55 -24
  27. package/Server/Services/UserEmailService.ts +83 -17
  28. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  29. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  30. package/Server/Services/UserNotificationRuleService.ts +26 -0
  31. package/Server/Services/UserPushService.ts +89 -0
  32. package/Server/Services/UserSmsService.ts +50 -17
  33. package/Server/Services/UserWhatsAppService.ts +48 -15
  34. package/Server/Types/Database/QueryHelper.ts +30 -0
  35. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  36. package/Server/Utils/ChannelVerification.ts +510 -0
  37. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  38. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  39. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  40. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  41. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  42. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  43. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  44. package/Server/Utils/TotpAuth.ts +137 -9
  45. package/Server/Utils/UserRegistrationToken.ts +182 -0
  46. package/Server/Utils/VerificationCode.ts +134 -0
  47. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  48. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  49. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  50. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  51. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  52. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  53. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  54. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  55. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  56. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  57. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  58. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  59. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  60. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  61. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  62. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  63. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  64. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  65. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  66. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  67. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  68. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  69. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  70. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  71. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  72. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  73. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  74. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  75. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  76. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  77. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  78. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  79. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  80. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  81. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  82. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  83. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  84. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  85. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  86. package/Tests/Server/Utils/Browser.test.ts +162 -0
  87. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  88. package/Tests/Server/Utils/Express.test.ts +371 -0
  89. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  90. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  91. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  92. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  93. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  94. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  95. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  96. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  97. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  98. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  99. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  100. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  101. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  102. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  103. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  104. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  105. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  106. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  107. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  108. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  109. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  110. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  111. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  112. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  113. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  114. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  115. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  116. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  117. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  118. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  119. package/Tests/UI/Components/Button.test.tsx +175 -1
  120. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  121. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  122. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  123. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  124. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  125. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  126. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  127. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  128. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  129. package/Tests/UI/Components/List.test.tsx +9 -2
  130. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  131. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  132. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  133. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  134. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  135. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  136. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  137. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  138. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  139. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  140. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  141. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  142. package/Tests/UI/Components/Toast.test.tsx +130 -7
  143. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  144. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  145. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  146. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  147. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  148. package/Tests/Utils/API.test.ts +16 -2
  149. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  150. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  151. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  152. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  153. package/Types/Email/EmailTemplateType.ts +1 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  155. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  156. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  157. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  158. package/Types/Permission.ts +35 -0
  159. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  160. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  161. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  162. package/Types/Service/ServiceLanguage.ts +144 -0
  163. package/Types/Text.ts +111 -19
  164. package/UI/Components/Button/Button.tsx +27 -14
  165. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  166. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  167. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  168. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  169. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  170. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  171. package/UI/Components/CommandPalette/Types.ts +49 -0
  172. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  173. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  174. package/UI/Components/Feed/FeedItem.tsx +1 -1
  175. package/UI/Components/List/List.tsx +37 -5
  176. package/UI/Components/List/ListSkeleton.tsx +54 -0
  177. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  178. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  179. package/UI/Components/Modal/Modal.tsx +2 -2
  180. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  181. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  182. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  183. package/UI/Components/Navbar/NavBar.tsx +14 -1
  184. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  185. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  186. package/UI/Components/SideOver/SideOver.tsx +37 -2
  187. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  188. package/UI/Components/Table/Table.tsx +74 -44
  189. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  190. package/UI/Components/Tabs/Tab.tsx +1 -1
  191. package/UI/Components/Toast/Toast.tsx +118 -53
  192. package/UI/Components/Toast/ToastInit.tsx +82 -32
  193. package/UI/Styles/Theme.css +40 -0
  194. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  195. package/UI/Utils/ModelListCache.ts +188 -0
  196. package/UI/Utils/Project.ts +29 -0
  197. package/Utils/API.ts +6 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  201. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  203. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  205. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  207. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  209. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  211. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  212. package/build/dist/Server/API/BaseAPI.js +69 -13
  213. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  214. package/build/dist/Server/API/UserCallAPI.js +42 -38
  215. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  216. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  217. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  218. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  219. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  220. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  221. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  222. package/build/dist/Server/API/UserPushAPI.js +95 -2
  223. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  224. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  225. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  226. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  227. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  236. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  237. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  239. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  240. package/build/dist/Server/Services/DatabaseService.js +74 -0
  241. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  242. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  243. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  244. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  245. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  246. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  247. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  248. package/build/dist/Server/Services/UserCallService.js +54 -22
  249. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  250. package/build/dist/Server/Services/UserEmailService.js +78 -17
  251. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  252. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  253. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  254. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  255. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  256. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  257. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  258. package/build/dist/Server/Services/UserPushService.js +77 -0
  259. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  260. package/build/dist/Server/Services/UserSmsService.js +50 -17
  261. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  262. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  263. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  264. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  265. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  266. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  267. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  268. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  269. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  270. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  271. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  272. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  273. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  274. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  275. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  276. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  277. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  278. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  279. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  280. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  281. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  282. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  283. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  284. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  285. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  286. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  287. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  288. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  289. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  290. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  291. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  292. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  293. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  294. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  295. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  296. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  297. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  298. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  299. package/build/dist/Types/Permission.js +33 -0
  300. package/build/dist/Types/Permission.js.map +1 -1
  301. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  302. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  303. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  304. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  305. package/build/dist/Types/Text.js +82 -17
  306. package/build/dist/Types/Text.js.map +1 -1
  307. package/build/dist/UI/Components/Button/Button.js +22 -14
  308. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  309. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  310. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  311. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  312. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  313. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  314. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  315. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  316. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  317. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  318. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  319. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  320. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  321. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  322. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  323. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  324. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  325. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  326. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  327. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  328. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  329. package/build/dist/UI/Components/List/List.js +19 -5
  330. package/build/dist/UI/Components/List/List.js.map +1 -1
  331. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  332. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  333. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  334. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  335. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  338. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  340. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  343. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  344. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  345. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  346. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  347. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  348. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  349. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  350. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  351. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  352. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  353. package/build/dist/UI/Components/Table/Table.js +35 -24
  354. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  355. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  356. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  357. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  358. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  359. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  360. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  361. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  362. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  363. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  364. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  365. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  366. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  367. package/build/dist/UI/Utils/Project.js +24 -1
  368. package/build/dist/UI/Utils/Project.js.map +1 -1
  369. package/build/dist/Utils/API.js +6 -1
  370. package/build/dist/Utils/API.js.map +1 -1
  371. package/jest.config.json +1 -1
  372. package/package.json +2 -3
  373. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  374. package/Tests/__mocks__/otpauth.js +0 -30
  375. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  376. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -0,0 +1,707 @@
1
+ import CustomCodeMonitoringCriteria from "../../../../../Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria";
2
+ import {
3
+ CheckOn,
4
+ CriteriaFilter,
5
+ FilterType,
6
+ } from "../../../../../Types/Monitor/CriteriaFilter";
7
+ import CustomCodeMonitorResponse, {
8
+ CustomCodeMonitorResult,
9
+ } from "../../../../../Types/Monitor/CustomCodeMonitor/CustomCodeMonitorResponse";
10
+ import { describe, expect, test } from "@jest/globals";
11
+
12
+ /*
13
+ * CustomCodeMonitoringCriteria.isMonitorInstanceCriteriaFilterMet is the
14
+ * evaluator that turns a custom-code / synthetic monitor's response into a
15
+ * breach message (truthy string) or a "no breach" verdict (null). It only
16
+ * understands three CheckOns exposed by the custom-code criteria UI:
17
+ * ExecutionTime, Error and ResultValue. Every other CheckOn falls through to
18
+ * null. The numeric / string / empty comparisons themselves are delegated to
19
+ * CompareCriteria, so these tests focus on the routing, threshold coercion and
20
+ * precedence rules this class owns, plus the edge cases each branch exposes.
21
+ */
22
+ function buildResponse(input: {
23
+ result?: CustomCodeMonitorResult | undefined;
24
+ scriptError?: string | undefined;
25
+ executionTimeInMS?: number | undefined;
26
+ }): CustomCodeMonitorResponse {
27
+ return {
28
+ result: input.result,
29
+ scriptError: input.scriptError,
30
+ logMessages: [],
31
+ capturedMetrics: [],
32
+ /*
33
+ * executionTimeInMS is typed as a required number, but production data can
34
+ * legitimately arrive undefined (e.g. a script that never started). The
35
+ * cast lets us exercise the `executionTimeInMS || 0` fallback in the
36
+ * source without loosening the response type everywhere.
37
+ */
38
+ executionTimeInMS: input.executionTimeInMS as number,
39
+ };
40
+ }
41
+
42
+ function evaluate(
43
+ monitorResponse: CustomCodeMonitorResponse,
44
+ criteriaFilter: CriteriaFilter,
45
+ ): Promise<string | null> {
46
+ return CustomCodeMonitoringCriteria.isMonitorInstanceCriteriaFilterMet({
47
+ monitorResponse,
48
+ criteriaFilter,
49
+ });
50
+ }
51
+
52
+ describe("CustomCodeMonitoringCriteria.isMonitorInstanceCriteriaFilterMet", () => {
53
+ describe("CheckOn.ExecutionTime (numeric comparison)", () => {
54
+ test("execution above threshold → met with an Execution Time message", async () => {
55
+ const result: string | null = await evaluate(
56
+ buildResponse({ result: "ok", executionTimeInMS: 1500 }),
57
+ {
58
+ checkOn: CheckOn.ExecutionTime,
59
+ filterType: FilterType.GreaterThan,
60
+ value: 1000,
61
+ },
62
+ );
63
+
64
+ expect(result).toBeTruthy();
65
+ expect(result).toContain("Execution Time");
66
+ expect(result).toContain("greater than");
67
+ });
68
+
69
+ test("execution below threshold → not met", async () => {
70
+ expect(
71
+ await evaluate(
72
+ buildResponse({ result: "ok", executionTimeInMS: 500 }),
73
+ {
74
+ checkOn: CheckOn.ExecutionTime,
75
+ filterType: FilterType.GreaterThan,
76
+ value: 1000,
77
+ },
78
+ ),
79
+ ).toBeNull();
80
+ });
81
+
82
+ test("execution equal to threshold with GreaterThan → not met (strict)", async () => {
83
+ expect(
84
+ await evaluate(
85
+ buildResponse({ result: "ok", executionTimeInMS: 1000 }),
86
+ {
87
+ checkOn: CheckOn.ExecutionTime,
88
+ filterType: FilterType.GreaterThan,
89
+ value: 1000,
90
+ },
91
+ ),
92
+ ).toBeNull();
93
+ });
94
+
95
+ test("GreaterThanOrEqualTo is met exactly at the boundary", async () => {
96
+ expect(
97
+ await evaluate(
98
+ buildResponse({ result: "ok", executionTimeInMS: 1000 }),
99
+ {
100
+ checkOn: CheckOn.ExecutionTime,
101
+ filterType: FilterType.GreaterThanOrEqualTo,
102
+ value: 1000,
103
+ },
104
+ ),
105
+ ).toBeTruthy();
106
+ });
107
+
108
+ test("LessThanOrEqualTo is met exactly at the boundary", async () => {
109
+ expect(
110
+ await evaluate(
111
+ buildResponse({ result: "ok", executionTimeInMS: 1000 }),
112
+ {
113
+ checkOn: CheckOn.ExecutionTime,
114
+ filterType: FilterType.LessThanOrEqualTo,
115
+ value: 1000,
116
+ },
117
+ ),
118
+ ).toBeTruthy();
119
+ });
120
+
121
+ test("EqualTo matches an exact execution time", async () => {
122
+ expect(
123
+ await evaluate(
124
+ buildResponse({ result: "ok", executionTimeInMS: 750 }),
125
+ {
126
+ checkOn: CheckOn.ExecutionTime,
127
+ filterType: FilterType.EqualTo,
128
+ value: 750,
129
+ },
130
+ ),
131
+ ).toBeTruthy();
132
+ });
133
+
134
+ test("NotEqualTo is met when the times differ", async () => {
135
+ expect(
136
+ await evaluate(
137
+ buildResponse({ result: "ok", executionTimeInMS: 749 }),
138
+ {
139
+ checkOn: CheckOn.ExecutionTime,
140
+ filterType: FilterType.NotEqualTo,
141
+ value: 750,
142
+ },
143
+ ),
144
+ ).toBeTruthy();
145
+ });
146
+
147
+ test("a string threshold is coerced to a number (parseInt)", async () => {
148
+ expect(
149
+ await evaluate(
150
+ buildResponse({ result: "ok", executionTimeInMS: 1500 }),
151
+ {
152
+ checkOn: CheckOn.ExecutionTime,
153
+ filterType: FilterType.GreaterThan,
154
+ value: "1000",
155
+ },
156
+ ),
157
+ ).toBeTruthy();
158
+ });
159
+
160
+ test("a threshold of 0 is honored (not dropped as falsy)", async () => {
161
+ expect(
162
+ await evaluate(buildResponse({ result: "ok", executionTimeInMS: 5 }), {
163
+ checkOn: CheckOn.ExecutionTime,
164
+ filterType: FilterType.GreaterThan,
165
+ value: 0,
166
+ }),
167
+ ).toBeTruthy();
168
+ });
169
+
170
+ test("a missing executionTimeInMS is treated as 0", async () => {
171
+ /* undefined execution time → 0, which is < 100 → met. */
172
+ const result: string | null = await evaluate(
173
+ buildResponse({ result: "ok", executionTimeInMS: undefined }),
174
+ {
175
+ checkOn: CheckOn.ExecutionTime,
176
+ filterType: FilterType.LessThan,
177
+ value: 100,
178
+ },
179
+ );
180
+
181
+ expect(result).toBeTruthy();
182
+ });
183
+
184
+ test("a missing executionTimeInMS (0) is not greater than 0", async () => {
185
+ expect(
186
+ await evaluate(
187
+ buildResponse({ result: "ok", executionTimeInMS: undefined }),
188
+ {
189
+ checkOn: CheckOn.ExecutionTime,
190
+ filterType: FilterType.GreaterThan,
191
+ value: 0,
192
+ },
193
+ ),
194
+ ).toBeNull();
195
+ });
196
+
197
+ test("an undefined threshold makes the comparison a no-op → not met", async () => {
198
+ expect(
199
+ await evaluate(
200
+ buildResponse({ result: "ok", executionTimeInMS: 5000 }),
201
+ {
202
+ checkOn: CheckOn.ExecutionTime,
203
+ filterType: FilterType.GreaterThan,
204
+ value: undefined,
205
+ },
206
+ ),
207
+ ).toBeNull();
208
+ });
209
+
210
+ test("a non-numeric string threshold is discarded (NaN guard) → not met", async () => {
211
+ expect(
212
+ await evaluate(
213
+ buildResponse({ result: "ok", executionTimeInMS: 5000 }),
214
+ {
215
+ checkOn: CheckOn.ExecutionTime,
216
+ filterType: FilterType.GreaterThan,
217
+ value: "not-a-number",
218
+ },
219
+ ),
220
+ ).toBeNull();
221
+ });
222
+ });
223
+
224
+ describe("CheckOn.Error (empty / not-empty and string comparison)", () => {
225
+ test("IsEmpty is met when there is no scriptError", async () => {
226
+ const result: string | null = await evaluate(
227
+ buildResponse({ result: "ok", scriptError: undefined }),
228
+ {
229
+ checkOn: CheckOn.Error,
230
+ filterType: FilterType.IsEmpty,
231
+ value: undefined,
232
+ },
233
+ );
234
+
235
+ expect(result).toBeTruthy();
236
+ expect(result).toContain("Error");
237
+ expect(result).toContain("empty");
238
+ });
239
+
240
+ test("IsEmpty is not met when a scriptError is present", async () => {
241
+ expect(
242
+ await evaluate(buildResponse({ result: "ok", scriptError: "Boom" }), {
243
+ checkOn: CheckOn.Error,
244
+ filterType: FilterType.IsEmpty,
245
+ value: undefined,
246
+ }),
247
+ ).toBeNull();
248
+ });
249
+
250
+ test("IsNotEmpty is met and echoes the error value", async () => {
251
+ const result: string | null = await evaluate(
252
+ buildResponse({ result: "ok", scriptError: "Boom" }),
253
+ {
254
+ checkOn: CheckOn.Error,
255
+ filterType: FilterType.IsNotEmpty,
256
+ value: undefined,
257
+ },
258
+ );
259
+
260
+ expect(result).toBeTruthy();
261
+ expect(result).toContain("Error");
262
+ expect(result).toContain("Boom");
263
+ });
264
+
265
+ test("IsNotEmpty is not met when there is no scriptError", async () => {
266
+ expect(
267
+ await evaluate(
268
+ buildResponse({ result: "ok", scriptError: undefined }),
269
+ {
270
+ checkOn: CheckOn.Error,
271
+ filterType: FilterType.IsNotEmpty,
272
+ value: undefined,
273
+ },
274
+ ),
275
+ ).toBeNull();
276
+ });
277
+
278
+ test("an empty-string scriptError counts as NOT empty", async () => {
279
+ /*
280
+ * compareEmptyAndNotEmpty only treats null / undefined as empty, so an
281
+ * empty string is reported as "not empty" (with an empty value).
282
+ */
283
+ expect(
284
+ await evaluate(buildResponse({ result: "ok", scriptError: "" }), {
285
+ checkOn: CheckOn.Error,
286
+ filterType: FilterType.IsNotEmpty,
287
+ value: undefined,
288
+ }),
289
+ ).toBeTruthy();
290
+ });
291
+
292
+ test("an empty-string scriptError is therefore not met by IsEmpty", async () => {
293
+ expect(
294
+ await evaluate(buildResponse({ result: "ok", scriptError: "" }), {
295
+ checkOn: CheckOn.Error,
296
+ filterType: FilterType.IsEmpty,
297
+ value: undefined,
298
+ }),
299
+ ).toBeNull();
300
+ });
301
+
302
+ test("Contains matches a substring of the scriptError", async () => {
303
+ const result: string | null = await evaluate(
304
+ buildResponse({
305
+ result: "ok",
306
+ scriptError: "TypeError: x is undefined",
307
+ }),
308
+ {
309
+ checkOn: CheckOn.Error,
310
+ filterType: FilterType.Contains,
311
+ value: "TypeError",
312
+ },
313
+ );
314
+
315
+ expect(result).toBeTruthy();
316
+ expect(result).toContain("contains");
317
+ });
318
+
319
+ test("Contains is not met when the substring is absent", async () => {
320
+ expect(
321
+ await evaluate(
322
+ buildResponse({
323
+ result: "ok",
324
+ scriptError: "TypeError: x is undefined",
325
+ }),
326
+ {
327
+ checkOn: CheckOn.Error,
328
+ filterType: FilterType.Contains,
329
+ value: "SyntaxError",
330
+ },
331
+ ),
332
+ ).toBeNull();
333
+ });
334
+
335
+ test("NotContains is met when the substring is absent", async () => {
336
+ expect(
337
+ await evaluate(
338
+ buildResponse({ result: "ok", scriptError: "Timeout after 30s" }),
339
+ {
340
+ checkOn: CheckOn.Error,
341
+ filterType: FilterType.NotContains,
342
+ value: "TypeError",
343
+ },
344
+ ),
345
+ ).toBeTruthy();
346
+ });
347
+
348
+ test("StartsWith matches the leading text", async () => {
349
+ expect(
350
+ await evaluate(
351
+ buildResponse({ result: "ok", scriptError: "TypeError: boom" }),
352
+ {
353
+ checkOn: CheckOn.Error,
354
+ filterType: FilterType.StartsWith,
355
+ value: "TypeError",
356
+ },
357
+ ),
358
+ ).toBeTruthy();
359
+ });
360
+
361
+ test("EndsWith matches the trailing text", async () => {
362
+ expect(
363
+ await evaluate(
364
+ buildResponse({ result: "ok", scriptError: "failed: boom" }),
365
+ {
366
+ checkOn: CheckOn.Error,
367
+ filterType: FilterType.EndsWith,
368
+ value: "boom",
369
+ },
370
+ ),
371
+ ).toBeTruthy();
372
+ });
373
+
374
+ test("EqualTo matches an exact error string", async () => {
375
+ const result: string | null = await evaluate(
376
+ buildResponse({ result: "ok", scriptError: "boom" }),
377
+ {
378
+ checkOn: CheckOn.Error,
379
+ filterType: FilterType.EqualTo,
380
+ value: "boom",
381
+ },
382
+ );
383
+
384
+ expect(result).toBeTruthy();
385
+ expect(result).toContain("equal to");
386
+ });
387
+
388
+ test("NotEqualTo is met when the error strings differ", async () => {
389
+ expect(
390
+ await evaluate(buildResponse({ result: "ok", scriptError: "boom" }), {
391
+ checkOn: CheckOn.Error,
392
+ filterType: FilterType.NotEqualTo,
393
+ value: "bang",
394
+ }),
395
+ ).toBeTruthy();
396
+ });
397
+
398
+ test("a string filter with no scriptError falls through to null", async () => {
399
+ /*
400
+ * The string-comparison block requires scriptError to be a string, so a
401
+ * Contains filter against an absent error is a no-op (and IsEmpty /
402
+ * IsNotEmpty did not fire either) → null.
403
+ */
404
+ expect(
405
+ await evaluate(
406
+ buildResponse({ result: "ok", scriptError: undefined }),
407
+ {
408
+ checkOn: CheckOn.Error,
409
+ filterType: FilterType.Contains,
410
+ value: "TypeError",
411
+ },
412
+ ),
413
+ ).toBeNull();
414
+ });
415
+
416
+ test("IsNotEmpty truncates a very long error to 500 chars plus an ellipsis", async () => {
417
+ const longError: string = "e".repeat(600);
418
+
419
+ const result: string | null = await evaluate(
420
+ buildResponse({ result: "ok", scriptError: longError }),
421
+ {
422
+ checkOn: CheckOn.Error,
423
+ filterType: FilterType.IsNotEmpty,
424
+ value: undefined,
425
+ },
426
+ );
427
+
428
+ expect(result).toBeTruthy();
429
+ expect(result!.endsWith("...")).toBe(true);
430
+ /* The full 600-char body must not be echoed verbatim. */
431
+ expect(result).not.toContain(longError);
432
+ });
433
+ });
434
+
435
+ describe("CheckOn.ResultValue (empty / numeric / string precedence)", () => {
436
+ test("numeric result above a numeric threshold → met", async () => {
437
+ const result: string | null = await evaluate(
438
+ buildResponse({ result: 42 }),
439
+ {
440
+ checkOn: CheckOn.ResultValue,
441
+ filterType: FilterType.GreaterThan,
442
+ value: 40,
443
+ },
444
+ );
445
+
446
+ expect(result).toBeTruthy();
447
+ expect(result).toContain("Result Value");
448
+ expect(result).toContain("greater than");
449
+ });
450
+
451
+ test("numeric result below a numeric threshold → not met", async () => {
452
+ expect(
453
+ await evaluate(buildResponse({ result: 42 }), {
454
+ checkOn: CheckOn.ResultValue,
455
+ filterType: FilterType.LessThan,
456
+ value: 40,
457
+ }),
458
+ ).toBeNull();
459
+ });
460
+
461
+ test("numeric result at the boundary with GreaterThanOrEqualTo → met", async () => {
462
+ expect(
463
+ await evaluate(buildResponse({ result: 40 }), {
464
+ checkOn: CheckOn.ResultValue,
465
+ filterType: FilterType.GreaterThanOrEqualTo,
466
+ value: 40,
467
+ }),
468
+ ).toBeTruthy();
469
+ });
470
+
471
+ test("numeric result with EqualTo → met on an exact match", async () => {
472
+ expect(
473
+ await evaluate(buildResponse({ result: 42 }), {
474
+ checkOn: CheckOn.ResultValue,
475
+ filterType: FilterType.EqualTo,
476
+ value: 42,
477
+ }),
478
+ ).toBeTruthy();
479
+ });
480
+
481
+ test("numeric result with a string threshold uses parseFloat (decimals kept)", async () => {
482
+ expect(
483
+ await evaluate(buildResponse({ result: 40.6 }), {
484
+ checkOn: CheckOn.ResultValue,
485
+ filterType: FilterType.GreaterThan,
486
+ value: "40.5",
487
+ }),
488
+ ).toBeTruthy();
489
+ });
490
+
491
+ test("string result with EqualTo → met on an exact match", async () => {
492
+ const result: string | null = await evaluate(
493
+ buildResponse({ result: "success" }),
494
+ {
495
+ checkOn: CheckOn.ResultValue,
496
+ filterType: FilterType.EqualTo,
497
+ value: "success",
498
+ },
499
+ );
500
+
501
+ expect(result).toBeTruthy();
502
+ expect(result).toContain("equal to");
503
+ });
504
+
505
+ test("string result with Contains → met on a substring", async () => {
506
+ expect(
507
+ await evaluate(buildResponse({ result: "healthy: true" }), {
508
+ checkOn: CheckOn.ResultValue,
509
+ filterType: FilterType.Contains,
510
+ value: "healthy",
511
+ }),
512
+ ).toBeTruthy();
513
+ });
514
+
515
+ test("string result with NotContains → met when absent", async () => {
516
+ expect(
517
+ await evaluate(buildResponse({ result: "error state" }), {
518
+ checkOn: CheckOn.ResultValue,
519
+ filterType: FilterType.NotContains,
520
+ value: "ok",
521
+ }),
522
+ ).toBeTruthy();
523
+ });
524
+
525
+ test("string result with StartsWith → met", async () => {
526
+ expect(
527
+ await evaluate(buildResponse({ result: "prefix-abc" }), {
528
+ checkOn: CheckOn.ResultValue,
529
+ filterType: FilterType.StartsWith,
530
+ value: "prefix",
531
+ }),
532
+ ).toBeTruthy();
533
+ });
534
+
535
+ test("string result with EndsWith → met", async () => {
536
+ expect(
537
+ await evaluate(buildResponse({ result: "abc-suffix" }), {
538
+ checkOn: CheckOn.ResultValue,
539
+ filterType: FilterType.EndsWith,
540
+ value: "suffix",
541
+ }),
542
+ ).toBeTruthy();
543
+ });
544
+
545
+ test("IsEmpty is met when the result is undefined", async () => {
546
+ const result: string | null = await evaluate(
547
+ buildResponse({ result: undefined }),
548
+ {
549
+ checkOn: CheckOn.ResultValue,
550
+ filterType: FilterType.IsEmpty,
551
+ value: undefined,
552
+ },
553
+ );
554
+
555
+ expect(result).toBeTruthy();
556
+ expect(result).toContain("empty");
557
+ });
558
+
559
+ test("IsEmpty is met when the result is null", async () => {
560
+ expect(
561
+ await evaluate(buildResponse({ result: null }), {
562
+ checkOn: CheckOn.ResultValue,
563
+ filterType: FilterType.IsEmpty,
564
+ value: undefined,
565
+ }),
566
+ ).toBeTruthy();
567
+ });
568
+
569
+ test("IsEmpty is NOT met when the result is 0 (a real value)", async () => {
570
+ /* 0 is a legitimate result, not "empty" — only null/undefined are. */
571
+ expect(
572
+ await evaluate(buildResponse({ result: 0 }), {
573
+ checkOn: CheckOn.ResultValue,
574
+ filterType: FilterType.IsEmpty,
575
+ value: undefined,
576
+ }),
577
+ ).toBeNull();
578
+ });
579
+
580
+ test("IsNotEmpty is met and echoes a present result", async () => {
581
+ const result: string | null = await evaluate(
582
+ buildResponse({ result: "data" }),
583
+ {
584
+ checkOn: CheckOn.ResultValue,
585
+ filterType: FilterType.IsNotEmpty,
586
+ value: undefined,
587
+ },
588
+ );
589
+
590
+ expect(result).toBeTruthy();
591
+ expect(result).toContain("data");
592
+ });
593
+
594
+ test("IsNotEmpty is not met when the result is undefined", async () => {
595
+ expect(
596
+ await evaluate(buildResponse({ result: undefined }), {
597
+ checkOn: CheckOn.ResultValue,
598
+ filterType: FilterType.IsNotEmpty,
599
+ value: undefined,
600
+ }),
601
+ ).toBeNull();
602
+ });
603
+
604
+ test("empty/not-empty takes precedence over the numeric comparison", async () => {
605
+ /*
606
+ * A numeric result with IsNotEmpty short-circuits into the not-empty
607
+ * message before any threshold comparison is attempted.
608
+ */
609
+ const result: string | null = await evaluate(
610
+ buildResponse({ result: 42 }),
611
+ {
612
+ checkOn: CheckOn.ResultValue,
613
+ filterType: FilterType.IsNotEmpty,
614
+ value: undefined,
615
+ },
616
+ );
617
+
618
+ expect(result).toBeTruthy();
619
+ expect(result).toContain("not empty");
620
+ });
621
+
622
+ test("a boolean result is reported by IsNotEmpty but is not numerically comparable", async () => {
623
+ expect(
624
+ await evaluate(buildResponse({ result: true }), {
625
+ checkOn: CheckOn.ResultValue,
626
+ filterType: FilterType.IsNotEmpty,
627
+ value: undefined,
628
+ }),
629
+ ).toBeTruthy();
630
+
631
+ /*
632
+ * GreaterThan on a boolean result matches neither the numeric nor the
633
+ * string branch, so it falls through to null.
634
+ */
635
+ expect(
636
+ await evaluate(buildResponse({ result: true }), {
637
+ checkOn: CheckOn.ResultValue,
638
+ filterType: FilterType.GreaterThan,
639
+ value: 0,
640
+ }),
641
+ ).toBeNull();
642
+ });
643
+
644
+ test("a numeric result with an unmatched string filter → not met", async () => {
645
+ /*
646
+ * Contains is not a numeric comparator, and a number is not a string, so
647
+ * neither branch fires → null.
648
+ */
649
+ expect(
650
+ await evaluate(buildResponse({ result: 42 }), {
651
+ checkOn: CheckOn.ResultValue,
652
+ filterType: FilterType.Contains,
653
+ value: "4",
654
+ }),
655
+ ).toBeNull();
656
+ });
657
+
658
+ test("a numeric-looking string result is not compared numerically", async () => {
659
+ /*
660
+ * "42" is a string, so it goes through compareCriteriaStrings, which has
661
+ * no GreaterThan handling → null (no lexicographic-as-numeric surprise).
662
+ */
663
+ expect(
664
+ await evaluate(buildResponse({ result: "42" }), {
665
+ checkOn: CheckOn.ResultValue,
666
+ filterType: FilterType.GreaterThan,
667
+ value: "40",
668
+ }),
669
+ ).toBeNull();
670
+ });
671
+
672
+ test("a string result with an undefined threshold → not met", async () => {
673
+ expect(
674
+ await evaluate(buildResponse({ result: "success" }), {
675
+ checkOn: CheckOn.ResultValue,
676
+ filterType: FilterType.EqualTo,
677
+ value: undefined,
678
+ }),
679
+ ).toBeNull();
680
+ });
681
+ });
682
+
683
+ describe("unhandled CheckOns", () => {
684
+ test("a non custom-code CheckOn returns null", async () => {
685
+ expect(
686
+ await evaluate(buildResponse({ result: 100, executionTimeInMS: 100 }), {
687
+ checkOn: CheckOn.LogCount,
688
+ filterType: FilterType.GreaterThan,
689
+ value: 0,
690
+ }),
691
+ ).toBeNull();
692
+ });
693
+
694
+ test("CheckOn.ResponseTime is not handled by the custom-code evaluator", async () => {
695
+ expect(
696
+ await evaluate(
697
+ buildResponse({ result: "ok", executionTimeInMS: 5000 }),
698
+ {
699
+ checkOn: CheckOn.ResponseTime,
700
+ filterType: FilterType.GreaterThan,
701
+ value: 10,
702
+ },
703
+ ),
704
+ ).toBeNull();
705
+ });
706
+ });
707
+ });