@oneuptime/common 14.0.9 → 14.0.11
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/AIConversation.ts +127 -1
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
- package/Models/DatabaseModels/CephCluster.ts +225 -0
- package/Models/DatabaseModels/CloudResource.ts +12 -0
- package/Models/DatabaseModels/DatabaseServer.ts +225 -0
- package/Models/DatabaseModels/DockerHost.ts +225 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +225 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/GlobalOidc.ts +0 -4
- package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
- package/Models/DatabaseModels/GlobalSso.ts +0 -4
- package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
- package/Models/DatabaseModels/Host.ts +225 -0
- package/Models/DatabaseModels/IncidentForm.ts +594 -0
- package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/IoTFleet.ts +12 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
- package/Models/DatabaseModels/MessageQueue.ts +1102 -0
- package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
- package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
- package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
- package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
- package/Models/DatabaseModels/PodmanHost.ts +225 -0
- package/Models/DatabaseModels/Project.ts +59 -0
- package/Models/DatabaseModels/ProjectOidc.ts +0 -4
- package/Models/DatabaseModels/ProjectSso.ts +0 -4
- package/Models/DatabaseModels/ProxmoxCluster.ts +225 -0
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RumApplication.ts +12 -0
- package/Models/DatabaseModels/RunnerJob.ts +144 -0
- package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
- package/Models/DatabaseModels/Service.ts +12 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
- package/Models/DatabaseModels/StatusPageSso.ts +0 -4
- package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
- package/Models/DatabaseModels/VMwareVCenter.ts +225 -0
- package/Server/API/AIChatAPI.ts +13 -114
- package/Server/API/AIInvestigationAPI.ts +3 -3
- package/Server/API/AIInvestigationConversationAPI.ts +266 -0
- package/Server/API/AutoRemediationAPI.ts +392 -1
- package/Server/API/IncidentFormAPI.ts +376 -0
- package/Server/API/ProjectOIDC.ts +16 -25
- package/Server/API/ProjectSSO.ts +16 -24
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- package/Server/API/StatusPageAPI.ts +42 -77
- package/Server/Enterprise/EnterpriseEdition.ts +93 -28
- package/Server/Enterprise/EnterpriseFeature.ts +25 -3
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
- package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
- package/Server/EnvironmentConfig.ts +1 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
- package/Server/Middleware/TelemetryIngest.ts +15 -5
- package/Server/Middleware/UserAuthorization.ts +16 -38
- package/Server/Services/AIService.ts +10 -13
- package/Server/Services/AnalyticsDatabaseService.ts +45 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
- package/Server/Services/CephClusterService.ts +109 -1
- package/Server/Services/DatabaseServerService.ts +116 -1
- package/Server/Services/DockerHostService.ts +109 -1
- package/Server/Services/DockerSwarmClusterService.ts +113 -1
- package/Server/Services/HostService.ts +126 -4
- package/Server/Services/IncidentCustomFieldService.ts +112 -2
- package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
- package/Server/Services/IncidentEpisodeService.ts +10 -1
- package/Server/Services/IncidentFormService.ts +1566 -0
- package/Server/Services/IncidentFormSubmissionService.ts +97 -0
- package/Server/Services/IncidentGroupingEngineService.ts +45 -8
- package/Server/Services/IncidentService.ts +123 -5
- package/Server/Services/IncidentTemplateService.ts +22 -0
- package/Server/Services/Index.ts +14 -0
- package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
- package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
- package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
- package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
- package/Server/Services/MessageQueueService.ts +1463 -0
- package/Server/Services/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/OpenTelemetryIngestService.ts +37 -4
- package/Server/Services/PodmanHostService.ts +109 -1
- package/Server/Services/ProjectService.ts +0 -59
- package/Server/Services/ProxmoxClusterService.ts +110 -1
- package/Server/Services/ResourceAiAccessService.ts +1439 -0
- package/Server/Services/ResourceAiAgentJobService.ts +202 -0
- package/Server/Services/ResourceAiAgentService.ts +2432 -0
- package/Server/Services/RunnerJobService.ts +611 -4
- package/Server/Services/StatusPagePrivateUserService.ts +1 -4
- package/Server/Services/StatusPageService.ts +1 -51
- package/Server/Services/TeamComplianceSettingService.ts +163 -42
- package/Server/Services/TelemetryUsageBillingService.ts +28 -0
- package/Server/Services/TraceRecordingRuleService.ts +33 -0
- package/Server/Services/UserNotificationRuleService.ts +8 -1
- package/Server/Services/VMwareVCenterService.ts +110 -1
- package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
- package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
- package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
- package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
- package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
- package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1442 -34
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +968 -34
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +622 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +882 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +125 -12
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +99 -15
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +99 -15
- package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
- package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
- package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
- package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
- package/Server/Utils/EditionEnforcement.ts +19 -202
- package/Server/Utils/LLM/LLMService.ts +259 -63
- package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
- package/Server/Utils/SameOriginRequest.ts +203 -0
- package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
- package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
- package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
- package/Server/Utils/VendorAssets.ts +3 -3
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +301 -225
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +38 -16
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +376 -144
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
- package/Tests/App/Accounts/IncidentFormPage.test.tsx +2036 -0
- package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
- package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
- package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
- package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
- package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
- package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
- package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
- package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +267 -12
- package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
- package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
- package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +23 -6
- package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
- package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
- package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
- package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
- package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
- package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
- package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
- package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
- package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
- package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
- package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
- package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
- package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
- package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
- package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
- package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
- package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
- package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
- package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
- package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
- package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
- package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
- package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
- package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
- package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
- package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
- package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
- package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
- package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
- package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
- package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
- package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
- package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
- package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
- package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
- package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
- package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
- package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
- package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
- package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
- package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
- package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
- package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
- package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
- package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
- package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
- package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
- package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
- package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
- package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
- package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
- package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +555 -0
- package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +2010 -0
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1455 -0
- package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
- package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
- package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
- package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
- package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
- package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
- package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
- package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
- package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
- package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
- package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
- package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
- package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
- package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
- package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
- package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +61 -10
- package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
- package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
- package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
- package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
- package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
- package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
- package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
- package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
- package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
- package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
- package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
- package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
- package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
- package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
- package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
- package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
- package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
- package/Tests/Server/Services/IncidentCreatedFeedTitle.test.ts +212 -0
- package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
- package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
- package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
- package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
- package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
- package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
- package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
- package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
- package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
- package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
- package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
- package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
- package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
- package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
- package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
- package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
- package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
- package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
- package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
- package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
- package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
- package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
- package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
- package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
- package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
- package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
- package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
- package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
- package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
- package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
- package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
- package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
- package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
- package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
- package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
- package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
- package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
- package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
- package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
- package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
- package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
- package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
- package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
- package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +694 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
- package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
- package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
- package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
- package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
- package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1251 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
- package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +1004 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +834 -0
- package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
- package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
- package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
- package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
- package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
- package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
- package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +20 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
- package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
- package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
- package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
- package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
- package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
- package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
- package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
- package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
- package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
- package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
- package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
- package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
- package/Tests/Types/Monitor/MetricEngineFold.ts +154 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
- package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
- package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +519 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
- package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
- package/Tests/Types/XML.test.ts +51 -0
- package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
- package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
- package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
- package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
- package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
- package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
- package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
- package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
- package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
- package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
- package/Tests/UI/Components/Icon.test.tsx +32 -0
- package/Tests/UI/Components/Input.test.tsx +31 -0
- package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
- package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
- package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
- package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
- package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
- package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
- package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
- package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
- package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
- package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
- package/Tests/UI/Components/TextArea.test.tsx +19 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
- package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
- package/Tests/UI/EsbuildConfig.test.ts +115 -39
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
- package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -0
- package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
- package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
- package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
- package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
- package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
- package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
- package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
- package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
- package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
- package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
- package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
- package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
- package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
- package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
- package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/AIAgentRunLimits.ts +146 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
- package/Types/Code/CodeType.ts +2 -0
- package/Types/Code/JsonSyntax.ts +923 -0
- package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
- package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
- package/Types/Icon/IconProp.ts +2 -0
- package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
- package/Types/Incident/IncidentFormPublic.ts +1145 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
- package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
- package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
- package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
- package/Types/MessageQueue/MessagingSystem.ts +518 -0
- package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
- package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
- package/Types/Monitor/RumAlertTemplates.ts +351 -4
- package/Types/Permission.ts +310 -0
- package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +580 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- package/Types/Rules/RuleRun.ts +4 -0
- package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
- package/Types/Runbook/RunbookStepType.ts +29 -0
- package/Types/Team/ComplianceNotificationChannel.ts +4 -3
- package/Types/Team/ComplianceRule.ts +71 -18
- package/Types/Team/ComplianceRuleType.ts +2 -2
- package/Types/Team/TeamComplianceStatus.ts +6 -2
- package/Types/Telemetry/EntityType.ts +16 -0
- package/Types/Telemetry/LockedFilterDetail.ts +22 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
- package/Types/XML.ts +26 -0
- package/UI/Components/CodeEditor/CodeEditor.css +379 -0
- package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
- package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
- package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
- package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
- package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
- package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
- package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
- package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
- package/UI/Components/Forms/Fields/FormField.tsx +8 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Icon/Icon.tsx +18 -0
- package/UI/Components/Input/Input.tsx +11 -4
- package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
- package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
- package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
- package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
- package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
- package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
- package/UI/Components/Table/EmptyTableMessage.ts +81 -0
- package/UI/Components/Table/Table.tsx +50 -21
- package/UI/Components/Table/TableRow.tsx +9 -1
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
- package/UI/Components/TextArea/TextArea.tsx +9 -2
- package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
- package/UI/Styles/Theme.css +8 -0
- package/UI/esbuild-config.js +2 -32
- package/Utils/AI/InvestigationReport.ts +121 -15
- package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
- package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
- package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
- package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
- package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
- package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
- package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
- package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
- package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
- package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
- package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
- package/Utils/LabelRuleImportExport.ts +2 -0
- package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
- package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
- package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
- package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
- package/Utils/Telemetry/EntityKey.ts +48 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
- package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +231 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +231 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +231 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
- package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
- package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js +231 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +61 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +12 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +231 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -103
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
- package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
- package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentFormAPI.js +245 -0
- package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
- package/build/dist/Server/API/ProjectOIDC.js +16 -24
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +16 -24
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
- package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +42 -75
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js +63 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.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/Infrastructure/Semaphore.js +6 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js +559 -0
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +10 -13
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +104 -0
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseServerService.js +99 -0
- package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +104 -0
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +114 -2
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +83 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFormService.js +1202 -0
- package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +106 -4
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +14 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueService.js +1140 -0
- package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +104 -0
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +0 -54
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
- package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/RunnerJobService.js +344 -5
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +0 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
- package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +8 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
- package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +12 -3
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1036 -32
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +661 -41
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +354 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +602 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +90 -14
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +73 -10
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +73 -10
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/EditionEnforcement.js +20 -158
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
- package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +3 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +186 -210
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +22 -16
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +273 -111
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
- package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
- package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +116 -29
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/Code/CodeType.js +2 -0
- package/build/dist/Types/Code/CodeType.js.map +1 -1
- package/build/dist/Types/Code/JsonSyntax.js +604 -0
- package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
- package/build/dist/Types/Icon/IconProp.js +2 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Permission.js +274 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +281 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +4 -3
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRule.js +48 -14
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
- package/build/dist/Types/Telemetry/EntityType.js +16 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/Types/XML.js +23 -0
- package/build/dist/Types/XML.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +8 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +11 -3
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
- package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
- package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +30 -11
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +9 -2
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
- package/build/dist/Utils/AI/InvestigationReport.js +71 -11
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
- package/build/dist/Utils/LabelRuleImportExport.js +2 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/package.json +1 -3
- package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
- package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
- package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
- package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
- package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
- package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
- package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
- package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
- package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
- package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
|
@@ -0,0 +1,1326 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Clipboard -> markdown for the MarkdownEditor's paste handlers.
|
|
3
|
+
*
|
|
4
|
+
* Markdown is the editor's source of truth, so a paste is turned into
|
|
5
|
+
* markdown first and only then rendered into the visual editor (or inserted
|
|
6
|
+
* into the source textarea). What is on the clipboard decides how:
|
|
7
|
+
*
|
|
8
|
+
* - text/html -- from Word, Outlook, Google Docs, a web page, or a note
|
|
9
|
+
* rendered by OneUptime itself -- is cleaned up as a DOM tree: lists are
|
|
10
|
+
* rebuilt with their nesting, bold / italic / strikethrough are read off
|
|
11
|
+
* inline styles, links and images are kept only for safe schemes, and
|
|
12
|
+
* whatever is not content (styles, buttons, icons) is dropped. The editor's
|
|
13
|
+
* own serializer then writes it out, so the result is markdown the editor
|
|
14
|
+
* already round-trips;
|
|
15
|
+
* - plain text is taken as markdown, as it always was, once the bullet
|
|
16
|
+
* characters other apps write ("•", "◦", Word's "o" and "§" before a
|
|
17
|
+
* tab) have become markdown list items at the right depth.
|
|
18
|
+
*
|
|
19
|
+
* Clipboard HTML is never assigned to innerHTML: Chromium runs an <img>'s
|
|
20
|
+
* onerror handler for markup parsed into a detached element. It is parsed
|
|
21
|
+
* with DOMParser, whose document is inert -- nothing in it loads or runs --
|
|
22
|
+
* and nothing from it reaches the page except the markdown written here.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { domToMarkdown } from "./MarkdownConverters";
|
|
26
|
+
import {
|
|
27
|
+
TAB_ONLY_BULLET_GLYPHS,
|
|
28
|
+
TEXT_BULLET_GLYPHS,
|
|
29
|
+
} from "./MarkdownListEditing";
|
|
30
|
+
|
|
31
|
+
// What the paste handlers read from a ClipboardEvent's DataTransfer.
|
|
32
|
+
export interface PastedClipboard {
|
|
33
|
+
getData: (format: string) => string;
|
|
34
|
+
types?: ReadonlyArray<string> | undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ClipboardToMarkdownOptions {
|
|
38
|
+
/*
|
|
39
|
+
* Whether the caller has image files from this paste that it can upload.
|
|
40
|
+
* Defaults to whether the clipboard lists any files at all.
|
|
41
|
+
*/
|
|
42
|
+
hasImageFiles?: boolean | undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* ---------------------------------------------------------------------------
|
|
47
|
+
* Plain text
|
|
48
|
+
* ---------------------------------------------------------------------------
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
const RE_GLYPH_BULLET_LINE: RegExp = new RegExp(
|
|
52
|
+
`^([ \\t]*)(?:([${TEXT_BULLET_GLYPHS}])|([${TAB_ONLY_BULLET_GLYPHS}])(?=\\t))[ \\t\\u00a0]+(.*)$`,
|
|
53
|
+
);
|
|
54
|
+
const RE_PAREN_NUMBER_LINE: RegExp = /^([ \t]*)(\d{1,9})\)[ \t]+(.*)$/;
|
|
55
|
+
const RE_TEXT_FENCE: RegExp = /^[ \t]*(`{3,}|~{3,})/;
|
|
56
|
+
const RE_LINE_BREAKS: RegExp = /\r\n?/g;
|
|
57
|
+
|
|
58
|
+
// A tab advances to the next multiple of four columns, as in CommonMark.
|
|
59
|
+
const TAB_WIDTH: number = 4;
|
|
60
|
+
|
|
61
|
+
const indentColumns: (whitespace: string) => number = (
|
|
62
|
+
whitespace: string,
|
|
63
|
+
): number => {
|
|
64
|
+
let column: number = 0;
|
|
65
|
+
for (const ch of whitespace) {
|
|
66
|
+
column += ch === "\t" ? TAB_WIDTH - (column % TAB_WIDTH) : 1;
|
|
67
|
+
}
|
|
68
|
+
return column;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
* Word writes a nested bullet's level only through its character -- "•",
|
|
73
|
+
* then "o", then "§" -- with no indentation in its plain text. These are
|
|
74
|
+
* the depths those characters (and the second and third level bullets of
|
|
75
|
+
* Slack and Google Docs) stand for when no indentation says otherwise.
|
|
76
|
+
*/
|
|
77
|
+
const GLYPH_DEPTH: { [glyph: string]: number } = {
|
|
78
|
+
o: 1,
|
|
79
|
+
"◦": 1,
|
|
80
|
+
"○": 1,
|
|
81
|
+
"§": 2,
|
|
82
|
+
"\uF0A7": 2,
|
|
83
|
+
"▪": 2,
|
|
84
|
+
"■": 2,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
interface BulletLine {
|
|
88
|
+
index: number;
|
|
89
|
+
indent: number;
|
|
90
|
+
glyph: string;
|
|
91
|
+
text: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
* Turns the bullet characters other apps put in their plain text into
|
|
96
|
+
* markdown list items, nested by their indentation -- or, for Word, which
|
|
97
|
+
* does not indent its plain text, by which of its bullet characters a line
|
|
98
|
+
* uses. "1) step" becomes "1. step", the only ordered form the editor's
|
|
99
|
+
* parser reads. Lines inside a fenced code block are left alone, and so is
|
|
100
|
+
* text with no such line at all, so prose like "price • quality" or an
|
|
101
|
+
* ordinary markdown document comes back exactly as it went in.
|
|
102
|
+
*/
|
|
103
|
+
export const normalizePlainTextListMarkers: (text: string) => string = (
|
|
104
|
+
text: string,
|
|
105
|
+
): string => {
|
|
106
|
+
const lines: Array<string> = text.replace(RE_LINE_BREAKS, "\n").split("\n");
|
|
107
|
+
const bullets: Array<BulletLine> = [];
|
|
108
|
+
let found: boolean = false;
|
|
109
|
+
let fence: string | null = null;
|
|
110
|
+
|
|
111
|
+
for (let index: number = 0; index < lines.length; index++) {
|
|
112
|
+
const line: string = lines[index] || "";
|
|
113
|
+
const fenceMatch: RegExpMatchArray | null = line.match(RE_TEXT_FENCE);
|
|
114
|
+
if (fence !== null) {
|
|
115
|
+
if (fenceMatch && (fenceMatch[1] || "").charAt(0) === fence.charAt(0)) {
|
|
116
|
+
fence = null;
|
|
117
|
+
}
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (fenceMatch) {
|
|
121
|
+
fence = fenceMatch[1] || "```";
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const bullet: RegExpMatchArray | null = line.match(RE_GLYPH_BULLET_LINE);
|
|
125
|
+
if (bullet) {
|
|
126
|
+
found = true;
|
|
127
|
+
bullets.push({
|
|
128
|
+
index,
|
|
129
|
+
indent: indentColumns(bullet[1] || ""),
|
|
130
|
+
glyph: bullet[2] || bullet[3] || "",
|
|
131
|
+
text: bullet[4] || "",
|
|
132
|
+
});
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const numbered: RegExpMatchArray | null = line.match(RE_PAREN_NUMBER_LINE);
|
|
136
|
+
if (numbered) {
|
|
137
|
+
found = true;
|
|
138
|
+
lines[index] =
|
|
139
|
+
`${numbered[1] || ""}${numbered[2] || ""}. ${numbered[3] || ""}`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!found) {
|
|
144
|
+
return text;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const indented: boolean = bullets.some((bullet: BulletLine): boolean => {
|
|
148
|
+
return bullet.indent > 0;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
/*
|
|
152
|
+
* Depth by indentation: each distinct indent deeper than the one above
|
|
153
|
+
* opens a level, and a shallower one closes levels back down to it. A
|
|
154
|
+
* paragraph between two bullets ends the list, so the next bullet starts
|
|
155
|
+
* again at the top.
|
|
156
|
+
*/
|
|
157
|
+
const open: Array<number> = [];
|
|
158
|
+
let depth: number = 0;
|
|
159
|
+
let previousIndex: number = -2;
|
|
160
|
+
for (const bullet of bullets) {
|
|
161
|
+
const gap: Array<string> = lines.slice(previousIndex + 1, bullet.index);
|
|
162
|
+
const listInterrupted: boolean =
|
|
163
|
+
previousIndex < 0 ||
|
|
164
|
+
gap.some((line: string): boolean => {
|
|
165
|
+
return line.trim().length > 0;
|
|
166
|
+
});
|
|
167
|
+
if (listInterrupted) {
|
|
168
|
+
open.length = 0;
|
|
169
|
+
depth = 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (indented) {
|
|
173
|
+
while (
|
|
174
|
+
open.length > 0 &&
|
|
175
|
+
(open[open.length - 1] as number) > bullet.indent
|
|
176
|
+
) {
|
|
177
|
+
open.pop();
|
|
178
|
+
}
|
|
179
|
+
if (
|
|
180
|
+
open.length === 0 ||
|
|
181
|
+
(open[open.length - 1] as number) < bullet.indent
|
|
182
|
+
) {
|
|
183
|
+
open.push(bullet.indent);
|
|
184
|
+
}
|
|
185
|
+
depth = open.length - 1;
|
|
186
|
+
} else {
|
|
187
|
+
const wanted: number = GLYPH_DEPTH[bullet.glyph] ?? 0;
|
|
188
|
+
// A level can only open one deeper than the item above it.
|
|
189
|
+
depth = listInterrupted ? 0 : Math.min(wanted, depth + 1);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
lines[bullet.index] = `${" ".repeat(depth)}- ${bullet.text}`;
|
|
193
|
+
previousIndex = bullet.index;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return lines.join("\n");
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/*
|
|
200
|
+
* ---------------------------------------------------------------------------
|
|
201
|
+
* HTML
|
|
202
|
+
* ---------------------------------------------------------------------------
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
// Never content: dropped with everything inside them.
|
|
206
|
+
const NON_CONTENT_SELECTOR: string = [
|
|
207
|
+
"script",
|
|
208
|
+
"style",
|
|
209
|
+
"meta",
|
|
210
|
+
"link",
|
|
211
|
+
"title",
|
|
212
|
+
"template",
|
|
213
|
+
"noscript",
|
|
214
|
+
"iframe",
|
|
215
|
+
"frame",
|
|
216
|
+
"frameset",
|
|
217
|
+
"object",
|
|
218
|
+
"embed",
|
|
219
|
+
"applet",
|
|
220
|
+
"canvas",
|
|
221
|
+
"audio",
|
|
222
|
+
"video",
|
|
223
|
+
"source",
|
|
224
|
+
"track",
|
|
225
|
+
"svg",
|
|
226
|
+
"math",
|
|
227
|
+
"button",
|
|
228
|
+
"select",
|
|
229
|
+
"textarea",
|
|
230
|
+
"datalist",
|
|
231
|
+
"dialog",
|
|
232
|
+
"xml",
|
|
233
|
+
/*
|
|
234
|
+
* MarkdownViewer marks the parts of its output that are chrome rather than
|
|
235
|
+
* the document -- a code block's language label and Copy button.
|
|
236
|
+
*/
|
|
237
|
+
"[data-markdown-ignore]",
|
|
238
|
+
].join(", ");
|
|
239
|
+
|
|
240
|
+
const BLOCK_TAGS: Set<string> = new Set<string>([
|
|
241
|
+
"address",
|
|
242
|
+
"article",
|
|
243
|
+
"aside",
|
|
244
|
+
"blockquote",
|
|
245
|
+
"body",
|
|
246
|
+
"br",
|
|
247
|
+
"dd",
|
|
248
|
+
"details",
|
|
249
|
+
"div",
|
|
250
|
+
"dl",
|
|
251
|
+
"dt",
|
|
252
|
+
"fieldset",
|
|
253
|
+
"figcaption",
|
|
254
|
+
"figure",
|
|
255
|
+
"footer",
|
|
256
|
+
"form",
|
|
257
|
+
"h1",
|
|
258
|
+
"h2",
|
|
259
|
+
"h3",
|
|
260
|
+
"h4",
|
|
261
|
+
"h5",
|
|
262
|
+
"h6",
|
|
263
|
+
"header",
|
|
264
|
+
"hr",
|
|
265
|
+
"li",
|
|
266
|
+
"main",
|
|
267
|
+
"nav",
|
|
268
|
+
"ol",
|
|
269
|
+
"p",
|
|
270
|
+
"pre",
|
|
271
|
+
"section",
|
|
272
|
+
"summary",
|
|
273
|
+
"table",
|
|
274
|
+
"tbody",
|
|
275
|
+
"td",
|
|
276
|
+
"tfoot",
|
|
277
|
+
"th",
|
|
278
|
+
"thead",
|
|
279
|
+
"tr",
|
|
280
|
+
"ul",
|
|
281
|
+
]);
|
|
282
|
+
|
|
283
|
+
// Formatting the serializer writes as markdown, and that is noise when empty.
|
|
284
|
+
const INLINE_FORMATTING_SELECTOR: string =
|
|
285
|
+
"strong, b, em, i, s, del, strike, u, sub, sup";
|
|
286
|
+
|
|
287
|
+
/*
|
|
288
|
+
* What makes clipboard HTML worth converting rather than taking the plain
|
|
289
|
+
* text beside it: structure or formatting that the plain text loses.
|
|
290
|
+
*/
|
|
291
|
+
const RICH_CONTENT_SELECTOR: string = [
|
|
292
|
+
"ul",
|
|
293
|
+
"ol",
|
|
294
|
+
"li",
|
|
295
|
+
"h1",
|
|
296
|
+
"h2",
|
|
297
|
+
"h3",
|
|
298
|
+
"h4",
|
|
299
|
+
"h5",
|
|
300
|
+
"h6",
|
|
301
|
+
"blockquote",
|
|
302
|
+
"pre",
|
|
303
|
+
"table",
|
|
304
|
+
"hr",
|
|
305
|
+
"img",
|
|
306
|
+
"a[href]",
|
|
307
|
+
"strong",
|
|
308
|
+
"b",
|
|
309
|
+
"em",
|
|
310
|
+
"i",
|
|
311
|
+
"s",
|
|
312
|
+
"del",
|
|
313
|
+
"strike",
|
|
314
|
+
"u",
|
|
315
|
+
"sub",
|
|
316
|
+
"sup",
|
|
317
|
+
"code",
|
|
318
|
+
].join(", ");
|
|
319
|
+
|
|
320
|
+
const LINK_SCHEMES: Array<string> = ["http", "https", "mailto", "tel"];
|
|
321
|
+
const IMAGE_SCHEMES: Array<string> = ["http", "https"];
|
|
322
|
+
|
|
323
|
+
const RE_URL_SCHEME: RegExp = /^([a-z][a-z0-9+.-]*):/i;
|
|
324
|
+
const RE_WHITESPACE_RUN: RegExp = /[ \t\n\r\f]+/g;
|
|
325
|
+
const RE_NBSP: RegExp = /\u00a0/g;
|
|
326
|
+
// Docusaurus writes a zero-width space as its heading permalink's only text.
|
|
327
|
+
const RE_ZERO_WIDTH: RegExp = /[\u200b-\u200d\u2060\ufeff]/g;
|
|
328
|
+
const RE_NOT_WHITESPACE: RegExp = /\S/;
|
|
329
|
+
const RE_LEADING_SPACE: RegExp = /^\s+/;
|
|
330
|
+
const RE_TRAILING_SPACE: RegExp = /\s+$/;
|
|
331
|
+
const RE_URL_BREAKING: RegExp = /[\s()]/g;
|
|
332
|
+
const RE_SESSION_RETRY: RegExp = /([?&])sessionRetry=[^&#]*(&?)/;
|
|
333
|
+
const RE_WORD_LIST_STYLE: RegExp = /mso-list:\s*l\d+\s+level(\d+)/i;
|
|
334
|
+
const RE_WORD_ORDERED_MARKER: RegExp = /^\(?[0-9a-zA-Z]{1,5}[.)]/;
|
|
335
|
+
const RE_WORD_MARKER_SPAN: RegExp = /mso-list:\s*ignore/i;
|
|
336
|
+
const RE_HIDDEN_STYLE: RegExp = /mso-hide:\s*all/i;
|
|
337
|
+
const RE_LANGUAGE: RegExp = /^[\w-]+$/;
|
|
338
|
+
const RE_VIEWER_TIMESTAMP: RegExp =
|
|
339
|
+
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?Z$/;
|
|
340
|
+
const RE_DOCS_GUID: RegExp = /^docs-internal-guid/;
|
|
341
|
+
|
|
342
|
+
const tagOf: (node: Node | null | undefined) => string = (
|
|
343
|
+
node: Node | null | undefined,
|
|
344
|
+
): string => {
|
|
345
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) {
|
|
346
|
+
return "";
|
|
347
|
+
}
|
|
348
|
+
return (node as Element).localName.toLowerCase();
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const isBlock: (node: Node | null | undefined) => boolean = (
|
|
352
|
+
node: Node | null | undefined,
|
|
353
|
+
): boolean => {
|
|
354
|
+
return BLOCK_TAGS.has(tagOf(node));
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const isList: (node: Node | null | undefined) => boolean = (
|
|
358
|
+
node: Node | null | undefined,
|
|
359
|
+
): boolean => {
|
|
360
|
+
const tag: string = tagOf(node);
|
|
361
|
+
return tag === "ul" || tag === "ol";
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
// Replaces an element with its children.
|
|
365
|
+
const unwrap: (element: Element) => void = (element: Element): void => {
|
|
366
|
+
const parent: ParentNode | null = element.parentNode;
|
|
367
|
+
if (!parent) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
while (element.firstChild) {
|
|
371
|
+
parent.insertBefore(element.firstChild, element);
|
|
372
|
+
}
|
|
373
|
+
element.remove();
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const elementsOf: (root: ParentNode, selector: string) => Array<HTMLElement> = (
|
|
377
|
+
root: ParentNode,
|
|
378
|
+
selector: string,
|
|
379
|
+
): Array<HTMLElement> => {
|
|
380
|
+
return Array.from(root.querySelectorAll<HTMLElement>(selector));
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const commentsOf: (root: Node) => Array<Comment> = (
|
|
384
|
+
root: Node,
|
|
385
|
+
): Array<Comment> => {
|
|
386
|
+
const comments: Array<Comment> = [];
|
|
387
|
+
const walk: (node: Node) => void = (node: Node): void => {
|
|
388
|
+
for (const child of Array.from(node.childNodes)) {
|
|
389
|
+
if (child.nodeType === Node.COMMENT_NODE) {
|
|
390
|
+
comments.push(child as Comment);
|
|
391
|
+
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
392
|
+
walk(child);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
walk(root);
|
|
397
|
+
return comments;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const textNodesOf: (root: Node) => Array<Text> = (root: Node): Array<Text> => {
|
|
401
|
+
const texts: Array<Text> = [];
|
|
402
|
+
const walk: (node: Node) => void = (node: Node): void => {
|
|
403
|
+
for (const child of Array.from(node.childNodes)) {
|
|
404
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
405
|
+
texts.push(child as Text);
|
|
406
|
+
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
407
|
+
walk(child);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
walk(root);
|
|
412
|
+
return texts;
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const isBoldWeight: (weight: string) => boolean = (weight: string): boolean => {
|
|
416
|
+
if (weight === "bold" || weight === "bolder") {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
const numeric: number = parseInt(weight, 10);
|
|
420
|
+
return !isNaN(numeric) && numeric >= 600;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const isNormalWeight: (weight: string) => boolean = (
|
|
424
|
+
weight: string,
|
|
425
|
+
): boolean => {
|
|
426
|
+
if (weight === "normal" || weight === "lighter") {
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
const numeric: number = parseInt(weight, 10);
|
|
430
|
+
return !isNaN(numeric) && numeric < 600;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
/*
|
|
434
|
+
* ---- 1. Things that are not content ---------------------------------------
|
|
435
|
+
*/
|
|
436
|
+
|
|
437
|
+
const removeNonContent: (body: HTMLElement) => void = (
|
|
438
|
+
body: HTMLElement,
|
|
439
|
+
): void => {
|
|
440
|
+
for (const element of elementsOf(body, NON_CONTENT_SELECTOR)) {
|
|
441
|
+
element.remove();
|
|
442
|
+
}
|
|
443
|
+
// A task list's checkbox is content; every other form control is not.
|
|
444
|
+
for (const input of elementsOf(body, "input")) {
|
|
445
|
+
if ((input.getAttribute("type") || "").toLowerCase() !== "checkbox") {
|
|
446
|
+
input.remove();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
for (const element of elementsOf(body, "[style]")) {
|
|
450
|
+
const style: string = element.getAttribute("style") || "";
|
|
451
|
+
if (element.style.display === "none" || RE_HIDDEN_STYLE.test(style)) {
|
|
452
|
+
element.remove();
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/*
|
|
456
|
+
* Word ends every paragraph with an <o:p>, empty or holding a for
|
|
457
|
+
* an empty paragraph. Anything else in one is kept as text.
|
|
458
|
+
*/
|
|
459
|
+
for (const element of elementsOf(body, "o\\:p")) {
|
|
460
|
+
if (
|
|
461
|
+
RE_NOT_WHITESPACE.test((element.textContent || "").replace(RE_NBSP, ""))
|
|
462
|
+
) {
|
|
463
|
+
unwrap(element);
|
|
464
|
+
} else {
|
|
465
|
+
element.remove();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
/*
|
|
471
|
+
* ---- 2. Word's list paragraphs --------------------------------------------
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/*
|
|
475
|
+
* Word writes a list as one paragraph per item, each with a
|
|
476
|
+
* "mso-list:l0 level2 lfo1" style and its bullet or number as text between
|
|
477
|
+
* <![if !supportLists]> and <![endif]> (which parse as comments), or in a
|
|
478
|
+
* span styled "mso-list:Ignore". Takes that marker out of the element and
|
|
479
|
+
* returns its text.
|
|
480
|
+
*/
|
|
481
|
+
const takeWordListMarker: (element: HTMLElement) => string = (
|
|
482
|
+
element: HTMLElement,
|
|
483
|
+
): string => {
|
|
484
|
+
let marker: string = "";
|
|
485
|
+
for (const comment of commentsOf(element)) {
|
|
486
|
+
if (comment.data.trim() !== "[if !supportLists]" || !comment.parentNode) {
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
let node: ChildNode | null = comment.nextSibling;
|
|
490
|
+
while (
|
|
491
|
+
node &&
|
|
492
|
+
!(
|
|
493
|
+
node.nodeType === Node.COMMENT_NODE &&
|
|
494
|
+
(node as Comment).data.trim() === "[endif]"
|
|
495
|
+
)
|
|
496
|
+
) {
|
|
497
|
+
const next: ChildNode | null = node.nextSibling;
|
|
498
|
+
marker += node.textContent || "";
|
|
499
|
+
node.remove();
|
|
500
|
+
node = next;
|
|
501
|
+
}
|
|
502
|
+
if (node) {
|
|
503
|
+
node.remove();
|
|
504
|
+
}
|
|
505
|
+
comment.remove();
|
|
506
|
+
}
|
|
507
|
+
for (const span of elementsOf(element, "span[style]")) {
|
|
508
|
+
if (
|
|
509
|
+
span.isConnected &&
|
|
510
|
+
RE_WORD_MARKER_SPAN.test(span.getAttribute("style") || "")
|
|
511
|
+
) {
|
|
512
|
+
marker += span.textContent || "";
|
|
513
|
+
span.remove();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return marker.replace(RE_NBSP, " ").trim();
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
interface NestedListEntry {
|
|
520
|
+
// 0 for a top-level item.
|
|
521
|
+
depth: number;
|
|
522
|
+
ordered: boolean;
|
|
523
|
+
// The nodes that make up the item.
|
|
524
|
+
content: Array<Node>;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/*
|
|
528
|
+
* Builds nested <ul>/<ol> elements out of a flat run of items that each know
|
|
529
|
+
* their depth. An item can only be one level deeper than the one before it;
|
|
530
|
+
* a change between ordered and unordered at the same depth starts a new list
|
|
531
|
+
* there, as it would in markdown.
|
|
532
|
+
*/
|
|
533
|
+
const buildNestedLists: (
|
|
534
|
+
doc: Document,
|
|
535
|
+
entries: Array<NestedListEntry>,
|
|
536
|
+
) => DocumentFragment = (
|
|
537
|
+
doc: Document,
|
|
538
|
+
entries: Array<NestedListEntry>,
|
|
539
|
+
): DocumentFragment => {
|
|
540
|
+
const fragment: DocumentFragment = doc.createDocumentFragment();
|
|
541
|
+
const levels: Array<{ list: HTMLElement; lastItem: HTMLElement | null }> = [];
|
|
542
|
+
for (const entry of entries) {
|
|
543
|
+
const depth: number = Math.min(entry.depth, levels.length);
|
|
544
|
+
while (levels.length > depth + 1) {
|
|
545
|
+
levels.pop();
|
|
546
|
+
}
|
|
547
|
+
const tag: string = entry.ordered ? "ol" : "ul";
|
|
548
|
+
const current:
|
|
549
|
+
| { list: HTMLElement; lastItem: HTMLElement | null }
|
|
550
|
+
| undefined = levels[depth];
|
|
551
|
+
if (!current || tagOf(current.list) !== tag) {
|
|
552
|
+
const list: HTMLElement = doc.createElement(tag);
|
|
553
|
+
const parent:
|
|
554
|
+
| { list: HTMLElement; lastItem: HTMLElement | null }
|
|
555
|
+
| undefined = levels[depth - 1];
|
|
556
|
+
if (depth === 0 || !parent) {
|
|
557
|
+
fragment.appendChild(list);
|
|
558
|
+
} else {
|
|
559
|
+
if (!parent.lastItem) {
|
|
560
|
+
parent.lastItem = doc.createElement("li");
|
|
561
|
+
parent.list.appendChild(parent.lastItem);
|
|
562
|
+
}
|
|
563
|
+
parent.lastItem.appendChild(list);
|
|
564
|
+
}
|
|
565
|
+
levels.length = depth;
|
|
566
|
+
levels.push({ list, lastItem: null });
|
|
567
|
+
}
|
|
568
|
+
const level: { list: HTMLElement; lastItem: HTMLElement | null } = levels[
|
|
569
|
+
depth
|
|
570
|
+
] as { list: HTMLElement; lastItem: HTMLElement | null };
|
|
571
|
+
const item: HTMLElement = doc.createElement("li");
|
|
572
|
+
for (const node of entry.content) {
|
|
573
|
+
item.appendChild(node);
|
|
574
|
+
}
|
|
575
|
+
level.list.appendChild(item);
|
|
576
|
+
level.lastItem = item;
|
|
577
|
+
}
|
|
578
|
+
return fragment;
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
const wordListLevel: (element: Element) => number = (
|
|
582
|
+
element: Element,
|
|
583
|
+
): number => {
|
|
584
|
+
if (tagOf(element) !== "p") {
|
|
585
|
+
return 0;
|
|
586
|
+
}
|
|
587
|
+
const match: RegExpMatchArray | null = (
|
|
588
|
+
element.getAttribute("style") || ""
|
|
589
|
+
).match(RE_WORD_LIST_STYLE);
|
|
590
|
+
return match ? parseInt(match[1] || "1", 10) : 0;
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// The next element sibling, stepping over whitespace and comments only.
|
|
594
|
+
const nextElementOnlyAfterGap: (node: Element) => Element | null = (
|
|
595
|
+
node: Element,
|
|
596
|
+
): Element | null => {
|
|
597
|
+
let next: ChildNode | null = node.nextSibling;
|
|
598
|
+
while (next) {
|
|
599
|
+
if (next.nodeType === Node.ELEMENT_NODE) {
|
|
600
|
+
return next as Element;
|
|
601
|
+
}
|
|
602
|
+
if (
|
|
603
|
+
next.nodeType === Node.TEXT_NODE &&
|
|
604
|
+
RE_NOT_WHITESPACE.test((next.textContent || "").replace(RE_NBSP, ""))
|
|
605
|
+
) {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
next = next.nextSibling;
|
|
609
|
+
}
|
|
610
|
+
return null;
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const rebuildWordListParagraphs: (body: HTMLElement) => void = (
|
|
614
|
+
body: HTMLElement,
|
|
615
|
+
): void => {
|
|
616
|
+
const doc: Document = body.ownerDocument;
|
|
617
|
+
for (const paragraph of elementsOf(body, "p[style]")) {
|
|
618
|
+
if (!paragraph.isConnected || wordListLevel(paragraph) === 0) {
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
const run: Array<HTMLElement> = [paragraph];
|
|
622
|
+
let next: Element | null = nextElementOnlyAfterGap(paragraph);
|
|
623
|
+
while (next && wordListLevel(next) > 0) {
|
|
624
|
+
run.push(next as HTMLElement);
|
|
625
|
+
next = nextElementOnlyAfterGap(next);
|
|
626
|
+
}
|
|
627
|
+
const entries: Array<NestedListEntry> = run.map(
|
|
628
|
+
(item: HTMLElement): NestedListEntry => {
|
|
629
|
+
const marker: string = takeWordListMarker(item);
|
|
630
|
+
return {
|
|
631
|
+
depth: wordListLevel(item) - 1,
|
|
632
|
+
ordered: RE_WORD_ORDERED_MARKER.test(marker.replace(/\s+/g, "")),
|
|
633
|
+
content: Array.from(item.childNodes),
|
|
634
|
+
};
|
|
635
|
+
},
|
|
636
|
+
);
|
|
637
|
+
const first: HTMLElement = run[0] as HTMLElement;
|
|
638
|
+
first.parentNode?.insertBefore(buildNestedLists(doc, entries), first);
|
|
639
|
+
run.forEach((item: HTMLElement, position: number): void => {
|
|
640
|
+
// The whitespace between two of the paragraphs goes with them.
|
|
641
|
+
let gap: ChildNode | null = position > 0 ? item.previousSibling : null;
|
|
642
|
+
while (gap && gap.nodeType !== Node.ELEMENT_NODE) {
|
|
643
|
+
const before: ChildNode | null = gap.previousSibling;
|
|
644
|
+
gap.remove();
|
|
645
|
+
gap = before;
|
|
646
|
+
}
|
|
647
|
+
item.remove();
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
// Markers Word left anywhere else (a list written as <li>s, say).
|
|
651
|
+
for (const element of elementsOf(body, "li, p")) {
|
|
652
|
+
if (
|
|
653
|
+
commentsOf(element).length > 0 ||
|
|
654
|
+
element.querySelector("span[style]")
|
|
655
|
+
) {
|
|
656
|
+
takeWordListMarker(element);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
/*
|
|
662
|
+
* ---- 3. Formatting written as styles (Google Docs, Word, browsers) --------
|
|
663
|
+
*/
|
|
664
|
+
|
|
665
|
+
const wrapIn: (element: Element, tag: string) => void = (
|
|
666
|
+
element: Element,
|
|
667
|
+
tag: string,
|
|
668
|
+
): void => {
|
|
669
|
+
const wrapper: HTMLElement = element.ownerDocument.createElement(tag);
|
|
670
|
+
element.parentNode?.insertBefore(wrapper, element);
|
|
671
|
+
wrapper.appendChild(element);
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
const readStyledFormatting: (body: HTMLElement) => void = (
|
|
675
|
+
body: HTMLElement,
|
|
676
|
+
): void => {
|
|
677
|
+
/*
|
|
678
|
+
* Google Docs wraps the whole copy in <b style="font-weight:normal"
|
|
679
|
+
* id="docs-internal-guid-...">. Taken at its tag, the entire paste came
|
|
680
|
+
* out as one bold run with stray "**" lines around it. A <b> or <strong>
|
|
681
|
+
* whose own style says normal weight is not bold either.
|
|
682
|
+
*/
|
|
683
|
+
for (const element of elementsOf(body, "b, strong")) {
|
|
684
|
+
if (
|
|
685
|
+
RE_DOCS_GUID.test(element.id) ||
|
|
686
|
+
isNormalWeight(element.style.fontWeight)
|
|
687
|
+
) {
|
|
688
|
+
unwrap(element);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/*
|
|
692
|
+
* Docs, and a browser copying part of a styled element, write formatting
|
|
693
|
+
* as span styles rather than tags. Only the three kinds markdown has are
|
|
694
|
+
* read, and only where the text is not already inside that formatting.
|
|
695
|
+
*/
|
|
696
|
+
for (const span of elementsOf(body, "span[style], font[style]")) {
|
|
697
|
+
const style: CSSStyleDeclaration = span.style;
|
|
698
|
+
const decoration: string = `${style.textDecorationLine || ""} ${style.textDecoration || ""}`;
|
|
699
|
+
if (
|
|
700
|
+
decoration.includes("line-through") &&
|
|
701
|
+
!span.closest("s, del, strike")
|
|
702
|
+
) {
|
|
703
|
+
wrapIn(span, "s");
|
|
704
|
+
}
|
|
705
|
+
if (
|
|
706
|
+
(style.fontStyle === "italic" || style.fontStyle === "oblique") &&
|
|
707
|
+
!span.closest("em, i")
|
|
708
|
+
) {
|
|
709
|
+
wrapIn(span, "em");
|
|
710
|
+
}
|
|
711
|
+
if (
|
|
712
|
+
isBoldWeight(style.fontWeight) &&
|
|
713
|
+
!span.closest("strong, b, h1, h2, h3, h4, h5, h6, th")
|
|
714
|
+
) {
|
|
715
|
+
wrapIn(span, "strong");
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
/*
|
|
721
|
+
* ---- 4. What MarkdownViewer renders ---------------------------------------
|
|
722
|
+
*/
|
|
723
|
+
|
|
724
|
+
/*
|
|
725
|
+
* The text of a preformatted element, with a line break for each <br> and
|
|
726
|
+
* for each block inside it -- an editor that writes one <div> per line.
|
|
727
|
+
*/
|
|
728
|
+
const preformattedText: (element: Element) => string = (
|
|
729
|
+
element: Element,
|
|
730
|
+
): string => {
|
|
731
|
+
let text: string = "";
|
|
732
|
+
const walk: (node: Node) => void = (node: Node): void => {
|
|
733
|
+
for (const child of Array.from(node.childNodes)) {
|
|
734
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
735
|
+
text += (child as Text).data;
|
|
736
|
+
} else if (tagOf(child) === "br") {
|
|
737
|
+
text += "\n";
|
|
738
|
+
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
739
|
+
const block: boolean = isBlock(child);
|
|
740
|
+
if (block && text.length > 0 && !text.endsWith("\n")) {
|
|
741
|
+
text += "\n";
|
|
742
|
+
}
|
|
743
|
+
walk(child);
|
|
744
|
+
if (block && !text.endsWith("\n")) {
|
|
745
|
+
text += "\n";
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
walk(element);
|
|
751
|
+
return text;
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
const restoreViewerMarkup: (body: HTMLElement) => void = (
|
|
755
|
+
body: HTMLElement,
|
|
756
|
+
): void => {
|
|
757
|
+
const doc: Document = body.ownerDocument;
|
|
758
|
+
/*
|
|
759
|
+
* A code block renders as a syntax-highlighted <div> with no <pre> and no
|
|
760
|
+
* language class, so on its own it would paste as highlighted spans of
|
|
761
|
+
* plain text. The viewer marks its root with the language instead.
|
|
762
|
+
*/
|
|
763
|
+
for (const block of elementsOf(body, "[data-markdown-code-block]")) {
|
|
764
|
+
if (!block.isConnected) {
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
const language: string = (block.getAttribute("data-language") || "").trim();
|
|
768
|
+
const source: Element = block.querySelector("code") || block;
|
|
769
|
+
const text: string = preformattedText(source);
|
|
770
|
+
/*
|
|
771
|
+
* Only the <pre> the code is in reached the clipboard -- the copy began
|
|
772
|
+
* and ended inside the code -- and it holds no line break: a
|
|
773
|
+
* double-clicked word, part of a command. Every browser keeps that <pre>
|
|
774
|
+
* around even a word, and as a fenced block the word split the sentence
|
|
775
|
+
* it was pasted into (the visual editor) or ran into the rest of the
|
|
776
|
+
* line (the markdown source), where the closing fence opened a new one
|
|
777
|
+
* that swallowed the rest of the note. It is inline code instead. A copy
|
|
778
|
+
* with a line break in it -- lines, or a line Chromium or Safari
|
|
779
|
+
* triple-clicks, break and all -- and one that carries the block's own
|
|
780
|
+
* root, all of the block, stay fenced blocks; so does text holding a
|
|
781
|
+
* backtick, which inline code would cut short.
|
|
782
|
+
*/
|
|
783
|
+
if (
|
|
784
|
+
tagOf(block) === "pre" &&
|
|
785
|
+
!text.includes("\n") &&
|
|
786
|
+
!text.includes("`") &&
|
|
787
|
+
RE_NOT_WHITESPACE.test(text)
|
|
788
|
+
) {
|
|
789
|
+
const inline: HTMLElement = doc.createElement("code");
|
|
790
|
+
inline.textContent = text;
|
|
791
|
+
block.parentNode?.insertBefore(inline, block);
|
|
792
|
+
block.remove();
|
|
793
|
+
continue;
|
|
794
|
+
}
|
|
795
|
+
const code: HTMLElement = doc.createElement("code");
|
|
796
|
+
if (language && language !== "text" && RE_LANGUAGE.test(language)) {
|
|
797
|
+
code.className = `language-${language}`;
|
|
798
|
+
}
|
|
799
|
+
code.textContent = text;
|
|
800
|
+
const pre: HTMLElement = doc.createElement("pre");
|
|
801
|
+
pre.appendChild(code);
|
|
802
|
+
block.parentNode?.insertBefore(pre, block);
|
|
803
|
+
block.remove();
|
|
804
|
+
}
|
|
805
|
+
/*
|
|
806
|
+
* A timestamp the viewer localized ("Apr 20, 2026 11:21 AM" for the
|
|
807
|
+
* reader) came from an inline-code ISO timestamp, which is what is put
|
|
808
|
+
* back, so it is localized again for whoever reads the new note.
|
|
809
|
+
*/
|
|
810
|
+
for (const time of elementsOf(body, "time[datetime]")) {
|
|
811
|
+
const iso: string = (time.getAttribute("datetime") || "").trim();
|
|
812
|
+
if (RE_VIEWER_TIMESTAMP.test(iso)) {
|
|
813
|
+
const code: HTMLElement = doc.createElement("code");
|
|
814
|
+
code.textContent = iso;
|
|
815
|
+
time.parentNode?.insertBefore(code, time);
|
|
816
|
+
time.remove();
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
/*
|
|
822
|
+
* ---- 5. Links and images ---------------------------------------------------
|
|
823
|
+
*/
|
|
824
|
+
|
|
825
|
+
/*
|
|
826
|
+
* The URL with its scheme checked against `schemes`, or null when it is not
|
|
827
|
+
* allowed. Browsers ignore control characters and whitespace in a scheme
|
|
828
|
+
* ("java\tscript:"), so they are dropped before the check. Scheme-less URLs
|
|
829
|
+
* (relative, or "//host/path") are allowed. Spaces and parentheses are
|
|
830
|
+
* encoded: either one ends a markdown link's URL early.
|
|
831
|
+
*/
|
|
832
|
+
const safeUrl: (raw: string, schemes: Array<string>) => string | null = (
|
|
833
|
+
raw: string,
|
|
834
|
+
schemes: Array<string>,
|
|
835
|
+
): string | null => {
|
|
836
|
+
let url: string = "";
|
|
837
|
+
for (const ch of raw) {
|
|
838
|
+
const code: number = ch.charCodeAt(0);
|
|
839
|
+
if (code >= 0x20 && code !== 0x7f) {
|
|
840
|
+
url += ch;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
url = url.trim();
|
|
844
|
+
if (!url) {
|
|
845
|
+
return null;
|
|
846
|
+
}
|
|
847
|
+
const scheme: RegExpMatchArray | null = url
|
|
848
|
+
.replace(/\s+/g, "")
|
|
849
|
+
.match(RE_URL_SCHEME);
|
|
850
|
+
if (scheme && !schemes.includes((scheme[1] || "").toLowerCase())) {
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
853
|
+
return url.replace(RE_URL_BREAKING, (ch: string): string => {
|
|
854
|
+
return encodeURIComponent(ch) === ch
|
|
855
|
+
? `%${ch.charCodeAt(0).toString(16).toUpperCase()}`
|
|
856
|
+
: encodeURIComponent(ch);
|
|
857
|
+
});
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
/*
|
|
861
|
+
* SessionAwareImage retries a private image with a "sessionRetry" cache
|
|
862
|
+
* buster; a copy of the rendered note carries it along, and it means nothing
|
|
863
|
+
* in the new one.
|
|
864
|
+
*/
|
|
865
|
+
const withoutSessionRetry: (url: string) => string = (url: string): string => {
|
|
866
|
+
return url.replace(
|
|
867
|
+
RE_SESSION_RETRY,
|
|
868
|
+
(_match: string, separator: string, more: string): string => {
|
|
869
|
+
return more ? separator : "";
|
|
870
|
+
},
|
|
871
|
+
);
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
const sanitizeLinksAndImages: (body: HTMLElement) => void = (
|
|
875
|
+
body: HTMLElement,
|
|
876
|
+
): void => {
|
|
877
|
+
for (const link of elementsOf(body, "a[href]")) {
|
|
878
|
+
const href: string | null = safeUrl(
|
|
879
|
+
link.getAttribute("href") || "",
|
|
880
|
+
LINK_SCHEMES,
|
|
881
|
+
);
|
|
882
|
+
if (href === null) {
|
|
883
|
+
unwrap(link);
|
|
884
|
+
} else {
|
|
885
|
+
link.setAttribute("href", href);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
for (const image of elementsOf(body, "img")) {
|
|
889
|
+
const src: string | null = safeUrl(
|
|
890
|
+
withoutSessionRetry(image.getAttribute("src") || ""),
|
|
891
|
+
IMAGE_SCHEMES,
|
|
892
|
+
);
|
|
893
|
+
if (src === null) {
|
|
894
|
+
// data:, blob:, file: and cid: images are not uploaded -- dropped.
|
|
895
|
+
image.remove();
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
image.setAttribute("src", src);
|
|
899
|
+
image.setAttribute(
|
|
900
|
+
"alt",
|
|
901
|
+
(image.getAttribute("alt") || "").replace(/[[\]\s]+/g, " ").trim(),
|
|
902
|
+
);
|
|
903
|
+
image.removeAttribute("title");
|
|
904
|
+
}
|
|
905
|
+
/*
|
|
906
|
+
* A link left with nothing to read -- the permalink icon GitHub puts
|
|
907
|
+
* beside every heading, a row of social icons, once their <svg>s are gone,
|
|
908
|
+
* or the empty or zero-width-space anchors of GitLab and Docusaurus --
|
|
909
|
+
* would be written out with its URL as its text: every heading copied from
|
|
910
|
+
* a README gained a line of "[https://github.com/...#install](...)". It is
|
|
911
|
+
* not content, so it is unwrapped. Whatever space it held stays, so the
|
|
912
|
+
* words either side of it do not run together. The URLs browsers put on
|
|
913
|
+
* the clipboard are absolute, so the link is known by its emptiness, not
|
|
914
|
+
* by an href starting with "#". This runs after the images are checked,
|
|
915
|
+
* so a link whose only image was dropped goes too.
|
|
916
|
+
*/
|
|
917
|
+
for (const link of elementsOf(body, "a[href]")) {
|
|
918
|
+
const text: string = (link.textContent || "")
|
|
919
|
+
.replace(RE_NBSP, "")
|
|
920
|
+
.replace(RE_ZERO_WIDTH, "");
|
|
921
|
+
if (RE_NOT_WHITESPACE.test(text) || link.querySelector("img")) {
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
for (const node of textNodesOf(link)) {
|
|
925
|
+
node.data = node.data.replace(RE_ZERO_WIDTH, "");
|
|
926
|
+
}
|
|
927
|
+
unwrap(link);
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
/*
|
|
932
|
+
* ---- 6. Lists --------------------------------------------------------------
|
|
933
|
+
*/
|
|
934
|
+
|
|
935
|
+
/*
|
|
936
|
+
* Outlook, and every browser's execCommand("indent"), write a nested list
|
|
937
|
+
* as a <ul> directly inside a <ul> -- invalid, and the serializer, which
|
|
938
|
+
* reads only a list's <li> children, dropped it and everything in it. It is
|
|
939
|
+
* moved into the item before it, as markdown nests it. Anything else loose
|
|
940
|
+
* in a list is wrapped in an item of its own rather than lost.
|
|
941
|
+
*/
|
|
942
|
+
const repairLists: (body: HTMLElement) => void = (body: HTMLElement): void => {
|
|
943
|
+
const doc: Document = body.ownerDocument;
|
|
944
|
+
for (const list of elementsOf(body, "ul, ol")) {
|
|
945
|
+
let loose: HTMLElement | null = null;
|
|
946
|
+
for (const child of Array.from(list.childNodes)) {
|
|
947
|
+
if (child.nodeType === Node.COMMENT_NODE) {
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
if (
|
|
951
|
+
child.nodeType === Node.TEXT_NODE &&
|
|
952
|
+
!RE_NOT_WHITESPACE.test((child.textContent || "").replace(RE_NBSP, ""))
|
|
953
|
+
) {
|
|
954
|
+
child.remove();
|
|
955
|
+
continue;
|
|
956
|
+
}
|
|
957
|
+
if (tagOf(child) === "li") {
|
|
958
|
+
loose = null;
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
if (isList(child)) {
|
|
962
|
+
const previous: Element | null = (child as Element)
|
|
963
|
+
.previousElementSibling;
|
|
964
|
+
if (previous && tagOf(previous) === "li") {
|
|
965
|
+
previous.appendChild(child);
|
|
966
|
+
loose = null;
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
if (!loose) {
|
|
971
|
+
loose = doc.createElement("li");
|
|
972
|
+
list.insertBefore(loose, child);
|
|
973
|
+
}
|
|
974
|
+
loose.appendChild(child);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
/*
|
|
978
|
+
* Google Docs puts each item's text in a <p>, which made every item a
|
|
979
|
+
* separate paragraph -- a blank line inside the item. An item with a
|
|
980
|
+
* single paragraph is tight, so the paragraph goes.
|
|
981
|
+
*/
|
|
982
|
+
for (const item of elementsOf(body, "li")) {
|
|
983
|
+
const paragraphs: Array<Element> = Array.from(item.children).filter(
|
|
984
|
+
(child: Element): boolean => {
|
|
985
|
+
return tagOf(child) === "p";
|
|
986
|
+
},
|
|
987
|
+
);
|
|
988
|
+
if (paragraphs.length === 1 && paragraphs[0]) {
|
|
989
|
+
unwrap(paragraphs[0]);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
|
|
994
|
+
/*
|
|
995
|
+
* ---- 7. Whitespace ---------------------------------------------------------
|
|
996
|
+
*/
|
|
997
|
+
|
|
998
|
+
// A sibling that renders as nothing: a comment, or text that is only whitespace.
|
|
999
|
+
const rendersNothing: (node: Node) => boolean = (node: Node): boolean => {
|
|
1000
|
+
return (
|
|
1001
|
+
node.nodeType === Node.COMMENT_NODE ||
|
|
1002
|
+
(node.nodeType === Node.TEXT_NODE &&
|
|
1003
|
+
!RE_NOT_WHITESPACE.test((node.textContent || "").replace(RE_NBSP, "")))
|
|
1004
|
+
);
|
|
1005
|
+
};
|
|
1006
|
+
|
|
1007
|
+
// Whether `node` is the last thing in its block (or comes right before a block or a <br>).
|
|
1008
|
+
const endsBlock: (node: Node) => boolean = (node: Node): boolean => {
|
|
1009
|
+
let current: Node = node;
|
|
1010
|
+
for (;;) {
|
|
1011
|
+
let next: Node | null = current.nextSibling;
|
|
1012
|
+
while (next && rendersNothing(next)) {
|
|
1013
|
+
next = next.nextSibling;
|
|
1014
|
+
}
|
|
1015
|
+
if (next) {
|
|
1016
|
+
return isBlock(next);
|
|
1017
|
+
}
|
|
1018
|
+
const parent: Node | null = current.parentNode;
|
|
1019
|
+
if (!parent || isBlock(parent) || parent.nodeType !== Node.ELEMENT_NODE) {
|
|
1020
|
+
return true;
|
|
1021
|
+
}
|
|
1022
|
+
current = parent;
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
1025
|
+
|
|
1026
|
+
/*
|
|
1027
|
+
* HTML ignores the line breaks and runs of spaces in its source; markdown
|
|
1028
|
+
* does not. Word hard-wraps its HTML ("Service\n is currently
|
|
1029
|
+
* unavailable"), so without this a pasted item came back as two lines.
|
|
1030
|
+
* Walking the text in order, a space is dropped where the browser would not
|
|
1031
|
+
* show one: at the start or end of a block, beside a <br>, and after a space
|
|
1032
|
+
* already written. Text in a <pre> is left exactly as it is.
|
|
1033
|
+
*/
|
|
1034
|
+
const collapseWhitespace: (body: HTMLElement) => void = (
|
|
1035
|
+
body: HTMLElement,
|
|
1036
|
+
): void => {
|
|
1037
|
+
// Whether the text so far ends in a space, or a block has just begun.
|
|
1038
|
+
let atSpace: boolean = true;
|
|
1039
|
+
const walk: (node: Node) => void = (node: Node): void => {
|
|
1040
|
+
for (const child of Array.from(node.childNodes)) {
|
|
1041
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
1042
|
+
const text: Text = child as Text;
|
|
1043
|
+
let value: string = text.data
|
|
1044
|
+
.replace(RE_NBSP, " ")
|
|
1045
|
+
.replace(RE_WHITESPACE_RUN, " ");
|
|
1046
|
+
if (atSpace && value.startsWith(" ")) {
|
|
1047
|
+
value = value.slice(1);
|
|
1048
|
+
}
|
|
1049
|
+
if (value.endsWith(" ") && endsBlock(text)) {
|
|
1050
|
+
value = value.slice(0, -1);
|
|
1051
|
+
}
|
|
1052
|
+
if (value.length === 0) {
|
|
1053
|
+
text.remove();
|
|
1054
|
+
continue;
|
|
1055
|
+
}
|
|
1056
|
+
text.data = value;
|
|
1057
|
+
atSpace = value.endsWith(" ");
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
if (child.nodeType !== Node.ELEMENT_NODE) {
|
|
1061
|
+
continue;
|
|
1062
|
+
}
|
|
1063
|
+
const tag: string = tagOf(child);
|
|
1064
|
+
if (tag === "pre") {
|
|
1065
|
+
atSpace = true;
|
|
1066
|
+
} else if (isBlock(child)) {
|
|
1067
|
+
atSpace = true;
|
|
1068
|
+
walk(child);
|
|
1069
|
+
atSpace = true;
|
|
1070
|
+
} else if (tag === "img" || tag === "input") {
|
|
1071
|
+
atSpace = false;
|
|
1072
|
+
} else {
|
|
1073
|
+
walk(child);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
walk(body);
|
|
1078
|
+
};
|
|
1079
|
+
|
|
1080
|
+
/*
|
|
1081
|
+
* "**bold **text" is not bold in CommonMark -- a closing "**" after a space
|
|
1082
|
+
* does not close anything -- so whitespace at either edge of a formatting
|
|
1083
|
+
* element moves outside it. A formatting element with no text at all would
|
|
1084
|
+
* come out as "****" and is replaced by the whitespace it held, if any.
|
|
1085
|
+
* Runs before the whitespace is collapsed, which tidies what this moves.
|
|
1086
|
+
*/
|
|
1087
|
+
const tidyInlineFormatting: (body: HTMLElement) => void = (
|
|
1088
|
+
body: HTMLElement,
|
|
1089
|
+
): void => {
|
|
1090
|
+
const doc: Document = body.ownerDocument;
|
|
1091
|
+
for (const element of elementsOf(
|
|
1092
|
+
body,
|
|
1093
|
+
INLINE_FORMATTING_SELECTOR,
|
|
1094
|
+
).reverse()) {
|
|
1095
|
+
const parent: ParentNode | null = element.parentNode;
|
|
1096
|
+
if (!parent) {
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
const content: string = element.textContent || "";
|
|
1100
|
+
if (!RE_NOT_WHITESPACE.test(content) && !element.querySelector("img, br")) {
|
|
1101
|
+
if (content) {
|
|
1102
|
+
parent.insertBefore(doc.createTextNode(" "), element);
|
|
1103
|
+
}
|
|
1104
|
+
element.remove();
|
|
1105
|
+
continue;
|
|
1106
|
+
}
|
|
1107
|
+
const texts: Array<Text> = textNodesOf(element);
|
|
1108
|
+
const first: Text | undefined = texts[0];
|
|
1109
|
+
const last: Text | undefined = texts[texts.length - 1];
|
|
1110
|
+
if (first && RE_LEADING_SPACE.test(first.data)) {
|
|
1111
|
+
first.data = first.data.replace(RE_LEADING_SPACE, "");
|
|
1112
|
+
parent.insertBefore(doc.createTextNode(" "), element);
|
|
1113
|
+
}
|
|
1114
|
+
if (last && RE_TRAILING_SPACE.test(last.data)) {
|
|
1115
|
+
last.data = last.data.replace(RE_TRAILING_SPACE, "");
|
|
1116
|
+
parent.insertBefore(doc.createTextNode(" "), element.nextSibling);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
body.normalize();
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
/*
|
|
1123
|
+
* ---------------------------------------------------------------------------
|
|
1124
|
+
* Pipeline
|
|
1125
|
+
* ---------------------------------------------------------------------------
|
|
1126
|
+
*/
|
|
1127
|
+
|
|
1128
|
+
/*
|
|
1129
|
+
* A <div> that keeps its whitespace ("white-space: pre") is what code
|
|
1130
|
+
* editors put on the clipboard -- VS Code writes one such <div> holding a
|
|
1131
|
+
* <div> of coloured spans per line. Its plain text is the real content
|
|
1132
|
+
* (often markdown source itself), so that is what gets pasted, as before.
|
|
1133
|
+
*
|
|
1134
|
+
* So is a table cell that keeps its whitespace: a code view drawn as a
|
|
1135
|
+
* table, one row per line beside a column of line numbers, as OneUptime's
|
|
1136
|
+
* own Kubernetes YAML tab and exception stack frames are. Chromium and
|
|
1137
|
+
* Safari write the cell's white-space on every cell they copy. Not counted,
|
|
1138
|
+
* lines of YAML copied there pasted as a one-column table with the first
|
|
1139
|
+
* line as its header and the indentation gone.
|
|
1140
|
+
*
|
|
1141
|
+
* Only those count, and not inside a <pre> or a list item. Google Docs puts
|
|
1142
|
+
* "white-space:pre" on every list item it copies, and Chromium, Safari and
|
|
1143
|
+
* Docs wrap each tab in a <span class="Apple-tab-span"> styled the same
|
|
1144
|
+
* way; taken for a code editor's copy, any Docs copy with a list or a tab
|
|
1145
|
+
* lost its lists, links and formatting to its plain text -- bare lines.
|
|
1146
|
+
*/
|
|
1147
|
+
const isCodeEditorCopy: (body: HTMLElement) => boolean = (
|
|
1148
|
+
body: HTMLElement,
|
|
1149
|
+
): boolean => {
|
|
1150
|
+
return elementsOf(body, "div[style], td[style], th[style]").some(
|
|
1151
|
+
(element: HTMLElement): boolean => {
|
|
1152
|
+
return element.style.whiteSpace === "pre" && !element.closest("pre, li");
|
|
1153
|
+
},
|
|
1154
|
+
);
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
const parseInertly: (html: string) => HTMLElement | null = (
|
|
1158
|
+
html: string,
|
|
1159
|
+
): HTMLElement | null => {
|
|
1160
|
+
if (typeof DOMParser === "undefined") {
|
|
1161
|
+
return null;
|
|
1162
|
+
}
|
|
1163
|
+
return new DOMParser().parseFromString(html, "text/html").body;
|
|
1164
|
+
};
|
|
1165
|
+
|
|
1166
|
+
// The clipboard HTML parsed and cleaned, ready for the serializer.
|
|
1167
|
+
const cleanPastedHtml: (html: string) => HTMLElement | null = (
|
|
1168
|
+
html: string,
|
|
1169
|
+
): HTMLElement | null => {
|
|
1170
|
+
if (!html) {
|
|
1171
|
+
return null;
|
|
1172
|
+
}
|
|
1173
|
+
const body: HTMLElement | null = parseInertly(html);
|
|
1174
|
+
if (!body) {
|
|
1175
|
+
return null;
|
|
1176
|
+
}
|
|
1177
|
+
removeNonContent(body);
|
|
1178
|
+
rebuildWordListParagraphs(body);
|
|
1179
|
+
readStyledFormatting(body);
|
|
1180
|
+
restoreViewerMarkup(body);
|
|
1181
|
+
sanitizeLinksAndImages(body);
|
|
1182
|
+
repairLists(body);
|
|
1183
|
+
tidyInlineFormatting(body);
|
|
1184
|
+
collapseWhitespace(body);
|
|
1185
|
+
return body;
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
const hasRichContent: (body: HTMLElement) => boolean = (
|
|
1189
|
+
body: HTMLElement,
|
|
1190
|
+
): boolean => {
|
|
1191
|
+
return (
|
|
1192
|
+
body.querySelector(RICH_CONTENT_SELECTOR) !== null &&
|
|
1193
|
+
!isCodeEditorCopy(body)
|
|
1194
|
+
);
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1197
|
+
const hasText: (body: HTMLElement) => boolean = (
|
|
1198
|
+
body: HTMLElement,
|
|
1199
|
+
): boolean => {
|
|
1200
|
+
return RE_NOT_WHITESPACE.test(body.textContent || "");
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
/*
|
|
1204
|
+
* Whether clipboard HTML carries structure or formatting its plain text
|
|
1205
|
+
* loses -- lists, headings, links, emphasis, tables, code, images -- and so
|
|
1206
|
+
* is worth converting. A plain paragraph is not: its plain text says the
|
|
1207
|
+
* same, and is what the editor has always pasted.
|
|
1208
|
+
*/
|
|
1209
|
+
export const isRichClipboardHtml: (html: string) => boolean = (
|
|
1210
|
+
html: string,
|
|
1211
|
+
): boolean => {
|
|
1212
|
+
const body: HTMLElement | null = cleanPastedHtml(html);
|
|
1213
|
+
return body !== null && hasRichContent(body);
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
// Clipboard HTML as the markdown the editor writes.
|
|
1217
|
+
export const pastedHtmlToMarkdown: (html: string) => string = (
|
|
1218
|
+
html: string,
|
|
1219
|
+
): string => {
|
|
1220
|
+
const body: HTMLElement | null = cleanPastedHtml(html);
|
|
1221
|
+
return body ? domToMarkdown(body) : "";
|
|
1222
|
+
};
|
|
1223
|
+
|
|
1224
|
+
const readClipboard: (clipboard: PastedClipboard, format: string) => string = (
|
|
1225
|
+
clipboard: PastedClipboard,
|
|
1226
|
+
format: string,
|
|
1227
|
+
): string => {
|
|
1228
|
+
try {
|
|
1229
|
+
return clipboard.getData(format) || "";
|
|
1230
|
+
} catch {
|
|
1231
|
+
return "";
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
// Whether a DataTransfer's `types` (an array, or a DOMStringList in older browsers) lists `format`.
|
|
1236
|
+
const listsType: (
|
|
1237
|
+
types: ReadonlyArray<string> | undefined,
|
|
1238
|
+
format: string,
|
|
1239
|
+
) => boolean = (
|
|
1240
|
+
types: ReadonlyArray<string> | undefined,
|
|
1241
|
+
format: string,
|
|
1242
|
+
): boolean => {
|
|
1243
|
+
if (!types) {
|
|
1244
|
+
return false;
|
|
1245
|
+
}
|
|
1246
|
+
for (let i: number = 0; i < types.length; i++) {
|
|
1247
|
+
if (types[i] === format) {
|
|
1248
|
+
return true;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
return false;
|
|
1252
|
+
};
|
|
1253
|
+
|
|
1254
|
+
const RE_STARTS_WITH_SPACE: RegExp = /^[ \t]/;
|
|
1255
|
+
const RE_ENDS_WITH_SPACE: RegExp = /[ \t]$/;
|
|
1256
|
+
|
|
1257
|
+
/*
|
|
1258
|
+
* A few words copied out of a line ("very " with its space) are pasted into
|
|
1259
|
+
* the middle of another, where the space between them and the next word
|
|
1260
|
+
* matters -- but as HTML the space sits at the edge of the document, where
|
|
1261
|
+
* it is trimmed like any block's. When the converted text is a single line,
|
|
1262
|
+
* the spaces at the plain text's edges are put back.
|
|
1263
|
+
*/
|
|
1264
|
+
const withEdgeSpacesOf: (plain: string, markdown: string) => string = (
|
|
1265
|
+
plain: string,
|
|
1266
|
+
markdown: string,
|
|
1267
|
+
): string => {
|
|
1268
|
+
if (!markdown || markdown.includes("\n")) {
|
|
1269
|
+
return markdown;
|
|
1270
|
+
}
|
|
1271
|
+
const leading: string = RE_STARTS_WITH_SPACE.test(plain) ? " " : "";
|
|
1272
|
+
const trailing: string = RE_ENDS_WITH_SPACE.test(plain) ? " " : "";
|
|
1273
|
+
return `${leading}${markdown}${trailing}`;
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
/*
|
|
1277
|
+
* The markdown to paste, or null to leave the paste to the caller -- to
|
|
1278
|
+
* upload the image files on the clipboard, or to let the browser do what it
|
|
1279
|
+
* does natively.
|
|
1280
|
+
*
|
|
1281
|
+
* Rich HTML with text in it wins, even over image files: Word and Excel put
|
|
1282
|
+
* a picture of the copied text on the clipboard beside the text itself.
|
|
1283
|
+
* HTML that is nothing but images ("Copy image" in a browser) gives way to
|
|
1284
|
+
* the files, since an upload beats a link to someone else's server; so does
|
|
1285
|
+
* plain text, which beside a file is its name (a file copied in Finder).
|
|
1286
|
+
* Otherwise the plain text is used, with other apps' bullets made markdown.
|
|
1287
|
+
*/
|
|
1288
|
+
export const clipboardToMarkdown: (
|
|
1289
|
+
clipboard: PastedClipboard,
|
|
1290
|
+
options?: ClipboardToMarkdownOptions,
|
|
1291
|
+
) => string | null = (
|
|
1292
|
+
clipboard: PastedClipboard,
|
|
1293
|
+
options?: ClipboardToMarkdownOptions,
|
|
1294
|
+
): string | null => {
|
|
1295
|
+
const preferFiles: boolean =
|
|
1296
|
+
options?.hasImageFiles ?? listsType(clipboard.types, "Files");
|
|
1297
|
+
// Line breaks as a textarea holds them, so a caller can compare the two.
|
|
1298
|
+
const plain: string = readClipboard(clipboard, "text/plain").replace(
|
|
1299
|
+
RE_LINE_BREAKS,
|
|
1300
|
+
"\n",
|
|
1301
|
+
);
|
|
1302
|
+
|
|
1303
|
+
const html: string = readClipboard(clipboard, "text/html");
|
|
1304
|
+
const body: HTMLElement | null = cleanPastedHtml(html);
|
|
1305
|
+
if (body && hasRichContent(body)) {
|
|
1306
|
+
const markdown: string = withEdgeSpacesOf(plain, domToMarkdown(body));
|
|
1307
|
+
if (hasText(body)) {
|
|
1308
|
+
return markdown;
|
|
1309
|
+
}
|
|
1310
|
+
if (!preferFiles && markdown) {
|
|
1311
|
+
return markdown;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
if (preferFiles) {
|
|
1316
|
+
return null;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
if (plain) {
|
|
1320
|
+
return normalizePlainTextListMarkers(plain);
|
|
1321
|
+
}
|
|
1322
|
+
if (body && hasText(body)) {
|
|
1323
|
+
return domToMarkdown(body);
|
|
1324
|
+
}
|
|
1325
|
+
return null;
|
|
1326
|
+
};
|