@oneuptime/common 12.0.6 → 12.0.7
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.
- package/Models/DatabaseModels/AIInsight.ts +1 -1
- package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
- package/Models/DatabaseModels/DeletedProject.ts +595 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Monitor.ts +111 -0
- package/Models/DatabaseModels/Project.ts +3 -3
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
- package/Server/API/FileAPI.ts +15 -2
- package/Server/API/MicrosoftTeamsAPI.ts +6 -1
- package/Server/API/ProjectAPI.ts +214 -0
- package/Server/API/StatusPageAPI.ts +39 -6
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Services/AIAgentService.ts +20 -0
- package/Server/Services/DashboardDomainService.ts +73 -28
- package/Server/Services/DatabaseService.ts +1 -0
- package/Server/Services/DeletedProjectService.ts +138 -0
- package/Server/Services/FileService.ts +61 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
- package/Server/Services/IncidentPublicNoteService.ts +18 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +311 -0
- package/Server/Services/ProbeService.ts +20 -0
- package/Server/Services/ProjectService.ts +297 -1
- package/Server/Services/PushNotificationService.ts +71 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
- package/Server/Services/StatusPageAnnouncementService.ts +53 -0
- package/Server/Services/StatusPageDomainService.ts +73 -28
- package/Server/Services/TeamMemberService.ts +117 -12
- package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
- package/Server/Services/UserWebhookService.ts +34 -109
- package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
- package/Server/Types/Database/DeleteById.ts +2 -0
- package/Server/Types/Database/DeleteOneBy.ts +6 -0
- package/Server/Types/Domain.ts +41 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
- package/Server/Types/Workflow/Components/API/Get.ts +2 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
- package/Server/Types/Workflow/Components/API/Post.ts +2 -1
- package/Server/Types/Workflow/Components/API/Put.ts +2 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +41 -2
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
- package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
- package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
- package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
- package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
- package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
- package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
- package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
- package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
- package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
- package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
- package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
- package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
- package/Server/Utils/DataSource/EgressGuard.ts +176 -16
- package/Server/Utils/DataSource/HttpFetch.ts +6 -45
- package/Server/Utils/Execute.ts +8 -0
- package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
- package/Server/Utils/LLM/LLMService.ts +57 -12
- package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
- package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
- package/Server/Utils/Monitor/MonitorResource.ts +36 -0
- package/Server/Utils/Response.ts +142 -6
- package/Server/Utils/SSRFProtection.ts +273 -60
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/VM/VMRunner.ts +88 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
- package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
- package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
- package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
- package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
- package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
- package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
- package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
- package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
- package/Tests/Server/API/ProjectAPI.test.ts +299 -1
- package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
- package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
- package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
- package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
- package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
- package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
- package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
- package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
- package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
- package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
- package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
- package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
- package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
- package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
- package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
- package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
- package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
- package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
- package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
- package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
- package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
- package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
- package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
- package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
- package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
- package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
- package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
- package/Tests/Types/JSONFunctions.test.ts +252 -1
- package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
- package/Tests/UI/Components/404.test.tsx +1 -1
- package/Tests/UI/Components/Alert.test.tsx +1 -1
- package/Tests/UI/Components/Badge.test.tsx +1 -1
- package/Tests/UI/Components/BasicForm.test.tsx +39 -10
- package/Tests/UI/Components/Button.test.tsx +1 -1
- package/Tests/UI/Components/Card.test.tsx +1 -1
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
- package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
- package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
- package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
- package/Tests/UI/Components/Dropdown.test.tsx +1 -1
- package/Tests/UI/Components/FilePicker.test.tsx +1 -1
- package/Tests/UI/Components/HiddenText.test.tsx +1 -1
- package/Tests/UI/Components/Input.test.tsx +1 -1
- package/Tests/UI/Components/Loader.test.tsx +1 -1
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +1 -1
- package/Tests/UI/Components/MasterPage.test.tsx +1 -1
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +489 -0
- package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
- package/Tests/UI/Components/NavBar.test.tsx +1 -1
- package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
- package/Tests/UI/Components/Pagination.test.tsx +1 -1
- package/Tests/UI/Components/Pill.test.tsx +1 -1
- package/Tests/UI/Components/Probe.test.tsx +1 -1
- package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
- package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
- package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
- package/Tests/UI/Components/SideOver.test.tsx +500 -6
- package/Tests/UI/Components/Tabs.test.tsx +1 -1
- package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +1 -1
- package/Tests/UI/Components/TextArea.test.tsx +1 -1
- package/Tests/UI/Components/Toast.test.tsx +1 -1
- package/Tests/UI/Components/Toggle.test.tsx +1 -1
- package/Tests/UI/Components/TopSection.test.tsx +1 -1
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
- package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
- package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
- package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
- package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
- package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
- package/Tests/Utils/Realtime.test.ts +78 -0
- package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
- package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
- package/Types/AI/FixPullRequestCiStatus.ts +1 -1
- package/Types/AI/FixVerificationStatus.ts +2 -2
- package/Types/API/Hostname.ts +92 -4
- package/Types/API/URL.ts +43 -25
- package/Types/Billing/BalanceAdjustmentType.ts +14 -0
- package/Types/Billing/ProjectBalanceType.ts +13 -0
- package/Types/Domain.ts +26 -0
- package/Types/File/MimeType.ts +11 -0
- package/Types/JSONFunctions.ts +15 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
- package/Types/Workflow/Components/BaseModel.ts +92 -28
- package/Typings/Index.d.ts +12 -0
- package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
- package/UI/Components/Modal/ConfirmModal.tsx +10 -5
- package/UI/Components/Modal/Modal.tsx +27 -47
- package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
- package/UI/Components/SideOver/SideOver.tsx +195 -68
- package/UI/Utils/PageScrollLock.ts +66 -0
- package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
- package/Utils/Dashboard/VariableInterpolation.ts +19 -1
- package/Utils/LegacySerializedArray.ts +60 -0
- package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
- package/Utils/Telemetry/SavedViewFilters.ts +88 -0
- package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
- package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
- package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +3 -3
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/FileAPI.js +14 -2
- package/build/dist/Server/API/FileAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +157 -4
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +27 -3
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +17 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +55 -18
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +1 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DeletedProjectService.js +124 -0
- package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
- package/build/dist/Server/Services/FileService.js +52 -0
- package/build/dist/Server/Services/FileService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +232 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +17 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +228 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +56 -0
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
- package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
- package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +97 -6
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +31 -87
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Domain.js +37 -0
- package/build/dist/Server/Types/Domain.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +35 -2
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/Execute.js +2 -2
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +112 -5
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +219 -53
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
- package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
- package/build/dist/Types/API/Hostname.js +73 -4
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/API/URL.js +42 -24
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
- package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
- package/build/dist/Types/Domain.js +22 -0
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +11 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +14 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +83 -28
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +24 -34
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +52 -0
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
- package/build/dist/Utils/LegacySerializedArray.js +51 -0
- package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
- package/jest.config.json +3 -0
- package/package.json +1 -1
- package/tsconfig.json +3 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { readLegacySerializedArray } from "../../Utils/LegacySerializedArray";
|
|
2
|
+
import { describe, expect, test } from "@jest/globals";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* The pre-fix serializer turned an array it received directly into a
|
|
6
|
+
* numeric-keyed object. Values written that way are still in databases and in
|
|
7
|
+
* browser local storage, so both shapes have to read back — while a genuine
|
|
8
|
+
* object that merely happens to carry a "0" key must not be mistaken for one
|
|
9
|
+
* of them.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
describe("readLegacySerializedArray", () => {
|
|
13
|
+
describe("Values that are already arrays", () => {
|
|
14
|
+
test("Returns an array unchanged", () => {
|
|
15
|
+
expect(readLegacySerializedArray(["time", "body"])).toEqual([
|
|
16
|
+
"time",
|
|
17
|
+
"body",
|
|
18
|
+
]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("Returns an empty array unchanged", () => {
|
|
22
|
+
expect(readLegacySerializedArray([])).toEqual([]);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("Leaves element types alone", () => {
|
|
26
|
+
const mixed: Array<unknown> = [1, "x", null, { a: 1 }, ["nested"]];
|
|
27
|
+
|
|
28
|
+
expect(readLegacySerializedArray(mixed)).toEqual(mixed);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("Returns the same reference, not a copy", () => {
|
|
32
|
+
const original: Array<unknown> = ["time"];
|
|
33
|
+
|
|
34
|
+
expect(readLegacySerializedArray(original)).toBe(original);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe("Values corrupted into numeric-keyed objects", () => {
|
|
39
|
+
test("Rebuilds a two-element array", () => {
|
|
40
|
+
expect(readLegacySerializedArray({ "0": "service", "1": "api" })).toEqual(
|
|
41
|
+
["service", "api"],
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("Rebuilds a longer array in index order", () => {
|
|
46
|
+
expect(
|
|
47
|
+
readLegacySerializedArray({
|
|
48
|
+
"0": "time",
|
|
49
|
+
"1": "body",
|
|
50
|
+
"2": "severityText",
|
|
51
|
+
}),
|
|
52
|
+
).toEqual(["time", "body", "severityText"]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("Rebuilds in index order even when the keys are out of order", () => {
|
|
56
|
+
expect(
|
|
57
|
+
readLegacySerializedArray({
|
|
58
|
+
"2": "third",
|
|
59
|
+
"0": "first",
|
|
60
|
+
"1": "second",
|
|
61
|
+
}),
|
|
62
|
+
).toEqual(["first", "second", "third"]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("Rebuilds a single-element array", () => {
|
|
66
|
+
expect(readLegacySerializedArray({ "0": "only" })).toEqual(["only"]);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("Keeps null and empty-string elements", () => {
|
|
70
|
+
expect(readLegacySerializedArray({ "0": null, "1": "" })).toEqual([
|
|
71
|
+
null,
|
|
72
|
+
"",
|
|
73
|
+
]);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("Reads an empty object as an empty array", () => {
|
|
77
|
+
// An empty array is exactly what the old serializer wrote as {}.
|
|
78
|
+
expect(readLegacySerializedArray({})).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("The result is a real array, so it can be destructured", () => {
|
|
82
|
+
const restored: Array<unknown> | null = readLegacySerializedArray({
|
|
83
|
+
"0": "service",
|
|
84
|
+
"1": "api",
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(Array.isArray(restored)).toBe(true);
|
|
88
|
+
expect(() => {
|
|
89
|
+
const [first]: Array<unknown> = restored as Array<unknown>;
|
|
90
|
+
return first;
|
|
91
|
+
}).not.toThrow();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("Values that are not arrays in any shape", () => {
|
|
96
|
+
test("Rejects null and undefined", () => {
|
|
97
|
+
expect(readLegacySerializedArray(null)).toBeNull();
|
|
98
|
+
expect(readLegacySerializedArray(undefined)).toBeNull();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("Rejects primitives", () => {
|
|
102
|
+
expect(readLegacySerializedArray("time")).toBeNull();
|
|
103
|
+
expect(readLegacySerializedArray(7)).toBeNull();
|
|
104
|
+
expect(readLegacySerializedArray(true)).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("Rejects a plain object with named keys", () => {
|
|
108
|
+
expect(readLegacySerializedArray({ facetKey: "service" })).toBeNull();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("Rejects an object that only partly looks like an array", () => {
|
|
112
|
+
// "0" is there but "1" is not, so the run of indices is incomplete.
|
|
113
|
+
expect(
|
|
114
|
+
readLegacySerializedArray({ "0": "service", foo: "bar" }),
|
|
115
|
+
).toBeNull();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("Rejects an object whose indices do not start at zero", () => {
|
|
119
|
+
expect(readLegacySerializedArray({ "1": "a", "2": "b" })).toBeNull();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("Rejects an object with a gap in its indices", () => {
|
|
123
|
+
expect(readLegacySerializedArray({ "0": "a", "2": "b" })).toBeNull();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("Rejects a real saved-view state object", () => {
|
|
127
|
+
/*
|
|
128
|
+
* Guards the boundary the other way: a JSON column's own object must
|
|
129
|
+
* never be read as a list of its values.
|
|
130
|
+
*/
|
|
131
|
+
expect(
|
|
132
|
+
readLegacySerializedArray({
|
|
133
|
+
search: "status:error",
|
|
134
|
+
pageSize: 50,
|
|
135
|
+
}),
|
|
136
|
+
).toBeNull();
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import MonitorDependencyRule, {
|
|
2
|
+
ParentMonitorStatusRef,
|
|
3
|
+
SuppressingParent,
|
|
4
|
+
} from "../../../Utils/Monitor/MonitorDependencyRule";
|
|
5
|
+
|
|
6
|
+
const parent: (
|
|
7
|
+
overrides: Partial<ParentMonitorStatusRef>,
|
|
8
|
+
) => ParentMonitorStatusRef = (
|
|
9
|
+
overrides: Partial<ParentMonitorStatusRef>,
|
|
10
|
+
): ParentMonitorStatusRef => {
|
|
11
|
+
return {
|
|
12
|
+
monitorId: "m1",
|
|
13
|
+
monitorName: "Router",
|
|
14
|
+
statusId: "s-online",
|
|
15
|
+
statusName: "Online",
|
|
16
|
+
isOfflineState: false,
|
|
17
|
+
...overrides,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
describe("MonitorDependencyRule.getSuppressingParents", () => {
|
|
22
|
+
describe("with a configured suppression status list", () => {
|
|
23
|
+
const configured: Set<string> = new Set<string>([
|
|
24
|
+
"s-offline",
|
|
25
|
+
"s-degraded",
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
test("a parent whose status is in the list suppresses", () => {
|
|
29
|
+
const result: Array<SuppressingParent> =
|
|
30
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
31
|
+
parents: [
|
|
32
|
+
parent({
|
|
33
|
+
monitorId: "m1",
|
|
34
|
+
monitorName: "Core Router",
|
|
35
|
+
statusId: "s-offline",
|
|
36
|
+
statusName: "Offline",
|
|
37
|
+
}),
|
|
38
|
+
],
|
|
39
|
+
configuredSuppressionStatusIds: configured,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(result).toEqual([
|
|
43
|
+
{ monitorId: "m1", monitorName: "Core Router", statusName: "Offline" },
|
|
44
|
+
]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("a parent whose status is not in the list does not suppress", () => {
|
|
48
|
+
const result: Array<SuppressingParent> =
|
|
49
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
50
|
+
parents: [parent({ statusId: "s-online" })],
|
|
51
|
+
configuredSuppressionStatusIds: configured,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
expect(result).toEqual([]);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("the configured list wins even when the parent is offline", () => {
|
|
58
|
+
/*
|
|
59
|
+
* isOfflineState is only the fallback signal. With an explicit list
|
|
60
|
+
* configured, an offline parent whose status id is not listed must NOT
|
|
61
|
+
* suppress — otherwise the operator's narrower rule is ignored.
|
|
62
|
+
*/
|
|
63
|
+
const result: Array<SuppressingParent> =
|
|
64
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
65
|
+
parents: [parent({ statusId: "s-online", isOfflineState: true })],
|
|
66
|
+
configuredSuppressionStatusIds: configured,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(result).toEqual([]);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("a parent with no current status never suppresses", () => {
|
|
73
|
+
// A never-evaluated parent (undefined statusId) must not silence children.
|
|
74
|
+
const result: Array<SuppressingParent> =
|
|
75
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
76
|
+
parents: [parent({ statusId: undefined, isOfflineState: true })],
|
|
77
|
+
configuredSuppressionStatusIds: configured,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
expect(result).toEqual([]);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe("with no configured list (offline fallback)", () => {
|
|
85
|
+
const empty: Set<string> = new Set<string>();
|
|
86
|
+
|
|
87
|
+
test("an offline parent suppresses", () => {
|
|
88
|
+
const result: Array<SuppressingParent> =
|
|
89
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
90
|
+
parents: [
|
|
91
|
+
parent({
|
|
92
|
+
monitorName: "Switch",
|
|
93
|
+
statusName: "Offline",
|
|
94
|
+
isOfflineState: true,
|
|
95
|
+
}),
|
|
96
|
+
],
|
|
97
|
+
configuredSuppressionStatusIds: empty,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(result).toEqual([
|
|
101
|
+
{ monitorId: "m1", monitorName: "Switch", statusName: "Offline" },
|
|
102
|
+
]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("a non-offline parent does not suppress", () => {
|
|
106
|
+
const result: Array<SuppressingParent> =
|
|
107
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
108
|
+
parents: [parent({ isOfflineState: false })],
|
|
109
|
+
configuredSuppressionStatusIds: empty,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
expect(result).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("falls back to the label 'Offline' when statusName is missing", () => {
|
|
116
|
+
const result: Array<SuppressingParent> =
|
|
117
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
118
|
+
parents: [parent({ statusName: undefined, isOfflineState: true })],
|
|
119
|
+
configuredSuppressionStatusIds: empty,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
expect(result[0]?.statusName).toBe("Offline");
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("returns only the suppressing subset, preserving input order", () => {
|
|
127
|
+
const result: Array<SuppressingParent> =
|
|
128
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
129
|
+
parents: [
|
|
130
|
+
parent({ monitorId: "a", statusId: "s-offline" }),
|
|
131
|
+
parent({ monitorId: "b", statusId: "s-online" }),
|
|
132
|
+
parent({ monitorId: "c", statusId: "s-offline" }),
|
|
133
|
+
],
|
|
134
|
+
configuredSuppressionStatusIds: new Set<string>(["s-offline"]),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
expect(
|
|
138
|
+
result.map((p: SuppressingParent) => {
|
|
139
|
+
return p.monitorId;
|
|
140
|
+
}),
|
|
141
|
+
).toEqual(["a", "c"]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("an empty parent list yields no suppressors", () => {
|
|
145
|
+
expect(
|
|
146
|
+
MonitorDependencyRule.getSuppressingParents({
|
|
147
|
+
parents: [],
|
|
148
|
+
configuredSuppressionStatusIds: new Set<string>(["s-offline"]),
|
|
149
|
+
}),
|
|
150
|
+
).toEqual([]);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe("MonitorDependencyRule.buildSuppressionReason", () => {
|
|
155
|
+
test("uses the singular noun for a single parent", () => {
|
|
156
|
+
const reason: string = MonitorDependencyRule.buildSuppressionReason([
|
|
157
|
+
{ monitorId: "m1", monitorName: "Router", statusName: "Offline" },
|
|
158
|
+
]);
|
|
159
|
+
expect(reason).toBe('parent monitor "Router" is Offline');
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("uses the plural noun and comma-joins multiple parents", () => {
|
|
163
|
+
const reason: string = MonitorDependencyRule.buildSuppressionReason([
|
|
164
|
+
{ monitorId: "m1", monitorName: "Router", statusName: "Offline" },
|
|
165
|
+
{ monitorId: "m2", monitorName: "Switch", statusName: "Degraded" },
|
|
166
|
+
]);
|
|
167
|
+
expect(reason).toBe(
|
|
168
|
+
'parent monitors "Router" is Offline, "Switch" is Degraded',
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test("quotes each monitor name so odd names stay legible", () => {
|
|
173
|
+
const reason: string = MonitorDependencyRule.buildSuppressionReason([
|
|
174
|
+
{
|
|
175
|
+
monitorId: "m1",
|
|
176
|
+
monitorName: "us-east, primary",
|
|
177
|
+
statusName: "Offline",
|
|
178
|
+
},
|
|
179
|
+
]);
|
|
180
|
+
// The name itself contains a comma; the quotes keep it from reading as two.
|
|
181
|
+
expect(reason).toBe('parent monitor "us-east, primary" is Offline');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("an empty parent list produces the singular stem with no names", () => {
|
|
185
|
+
// Degenerate input still returns a string rather than throwing.
|
|
186
|
+
expect(MonitorDependencyRule.buildSuppressionReason([])).toBe(
|
|
187
|
+
"parent monitor ",
|
|
188
|
+
);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import RealtimeUtil from "../../Utils/Realtime";
|
|
2
|
+
import ObjectID from "../../Types/ObjectID";
|
|
3
|
+
import ModelEventType from "../../Types/Realtime/ModelEventType";
|
|
4
|
+
|
|
5
|
+
describe("RealtimeUtil.getRoomId", () => {
|
|
6
|
+
test("joins tenant, model and event type with hyphens", () => {
|
|
7
|
+
expect(
|
|
8
|
+
RealtimeUtil.getRoomId("tenant1", "Monitor", ModelEventType.Create),
|
|
9
|
+
).toBe("tenant1-Monitor-Create");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("appends the model id when one is given", () => {
|
|
13
|
+
expect(
|
|
14
|
+
RealtimeUtil.getRoomId(
|
|
15
|
+
"tenant1",
|
|
16
|
+
"Monitor",
|
|
17
|
+
ModelEventType.Update,
|
|
18
|
+
"model9",
|
|
19
|
+
),
|
|
20
|
+
).toBe("tenant1-Monitor-Update-model9");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("accepts ObjectID for tenant and model id, using their string form", () => {
|
|
24
|
+
const tenant: ObjectID = new ObjectID(
|
|
25
|
+
"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
26
|
+
);
|
|
27
|
+
const modelId: ObjectID = new ObjectID(
|
|
28
|
+
"bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
expect(
|
|
32
|
+
RealtimeUtil.getRoomId(
|
|
33
|
+
tenant,
|
|
34
|
+
"Incident",
|
|
35
|
+
ModelEventType.Delete,
|
|
36
|
+
modelId,
|
|
37
|
+
),
|
|
38
|
+
).toBe(`${tenant.toString()}-Incident-Delete-${modelId.toString()}`);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("the room id changes with the event type (rooms are per-event)", () => {
|
|
42
|
+
const create: string = RealtimeUtil.getRoomId(
|
|
43
|
+
"t",
|
|
44
|
+
"Monitor",
|
|
45
|
+
ModelEventType.Create,
|
|
46
|
+
);
|
|
47
|
+
const update: string = RealtimeUtil.getRoomId(
|
|
48
|
+
"t",
|
|
49
|
+
"Monitor",
|
|
50
|
+
ModelEventType.Update,
|
|
51
|
+
);
|
|
52
|
+
expect(create).not.toBe(update);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("the id-scoped room is distinct from the collection-wide room", () => {
|
|
56
|
+
// A subscriber to one model must not collect the whole collection's events.
|
|
57
|
+
const collectionRoom: string = RealtimeUtil.getRoomId(
|
|
58
|
+
"t",
|
|
59
|
+
"Monitor",
|
|
60
|
+
ModelEventType.Update,
|
|
61
|
+
);
|
|
62
|
+
const itemRoom: string = RealtimeUtil.getRoomId(
|
|
63
|
+
"t",
|
|
64
|
+
"Monitor",
|
|
65
|
+
ModelEventType.Update,
|
|
66
|
+
"m1",
|
|
67
|
+
);
|
|
68
|
+
expect(itemRoom).not.toBe(collectionRoom);
|
|
69
|
+
expect(itemRoom.startsWith(collectionRoom)).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("an empty-string model id is falsy, so no id segment is appended", () => {
|
|
73
|
+
// Documents the `if (modelId)` guard: "" behaves like an omitted id.
|
|
74
|
+
expect(
|
|
75
|
+
RealtimeUtil.getRoomId("t", "Monitor", ModelEventType.Create, ""),
|
|
76
|
+
).toBe("t-Monitor-Create");
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import JSONFunctions from "../../../Types/JSONFunctions";
|
|
2
|
+
import TelemetrySavedViewState from "../../../Types/Telemetry/TelemetrySavedViewState";
|
|
3
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
4
|
+
import {
|
|
5
|
+
readSavedViewFilters,
|
|
6
|
+
SavedViewFilterTuple,
|
|
7
|
+
} from "../../../Utils/Telemetry/SavedViewFilters";
|
|
8
|
+
import { describe, expect, test } from "@jest/globals";
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Facet filters are stored as [facetKey, value] tuples inside a JSON column,
|
|
12
|
+
* and for a while the serializer rewrote every one of them into
|
|
13
|
+
* { "0": facetKey, "1": value }. Those rows are still in the database, so the
|
|
14
|
+
* explorers cannot destructure saved filters directly — a single bad row used
|
|
15
|
+
* to take the whole Traces page down with
|
|
16
|
+
* "TypeError: (destructured parameter) is not iterable".
|
|
17
|
+
*
|
|
18
|
+
* These tests cover both shapes and the junk in between.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// The shape a pre-fix serializer left in the database.
|
|
22
|
+
const LEGACY_CORRUPTED_FILTERS: unknown = [
|
|
23
|
+
{ "0": "primaryEntityId", "1": "6512f1a0a1b2c3d4e5f60718" },
|
|
24
|
+
{ "0": "attributes.http.method", "1": "GET" },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
describe("readSavedViewFilters", () => {
|
|
28
|
+
describe("Well-formed saved state", () => {
|
|
29
|
+
test("Reads tuples that were stored correctly", () => {
|
|
30
|
+
expect(
|
|
31
|
+
readSavedViewFilters([
|
|
32
|
+
["service", "api"],
|
|
33
|
+
["status", "error"],
|
|
34
|
+
]),
|
|
35
|
+
).toEqual([
|
|
36
|
+
["service", "api"],
|
|
37
|
+
["status", "error"],
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("Reads a single tuple", () => {
|
|
42
|
+
expect(readSavedViewFilters([["service", "api"]])).toEqual([
|
|
43
|
+
["service", "api"],
|
|
44
|
+
]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("Returns an empty list for an empty list", () => {
|
|
48
|
+
expect(readSavedViewFilters([])).toEqual([]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("Keeps a filter whose value is deliberately the empty string", () => {
|
|
52
|
+
expect(readSavedViewFilters([["statusMessage", ""]])).toEqual([
|
|
53
|
+
["statusMessage", ""],
|
|
54
|
+
]);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("Ignores anything beyond the first two elements of a tuple", () => {
|
|
58
|
+
expect(
|
|
59
|
+
readSavedViewFilters([["service", "api", "extra", "junk"]]),
|
|
60
|
+
).toEqual([["service", "api"]]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("Preserves order", () => {
|
|
64
|
+
expect(
|
|
65
|
+
readSavedViewFilters([
|
|
66
|
+
["c", "3"],
|
|
67
|
+
["a", "1"],
|
|
68
|
+
["b", "2"],
|
|
69
|
+
]),
|
|
70
|
+
).toEqual([
|
|
71
|
+
["c", "3"],
|
|
72
|
+
["a", "1"],
|
|
73
|
+
["b", "2"],
|
|
74
|
+
]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("Returns real arrays, so callers can destructure them", () => {
|
|
78
|
+
const filters: Array<SavedViewFilterTuple> = readSavedViewFilters([
|
|
79
|
+
["service", "api"],
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
const read: Array<string> = filters.map(
|
|
83
|
+
([facetKey, value]: SavedViewFilterTuple): string => {
|
|
84
|
+
return `${facetKey}:${value}`;
|
|
85
|
+
},
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
expect(read).toEqual(["service:api"]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("Legacy rows corrupted by the old serializer", () => {
|
|
93
|
+
test("Reads { '0': key, '1': value } back into a tuple", () => {
|
|
94
|
+
expect(readSavedViewFilters(LEGACY_CORRUPTED_FILTERS)).toEqual([
|
|
95
|
+
["primaryEntityId", "6512f1a0a1b2c3d4e5f60718"],
|
|
96
|
+
["attributes.http.method", "GET"],
|
|
97
|
+
]);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("A healed legacy row is destructurable", () => {
|
|
101
|
+
const filters: Array<SavedViewFilterTuple> = readSavedViewFilters(
|
|
102
|
+
LEGACY_CORRUPTED_FILTERS,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
expect(() => {
|
|
106
|
+
return filters.map(([facetKey]: SavedViewFilterTuple): string => {
|
|
107
|
+
return facetKey;
|
|
108
|
+
});
|
|
109
|
+
}).not.toThrow();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("Reads a list that mixes healed and correct rows", () => {
|
|
113
|
+
expect(
|
|
114
|
+
readSavedViewFilters([
|
|
115
|
+
{ "0": "service", "1": "api" },
|
|
116
|
+
["status", "error"],
|
|
117
|
+
]),
|
|
118
|
+
).toEqual([
|
|
119
|
+
["service", "api"],
|
|
120
|
+
["status", "error"],
|
|
121
|
+
]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("Heals exactly what the old serializer produced, end to end", () => {
|
|
125
|
+
/*
|
|
126
|
+
* Reproduce the corruption the way it actually happened — through the
|
|
127
|
+
* pre-fix serializer — rather than hand-writing the broken shape.
|
|
128
|
+
*/
|
|
129
|
+
const corrupted: JSONObject = {
|
|
130
|
+
filters: [
|
|
131
|
+
{ "0": "service", "1": "api" },
|
|
132
|
+
{ "0": "status", "1": "error" },
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
expect(readSavedViewFilters(corrupted["filters"])).toEqual([
|
|
137
|
+
["service", "api"],
|
|
138
|
+
["status", "error"],
|
|
139
|
+
]);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("Malformed saved state never throws", () => {
|
|
144
|
+
test("Returns an empty list for undefined, null and non-arrays", () => {
|
|
145
|
+
expect(readSavedViewFilters(undefined)).toEqual([]);
|
|
146
|
+
expect(readSavedViewFilters(null)).toEqual([]);
|
|
147
|
+
expect(readSavedViewFilters("service:api")).toEqual([]);
|
|
148
|
+
expect(readSavedViewFilters(42)).toEqual([]);
|
|
149
|
+
expect(readSavedViewFilters(true)).toEqual([]);
|
|
150
|
+
expect(readSavedViewFilters({})).toEqual([]);
|
|
151
|
+
expect(readSavedViewFilters({ service: "api" })).toEqual([]);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("Drops entries that are not tuple-shaped at all", () => {
|
|
155
|
+
expect(
|
|
156
|
+
readSavedViewFilters([
|
|
157
|
+
"service:api",
|
|
158
|
+
42,
|
|
159
|
+
null,
|
|
160
|
+
undefined,
|
|
161
|
+
true,
|
|
162
|
+
["status", "error"],
|
|
163
|
+
]),
|
|
164
|
+
).toEqual([["status", "error"]]);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("Drops entries with no usable facet key", () => {
|
|
168
|
+
expect(
|
|
169
|
+
readSavedViewFilters([
|
|
170
|
+
[],
|
|
171
|
+
["", "api"],
|
|
172
|
+
[null, "api"],
|
|
173
|
+
[{ nested: true }, "api"],
|
|
174
|
+
["service", "api"],
|
|
175
|
+
]),
|
|
176
|
+
).toEqual([["service", "api"]]);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("Falls back to an empty value when the stored value is unusable", () => {
|
|
180
|
+
expect(readSavedViewFilters([["service", null]])).toEqual([
|
|
181
|
+
["service", ""],
|
|
182
|
+
]);
|
|
183
|
+
expect(readSavedViewFilters([["service"]])).toEqual([["service", ""]]);
|
|
184
|
+
expect(readSavedViewFilters([["service", { nested: true }]])).toEqual([
|
|
185
|
+
["service", ""],
|
|
186
|
+
]);
|
|
187
|
+
expect(readSavedViewFilters([["service", ["a"]]])).toEqual([
|
|
188
|
+
["service", ""],
|
|
189
|
+
]);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("Stringifies values that came back as numbers or booleans", () => {
|
|
193
|
+
expect(
|
|
194
|
+
readSavedViewFilters([
|
|
195
|
+
["duration", 500],
|
|
196
|
+
["hasException", true],
|
|
197
|
+
]),
|
|
198
|
+
).toEqual([
|
|
199
|
+
["duration", "500"],
|
|
200
|
+
["hasException", "true"],
|
|
201
|
+
]);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("Drops non-finite numeric values rather than writing 'NaN' into a chip", () => {
|
|
205
|
+
expect(readSavedViewFilters([["duration", NaN]])).toEqual([
|
|
206
|
+
["duration", ""],
|
|
207
|
+
]);
|
|
208
|
+
expect(readSavedViewFilters([["duration", Infinity]])).toEqual([
|
|
209
|
+
["duration", ""],
|
|
210
|
+
]);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test("Reads a numeric facet key stored as a number", () => {
|
|
214
|
+
expect(readSavedViewFilters([[7, "api"]])).toEqual([["7", "api"]]);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe("Round trip through the serializer that stores the view", () => {
|
|
219
|
+
test("Filters written by the fixed serializer read straight back", () => {
|
|
220
|
+
const state: TelemetrySavedViewState = {
|
|
221
|
+
search: "status:error",
|
|
222
|
+
filters: [
|
|
223
|
+
["service", "api"],
|
|
224
|
+
["attributes.http.method", "GET"],
|
|
225
|
+
],
|
|
226
|
+
pageSize: 50,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const stored: JSONObject = JSONFunctions.deserialize(
|
|
230
|
+
JSON.parse(
|
|
231
|
+
JSON.stringify(JSONFunctions.serialize(state as JSONObject)),
|
|
232
|
+
),
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
expect(readSavedViewFilters(stored["filters"])).toEqual(state.filters);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test("A view with no filters at all reads as no filters", () => {
|
|
239
|
+
const state: TelemetrySavedViewState = { search: "status:error" };
|
|
240
|
+
|
|
241
|
+
const stored: JSONObject = JSONFunctions.serialize(state as JSONObject);
|
|
242
|
+
|
|
243
|
+
expect(readSavedViewFilters(stored["filters"])).toEqual([]);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* The real detector is only installed in the frontend feature sets. Tests that
|
|
5
|
+
* render status page components import Utils/i18n, which registers this plugin,
|
|
6
|
+
* so a minimal stand-in that always resolves to English is enough.
|
|
7
|
+
*/
|
|
8
|
+
class LanguageDetector {
|
|
9
|
+
init() {}
|
|
10
|
+
|
|
11
|
+
detect() {
|
|
12
|
+
return "en";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
cacheUserLanguage() {}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
LanguageDetector.type = "languageDetector";
|
|
19
|
+
|
|
20
|
+
module.exports = LanguageDetector;
|
|
21
|
+
module.exports.default = LanguageDetector;
|
|
@@ -3,7 +3,7 @@ import CodeFixTaskType from "./CodeFixTaskType";
|
|
|
3
3
|
/*
|
|
4
4
|
* The rolled-up CI conclusion recorded on an AI fix pull request
|
|
5
5
|
* (AIAgentTaskPullRequest.ciStatus) — B4 Tier 1: verification via the
|
|
6
|
-
* customer's OWN CI on the
|
|
6
|
+
* customer's OWN CI on the fix PRs. We read check-run conclusions through
|
|
7
7
|
* the GitHub App; we never re-run or gate the customer's CI.
|
|
8
8
|
*
|
|
9
9
|
* G9 honesty rule: only Green and ExpectedFailureObserved ever count as
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - Passed: every configured command (setup, build, test) exited 0 —
|
|
8
8
|
* possibly after bounded agent repair attempts.
|
|
9
9
|
* - Failed: a configured command still failed after the repair attempts
|
|
10
|
-
* were exhausted. The PR still opens
|
|
11
|
-
* the work is not lost — the human reviewer decides.
|
|
10
|
+
* were exhausted. The PR still opens, with the failure clearly labeled
|
|
11
|
+
* in its body, so the work is not lost — the human reviewer decides.
|
|
12
12
|
* - Skipped: the repository has no verification commands configured, so
|
|
13
13
|
* nothing could be verified.
|
|
14
14
|
*/
|