@oneuptime/common 12.0.6 → 12.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (594) hide show
  1. package/Models/DatabaseModels/AIInsight.ts +1 -1
  2. package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
  3. package/Models/DatabaseModels/DeletedProject.ts +595 -0
  4. package/Models/DatabaseModels/Index.ts +2 -0
  5. package/Models/DatabaseModels/Monitor.ts +111 -0
  6. package/Models/DatabaseModels/Project.ts +3 -3
  7. package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
  8. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
  9. package/Models/DatabaseModels/WorkflowLog.ts +38 -0
  10. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
  11. package/Server/API/FileAPI.ts +15 -2
  12. package/Server/API/MicrosoftTeamsAPI.ts +6 -1
  13. package/Server/API/ProjectAPI.ts +214 -0
  14. package/Server/API/StatusPageAPI.ts +39 -6
  15. package/Server/API/UserAPI.ts +16 -1
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  22. package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
  23. package/Server/Services/AIAgentService.ts +20 -0
  24. package/Server/Services/DashboardDomainService.ts +73 -28
  25. package/Server/Services/DatabaseService.ts +1 -0
  26. package/Server/Services/DeletedProjectService.ts +138 -0
  27. package/Server/Services/FileService.ts +61 -0
  28. package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
  29. package/Server/Services/IncidentPublicNoteService.ts +18 -0
  30. package/Server/Services/Index.ts +2 -0
  31. package/Server/Services/MonitorService.ts +311 -0
  32. package/Server/Services/ProbeService.ts +20 -0
  33. package/Server/Services/ProjectService.ts +297 -1
  34. package/Server/Services/PushNotificationService.ts +71 -0
  35. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
  36. package/Server/Services/StatusPageAnnouncementService.ts +53 -0
  37. package/Server/Services/StatusPageDomainService.ts +73 -28
  38. package/Server/Services/TeamMemberService.ts +117 -12
  39. package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
  40. package/Server/Services/TelemetryEntityService.ts +114 -1
  41. package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
  42. package/Server/Services/UserWebhookService.ts +34 -109
  43. package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
  44. package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
  45. package/Server/Types/Database/DeleteById.ts +2 -0
  46. package/Server/Types/Database/DeleteOneBy.ts +6 -0
  47. package/Server/Types/Domain.ts +41 -0
  48. package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
  49. package/Server/Types/Workflow/Components/API/Get.ts +2 -1
  50. package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
  51. package/Server/Types/Workflow/Components/API/Post.ts +2 -1
  52. package/Server/Types/Workflow/Components/API/Put.ts +2 -1
  53. package/Server/Types/Workflow/Components/API/Utils.ts +85 -3
  54. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
  55. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
  56. package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
  57. package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
  58. package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
  59. package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
  60. package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
  61. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
  62. package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
  63. package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
  64. package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
  65. package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
  66. package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
  67. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
  68. package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
  69. package/Server/Types/Workflow/TriggerCode.ts +12 -0
  70. package/Server/Types/Workflow/Workflow.ts +5 -0
  71. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  72. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
  73. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
  74. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
  75. package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
  76. package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
  77. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
  78. package/Server/Utils/DataSource/EgressGuard.ts +176 -16
  79. package/Server/Utils/DataSource/HttpFetch.ts +6 -45
  80. package/Server/Utils/Execute.ts +8 -0
  81. package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
  82. package/Server/Utils/LLM/LLMService.ts +57 -12
  83. package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
  84. package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
  85. package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
  86. package/Server/Utils/Monitor/MonitorResource.ts +36 -0
  87. package/Server/Utils/Response.ts +142 -6
  88. package/Server/Utils/SSRFProtection.ts +273 -60
  89. package/Server/Utils/StartServer.ts +8 -0
  90. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
  91. package/Server/Utils/VM/VMAPI.ts +56 -8
  92. package/Server/Utils/VM/VMRunner.ts +88 -1
  93. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
  94. package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
  95. package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
  96. package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
  97. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
  98. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
  99. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
  100. package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
  101. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
  102. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
  103. package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
  104. package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
  105. package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
  106. package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
  107. package/Tests/Server/API/ProjectAPI.test.ts +299 -1
  108. package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
  109. package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
  110. package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
  111. package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
  112. package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
  113. package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
  114. package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
  115. package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
  116. package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
  117. package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
  118. package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
  119. package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
  120. package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
  121. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
  122. package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
  123. package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
  124. package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
  125. package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
  126. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
  127. package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
  128. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
  129. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
  130. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
  131. package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
  132. package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
  133. package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
  134. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
  135. package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
  136. package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
  137. package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
  138. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
  139. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
  140. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
  141. package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
  142. package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
  143. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
  144. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
  145. package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
  146. package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
  147. package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
  148. package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
  149. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
  150. package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
  151. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
  152. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
  153. package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
  154. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
  155. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
  156. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
  157. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
  158. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
  159. package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
  160. package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
  161. package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
  162. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
  163. package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
  164. package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
  165. package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
  166. package/Tests/Types/JSONFunctions.test.ts +252 -1
  167. package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
  168. package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
  169. package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
  170. package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
  171. package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
  172. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
  173. package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
  174. package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
  175. package/Tests/Types/Workflow/Templates.test.ts +403 -0
  176. package/Tests/UI/Components/404.test.tsx +1 -1
  177. package/Tests/UI/Components/Alert.test.tsx +1 -1
  178. package/Tests/UI/Components/Badge.test.tsx +1 -1
  179. package/Tests/UI/Components/BasicForm.test.tsx +39 -10
  180. package/Tests/UI/Components/Button.test.tsx +1 -1
  181. package/Tests/UI/Components/Card.test.tsx +1 -1
  182. package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
  183. package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
  184. package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
  185. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
  186. package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
  187. package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
  188. package/Tests/UI/Components/Dropdown.test.tsx +1 -1
  189. package/Tests/UI/Components/FilePicker.test.tsx +1 -1
  190. package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
  191. package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
  192. package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
  193. package/Tests/UI/Components/HiddenText.test.tsx +1 -1
  194. package/Tests/UI/Components/Input.test.tsx +1 -1
  195. package/Tests/UI/Components/Loader.test.tsx +1 -1
  196. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +43 -1
  197. package/Tests/UI/Components/MasterPage.test.tsx +1 -1
  198. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +579 -0
  199. package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
  200. package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
  201. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
  202. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
  203. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
  204. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
  205. package/Tests/UI/Components/NavBar.test.tsx +1 -1
  206. package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
  207. package/Tests/UI/Components/Pagination.test.tsx +1 -1
  208. package/Tests/UI/Components/Pill.test.tsx +1 -1
  209. package/Tests/UI/Components/Probe.test.tsx +1 -1
  210. package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
  211. package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
  212. package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
  213. package/Tests/UI/Components/SideOver.test.tsx +500 -6
  214. package/Tests/UI/Components/Tabs.test.tsx +1 -1
  215. package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
  216. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +50 -8
  217. package/Tests/UI/Components/TextArea.test.tsx +1 -1
  218. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
  219. package/Tests/UI/Components/Toast.test.tsx +1 -1
  220. package/Tests/UI/Components/Toggle.test.tsx +1 -1
  221. package/Tests/UI/Components/TopSection.test.tsx +1 -1
  222. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
  223. package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
  224. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
  225. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
  226. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
  227. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
  228. package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
  229. package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
  230. package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
  231. package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
  232. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
  233. package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
  234. package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
  235. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
  236. package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
  237. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
  238. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
  239. package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
  240. package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
  241. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
  242. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
  243. package/Tests/Utils/Realtime.test.ts +78 -0
  244. package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
  245. package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
  246. package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
  247. package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
  248. package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
  249. package/Types/AI/FixPullRequestCiStatus.ts +1 -1
  250. package/Types/AI/FixVerificationStatus.ts +2 -2
  251. package/Types/API/Hostname.ts +92 -4
  252. package/Types/API/URL.ts +43 -25
  253. package/Types/Billing/BalanceAdjustmentType.ts +14 -0
  254. package/Types/Billing/ProjectBalanceType.ts +13 -0
  255. package/Types/Domain.ts +26 -0
  256. package/Types/File/MimeType.ts +11 -0
  257. package/Types/JSONFunctions.ts +15 -0
  258. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
  259. package/Types/SerializableObjectDictionary.ts +133 -39
  260. package/Types/Telemetry/EntitySource.ts +40 -0
  261. package/Types/Telemetry/EntityType.ts +27 -0
  262. package/Types/Telemetry/EntityTypeGroups.ts +65 -0
  263. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
  264. package/Types/Workflow/Component.ts +29 -0
  265. package/Types/Workflow/Components/API.ts +35 -0
  266. package/Types/Workflow/Components/BaseModel.ts +96 -28
  267. package/Types/Workflow/StepTrace.ts +181 -0
  268. package/Types/Workflow/TemplateSyntax.ts +499 -0
  269. package/Types/Workflow/Templates.ts +316 -0
  270. package/Typings/Index.d.ts +12 -0
  271. package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
  272. package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
  273. package/UI/Components/Dictionary/Dictionary.tsx +23 -6
  274. package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
  275. package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
  276. package/UI/Components/Forms/Types/Field.ts +7 -0
  277. package/UI/Components/Forms/Validation.ts +63 -1
  278. package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
  279. package/UI/Components/Input/Input.tsx +31 -3
  280. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
  281. package/UI/Components/Modal/ConfirmModal.tsx +10 -5
  282. package/UI/Components/Modal/Modal.tsx +64 -51
  283. package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
  284. package/UI/Components/SideOver/SideOver.tsx +195 -68
  285. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
  286. package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
  287. package/UI/Components/Workflow/Component.tsx +28 -26
  288. package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
  289. package/UI/Components/Workflow/GraphLint.ts +591 -0
  290. package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
  291. package/UI/Components/Workflow/ModelSchema.ts +196 -0
  292. package/UI/Components/Workflow/RunForm.tsx +41 -7
  293. package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
  294. package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
  295. package/UI/Components/Workflow/Utils.ts +93 -1
  296. package/UI/Components/Workflow/Workflow.tsx +77 -4
  297. package/UI/Types/LayeredDismissal.ts +31 -0
  298. package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
  299. package/UI/Utils/PageScrollLock.ts +66 -0
  300. package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
  301. package/Utils/Dashboard/VariableInterpolation.ts +19 -1
  302. package/Utils/LegacySerializedArray.ts +60 -0
  303. package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
  304. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
  305. package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
  306. package/Utils/Telemetry/EntityKey.ts +66 -0
  307. package/Utils/Telemetry/SavedViewFilters.ts +88 -0
  308. package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
  309. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
  311. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
  313. package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
  314. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  315. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  316. package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
  317. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  318. package/build/dist/Models/DatabaseModels/Project.js +3 -3
  319. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  320. package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
  321. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
  322. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
  323. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
  324. package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
  325. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  326. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  327. package/build/dist/Server/API/FileAPI.js +14 -2
  328. package/build/dist/Server/API/FileAPI.js.map +1 -1
  329. package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
  330. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  331. package/build/dist/Server/API/ProjectAPI.js +157 -4
  332. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  333. package/build/dist/Server/API/StatusPageAPI.js +27 -3
  334. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  335. package/build/dist/Server/API/UserAPI.js +16 -1
  336. package/build/dist/Server/API/UserAPI.js.map +1 -1
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  349. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
  350. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  351. package/build/dist/Server/Services/AIAgentService.js +17 -0
  352. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  353. package/build/dist/Server/Services/DashboardDomainService.js +55 -18
  354. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  355. package/build/dist/Server/Services/DatabaseService.js +1 -0
  356. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  357. package/build/dist/Server/Services/DeletedProjectService.js +124 -0
  358. package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
  359. package/build/dist/Server/Services/FileService.js +52 -0
  360. package/build/dist/Server/Services/FileService.js.map +1 -1
  361. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
  362. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  363. package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
  364. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  365. package/build/dist/Server/Services/Index.js +2 -0
  366. package/build/dist/Server/Services/Index.js.map +1 -1
  367. package/build/dist/Server/Services/MonitorService.js +232 -0
  368. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  369. package/build/dist/Server/Services/ProbeService.js +17 -0
  370. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  371. package/build/dist/Server/Services/ProjectService.js +228 -6
  372. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  373. package/build/dist/Server/Services/PushNotificationService.js +56 -0
  374. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  375. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
  376. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  377. package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
  378. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  379. package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
  380. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  381. package/build/dist/Server/Services/TeamMemberService.js +97 -6
  382. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  383. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
  384. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  385. package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
  386. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  387. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
  388. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  389. package/build/dist/Server/Services/UserWebhookService.js +31 -87
  390. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  391. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
  392. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  393. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
  394. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  395. package/build/dist/Server/Types/Domain.js +37 -0
  396. package/build/dist/Server/Types/Domain.js.map +1 -1
  397. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
  398. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  399. package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
  400. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  401. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
  402. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  403. package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
  404. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  405. package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
  406. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  407. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +63 -2
  408. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  409. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
  410. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  411. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
  412. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  413. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
  414. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
  415. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
  416. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
  417. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
  418. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
  419. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
  420. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
  421. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
  422. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
  423. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
  424. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
  425. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
  426. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
  427. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
  428. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
  429. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
  430. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
  431. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
  432. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
  433. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
  434. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
  435. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
  436. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  437. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
  438. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
  439. package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
  440. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  441. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
  442. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
  443. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
  444. package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
  445. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
  446. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
  447. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
  448. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  449. package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
  450. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  451. package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
  452. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  453. package/build/dist/Server/Utils/Execute.js +2 -2
  454. package/build/dist/Server/Utils/Execute.js.map +1 -1
  455. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
  456. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
  457. package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
  458. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
  460. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  461. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
  462. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
  464. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  465. package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
  466. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  467. package/build/dist/Server/Utils/Response.js +112 -5
  468. package/build/dist/Server/Utils/Response.js.map +1 -1
  469. package/build/dist/Server/Utils/SSRFProtection.js +219 -53
  470. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  471. package/build/dist/Server/Utils/StartServer.js +7 -0
  472. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  473. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
  474. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
  475. package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
  476. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  477. package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
  478. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  479. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
  480. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  481. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
  482. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  483. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  484. package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
  485. package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
  486. package/build/dist/Types/API/Hostname.js +73 -4
  487. package/build/dist/Types/API/Hostname.js.map +1 -1
  488. package/build/dist/Types/API/URL.js +42 -24
  489. package/build/dist/Types/API/URL.js.map +1 -1
  490. package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
  491. package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
  492. package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
  493. package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
  494. package/build/dist/Types/Domain.js +22 -0
  495. package/build/dist/Types/Domain.js.map +1 -1
  496. package/build/dist/Types/File/MimeType.js +11 -0
  497. package/build/dist/Types/File/MimeType.js.map +1 -1
  498. package/build/dist/Types/JSONFunctions.js +14 -0
  499. package/build/dist/Types/JSONFunctions.js.map +1 -1
  500. package/build/dist/Types/SerializableObjectDictionary.js +133 -39
  501. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  502. package/build/dist/Types/Telemetry/EntitySource.js +39 -0
  503. package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
  504. package/build/dist/Types/Telemetry/EntityType.js +27 -0
  505. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  506. package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
  507. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
  508. package/build/dist/Types/Workflow/Component.js +21 -0
  509. package/build/dist/Types/Workflow/Component.js.map +1 -1
  510. package/build/dist/Types/Workflow/Components/API.js +35 -0
  511. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  512. package/build/dist/Types/Workflow/Components/BaseModel.js +87 -28
  513. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  514. package/build/dist/Types/Workflow/StepTrace.js +104 -0
  515. package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
  516. package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
  517. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
  518. package/build/dist/Types/Workflow/Templates.js +218 -0
  519. package/build/dist/Types/Workflow/Templates.js.map +1 -0
  520. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
  521. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
  522. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
  523. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
  524. package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
  525. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  526. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
  527. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  528. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
  529. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  530. package/build/dist/UI/Components/Forms/Validation.js +44 -0
  531. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  532. package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
  533. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
  534. package/build/dist/UI/Components/Input/Input.js +12 -4
  535. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  536. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
  537. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  538. package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
  539. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  540. package/build/dist/UI/Components/Modal/Modal.js +55 -39
  541. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  542. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
  543. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  544. package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
  545. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  546. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
  547. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  548. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
  549. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  550. package/build/dist/UI/Components/Workflow/Component.js +20 -19
  551. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  552. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
  553. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  554. package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
  555. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
  556. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
  557. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
  558. package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
  559. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
  560. package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
  561. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  562. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
  563. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
  564. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
  565. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
  566. package/build/dist/UI/Components/Workflow/Utils.js +73 -1
  567. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  568. package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
  569. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  570. package/build/dist/UI/Types/LayeredDismissal.js +21 -0
  571. package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
  572. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
  573. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  574. package/build/dist/UI/Utils/PageScrollLock.js +52 -0
  575. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
  576. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
  577. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
  578. package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
  579. package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
  580. package/build/dist/Utils/LegacySerializedArray.js +51 -0
  581. package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
  582. package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
  583. package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
  584. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
  585. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
  586. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
  587. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  588. package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
  589. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  590. package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
  591. package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
  592. package/jest.config.json +3 -0
  593. package/package.json +1 -1
  594. package/tsconfig.json +3 -1
@@ -0,0 +1,138 @@
1
+ import { IsBillingEnabled } from "../EnvironmentConfig";
2
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
3
+ import DatabaseService from "./DatabaseService";
4
+ import UserService from "./UserService";
5
+ import Model from "../../Models/DatabaseModels/DeletedProject";
6
+ import Project from "../../Models/DatabaseModels/Project";
7
+ import User from "../../Models/DatabaseModels/User";
8
+ import OneUptimeDate from "../../Types/Date";
9
+ import ObjectID from "../../Types/ObjectID";
10
+ import Phone from "../../Types/Phone";
11
+
12
+ export class Service extends DatabaseService<Model> {
13
+ public constructor() {
14
+ super(Model);
15
+ }
16
+
17
+ /*
18
+ * Records a project that has just been deleted so the team can follow up with
19
+ * the customer. The project row is already gone by the time this runs, so
20
+ * everything written here has to come from the snapshot the caller took
21
+ * before the delete (ProjectService.onBeforeDelete).
22
+ *
23
+ * SaaS only. Self-hosted installs have no one to reach out to, and the
24
+ * gate lives here rather than at the call site so every caller gets it.
25
+ *
26
+ * Returns the row it wrote, or null when logging was skipped.
27
+ */
28
+ @CaptureSpan()
29
+ public async logProjectDeletion(data: {
30
+ project: Project;
31
+ deletedByUserId?: ObjectID | undefined;
32
+ deletionReason?: string | undefined;
33
+ }): Promise<Model | null> {
34
+ if (!IsBillingEnabled) {
35
+ return null;
36
+ }
37
+
38
+ const project: Project = data.project;
39
+
40
+ if (!project.id) {
41
+ return null;
42
+ }
43
+
44
+ /*
45
+ * Who to reach out to. The user who deleted the project is usually also
46
+ * the one who created it - reuse the snapshot in that case instead of
47
+ * spending a query on it.
48
+ */
49
+ let deletedByUser: User | null = null;
50
+
51
+ if (data.deletedByUserId) {
52
+ if (
53
+ project.createdByUser &&
54
+ project.createdByUserId?.toString() === data.deletedByUserId.toString()
55
+ ) {
56
+ deletedByUser = project.createdByUser;
57
+ } else {
58
+ deletedByUser = await UserService.findOneById({
59
+ id: data.deletedByUserId,
60
+ select: {
61
+ _id: true,
62
+ name: true,
63
+ email: true,
64
+ companyName: true,
65
+ companyPhoneNumber: true,
66
+ companySize: true,
67
+ jobRole: true,
68
+ },
69
+ props: {
70
+ isRoot: true,
71
+ },
72
+ });
73
+ }
74
+ }
75
+
76
+ const createdByUser: User | undefined = project.createdByUser;
77
+
78
+ const deletedProject: Model = new Model();
79
+
80
+ deletedProject.projectId = project.id;
81
+ deletedProject.projectName = project.name || "";
82
+ deletedProject.projectSlug = project.slug;
83
+ deletedProject.projectCreatedAt = project.createdAt;
84
+ deletedProject.projectDeletedAt = OneUptimeDate.getCurrentDate();
85
+ deletedProject.deletionReason = data.deletionReason;
86
+
87
+ deletedProject.projectDeletedByUserId = data.deletedByUserId;
88
+ deletedProject.projectDeletedByUserName = deletedByUser?.name?.toString();
89
+ deletedProject.projectDeletedByUserEmail = deletedByUser?.email;
90
+
91
+ deletedProject.projectCreatedByUserId = project.createdByUserId;
92
+ deletedProject.projectCreatedByUserName = createdByUser?.name?.toString();
93
+ deletedProject.projectCreatedByUserEmail = createdByUser?.email;
94
+
95
+ /*
96
+ * Company details are collected at signup and hang off the User, so take
97
+ * them from whoever created the project and fall back to whoever deleted
98
+ * it - between the two there is usually one filled-in answer.
99
+ */
100
+ const companyName: string | undefined =
101
+ createdByUser?.companyName || deletedByUser?.companyName;
102
+ const companyPhoneNumber: Phone | undefined =
103
+ createdByUser?.companyPhoneNumber || deletedByUser?.companyPhoneNumber;
104
+ const companySize: string | undefined =
105
+ createdByUser?.companySize || deletedByUser?.companySize;
106
+ const jobRole: string | undefined =
107
+ createdByUser?.jobRole || deletedByUser?.jobRole;
108
+
109
+ deletedProject.companyName = companyName;
110
+ deletedProject.companyPhoneNumber = companyPhoneNumber;
111
+ deletedProject.companySize = companySize;
112
+ deletedProject.jobRole = jobRole;
113
+
114
+ deletedProject.planName = project.planName;
115
+ deletedProject.paymentProviderPlanId = project.paymentProviderPlanId;
116
+ deletedProject.paymentProviderCustomerId =
117
+ project.paymentProviderCustomerId;
118
+ deletedProject.paymentProviderSubscriptionId =
119
+ project.paymentProviderSubscriptionId;
120
+ deletedProject.paymentProviderSubscriptionStatus =
121
+ project.paymentProviderSubscriptionStatus;
122
+ deletedProject.paymentProviderSubscriptionSeats =
123
+ project.paymentProviderSubscriptionSeats;
124
+ deletedProject.trialEndsAt = project.trialEndsAt;
125
+
126
+ deletedProject.activeMonitorCount = project.currentActiveMonitorsCount;
127
+ deletedProject.wasProjectBlocked = project.isBlocked ?? false;
128
+
129
+ return await this.create({
130
+ data: deletedProject,
131
+ props: {
132
+ isRoot: true,
133
+ },
134
+ });
135
+ }
136
+ }
137
+
138
+ export default new Service();
@@ -4,15 +4,30 @@ import FindBy from "../Types/Database/FindBy";
4
4
  import { OnCreate, OnDelete, OnFind, OnUpdate } from "../Types/Database/Hooks";
5
5
  import UpdateBy from "../Types/Database/UpdateBy";
6
6
  import DatabaseService from "./DatabaseService";
7
+ import BadDataException from "../../Types/Exception/BadDataException";
7
8
  import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
8
9
  import File from "../../Models/DatabaseModels/File";
10
+ import MimeType from "../../Types/File/MimeType";
11
+ import ObjectID from "../../Types/ObjectID";
9
12
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
13
+ import logger from "../Utils/Logger";
10
14
  import crypto from "crypto";
11
15
 
12
16
  const generateImageAccessToken: () => string = (): string => {
13
17
  return crypto.randomBytes(32).toString("hex");
14
18
  };
15
19
 
20
+ /*
21
+ * fileType is declared as MimeType but persisted as a varchar, so the enum
22
+ * buys nothing at runtime - the API will happily store "text/html" if a client
23
+ * asks for it. Response.sendFileResponse refuses to echo an unknown type back,
24
+ * but keeping junk out of the column in the first place means the stored row
25
+ * matches what we are willing to serve.
26
+ */
27
+ const ALLOWED_MIME_TYPES: Set<string> = new Set<string>(
28
+ Object.values(MimeType),
29
+ );
30
+
16
31
  export class Service extends DatabaseService<File> {
17
32
  public constructor() {
18
33
  super(File);
@@ -22,6 +37,18 @@ export class Service extends DatabaseService<File> {
22
37
  protected override async onBeforeCreate(
23
38
  createBy: CreateBy<File>,
24
39
  ): Promise<OnCreate<File>> {
40
+ const fileType: string = (createBy.data.fileType || "")
41
+ .trim()
42
+ .toLowerCase();
43
+
44
+ if (!ALLOWED_MIME_TYPES.has(fileType)) {
45
+ throw new BadDataException(
46
+ "This file type is not supported. Please upload a supported file type.",
47
+ );
48
+ }
49
+
50
+ createBy.data.fileType = fileType as MimeType;
51
+
25
52
  /*
26
53
  * Always generate an unguessable access token server-side. The token
27
54
  * is the only safe way to address an inline-uploaded image in
@@ -56,6 +83,40 @@ export class Service extends DatabaseService<File> {
56
83
  return { deleteBy, carryForward: null };
57
84
  }
58
85
 
86
+ /*
87
+ * Marks a file as anonymously readable. Uploads from the file picker
88
+ * arrive private, so attaching one as an intentionally public asset
89
+ * (probe icon, AI agent icon) is the point at which it becomes public
90
+ * — those are served by the id-based image route, which serves only
91
+ * public files. Best-effort: a visibility sync failure must never fail
92
+ * the write the user actually asked for.
93
+ */
94
+ @CaptureSpan()
95
+ public async makeFilePublic(
96
+ fileId: ObjectID | undefined | null,
97
+ ): Promise<void> {
98
+ if (!fileId) {
99
+ return;
100
+ }
101
+
102
+ try {
103
+ await this.updateOneById({
104
+ id: fileId,
105
+ data: {
106
+ isPublic: true,
107
+ },
108
+ props: {
109
+ isRoot: true,
110
+ ignoreHooks: true,
111
+ },
112
+ });
113
+ } catch (err) {
114
+ logger.error(
115
+ `Failed to mark file ${fileId.toString()} public: ${String(err)}`,
116
+ );
117
+ }
118
+ }
119
+
59
120
  @CaptureSpan()
60
121
  protected override async onBeforeFind(
61
122
  findBy: FindBy<File>,
@@ -14,6 +14,7 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
14
14
  import StatusPageSubscriberNotificationStatus from "../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
15
15
  import File from "../../Models/DatabaseModels/File";
16
16
  import FileAttachmentMarkdownUtil from "../Utils/FileAttachmentMarkdownUtil";
17
+ import { syncIsPublicForMarkdownImages } from "../Utils/InlineImageAccessTokenSync";
17
18
 
18
19
  export class Service extends DatabaseService<Model> {
19
20
  public constructor() {
@@ -116,6 +117,17 @@ export class Service extends DatabaseService<Model> {
116
117
  const userId: ObjectID | null | undefined =
117
118
  createdItem.createdByUserId || createdItem.createdByUser?.id;
118
119
 
120
+ /*
121
+ * A public note is always rendered on the status page, so any inline
122
+ * image the markdown editor uploaded as private must flip to public
123
+ * for anonymous status page viewers to be able to render it.
124
+ */
125
+ await syncIsPublicForMarkdownImages(
126
+ createdItem.note,
127
+ true,
128
+ `incident episode public note ${createdItem.id?.toString()}`,
129
+ );
130
+
119
131
  const incidentEpisodeId: ObjectID = createdItem.incidentEpisodeId!;
120
132
  const projectId: ObjectID = createdItem.projectId!;
121
133
  const episodeNumberResult: {
@@ -185,6 +197,12 @@ ${(createdItem.note || "") + attachmentsMarkdown}
185
197
  for (const updatedItem of updatedItems) {
186
198
  const episode: IncidentEpisode = updatedItem.incidentEpisode!;
187
199
 
200
+ await syncIsPublicForMarkdownImages(
201
+ updatedItem.note,
202
+ true,
203
+ `incident episode public note ${updatedItem.id?.toString()}`,
204
+ );
205
+
188
206
  const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
189
207
  updatedItem.id!,
190
208
  "/incident-episode-public-note/attachment",
@@ -14,6 +14,7 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
14
14
  import StatusPageSubscriberNotificationStatus from "../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
15
15
  import File from "../../Models/DatabaseModels/File";
16
16
  import FileAttachmentMarkdownUtil from "../Utils/FileAttachmentMarkdownUtil";
17
+ import { syncIsPublicForMarkdownImages } from "../Utils/InlineImageAccessTokenSync";
17
18
 
18
19
  export class Service extends DatabaseService<Model> {
19
20
  public constructor() {
@@ -116,6 +117,17 @@ export class Service extends DatabaseService<Model> {
116
117
  const userId: ObjectID | null | undefined =
117
118
  createdItem.createdByUserId || createdItem.createdByUser?.id;
118
119
 
120
+ /*
121
+ * A public note is always rendered on the status page, so any inline
122
+ * image the markdown editor uploaded as private must flip to public
123
+ * for anonymous status page viewers to be able to render it.
124
+ */
125
+ await syncIsPublicForMarkdownImages(
126
+ createdItem.note,
127
+ true,
128
+ `incident public note ${createdItem.id?.toString()}`,
129
+ );
130
+
119
131
  const incidentId: ObjectID = createdItem.incidentId!;
120
132
  const projectId: ObjectID = createdItem.projectId!;
121
133
  const incidentNumberResult: {
@@ -187,6 +199,12 @@ ${(createdItem.note || "") + attachmentsMarkdown}
187
199
  for (const updatedItem of updatedItems) {
188
200
  const incident: Incident = updatedItem.incident!;
189
201
 
202
+ await syncIsPublicForMarkdownImages(
203
+ updatedItem.note,
204
+ true,
205
+ `incident public note ${updatedItem.id?.toString()}`,
206
+ );
207
+
190
208
  const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
191
209
  updatedItem.id!,
192
210
  "/incident-public-note/attachment",
@@ -283,10 +283,12 @@ import NetworkFlowService from "./NetworkFlowService";
283
283
  import OnCallDutyPolicyTimeLogService from "./OnCallDutyPolicyTimeLogService";
284
284
  import ProjectSCIMLogService from "./ProjectSCIMLogService";
285
285
  import StatusPageSCIMLogService from "./StatusPageSCIMLogService";
286
+ import DeletedProjectService from "./DeletedProjectService";
286
287
 
287
288
  const services: Array<BaseService> = [
288
289
  OnCallDutyPolicyTimeLogService,
289
290
  AcmeCertificateService,
291
+ DeletedProjectService,
290
292
  PromoCodeService,
291
293
  EnterpriseLicenseService,
292
294
  EnterpriseLicenseInstanceService,
@@ -464,9 +464,307 @@ export class Service extends DatabaseService<Model> {
464
464
  }
465
465
  }
466
466
 
467
+ if (
468
+ updateBy.data.dependsOnMonitors !== undefined ||
469
+ updateBy.data.suppressAlertsWhenParentMonitorStatuses !== undefined
470
+ ) {
471
+ /*
472
+ * The matched monitors' own ids (self/cycle checks) and projects
473
+ * (parent scoping) are needed; root/API updates do not always carry
474
+ * a tenantId. Validation itself is hoisted: the proposed lists are
475
+ * identical for every matched monitor, so existence/project checks
476
+ * run once per distinct project and the cycle walk runs once for
477
+ * all targets — not once per monitor (a bulk update could match
478
+ * thousands).
479
+ */
480
+ const monitorsToValidate: Array<Model> = await this.findBy({
481
+ query: updateBy.query,
482
+ select: {
483
+ _id: true,
484
+ projectId: true,
485
+ },
486
+ limit: LIMIT_MAX,
487
+ skip: 0,
488
+ props: {
489
+ isRoot: true,
490
+ ignoreHooks: true,
491
+ },
492
+ });
493
+
494
+ await this.validateDependencyConfiguration({
495
+ targets: monitorsToValidate.map((monitor: Model) => {
496
+ return {
497
+ monitorId: monitor.id || null,
498
+ projectId: updateBy.props.tenantId || monitor.projectId || null,
499
+ };
500
+ }),
501
+ proposedParents: updateBy.data.dependsOnMonitors,
502
+ proposedSuppressionStatuses:
503
+ updateBy.data.suppressAlertsWhenParentMonitorStatuses,
504
+ });
505
+ }
506
+
467
507
  return { updateBy, carryForward: null };
468
508
  }
469
509
 
510
+ /*
511
+ * Guards for the alert-dependency configuration. `undefined` means "not
512
+ * part of this write" and validates nothing; null or an empty array
513
+ * (clearing the config) is always valid. The proposed lists arrive in
514
+ * whatever shape the API produced — relation objects, ObjectIDs, or
515
+ * bare uuid strings (which DatabaseService.sanitizeCreateOrUpdate only
516
+ * converts to entities AFTER this hook has run) — so extraction goes
517
+ * through resolveReferenceId, and every id comparison is normalized to
518
+ * lower case because Postgres matches uuids case-insensitively while
519
+ * ObjectID preserves the caller's casing.
520
+ */
521
+ public async validateDependencyConfiguration(input: {
522
+ /**
523
+ * The monitors this write applies to. monitorId is null on create —
524
+ * a new monitor cannot be part of a cycle yet.
525
+ */
526
+ targets: Array<{
527
+ monitorId: ObjectID | null;
528
+ projectId: ObjectID | null;
529
+ }>;
530
+ proposedParents: unknown;
531
+ proposedSuppressionStatuses: unknown;
532
+ }): Promise<void> {
533
+ const distinctProjectIds: Array<ObjectID> = [];
534
+ const seenProjectIds: Set<string> = new Set<string>();
535
+
536
+ for (const target of input.targets) {
537
+ const key: string | undefined = target.projectId
538
+ ?.toString()
539
+ .trim()
540
+ .toLowerCase();
541
+
542
+ if (key && !seenProjectIds.has(key)) {
543
+ seenProjectIds.add(key);
544
+ distinctProjectIds.push(target.projectId!);
545
+ }
546
+ }
547
+
548
+ if (input.proposedParents !== undefined) {
549
+ const parentIds: Array<ObjectID> = this.extractRelationIds(
550
+ input.proposedParents,
551
+ );
552
+
553
+ if (parentIds.length > 0) {
554
+ const parentIdSet: Set<string> = new Set<string>(
555
+ parentIds.map((id: ObjectID) => {
556
+ return id.toString();
557
+ }),
558
+ );
559
+
560
+ for (const target of input.targets) {
561
+ const targetKey: string | undefined = target.monitorId
562
+ ?.toString()
563
+ .trim()
564
+ .toLowerCase();
565
+
566
+ if (targetKey && parentIdSet.has(targetKey)) {
567
+ throw new BadDataException("A monitor cannot depend on itself.");
568
+ }
569
+ }
570
+
571
+ /*
572
+ * Existence + same-project via the house validator (which owns
573
+ * the case normalization and message wording). Once per distinct
574
+ * project: parents must belong to every matched monitor's
575
+ * project, so a cross-project bulk update correctly fails.
576
+ */
577
+ for (const projectId of distinctProjectIds) {
578
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject(
579
+ {
580
+ projectId: projectId,
581
+ subject: "monitor",
582
+ references: parentIds.map((parentId: ObjectID) => {
583
+ return {
584
+ modelName: "Monitor",
585
+ id: parentId,
586
+ service: this,
587
+ };
588
+ }),
589
+ },
590
+ );
591
+ }
592
+
593
+ const targetMonitorIds: Array<ObjectID> = input.targets
594
+ .map((target: { monitorId: ObjectID | null }) => {
595
+ return target.monitorId;
596
+ })
597
+ .filter((monitorId: ObjectID | null): monitorId is ObjectID => {
598
+ return Boolean(monitorId);
599
+ });
600
+
601
+ if (targetMonitorIds.length > 0) {
602
+ await this.throwIfDependencyCycle({
603
+ targetMonitorIds,
604
+ proposedParentIds: parentIds,
605
+ });
606
+ }
607
+ }
608
+ }
609
+
610
+ if (input.proposedSuppressionStatuses !== undefined) {
611
+ const statusIds: Array<ObjectID> = this.extractRelationIds(
612
+ input.proposedSuppressionStatuses,
613
+ );
614
+
615
+ if (statusIds.length > 0) {
616
+ for (const projectId of distinctProjectIds) {
617
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject(
618
+ {
619
+ projectId: projectId,
620
+ subject: "monitor",
621
+ references: statusIds.map((statusId: ObjectID) => {
622
+ return {
623
+ modelName: "Monitor Status",
624
+ id: statusId,
625
+ service: MonitorStatusService,
626
+ };
627
+ }),
628
+ },
629
+ );
630
+ }
631
+ }
632
+ }
633
+ }
634
+
635
+ /*
636
+ * Walk the dependency graph upward from the proposed parents; reaching
637
+ * any monitor being updated means the write would close a cycle, which
638
+ * would make suppression self-referential (A suppressed because of B,
639
+ * B suppressed because of A) and must be rejected. One BFS covers every
640
+ * target of a bulk update. The visited set bounds the walk even if a
641
+ * cycle already exists among ancestors, and the depth cap keeps the
642
+ * check cheap on degenerate graphs.
643
+ *
644
+ * This validates committed state, so two updates racing each other can
645
+ * still jointly commit a cycle this walk could not see; the runtime
646
+ * mutual-cycle guard in MonitorDependencySuppression fails open (pages
647
+ * instead of suppressing) if that ever happens.
648
+ */
649
+ private async throwIfDependencyCycle(input: {
650
+ targetMonitorIds: Array<ObjectID>;
651
+ proposedParentIds: Array<ObjectID>;
652
+ }): Promise<void> {
653
+ const maxDepth: number = 32;
654
+
655
+ const targetIdSet: Set<string> = new Set<string>(
656
+ input.targetMonitorIds.map((monitorId: ObjectID) => {
657
+ return monitorId.toString().trim().toLowerCase();
658
+ }),
659
+ );
660
+
661
+ const visited: Set<string> = new Set<string>();
662
+ let frontier: Array<ObjectID> = [...input.proposedParentIds];
663
+
664
+ for (let depth: number = 0; depth < maxDepth; depth++) {
665
+ if (frontier.length === 0) {
666
+ return;
667
+ }
668
+
669
+ if (
670
+ frontier.some((id: ObjectID) => {
671
+ return targetIdSet.has(id.toString().trim().toLowerCase());
672
+ })
673
+ ) {
674
+ throw new BadDataException(
675
+ "This dependency would create a cycle: one of the selected monitors (or a monitor it depends on) already depends on this monitor.",
676
+ );
677
+ }
678
+
679
+ for (const id of frontier) {
680
+ visited.add(id.toString().trim().toLowerCase());
681
+ }
682
+
683
+ const rows: Array<Model> = await this.findBy({
684
+ query: {
685
+ _id: QueryHelper.any(frontier),
686
+ },
687
+ select: {
688
+ _id: true,
689
+ dependsOnMonitors: {
690
+ _id: true,
691
+ },
692
+ },
693
+ limit: LIMIT_PER_PROJECT,
694
+ skip: 0,
695
+ props: {
696
+ isRoot: true,
697
+ },
698
+ });
699
+
700
+ /*
701
+ * Fail CLOSED on truncation: a frontier level wider than the query
702
+ * limit means ancestors were dropped and a real cycle routed
703
+ * through the remainder would be admitted. Refuse instead — the
704
+ * sibling existence check fails closed the same way.
705
+ */
706
+ if (rows.length >= LIMIT_PER_PROJECT) {
707
+ throw new BadDataException(
708
+ "This dependency graph is too large to verify for cycles. Please reduce the number of monitors sharing one dependency level.",
709
+ );
710
+ }
711
+
712
+ const next: Array<ObjectID> = [];
713
+
714
+ for (const row of rows) {
715
+ for (const grandParentId of this.extractRelationIds(
716
+ row.dependsOnMonitors || [],
717
+ )) {
718
+ if (!visited.has(grandParentId.toString())) {
719
+ next.push(grandParentId);
720
+ visited.add(grandParentId.toString());
721
+ }
722
+ }
723
+ }
724
+
725
+ frontier = next;
726
+ }
727
+
728
+ if (frontier.length > 0) {
729
+ throw new BadDataException(
730
+ `Monitor dependency chains deeper than ${maxDepth} levels are not supported.`,
731
+ );
732
+ }
733
+ }
734
+
735
+ /*
736
+ * Ids arrive as relation objects ({_id}), ObjectIDs, or bare uuid
737
+ * strings depending on which API path produced the payload —
738
+ * resolveReferenceId handles all three (reading only ._id/.id here
739
+ * silently missed the bare-string shape, which DatabaseService
740
+ * persists). Returned ids are normalized to lower case so every
741
+ * comparison downstream matches the way Postgres matches uuids. null /
742
+ * non-array input (explicit null is TypeORM's clear-all for relation
743
+ * columns) yields an empty list: nothing to validate.
744
+ */
745
+ private extractRelationIds(relationArray: unknown): Array<ObjectID> {
746
+ if (!Array.isArray(relationArray)) {
747
+ return [];
748
+ }
749
+
750
+ const ids: Array<ObjectID> = [];
751
+ const seen: Set<string> = new Set<string>();
752
+
753
+ for (const item of relationArray) {
754
+ const rawId: string | undefined = resolveReferenceId(item)
755
+ ?.toString()
756
+ .trim()
757
+ .toLowerCase();
758
+
759
+ if (rawId && !seen.has(rawId)) {
760
+ seen.add(rawId);
761
+ ids.push(new ObjectID(rawId));
762
+ }
763
+ }
764
+
765
+ return ids;
766
+ }
767
+
470
768
  private async getProjectIdsForUpdateQuery(
471
769
  updateBy: UpdateBy<Model>,
472
770
  ): Promise<Array<ObjectID>> {
@@ -781,6 +1079,19 @@ export class Service extends DatabaseService<Model> {
781
1079
  projectId: createBy.props.tenantId,
782
1080
  });
783
1081
 
1082
+ await this.validateDependencyConfiguration({
1083
+ // A new monitor cannot be part of a cycle yet, hence monitorId null.
1084
+ targets: [
1085
+ {
1086
+ monitorId: null,
1087
+ projectId: createBy.props.tenantId,
1088
+ },
1089
+ ],
1090
+ proposedParents: createBy.data.dependsOnMonitors,
1091
+ proposedSuppressionStatuses:
1092
+ createBy.data.suppressAlertsWhenParentMonitorStatuses,
1093
+ });
1094
+
784
1095
  /*
785
1096
  * A new monitor starts in the project's operational status. A project can
786
1097
  * hold MORE than one operational state (a user - or an E2E fixture - can
@@ -29,6 +29,7 @@ import DatabaseConfig from "../DatabaseConfig";
29
29
  import URL from "../../Types/API/URL";
30
30
  import UpdateBy from "../Types/Database/UpdateBy";
31
31
  import MonitorService from "./MonitorService";
32
+ import FileService from "./FileService";
32
33
  import PushNotificationMessage from "../../Types/PushNotification/PushNotificationMessage";
33
34
  import PushNotificationUtil from "../Utils/PushNotificationUtil";
34
35
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
@@ -435,6 +436,21 @@ export class Service extends DatabaseService<Model> {
435
436
  return { createBy: createBy, carryForward: [] };
436
437
  }
437
438
 
439
+ /*
440
+ * A probe icon is rendered by the id-based image route, which serves
441
+ * only public files. The file picker uploads it private, so attaching
442
+ * it to a probe is the point at which it becomes public.
443
+ */
444
+ @CaptureSpan()
445
+ protected override async onCreateSuccess(
446
+ _onCreate: OnCreate<Model>,
447
+ createdItem: Model,
448
+ ): Promise<Model> {
449
+ await FileService.makeFilePublic(createdItem.iconFileId);
450
+
451
+ return createdItem;
452
+ }
453
+
438
454
  /*
439
455
  * Only global probes and probes belonging to this project may be attached to
440
456
  * that project's monitors. Probe ids reach the server from the browser - the
@@ -626,6 +642,10 @@ export class Service extends DatabaseService<Model> {
626
642
  await this.invalidateProbeAuthCache(updatedItemIds);
627
643
  }
628
644
 
645
+ await FileService.makeFilePublic(
646
+ onUpdate.updateBy.data.iconFileId as ObjectID | undefined,
647
+ );
648
+
629
649
  if (
630
650
  onUpdate.carryForward &&
631
651
  onUpdate.carryForward.probesToNotifyOwners.length > 0