@oneuptime/common 11.7.2 → 11.7.4
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/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Index.ts +5 -0
- package/Models/DatabaseModels/LogDropFilter.ts +89 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
- package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
- package/Models/DatabaseModels/TableView.ts +40 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
- package/Server/API/AlertAPI.ts +32 -17
- package/Server/API/BaseAPI.ts +31 -2
- package/Server/API/BaseAnalyticsAPI.ts +36 -2
- package/Server/API/CommonAPI.ts +57 -0
- package/Server/API/IncidentAPI.ts +60 -33
- package/Server/API/IncidentEpisodeAPI.ts +31 -16
- package/Server/API/MonitorAPI.ts +30 -0
- package/Server/API/MonitorTemplateAPI.ts +8 -0
- package/Server/API/ProbeAPI.ts +196 -15
- package/Server/API/ProjectAPI.ts +79 -1
- package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
- package/Server/API/StatusPageAPI.ts +74 -37
- package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Services/AlertEpisodeService.ts +47 -0
- package/Server/Services/AlertService.ts +125 -0
- package/Server/Services/BillingService.ts +98 -0
- package/Server/Services/DatabaseService.ts +184 -20
- package/Server/Services/IncidentEpisodeService.ts +47 -0
- package/Server/Services/IncidentService.ts +123 -0
- package/Server/Services/IncidentTemplateService.ts +123 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/LogDropFilterService.ts +133 -0
- package/Server/Services/MonitorProbeService.ts +94 -4
- package/Server/Services/MonitorService.ts +48 -43
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
- package/Server/Services/ProbeService.ts +66 -0
- package/Server/Services/ProjectService.ts +131 -7
- package/Server/Services/RecommendationDismissalService.ts +52 -0
- package/Server/Services/RunbookAgentJobService.ts +68 -7
- package/Server/Services/ScheduledMaintenanceService.ts +103 -0
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
- package/Server/Services/StatusPageGroupService.ts +186 -0
- package/Server/Services/TraceDropFilterService.ts +133 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
- package/Server/Types/Workflow/Components/API/Get.ts +12 -0
- package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
- package/Server/Types/Workflow/Components/API/Post.ts +12 -0
- package/Server/Types/Workflow/Components/API/Put.ts +13 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
- package/Server/Utils/DropFilterValidation.ts +127 -0
- package/Server/Utils/Errors.ts +5 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
- package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
- package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
- package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
- package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
- package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
- package/Tests/Server/API/ProbeAPI.test.ts +422 -53
- package/Tests/Server/API/ProjectAPI.test.ts +180 -0
- package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
- package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
- package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
- package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
- package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
- package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
- package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
- package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
- package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
- package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
- package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
- package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
- package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
- package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
- package/Tests/Types/DateUserTimezone.test.ts +52 -0
- package/Tests/Types/JSONFunctions.test.ts +103 -1
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
- package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
- package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
- package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
- package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
- package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
- package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
- package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
- package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
- package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
- package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
- package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
- package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
- package/Tests/UI/Components/InfoCard.test.tsx +358 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
- package/Tests/UI/Components/Modal.test.tsx +43 -5
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
- package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
- package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
- package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
- package/Tests/Utils/UserPreferences.test.ts +563 -0
- package/Types/Date.ts +15 -6
- package/Types/JSONFunctions.ts +7 -2
- package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
- package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
- package/Types/Permission.ts +45 -0
- package/Types/Recommendation/RecommendationType.ts +20 -0
- package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
- package/Types/Runbook/RunbookStepTimeout.ts +202 -0
- package/Types/Telemetry/DropFilterSampling.ts +92 -0
- package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
- package/UI/Components/Accordion/Accordion.tsx +10 -2
- package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
- package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
- package/UI/Components/Error/PageError.tsx +0 -4
- package/UI/Components/ErrorBoundary.tsx +252 -15
- package/UI/Components/InfoCard/InfoCard.tsx +58 -1
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
- package/UI/Components/MasterPage/MasterPage.tsx +65 -0
- package/UI/Components/Modal/Modal.tsx +16 -60
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
- package/UI/Components/ModelTable/Column.ts +17 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
- package/UI/Components/ModelTable/TableView.tsx +24 -2
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
- package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
- package/UI/Components/SideMenu/SideMenu.tsx +24 -4
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
- package/UI/Components/Table/Table.tsx +14 -1
- package/UI/Components/Table/TableRow.tsx +180 -175
- package/UI/Components/Table/Types/Column.ts +2 -0
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
- package/UI/Utils/DropdownAlignment.ts +162 -0
- package/UI/Utils/TableFilterUrlState.ts +59 -20
- package/Utils/API.ts +106 -2
- package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
- package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
- package/Utils/StatusPage/GroupTree.ts +307 -0
- package/Utils/StatusPage/ResourceUptime.ts +90 -17
- package/Utils/UserPreferences.ts +53 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TableView.js +40 -0
- package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +22 -13
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +22 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +42 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +43 -26
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +23 -0
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
- package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
- package/build/dist/Server/API/ProbeAPI.js +131 -15
- package/build/dist/Server/API/ProbeAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +62 -3
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +61 -33
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +95 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +71 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +140 -17
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +100 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
- package/build/dist/Server/Services/IncidentTemplateService.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/LogDropFilterService.js +93 -0
- package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +73 -5
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +34 -39
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +64 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +103 -7
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
- package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
- package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
- package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
- package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
- package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
- package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
- package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
- package/build/dist/Server/Utils/Errors.js +3 -0
- package/build/dist/Server/Utils/Errors.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
- package/build/dist/Types/Date.js +14 -4
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +8 -3
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
- package/build/dist/Types/Permission.js +40 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
- package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
- package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Error/PageError.js +1 -3
- package/build/dist/UI/Components/Error/PageError.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +145 -11
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +4 -32
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +308 -40
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
- package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +15 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +11 -6
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
- package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
- package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/Utils/API.js +39 -2
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/UserPreferences.js +33 -0
- package/build/dist/Utils/UserPreferences.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DropFilterCandidate,
|
|
3
|
+
DropFilterValidationOptions,
|
|
4
|
+
isSqlExpressionValue,
|
|
5
|
+
SAMPLE_ACTION,
|
|
6
|
+
validateDropFilter,
|
|
7
|
+
validateDropFilterFilterQuery,
|
|
8
|
+
validateDropFilterSamplePercentage,
|
|
9
|
+
} from "../../../Server/Utils/DropFilterValidation";
|
|
10
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
11
|
+
import {
|
|
12
|
+
MAX_SAMPLE_PERCENTAGE,
|
|
13
|
+
MIN_SAMPLE_PERCENTAGE,
|
|
14
|
+
} from "../../../Types/Telemetry/DropFilterSampling";
|
|
15
|
+
import LogDropFilterAction from "../../../Types/Log/LogDropFilterAction";
|
|
16
|
+
import TraceDropFilterAction from "../../../Types/Trace/TraceDropFilterAction";
|
|
17
|
+
import { describe, expect, it } from "@jest/globals";
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* Contract under test — the save-time gate on drop filters.
|
|
21
|
+
*
|
|
22
|
+
* Both drop-filter models used to accept configurations the ingest engine
|
|
23
|
+
* could not honour, and both failed silently AND destructively:
|
|
24
|
+
*
|
|
25
|
+
* - A blank `filterQuery` compiles to "match every record", so saving a
|
|
26
|
+
* drop filter with an empty query discarded 100% of a project's
|
|
27
|
+
* telemetry with nothing to notice it by.
|
|
28
|
+
* - `action = "sample"` could be saved with no percentage, which the engine
|
|
29
|
+
* read as "throw away half".
|
|
30
|
+
*
|
|
31
|
+
* The API boundary is the only place a human is present to read the error,
|
|
32
|
+
* which is why this runs on create and on update rather than only in the
|
|
33
|
+
* dashboard form.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
const LOGS: DropFilterValidationOptions = { recordNoun: "logs" };
|
|
37
|
+
const SPANS: DropFilterValidationOptions = { recordNoun: "spans" };
|
|
38
|
+
|
|
39
|
+
function candidate(
|
|
40
|
+
overrides: Partial<DropFilterCandidate>,
|
|
41
|
+
): DropFilterCandidate {
|
|
42
|
+
return {
|
|
43
|
+
action: "drop",
|
|
44
|
+
samplePercentage: null,
|
|
45
|
+
filterQuery: "severityText = 'Error'",
|
|
46
|
+
...overrides,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe("drop filter action vocabulary", () => {
|
|
51
|
+
/*
|
|
52
|
+
* The validator compares a raw string so one implementation can serve both
|
|
53
|
+
* services. If either enum ever renames its member, this fails instead of
|
|
54
|
+
* silently skipping sample validation.
|
|
55
|
+
*/
|
|
56
|
+
it("matches the literal both action enums use for sampling", () => {
|
|
57
|
+
expect(LogDropFilterAction.Sample).toBe(SAMPLE_ACTION);
|
|
58
|
+
expect(TraceDropFilterAction.Sample).toBe(SAMPLE_ACTION);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("validateDropFilterFilterQuery", () => {
|
|
63
|
+
it("accepts a query with an actual condition", () => {
|
|
64
|
+
expect(() => {
|
|
65
|
+
return validateDropFilterFilterQuery("body CONTAINS 'debug'", LOGS);
|
|
66
|
+
}).not.toThrow();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* The destructive case: empty means match-all, and match-all plus a drop
|
|
71
|
+
* action means the project loses everything.
|
|
72
|
+
*/
|
|
73
|
+
it("rejects an empty query", () => {
|
|
74
|
+
expect(() => {
|
|
75
|
+
return validateDropFilterFilterQuery("", LOGS);
|
|
76
|
+
}).toThrow(BadDataException);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("rejects a whitespace-only query", () => {
|
|
80
|
+
for (const blank of [" ", " ", "\t", "\n", " \t\n "]) {
|
|
81
|
+
expect(() => {
|
|
82
|
+
return validateDropFilterFilterQuery(blank, LOGS);
|
|
83
|
+
}).toThrow(BadDataException);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("rejects a missing query", () => {
|
|
88
|
+
expect(() => {
|
|
89
|
+
return validateDropFilterFilterQuery(undefined, LOGS);
|
|
90
|
+
}).toThrow(BadDataException);
|
|
91
|
+
expect(() => {
|
|
92
|
+
return validateDropFilterFilterQuery(null, LOGS);
|
|
93
|
+
}).toThrow(BadDataException);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
* The message has to explain the consequence, not just name the field —
|
|
98
|
+
* "Filter query is required" alone does not tell someone that saving it
|
|
99
|
+
* blank would have deleted all their logs.
|
|
100
|
+
*/
|
|
101
|
+
it("explains the consequence in the message, in the caller's vocabulary", () => {
|
|
102
|
+
expect(() => {
|
|
103
|
+
return validateDropFilterFilterQuery("", LOGS);
|
|
104
|
+
}).toThrow(/discard all of this project's logs/);
|
|
105
|
+
|
|
106
|
+
expect(() => {
|
|
107
|
+
return validateDropFilterFilterQuery("", SPANS);
|
|
108
|
+
}).toThrow(/discard all of this project's spans/);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe("validateDropFilterSamplePercentage", () => {
|
|
113
|
+
it("ignores the percentage entirely for a drop-action filter", () => {
|
|
114
|
+
for (const percentage of [null, undefined, 0, -5, 100, 1000]) {
|
|
115
|
+
expect(() => {
|
|
116
|
+
return validateDropFilterSamplePercentage(
|
|
117
|
+
candidate({ action: "drop", samplePercentage: percentage }),
|
|
118
|
+
LOGS,
|
|
119
|
+
);
|
|
120
|
+
}).not.toThrow();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("accepts a sample filter inside the usable range", () => {
|
|
125
|
+
for (const percentage of [
|
|
126
|
+
MIN_SAMPLE_PERCENTAGE,
|
|
127
|
+
10,
|
|
128
|
+
50,
|
|
129
|
+
MAX_SAMPLE_PERCENTAGE,
|
|
130
|
+
]) {
|
|
131
|
+
expect(() => {
|
|
132
|
+
return validateDropFilterSamplePercentage(
|
|
133
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: percentage }),
|
|
134
|
+
LOGS,
|
|
135
|
+
);
|
|
136
|
+
}).not.toThrow();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("rejects a sample filter with no percentage at all", () => {
|
|
141
|
+
for (const missing of [null, undefined]) {
|
|
142
|
+
expect(() => {
|
|
143
|
+
return validateDropFilterSamplePercentage(
|
|
144
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: missing }),
|
|
145
|
+
LOGS,
|
|
146
|
+
);
|
|
147
|
+
}).toThrow(BadDataException);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("rejects a sample filter with a non-finite percentage", () => {
|
|
152
|
+
for (const bad of [NaN, Infinity, -Infinity]) {
|
|
153
|
+
expect(() => {
|
|
154
|
+
return validateDropFilterSamplePercentage(
|
|
155
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: bad }),
|
|
156
|
+
LOGS,
|
|
157
|
+
);
|
|
158
|
+
}).toThrow(BadDataException);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* 0 and 100 are the two values a user reaches for when they mean something
|
|
164
|
+
* else. Point them at the tool that actually does it rather than accepting
|
|
165
|
+
* a filter the engine will treat as a no-op.
|
|
166
|
+
*/
|
|
167
|
+
it("rejects 0 and points at the Drop action instead", () => {
|
|
168
|
+
expect(() => {
|
|
169
|
+
return validateDropFilterSamplePercentage(
|
|
170
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: 0 }),
|
|
171
|
+
LOGS,
|
|
172
|
+
);
|
|
173
|
+
}).toThrow(/"Drop" action/);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("rejects 100 and points at disabling the filter instead", () => {
|
|
177
|
+
expect(() => {
|
|
178
|
+
return validateDropFilterSamplePercentage(
|
|
179
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: 100 }),
|
|
180
|
+
LOGS,
|
|
181
|
+
);
|
|
182
|
+
}).toThrow(/disable the filter/);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("rejects percentages outside the range on both sides", () => {
|
|
186
|
+
for (const outOfRange of [-1, 0, 100, 101, 1000]) {
|
|
187
|
+
expect(() => {
|
|
188
|
+
return validateDropFilterSamplePercentage(
|
|
189
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: outOfRange }),
|
|
190
|
+
LOGS,
|
|
191
|
+
);
|
|
192
|
+
}).toThrow(BadDataException);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("names the allowed range in the message so the fix is obvious", () => {
|
|
197
|
+
expect(() => {
|
|
198
|
+
return validateDropFilterSamplePercentage(
|
|
199
|
+
candidate({ action: SAMPLE_ACTION, samplePercentage: null }),
|
|
200
|
+
LOGS,
|
|
201
|
+
);
|
|
202
|
+
}).toThrow(
|
|
203
|
+
new RegExp(`${MIN_SAMPLE_PERCENTAGE} and ${MAX_SAMPLE_PERCENTAGE}`),
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe("validateDropFilter", () => {
|
|
209
|
+
it("accepts a well-formed drop filter", () => {
|
|
210
|
+
expect(() => {
|
|
211
|
+
return validateDropFilter(
|
|
212
|
+
candidate({ action: "drop", filterQuery: "severityText = 'Debug'" }),
|
|
213
|
+
LOGS,
|
|
214
|
+
);
|
|
215
|
+
}).not.toThrow();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("accepts a well-formed sample filter", () => {
|
|
219
|
+
expect(() => {
|
|
220
|
+
return validateDropFilter(
|
|
221
|
+
candidate({
|
|
222
|
+
action: SAMPLE_ACTION,
|
|
223
|
+
samplePercentage: 10,
|
|
224
|
+
filterQuery: "severityText = 'Debug'",
|
|
225
|
+
}),
|
|
226
|
+
LOGS,
|
|
227
|
+
);
|
|
228
|
+
}).not.toThrow();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
/*
|
|
232
|
+
* The query check runs first on purpose. A row that is broken both ways
|
|
233
|
+
* should surface the more destructive problem, because a match-all drop
|
|
234
|
+
* filter deletes everything while a bad percentage only samples.
|
|
235
|
+
*/
|
|
236
|
+
it("reports the empty query first when a candidate is broken both ways", () => {
|
|
237
|
+
expect(() => {
|
|
238
|
+
return validateDropFilter(
|
|
239
|
+
candidate({
|
|
240
|
+
action: SAMPLE_ACTION,
|
|
241
|
+
samplePercentage: null,
|
|
242
|
+
filterQuery: "",
|
|
243
|
+
}),
|
|
244
|
+
LOGS,
|
|
245
|
+
);
|
|
246
|
+
}).toThrow(/Filter query is required/);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
describe("isSqlExpressionValue", () => {
|
|
251
|
+
/*
|
|
252
|
+
* `PartialEntity` values may be raw SQL expressions. We cannot evaluate one
|
|
253
|
+
* to validate it, and stringifying a function to compare it would be worse
|
|
254
|
+
* than skipping — so the update hook detects and skips.
|
|
255
|
+
*/
|
|
256
|
+
it("detects a raw SQL expression value", () => {
|
|
257
|
+
expect(
|
|
258
|
+
isSqlExpressionValue(() => {
|
|
259
|
+
return "NOW()";
|
|
260
|
+
}),
|
|
261
|
+
).toBe(true);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it("treats every ordinary literal as a plain value", () => {
|
|
265
|
+
for (const literal of ["sample", "", 0, 50, null, undefined, {}, []]) {
|
|
266
|
+
expect(isSqlExpressionValue(literal)).toBe(false);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import SpanUtil, {
|
|
2
|
+
SpanAttributes,
|
|
3
|
+
} from "../../../../Server/Utils/Telemetry/SpanUtil";
|
|
4
|
+
import { describe, expect, it, jest } from "@jest/globals";
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* SpanUtil.addAttributesToSpan copies telemetry attributes onto a span, but it
|
|
8
|
+
* must drop undefined/null values - OpenTelemetry rejects those and throwing
|
|
9
|
+
* mid-request would break the traced operation. This pins the filtering so a
|
|
10
|
+
* partially-populated SpanAttributes object stays safe to pass in.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// A stand-in Span that just records what setAttribute was called with.
|
|
14
|
+
function fakeSpan(): {
|
|
15
|
+
span: { setAttribute: (key: string, value: unknown) => void };
|
|
16
|
+
calls: Array<[string, unknown]>;
|
|
17
|
+
} {
|
|
18
|
+
const calls: Array<[string, unknown]> = [];
|
|
19
|
+
const setAttribute: (key: string, value: unknown) => void = jest.fn(
|
|
20
|
+
(key: string, value: unknown): void => {
|
|
21
|
+
calls.push([key, value]);
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
return { span: { setAttribute }, calls };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe("SpanUtil.addAttributesToSpan", () => {
|
|
28
|
+
it("sets every defined attribute on the span", () => {
|
|
29
|
+
const { span, calls } = fakeSpan();
|
|
30
|
+
|
|
31
|
+
const attributes: SpanAttributes = {
|
|
32
|
+
userId: "user-1",
|
|
33
|
+
projectId: "project-1",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
SpanUtil.addAttributesToSpan({
|
|
37
|
+
span: span as never,
|
|
38
|
+
attributes,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
expect(calls).toContainEqual(["userId", "user-1"]);
|
|
42
|
+
expect(calls).toContainEqual(["projectId", "project-1"]);
|
|
43
|
+
expect(calls).toHaveLength(2);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("skips undefined and null values (OpenTelemetry rejects them)", () => {
|
|
47
|
+
const { span, calls } = fakeSpan();
|
|
48
|
+
|
|
49
|
+
const attributes: SpanAttributes = {
|
|
50
|
+
userId: "user-1",
|
|
51
|
+
projectId: undefined,
|
|
52
|
+
// null is not part of the typed surface but can arrive at runtime.
|
|
53
|
+
monitorId: null as unknown as string,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
SpanUtil.addAttributesToSpan({
|
|
57
|
+
span: span as never,
|
|
58
|
+
attributes,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
expect(calls).toEqual([["userId", "user-1"]]);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("preserves falsy-but-defined values like empty string, 0 and false", () => {
|
|
65
|
+
const { span, calls } = fakeSpan();
|
|
66
|
+
|
|
67
|
+
const attributes: SpanAttributes = {
|
|
68
|
+
channelId: "",
|
|
69
|
+
retryCount: 0,
|
|
70
|
+
isRetry: false,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
SpanUtil.addAttributesToSpan({
|
|
74
|
+
span: span as never,
|
|
75
|
+
attributes,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(calls).toContainEqual(["channelId", ""]);
|
|
79
|
+
expect(calls).toContainEqual(["retryCount", 0]);
|
|
80
|
+
expect(calls).toContainEqual(["isRetry", false]);
|
|
81
|
+
expect(calls).toHaveLength(3);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("does nothing for an empty attribute object", () => {
|
|
85
|
+
const { span, calls } = fakeSpan();
|
|
86
|
+
|
|
87
|
+
SpanUtil.addAttributesToSpan({
|
|
88
|
+
span: span as never,
|
|
89
|
+
attributes: {},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(calls).toHaveLength(0);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -139,6 +139,58 @@ describe("OneUptimeDate user timezone", () => {
|
|
|
139
139
|
expect(formatted).toContain("EDT");
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
+
it("names the abbreviation in effect on the formatted date, not today's", () => {
|
|
143
|
+
OneUptimeDate.setUserTimezone(NY);
|
|
144
|
+
|
|
145
|
+
/*
|
|
146
|
+
* The abbreviation used to be looked up for "now", so all summer every
|
|
147
|
+
* winter timestamp read "EDT" — and 13:00 EDT is a different instant
|
|
148
|
+
* than the 13:00 EST that was actually stored.
|
|
149
|
+
*/
|
|
150
|
+
const winter: string = OneUptimeDate.getDateAsLocalFormattedString(
|
|
151
|
+
new Date("2026-01-15T18:00:00Z"),
|
|
152
|
+
);
|
|
153
|
+
const summer: string = OneUptimeDate.getDateAsLocalFormattedString(
|
|
154
|
+
new Date("2026-07-15T18:00:00Z"),
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
expect(winter).toContain("13:00");
|
|
158
|
+
expect(winter).toContain("EST");
|
|
159
|
+
expect(winter).not.toContain("EDT");
|
|
160
|
+
|
|
161
|
+
expect(summer).toContain("14:00");
|
|
162
|
+
expect(summer).toContain("EDT");
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("labels each pass of a folded fall-back hour with its own abbreviation", () => {
|
|
166
|
+
OneUptimeDate.setUserTimezone(NY);
|
|
167
|
+
|
|
168
|
+
// 01:30 local happens twice on 2026-11-01 — once EDT, once EST.
|
|
169
|
+
const firstPass: string = OneUptimeDate.getDateAsLocalFormattedString(
|
|
170
|
+
new Date("2026-11-01T05:30:00Z"),
|
|
171
|
+
);
|
|
172
|
+
const secondPass: string = OneUptimeDate.getDateAsLocalFormattedString(
|
|
173
|
+
new Date("2026-11-01T06:30:00Z"),
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
expect(firstPass).toContain("01:30");
|
|
177
|
+
expect(secondPass).toContain("01:30");
|
|
178
|
+
// Identical wall clocks; the abbreviation is what tells them apart.
|
|
179
|
+
expect(firstPass).toContain("EDT");
|
|
180
|
+
expect(secondPass).toContain("EST");
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("still omits the abbreviation when only the date is shown", () => {
|
|
184
|
+
OneUptimeDate.setUserTimezone(NY);
|
|
185
|
+
|
|
186
|
+
const dateOnly: string = OneUptimeDate.getDateAsLocalFormattedString(
|
|
187
|
+
new Date("2026-01-15T18:00:00Z"),
|
|
188
|
+
true,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
expect(dateOnly).toBe("Jan 15, 2026");
|
|
192
|
+
});
|
|
193
|
+
|
|
142
194
|
it("reads the hour and minute of an instant in the user timezone", () => {
|
|
143
195
|
OneUptimeDate.setUserTimezone(KOLKATA);
|
|
144
196
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JSONArray, JSONObject } from "../../Types/JSON";
|
|
1
|
+
import { JSONArray, JSONObject, ObjectType } from "../../Types/JSON";
|
|
2
2
|
import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
3
3
|
import JSONFunctions from "../../Types/JSONFunctions";
|
|
4
4
|
|
|
@@ -262,4 +262,106 @@ describe("JSONFunctions Class", () => {
|
|
|
262
262
|
expect(size).toBeGreaterThanOrEqual(0);
|
|
263
263
|
});
|
|
264
264
|
});
|
|
265
|
+
|
|
266
|
+
describe("serialize and serializeArray Methods", () => {
|
|
267
|
+
test("Passes primitives and null through, and drops undefined keys", () => {
|
|
268
|
+
const input: JSONObject = {
|
|
269
|
+
n: 1,
|
|
270
|
+
s: "x",
|
|
271
|
+
b: true,
|
|
272
|
+
nil: null,
|
|
273
|
+
gone: undefined,
|
|
274
|
+
};
|
|
275
|
+
expect(JSONFunctions.serialize(input)).toEqual({
|
|
276
|
+
n: 1,
|
|
277
|
+
s: "x",
|
|
278
|
+
b: true,
|
|
279
|
+
nil: null,
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("Tags a Date value with its DateTime object type", () => {
|
|
284
|
+
const serialized: JSONObject = JSONFunctions.serialize({
|
|
285
|
+
when: new Date("2023-01-01T00:00:00.000Z"),
|
|
286
|
+
});
|
|
287
|
+
const when: JSONObject = serialized["when"] as JSONObject;
|
|
288
|
+
expect(when["_type"]).toBe(ObjectType.DateTime);
|
|
289
|
+
expect(typeof when["value"]).toBe("string");
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("Serializes nested objects recursively", () => {
|
|
293
|
+
expect(JSONFunctions.serialize({ a: { b: 2 } })).toEqual({ a: { b: 2 } });
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
test("Serializes each value inside an array", () => {
|
|
297
|
+
expect(JSONFunctions.serialize({ arr: [1, "x", null] })).toEqual({
|
|
298
|
+
arr: [1, "x", null],
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test("serializeArray serializes each object in the array", () => {
|
|
303
|
+
const input: JSONArray = [{ a: 1 }, { b: 2 }];
|
|
304
|
+
expect(JSONFunctions.serializeArray(input)).toEqual([{ a: 1 }, { b: 2 }]);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
describe("deserialize and deserializeArray Methods", () => {
|
|
309
|
+
test("Passes primitives and null through", () => {
|
|
310
|
+
const input: JSONObject = { n: 1, s: "x", nil: null };
|
|
311
|
+
expect(JSONFunctions.deserialize(input)).toEqual({
|
|
312
|
+
n: 1,
|
|
313
|
+
s: "x",
|
|
314
|
+
nil: null,
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
test("Rebuilds a Buffer-tagged value into a Buffer", () => {
|
|
319
|
+
const input: JSONObject = {
|
|
320
|
+
payload: {
|
|
321
|
+
_type: ObjectType.Buffer,
|
|
322
|
+
value: { type: ObjectType.Buffer, data: [1, 2, 3] },
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
const deserialized: JSONObject = JSONFunctions.deserialize(input);
|
|
326
|
+
expect(Buffer.isBuffer(deserialized["payload"])).toBe(true);
|
|
327
|
+
expect(deserialized["payload"]).toEqual(Buffer.from([1, 2, 3]));
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
test("deserializeArray deserializes each object in the array", () => {
|
|
331
|
+
const input: JSONArray = [{ a: 1 }, { b: 2 }];
|
|
332
|
+
expect(JSONFunctions.deserializeArray(input)).toEqual([
|
|
333
|
+
{ a: 1 },
|
|
334
|
+
{ b: 2 },
|
|
335
|
+
]);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
describe("serializeValue and deserializeValue Methods", () => {
|
|
340
|
+
test("Pass numbers and non-empty strings through unchanged", () => {
|
|
341
|
+
expect(JSONFunctions.serializeValue(5)).toBe(5);
|
|
342
|
+
expect(JSONFunctions.serializeValue("hi")).toBe("hi");
|
|
343
|
+
expect(JSONFunctions.deserializeValue(5)).toBe(5);
|
|
344
|
+
expect(JSONFunctions.deserializeValue("hi")).toBe("hi");
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
test("Pass null through unchanged", () => {
|
|
348
|
+
expect(JSONFunctions.serializeValue(null)).toBeNull();
|
|
349
|
+
expect(JSONFunctions.deserializeValue(null)).toBeNull();
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
describe("serialize and deserialize round trip", () => {
|
|
354
|
+
test("A plain object survives a serialize -> JSON -> deserialize round trip", () => {
|
|
355
|
+
const original: JSONObject = {
|
|
356
|
+
a: 1,
|
|
357
|
+
b: "x",
|
|
358
|
+
c: { d: 2 },
|
|
359
|
+
e: [1, 2, 3],
|
|
360
|
+
};
|
|
361
|
+
const roundTripped: JSONObject = JSONFunctions.deserialize(
|
|
362
|
+
JSON.parse(JSON.stringify(JSONFunctions.serialize(original))),
|
|
363
|
+
);
|
|
364
|
+
expect(roundTripped).toEqual(original);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
265
367
|
});
|