@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,72 @@
|
|
|
1
|
+
import LocalStorage from "../../../UI/Utils/LocalStorage";
|
|
2
|
+
import { readLegacySerializedArray } from "../../../Utils/LegacySerializedArray";
|
|
3
|
+
import { beforeEach, describe, expect, test } from "@jest/globals";
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* LocalStorage.setItem hands the caller's value straight to
|
|
7
|
+
* JSONFunctions.serializeValue rather than wrapping it in an object first, so
|
|
8
|
+
* a TOP-LEVEL array took the same broken path as a nested one and came back as
|
|
9
|
+
* { "0": ..., "1": ... }. This is not the saved-view case: the array is flat.
|
|
10
|
+
*
|
|
11
|
+
* It shipped. The logs explorer stores its selected columns here, read back
|
|
12
|
+
* behind an Array.isArray guard, so the corruption showed up as the column
|
|
13
|
+
* picker silently resetting to defaults on every reload — no error anywhere.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
describe("LocalStorage round-trips arrays", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
localStorage.clear();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("A flat string array comes back as an array", () => {
|
|
22
|
+
LocalStorage.setItem("columns", ["time", "body", "severityText"]);
|
|
23
|
+
|
|
24
|
+
const restored: unknown = LocalStorage.getItem("columns");
|
|
25
|
+
|
|
26
|
+
expect(Array.isArray(restored)).toBe(true);
|
|
27
|
+
expect(restored).toEqual(["time", "body", "severityText"]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("The stored JSON is an array, not a numeric-keyed object", () => {
|
|
31
|
+
LocalStorage.setItem("columns", ["time", "body"]);
|
|
32
|
+
|
|
33
|
+
expect(localStorage.getItem("columns")).toBe('["time","body"]');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("An empty array round-trips", () => {
|
|
37
|
+
LocalStorage.setItem("columns", []);
|
|
38
|
+
|
|
39
|
+
expect(LocalStorage.getItem("columns")).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("An array of numbers round-trips", () => {
|
|
43
|
+
LocalStorage.setItem("sizes", [10, 25, 50]);
|
|
44
|
+
|
|
45
|
+
expect(LocalStorage.getItem("sizes")).toEqual([10, 25, 50]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("An array nested inside a stored object round-trips", () => {
|
|
49
|
+
LocalStorage.setItem("state", { columns: ["time"], filters: [["a", "b"]] });
|
|
50
|
+
|
|
51
|
+
expect(LocalStorage.getItem("state")).toEqual({
|
|
52
|
+
columns: ["time"],
|
|
53
|
+
filters: [["a", "b"]],
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("A plain object is still stored as an object", () => {
|
|
58
|
+
LocalStorage.setItem("prefs", { pageSize: 50 });
|
|
59
|
+
|
|
60
|
+
expect(LocalStorage.getItem("prefs")).toEqual({ pageSize: 50 });
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("A value written by the old serializer still reads back as a list", () => {
|
|
64
|
+
// What a pre-fix build left in the browser.
|
|
65
|
+
localStorage.setItem("columns", '{"0":"time","1":"body"}');
|
|
66
|
+
|
|
67
|
+
const restored: unknown = LocalStorage.getItem("columns");
|
|
68
|
+
|
|
69
|
+
expect(Array.isArray(restored)).toBe(false);
|
|
70
|
+
expect(readLegacySerializedArray(restored)).toEqual(["time", "body"]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -216,7 +216,12 @@ describe("HtmlWidgetDocument", () => {
|
|
|
216
216
|
).toEqual({ clusters: "eu-1,us-1" });
|
|
217
217
|
});
|
|
218
218
|
|
|
219
|
-
|
|
219
|
+
/*
|
|
220
|
+
* A multi-select with no picks is "All", and the default does not
|
|
221
|
+
* override it — same rule the chart widgets follow. The author sees
|
|
222
|
+
* an empty string, which is what "no scope" looks like in a template.
|
|
223
|
+
*/
|
|
224
|
+
it("renders an empty string when a multi-select has no picks", () => {
|
|
220
225
|
expect(
|
|
221
226
|
HtmlWidgetDocument.resolveVariables([
|
|
222
227
|
makeVariable({
|
|
@@ -226,7 +231,19 @@ describe("HtmlWidgetDocument", () => {
|
|
|
226
231
|
defaultValue: "eu-1",
|
|
227
232
|
}),
|
|
228
233
|
]),
|
|
229
|
-
).toEqual({ clusters: "
|
|
234
|
+
).toEqual({ clusters: "" });
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("renders an empty string for an untouched multi-select with a default", () => {
|
|
238
|
+
expect(
|
|
239
|
+
HtmlWidgetDocument.resolveVariables([
|
|
240
|
+
makeVariable({
|
|
241
|
+
name: "clusters",
|
|
242
|
+
isMultiSelect: true,
|
|
243
|
+
defaultValue: "eu-1",
|
|
244
|
+
}),
|
|
245
|
+
]),
|
|
246
|
+
).toEqual({ clusters: "" });
|
|
230
247
|
});
|
|
231
248
|
|
|
232
249
|
it("maps an unset variable to an empty string rather than dropping it", () => {
|
|
@@ -105,6 +105,50 @@ describe("DashboardModelQueryInterpolation.applyToQuery - writing predicates", (
|
|
|
105
105
|
expect((result["hostname"] as Includes).values).toEqual(["web1", "web2"]);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
+
/*
|
|
109
|
+
* Resource list widgets share DashboardVariableInterpolation.resolveValue
|
|
110
|
+
* with the metric widgets, so they inherit the "All" rule: an empty
|
|
111
|
+
* multi-select filters nothing, and the variable's single-select Default
|
|
112
|
+
* does not stand in for the picks the user did not make.
|
|
113
|
+
*/
|
|
114
|
+
test("an empty multi-select writes no predicate, Default or not", () => {
|
|
115
|
+
const query: Record<string, unknown> = { kind: "Container" };
|
|
116
|
+
const result: Record<string, unknown> =
|
|
117
|
+
DashboardModelQueryInterpolation.applyToQuery(
|
|
118
|
+
query,
|
|
119
|
+
[
|
|
120
|
+
attrVariable("host.name", {
|
|
121
|
+
isMultiSelect: true,
|
|
122
|
+
selectedValues: [],
|
|
123
|
+
defaultValue: "web1",
|
|
124
|
+
}),
|
|
125
|
+
],
|
|
126
|
+
MAP,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
expect(result).toBe(query);
|
|
130
|
+
expect(result["hostname"]).toBeUndefined();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("a cleared multi-select removes a prior filter on that column", () => {
|
|
134
|
+
const query: Record<string, unknown> = { hostname: "web1", kind: "Pod" };
|
|
135
|
+
const result: Record<string, unknown> =
|
|
136
|
+
DashboardModelQueryInterpolation.applyToQuery(
|
|
137
|
+
query,
|
|
138
|
+
[
|
|
139
|
+
attrVariable("host.name", {
|
|
140
|
+
isMultiSelect: true,
|
|
141
|
+
selectedValues: [],
|
|
142
|
+
defaultValue: "web1",
|
|
143
|
+
}),
|
|
144
|
+
],
|
|
145
|
+
MAP,
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
expect(result).toEqual({ kind: "Pod" });
|
|
149
|
+
expect(query).toEqual({ hostname: "web1", kind: "Pod" }); // input untouched
|
|
150
|
+
});
|
|
151
|
+
|
|
108
152
|
test("maps two variables onto their respective columns", () => {
|
|
109
153
|
const result: Record<string, unknown> =
|
|
110
154
|
DashboardModelQueryInterpolation.applyToQuery(
|
|
@@ -2,6 +2,7 @@ import Includes from "../../../Types/BaseDatabase/Includes";
|
|
|
2
2
|
import DashboardVariable, {
|
|
3
3
|
DashboardVariableType,
|
|
4
4
|
} from "../../../Types/Dashboard/DashboardVariable";
|
|
5
|
+
import MetricQueryConfigData from "../../../Types/Metrics/MetricQueryConfigData";
|
|
5
6
|
import DashboardVariableInterpolation from "../../../Utils/Dashboard/VariableInterpolation";
|
|
6
7
|
|
|
7
8
|
function makeVariable(
|
|
@@ -15,6 +16,24 @@ function makeVariable(
|
|
|
15
16
|
} as DashboardVariable;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
function makeQueryConfig(
|
|
20
|
+
attributes: Record<string, unknown> | undefined,
|
|
21
|
+
): MetricQueryConfigData {
|
|
22
|
+
return {
|
|
23
|
+
metricQueryData: {
|
|
24
|
+
filterData: attributes === undefined ? {} : { attributes },
|
|
25
|
+
},
|
|
26
|
+
} as unknown as MetricQueryConfigData;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function attributesOf(
|
|
30
|
+
config: MetricQueryConfigData,
|
|
31
|
+
): Record<string, unknown> | undefined {
|
|
32
|
+
return config.metricQueryData.filterData.attributes as unknown as
|
|
33
|
+
| Record<string, unknown>
|
|
34
|
+
| undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
18
37
|
describe("DashboardVariableInterpolation", () => {
|
|
19
38
|
describe("resolveValue", () => {
|
|
20
39
|
test("returns scalar for a single-select with selectedValue", () => {
|
|
@@ -76,14 +95,117 @@ describe("DashboardVariableInterpolation", () => {
|
|
|
76
95
|
});
|
|
77
96
|
});
|
|
78
97
|
|
|
79
|
-
|
|
98
|
+
/*
|
|
99
|
+
* The contract for multi-select, and the reason it is not simply
|
|
100
|
+
* "reuse the single-select fallback": the selector renders "All"
|
|
101
|
+
* whenever `selectedValues` is empty and has no way to render
|
|
102
|
+
* anything else. If an empty list resolved to `defaultValue`, every
|
|
103
|
+
* multi-select variable with a Default would filter its widgets from
|
|
104
|
+
* behind a control that says the widgets are unfiltered — and the
|
|
105
|
+
* popover's own Clear button is the fastest way to get there.
|
|
106
|
+
*/
|
|
107
|
+
describe("an empty multi-select means All", () => {
|
|
108
|
+
test("ignores defaultValue when the list is empty", () => {
|
|
109
|
+
const variable: DashboardVariable = makeVariable({
|
|
110
|
+
isMultiSelect: true,
|
|
111
|
+
selectedValues: [],
|
|
112
|
+
defaultValue: "d",
|
|
113
|
+
});
|
|
114
|
+
expect(
|
|
115
|
+
DashboardVariableInterpolation.resolveValue(variable),
|
|
116
|
+
).toBeUndefined();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("ignores defaultValue when the list is unset", () => {
|
|
120
|
+
const variable: DashboardVariable = makeVariable({
|
|
121
|
+
isMultiSelect: true,
|
|
122
|
+
defaultValue: "d",
|
|
123
|
+
});
|
|
124
|
+
expect(
|
|
125
|
+
DashboardVariableInterpolation.resolveValue(variable),
|
|
126
|
+
).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("ignores defaultValue when every pick is blank", () => {
|
|
130
|
+
const variable: DashboardVariable = makeVariable({
|
|
131
|
+
isMultiSelect: true,
|
|
132
|
+
selectedValues: ["", ""],
|
|
133
|
+
defaultValue: "d",
|
|
134
|
+
});
|
|
135
|
+
expect(
|
|
136
|
+
DashboardVariableInterpolation.resolveValue(variable),
|
|
137
|
+
).toBeUndefined();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* A variable that was single-select before the author ticked
|
|
142
|
+
* "Allow multi-select" still carries the scalar it was left on.
|
|
143
|
+
* The multi list is the only source of truth once the flag is set,
|
|
144
|
+
* so that stale scalar must not resurface as a filter.
|
|
145
|
+
*/
|
|
146
|
+
test("ignores a stale selectedValue left over from single-select", () => {
|
|
147
|
+
const variable: DashboardVariable = makeVariable({
|
|
148
|
+
isMultiSelect: true,
|
|
149
|
+
selectedValues: [],
|
|
150
|
+
selectedValue: "stale",
|
|
151
|
+
defaultValue: "d",
|
|
152
|
+
});
|
|
153
|
+
expect(
|
|
154
|
+
DashboardVariableInterpolation.resolveValue(variable),
|
|
155
|
+
).toBeUndefined();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("still resolves once the user picks something", () => {
|
|
159
|
+
const variable: DashboardVariable = makeVariable({
|
|
160
|
+
isMultiSelect: true,
|
|
161
|
+
selectedValues: ["a"],
|
|
162
|
+
defaultValue: "d",
|
|
163
|
+
});
|
|
164
|
+
expect(DashboardVariableInterpolation.resolveValue(variable)).toEqual({
|
|
165
|
+
multi: ["a"],
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/*
|
|
171
|
+
* The mirror of the rule above on the single-select side. "" is the
|
|
172
|
+
* value of the selector's "All" option — a real choice — so it must
|
|
173
|
+
* not fall back to the default. `??` draws that line; `||` would not.
|
|
174
|
+
*/
|
|
175
|
+
test("an explicit empty scalar is All, not a fallback to the default", () => {
|
|
80
176
|
const variable: DashboardVariable = makeVariable({
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
177
|
+
selectedValue: "",
|
|
178
|
+
defaultValue: "staging",
|
|
179
|
+
});
|
|
180
|
+
expect(
|
|
181
|
+
DashboardVariableInterpolation.resolveValue(variable),
|
|
182
|
+
).toBeUndefined();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("defaultValue still applies to a single-select that is untouched", () => {
|
|
186
|
+
expect(
|
|
187
|
+
DashboardVariableInterpolation.resolveValue(
|
|
188
|
+
makeVariable({ defaultValue: "staging", isMultiSelect: false }),
|
|
189
|
+
),
|
|
190
|
+
).toEqual({ scalar: "staging" });
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test("an empty defaultValue is not a filter", () => {
|
|
194
|
+
expect(
|
|
195
|
+
DashboardVariableInterpolation.resolveValue(
|
|
196
|
+
makeVariable({ defaultValue: "" }),
|
|
197
|
+
),
|
|
198
|
+
).toBeUndefined();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test("selectedValues on a single-select variable is ignored", () => {
|
|
202
|
+
const variable: DashboardVariable = makeVariable({
|
|
203
|
+
isMultiSelect: false,
|
|
204
|
+
selectedValues: ["a", "b"],
|
|
205
|
+
selectedValue: "prod",
|
|
84
206
|
});
|
|
85
207
|
expect(DashboardVariableInterpolation.resolveValue(variable)).toEqual({
|
|
86
|
-
scalar: "
|
|
208
|
+
scalar: "prod",
|
|
87
209
|
});
|
|
88
210
|
});
|
|
89
211
|
});
|
|
@@ -178,6 +300,74 @@ describe("DashboardVariableInterpolation", () => {
|
|
|
178
300
|
expect(result).toEqual({ "k8s.cluster.name": "prod" });
|
|
179
301
|
});
|
|
180
302
|
|
|
303
|
+
/*
|
|
304
|
+
* The user-visible bug this contract exists for: the popover reads
|
|
305
|
+
* "All" the moment the last pick is removed, so the widget has to be
|
|
306
|
+
* unfiltered at that moment too — including dropping the widget's own
|
|
307
|
+
* base filter on that key, exactly as an "All" single-select does.
|
|
308
|
+
*/
|
|
309
|
+
test("a cleared multi-select with a default removes the filter", () => {
|
|
310
|
+
const variable: DashboardVariable = makeVariable({
|
|
311
|
+
attributeKey: "k8s.cluster.name",
|
|
312
|
+
isMultiSelect: true,
|
|
313
|
+
selectedValues: [],
|
|
314
|
+
defaultValue: "prod",
|
|
315
|
+
});
|
|
316
|
+
const result: Record<string, unknown> =
|
|
317
|
+
DashboardVariableInterpolation.applyToAttributes(
|
|
318
|
+
{ "k8s.cluster.name": "staging", other: "keep" },
|
|
319
|
+
[variable],
|
|
320
|
+
);
|
|
321
|
+
expect(result).toEqual({ other: "keep" });
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
test("a cleared multi-select with a default adds nothing", () => {
|
|
325
|
+
const attrs: Record<string, unknown> = { other: "keep" };
|
|
326
|
+
const variable: DashboardVariable = makeVariable({
|
|
327
|
+
attributeKey: "k8s.cluster.name",
|
|
328
|
+
isMultiSelect: true,
|
|
329
|
+
selectedValues: [],
|
|
330
|
+
defaultValue: "prod",
|
|
331
|
+
});
|
|
332
|
+
const result: Record<string, unknown> =
|
|
333
|
+
DashboardVariableInterpolation.applyToAttributes(attrs, [variable]);
|
|
334
|
+
expect(result).toBe(attrs);
|
|
335
|
+
expect(result["k8s.cluster.name"]).toBeUndefined();
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test("an untouched multi-select with a default adds nothing", () => {
|
|
339
|
+
const attrs: Record<string, unknown> = {};
|
|
340
|
+
const variable: DashboardVariable = makeVariable({
|
|
341
|
+
attributeKey: "k8s.cluster.name",
|
|
342
|
+
isMultiSelect: true,
|
|
343
|
+
defaultValue: "prod",
|
|
344
|
+
});
|
|
345
|
+
expect(
|
|
346
|
+
DashboardVariableInterpolation.applyToAttributes(attrs, [variable]),
|
|
347
|
+
).toBe(attrs);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
test("clearing one multi-select does not disturb another variable", () => {
|
|
351
|
+
const cleared: DashboardVariable = makeVariable({
|
|
352
|
+
id: "v1",
|
|
353
|
+
attributeKey: "cluster",
|
|
354
|
+
isMultiSelect: true,
|
|
355
|
+
selectedValues: [],
|
|
356
|
+
defaultValue: "prod",
|
|
357
|
+
});
|
|
358
|
+
const picked: DashboardVariable = makeVariable({
|
|
359
|
+
id: "v2",
|
|
360
|
+
attributeKey: "namespace",
|
|
361
|
+
selectedValue: "default",
|
|
362
|
+
});
|
|
363
|
+
const result: Record<string, unknown> =
|
|
364
|
+
DashboardVariableInterpolation.applyToAttributes(
|
|
365
|
+
{ cluster: "staging" },
|
|
366
|
+
[cleared, picked],
|
|
367
|
+
);
|
|
368
|
+
expect(result).toEqual({ namespace: "default" });
|
|
369
|
+
});
|
|
370
|
+
|
|
181
371
|
test("applies multiple variables at once", () => {
|
|
182
372
|
const v1: DashboardVariable = makeVariable({
|
|
183
373
|
id: "v1",
|
|
@@ -194,4 +384,97 @@ describe("DashboardVariableInterpolation", () => {
|
|
|
194
384
|
expect(result).toEqual({ cluster: "prod", namespace: "default" });
|
|
195
385
|
});
|
|
196
386
|
});
|
|
387
|
+
|
|
388
|
+
/*
|
|
389
|
+
* Metric charts and gauges go through the query-config wrapper rather
|
|
390
|
+
* than calling applyToAttributes directly, so the "All" contract is
|
|
391
|
+
* pinned at that level too — this is the path a user actually watches
|
|
392
|
+
* change when they clear the popover.
|
|
393
|
+
*/
|
|
394
|
+
describe("applyToQueryConfig", () => {
|
|
395
|
+
test("injects an Includes for a multi-select with picks", () => {
|
|
396
|
+
const config: MetricQueryConfigData = makeQueryConfig({});
|
|
397
|
+
const result: MetricQueryConfigData =
|
|
398
|
+
DashboardVariableInterpolation.applyToQueryConfig(config, [
|
|
399
|
+
makeVariable({
|
|
400
|
+
attributeKey: "k8s.cluster.name",
|
|
401
|
+
isMultiSelect: true,
|
|
402
|
+
selectedValues: ["eu-1", "us-1"],
|
|
403
|
+
}),
|
|
404
|
+
]);
|
|
405
|
+
const value: unknown = attributesOf(result)?.["k8s.cluster.name"];
|
|
406
|
+
expect(value).toBeInstanceOf(Includes);
|
|
407
|
+
expect((value as Includes).values).toEqual(["eu-1", "us-1"]);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test("a cleared multi-select with a default leaves the query unfiltered", () => {
|
|
411
|
+
const config: MetricQueryConfigData = makeQueryConfig({
|
|
412
|
+
"k8s.cluster.name": "prod",
|
|
413
|
+
});
|
|
414
|
+
const result: MetricQueryConfigData =
|
|
415
|
+
DashboardVariableInterpolation.applyToQueryConfig(config, [
|
|
416
|
+
makeVariable({
|
|
417
|
+
attributeKey: "k8s.cluster.name",
|
|
418
|
+
isMultiSelect: true,
|
|
419
|
+
selectedValues: [],
|
|
420
|
+
defaultValue: "prod",
|
|
421
|
+
}),
|
|
422
|
+
]);
|
|
423
|
+
expect(attributesOf(result)).toEqual({});
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
test("returns the same config reference when nothing changes", () => {
|
|
427
|
+
const config: MetricQueryConfigData = makeQueryConfig({});
|
|
428
|
+
expect(
|
|
429
|
+
DashboardVariableInterpolation.applyToQueryConfig(config, [
|
|
430
|
+
makeVariable({
|
|
431
|
+
attributeKey: "k8s.cluster.name",
|
|
432
|
+
isMultiSelect: true,
|
|
433
|
+
selectedValues: [],
|
|
434
|
+
defaultValue: "prod",
|
|
435
|
+
}),
|
|
436
|
+
]),
|
|
437
|
+
).toBe(config);
|
|
438
|
+
expect(
|
|
439
|
+
DashboardVariableInterpolation.applyToQueryConfig(config, []),
|
|
440
|
+
).toBe(config);
|
|
441
|
+
expect(
|
|
442
|
+
DashboardVariableInterpolation.applyToQueryConfig(config, undefined),
|
|
443
|
+
).toBe(config);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test("leaves a config with no filterData alone", () => {
|
|
447
|
+
const config: MetricQueryConfigData = {
|
|
448
|
+
metricQueryData: {},
|
|
449
|
+
} as unknown as MetricQueryConfigData;
|
|
450
|
+
expect(
|
|
451
|
+
DashboardVariableInterpolation.applyToQueryConfig(config, [
|
|
452
|
+
makeVariable({
|
|
453
|
+
attributeKey: "k8s.cluster.name",
|
|
454
|
+
selectedValue: "prod",
|
|
455
|
+
}),
|
|
456
|
+
]),
|
|
457
|
+
).toBe(config);
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
test("applyToQueryConfigs maps every config", () => {
|
|
461
|
+
const configs: Array<MetricQueryConfigData> = [
|
|
462
|
+
makeQueryConfig({ "k8s.cluster.name": "prod" }),
|
|
463
|
+
makeQueryConfig({ "k8s.cluster.name": "prod", keep: "me" }),
|
|
464
|
+
];
|
|
465
|
+
const result: Array<MetricQueryConfigData> =
|
|
466
|
+
DashboardVariableInterpolation.applyToQueryConfigs(configs, [
|
|
467
|
+
makeVariable({
|
|
468
|
+
attributeKey: "k8s.cluster.name",
|
|
469
|
+
isMultiSelect: true,
|
|
470
|
+
selectedValues: [],
|
|
471
|
+
defaultValue: "prod",
|
|
472
|
+
}),
|
|
473
|
+
]);
|
|
474
|
+
expect(attributesOf(result[0] as MetricQueryConfigData)).toEqual({});
|
|
475
|
+
expect(attributesOf(result[1] as MetricQueryConfigData)).toEqual({
|
|
476
|
+
keep: "me",
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
});
|
|
197
480
|
});
|
|
@@ -4,6 +4,7 @@ import DashboardVariableUrlState, {
|
|
|
4
4
|
import DashboardVariable, {
|
|
5
5
|
DashboardVariableType,
|
|
6
6
|
} from "../../../Types/Dashboard/DashboardVariable";
|
|
7
|
+
import DashboardVariableInterpolation from "../../../Utils/Dashboard/VariableInterpolation";
|
|
7
8
|
|
|
8
9
|
function makeVariable(data: Partial<DashboardVariable>): DashboardVariable {
|
|
9
10
|
return {
|
|
@@ -147,6 +148,47 @@ describe("DashboardVariableUrlState", () => {
|
|
|
147
148
|
expect(applied[0]?.selectedValue).toBe("prod");
|
|
148
149
|
expect(applied[1]?.selectedValues).toEqual(["us", "eu"]);
|
|
149
150
|
});
|
|
151
|
+
|
|
152
|
+
/*
|
|
153
|
+
* "All" is the absence of a var- param — writeToBrowserUrl emits
|
|
154
|
+
* nothing for an empty selection, so a reload cannot tell "cleared"
|
|
155
|
+
* from "never touched" and must treat both as All. That only holds
|
|
156
|
+
* because resolveValue ignores defaultValue for a multi-select; if it
|
|
157
|
+
* fell back, a viewer who cleared the popover would silently get the
|
|
158
|
+
* author's Default back on every refresh and on every shared link.
|
|
159
|
+
*/
|
|
160
|
+
test("a cleared multi-select survives a url round trip as All", () => {
|
|
161
|
+
window.history.replaceState({}, "", "/dashboard");
|
|
162
|
+
DashboardVariableUrlState.writeToBrowserUrl([
|
|
163
|
+
makeVariable({
|
|
164
|
+
name: "region",
|
|
165
|
+
isMultiSelect: true,
|
|
166
|
+
selectedValues: [],
|
|
167
|
+
defaultValue: "us",
|
|
168
|
+
}),
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
expect(window.location.search).toBe("");
|
|
172
|
+
|
|
173
|
+
const applied: Array<DashboardVariable> =
|
|
174
|
+
DashboardVariableUrlState.applyUrlToVariables(
|
|
175
|
+
[
|
|
176
|
+
makeVariable({
|
|
177
|
+
name: "region",
|
|
178
|
+
isMultiSelect: true,
|
|
179
|
+
defaultValue: "us",
|
|
180
|
+
}),
|
|
181
|
+
],
|
|
182
|
+
DashboardVariableUrlState.parseFromSearch(window.location.search),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
expect(applied[0]?.selectedValues).toBeUndefined();
|
|
186
|
+
expect(
|
|
187
|
+
DashboardVariableInterpolation.resolveValue(
|
|
188
|
+
applied[0] as DashboardVariable,
|
|
189
|
+
),
|
|
190
|
+
).toBeUndefined();
|
|
191
|
+
});
|
|
150
192
|
});
|
|
151
193
|
|
|
152
194
|
describe("writeToBrowserUrl", () => {
|
|
@@ -52,6 +52,33 @@ describe("DataSourceQueryText.applyVariables", () => {
|
|
|
52
52
|
expect(result).toBe("default-cluster");
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
/*
|
|
56
|
+
* An empty multi-select is "All", so it resolves to nothing and the token
|
|
57
|
+
* is left standing — the connector then names the unbound variable
|
|
58
|
+
* instead of silently querying the author's Default, which is a
|
|
59
|
+
* single-select concept the picks were never seeded from.
|
|
60
|
+
*/
|
|
61
|
+
test("an empty multi-select leaves the token untouched, Default or not", () => {
|
|
62
|
+
const result: string = DataSourceQueryText.applyVariables(
|
|
63
|
+
'up{cluster=~"{{cluster}}"}',
|
|
64
|
+
[
|
|
65
|
+
makeVariable({
|
|
66
|
+
isMultiSelect: true,
|
|
67
|
+
selectedValues: [],
|
|
68
|
+
defaultValue: "prod",
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
);
|
|
72
|
+
expect(result).toBe('up{cluster=~"{{cluster}}"}');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("an untouched multi-select leaves the token untouched too", () => {
|
|
76
|
+
const result: string = DataSourceQueryText.applyVariables("{{cluster}}", [
|
|
77
|
+
makeVariable({ isMultiSelect: true, defaultValue: "prod" }),
|
|
78
|
+
]);
|
|
79
|
+
expect(result).toBe("{{cluster}}");
|
|
80
|
+
});
|
|
81
|
+
|
|
55
82
|
test("leaves the token untouched when the variable is unresolved", () => {
|
|
56
83
|
const result: string = DataSourceQueryText.applyVariables("{{cluster}}", [
|
|
57
84
|
makeVariable({}),
|