@oneuptime/common 14.0.10 → 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/CephCluster.ts +12 -0
- package/Models/DatabaseModels/CloudResource.ts +12 -0
- package/Models/DatabaseModels/DatabaseServer.ts +12 -0
- package/Models/DatabaseModels/DockerHost.ts +12 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +12 -0
- 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 +12 -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 +14 -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 +12 -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 +12 -0
- package/Models/DatabaseModels/RumApplication.ts +12 -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 +12 -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/IncidentFormAPI.ts +376 -0
- package/Server/API/ProjectOIDC.ts +16 -25
- package/Server/API/ProjectSSO.ts +16 -24
- 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/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 +8 -0
- package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
- package/Server/Middleware/UserAuthorization.ts +16 -38
- package/Server/Services/AIService.ts +10 -13
- 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/OpenTelemetryIngestService.ts +37 -4
- package/Server/Services/ProjectService.ts +0 -59
- package/Server/Services/StatusPagePrivateUserService.ts +1 -4
- package/Server/Services/StatusPageService.ts +1 -51
- package/Server/Services/TeamComplianceSettingService.ts +163 -42
- package/Server/Services/UserNotificationRuleService.ts +8 -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 +7 -1
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +34 -14
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +69 -24
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +9 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +53 -10
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +27 -10
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +27 -10
- 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/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/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/Incident.ts +3 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +3 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +10 -1
- 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 +174 -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 +5 -0
- 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/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/ResourceAiAgentAttentionServerParity.test.ts +555 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +298 -9
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +453 -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/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 +28 -9
- package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
- package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -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/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/{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/AddIncidentFormsMigration.test.ts +438 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
- package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
- package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
- 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/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/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/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
- 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/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 +266 -25
- 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/RemediationExecutionRunner.test.ts +14 -25
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +297 -15
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +10 -6
- 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/EditionEnforcement.test.ts +107 -147
- 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/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/Types/AI/AIAgentRunLimits.test.ts +255 -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/ResourceAiAgent/ResourceAiAccess.test.ts +5 -3
- 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/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -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/Types/AI/AIAgentRunLimits.ts +146 -0
- 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/Permission.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +10 -4
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- package/Types/Rules/RuleRun.ts +4 -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/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/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/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/CephCluster.js +12 -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 +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +12 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.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 +12 -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 +14 -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 +12 -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 +12 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
- package/build/dist/Models/DatabaseModels/RumApplication.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 +12 -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/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/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/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 +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.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/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/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/OpenTelemetryIngestService.js +25 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.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/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/UserNotificationRuleService.js +8 -1
- package/build/dist/Server/Services/UserNotificationRuleService.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 +7 -2
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +29 -14
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +38 -14
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +2 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +40 -10
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +19 -7
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +19 -7
- 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/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/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/Incident.js +3 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +3 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +10 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
- 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/Permission.js +274 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +10 -4
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -1
- 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/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/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/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/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,988 @@
|
|
|
1
|
+
import { escapeMarkdownInline } from "./MarkdownEscape";
|
|
2
|
+
import { Lexer } from "marked";
|
|
3
|
+
/*
|
|
4
|
+
* MARKDOWN WRITTEN BY SOMEBODY OUTSIDE - an incident form's reporter, who
|
|
5
|
+
* needs no account, only the form's link - made safe to store as an
|
|
6
|
+
* incident's own text.
|
|
7
|
+
*
|
|
8
|
+
* Nobody reads such text over before it is posted: the incident's title and
|
|
9
|
+
* description go straight into its "Incident Created" feed item, which is
|
|
10
|
+
* posted to the project's Slack and Microsoft Teams channels, and the
|
|
11
|
+
* description and Markdown custom field answers are rendered for every
|
|
12
|
+
* responder who opens the incident (the dashboard renders incident text
|
|
13
|
+
* without the viewer's safe mode) and in the owners' and on-call emails.
|
|
14
|
+
* Three things in it act on their own there, before anybody decides to
|
|
15
|
+
* click anything:
|
|
16
|
+
*
|
|
17
|
+
* - CHAT CONTROL SEQUENCES. Slack reads <!channel>, <!here>, <!everyone>,
|
|
18
|
+
* <!subteam^ID>, <@U123> and <#C123> in a bot's message as mentions, so
|
|
19
|
+
* a stranger could make OneUptime's bot notify a whole channel.
|
|
20
|
+
* neutralizeChatControlSequences puts an invisible word joiner (U+2060)
|
|
21
|
+
* between the "<" and the "!", "@" or "#": the text reads as typed, but
|
|
22
|
+
* is no longer a sequence Slack (or slackify, which then escapes the
|
|
23
|
+
* lone "<") recognises. It is applied everywhere in the text, code
|
|
24
|
+
* included: slackify passes code through untouched, so a mention inside
|
|
25
|
+
* a code span would reach Slack as it is. Only what Slack acts on is
|
|
26
|
+
* broken - "<!" and a word, "<@" or "<#" and an id - so an HTML comment
|
|
27
|
+
* (<!--), CDATA, a <!DOCTYPE html> or a PowerShell "<# ... #>" pasted
|
|
28
|
+
* into a report is stored exactly as typed.
|
|
29
|
+
*
|
|
30
|
+
* - IMAGES.  is fetched from the
|
|
31
|
+
* outsider's server by every responder's browser and mail client that
|
|
32
|
+
* shows the incident: a zero-click beacon of who looked, when, and from
|
|
33
|
+
* where. Each image becomes a plain link to the same address, so nothing
|
|
34
|
+
* is fetched until somebody chooses to follow it: the "!" is escaped,
|
|
35
|
+
* which is the one change that turns an image into a link without
|
|
36
|
+
* rewriting anything else, and an image with no alt text is given its
|
|
37
|
+
* address as the link's text, so the link is not an empty, invisible
|
|
38
|
+
* one. Reference-style images (![alt][ref], ![ref]) are covered: they
|
|
39
|
+
* start with the same "![".
|
|
40
|
+
*
|
|
41
|
+
* - MERMAID DIAGRAMS. A ```mermaid fence is rendered as a diagram, which
|
|
42
|
+
* runs mermaid's renderer (and can load images) in the responder's
|
|
43
|
+
* browser. Its language becomes "text", so it shows as the code the
|
|
44
|
+
* reporter typed.
|
|
45
|
+
*
|
|
46
|
+
* WHAT MAKES IT SAFE DOES NOT DEPEND ON HOW ANY ONE RENDERER READS THE TEXT.
|
|
47
|
+
* The same text is read by marked (the emails), by remark with its GitHub
|
|
48
|
+
* extensions, footnotes included (the dashboard), and by slackify, and they
|
|
49
|
+
* do not agree on everything. "[a]: https://a.example" followed by an
|
|
50
|
+
* indented "" line, or a footnote's indented paragraph, is an
|
|
51
|
+
* indented code block to marked and a paragraph - with a live image - to
|
|
52
|
+
* the dashboard; a footnote definition is no more than a link definition to
|
|
53
|
+
* marked. So the guarantee is made on the characters, where every renderer
|
|
54
|
+
* agrees:
|
|
55
|
+
*
|
|
56
|
+
* - Nothing is an image unless it starts with " - is broken:
|
|
64
|
+
* a backslash goes before the "!", or an invisible word joiner between
|
|
65
|
+
* the "!" and the "[". Either way no renderer finds an image there.
|
|
66
|
+
* The one exception is fenced code that every renderer reads as such
|
|
67
|
+
* (see findTrustedCode): no renderer finds an image in it, so it is
|
|
68
|
+
* left byte for byte.
|
|
69
|
+
* - The dashboard draws a diagram only for a fenced code block whose
|
|
70
|
+
* language is "mermaid" - and CommonMark decodes character references
|
|
71
|
+
* in a fence's info string, so ```mermaid is one too. After the
|
|
72
|
+
* first fence run of every line, every "mermaid" in the info string as
|
|
73
|
+
* the dashboard decodes it is broken: a real fence's language is
|
|
74
|
+
* renamed "text", and any other "mermaid" gets a word joiner before it,
|
|
75
|
+
* so no language reads "mermaid" and no class reads "language-mermaid".
|
|
76
|
+
*
|
|
77
|
+
* A real Markdown lexer (marked) only decides which of those the text gets,
|
|
78
|
+
* so that it still reads as typed: an image it finds gets the backslash (and
|
|
79
|
+
* its address as link text when it had no alt text); a "![" inside what it
|
|
80
|
+
* reads as a code span, a code block or raw HTML - where a backslash would
|
|
81
|
+
* show - gets the invisible joiner; any other "![" gets the backslash, which
|
|
82
|
+
* every renderer turns back into the "!" as typed, in a link's address too.
|
|
83
|
+
* A mermaid fence it finds is renamed; any other "mermaid" after a fence run
|
|
84
|
+
* gets the joiner. The joiner cannot be seen, but it is a character: a copy
|
|
85
|
+
* of the text keeps it. Code with no image syntax that could be completed -
|
|
86
|
+
* "Wow![sic]", Rust's vec![1, 2] in a paragraph of its own, anything inside
|
|
87
|
+
* a fenced block every renderer reads as code - is left byte for byte.
|
|
88
|
+
*
|
|
89
|
+
* The lexer does not say where in the text a token came from, so every place
|
|
90
|
+
* to change is first tagged with a numbered marker the lexer passes through
|
|
91
|
+
* untouched (private use characters, inert to Markdown); a marker that ends
|
|
92
|
+
* up right before an image token, inside a code span, a code block or HTML,
|
|
93
|
+
* or at the start of a code block's language, says what that place is.
|
|
94
|
+
*
|
|
95
|
+
* THE LEXER ONLY READS SHORT TEXT. marked takes time that grows with the
|
|
96
|
+
* square of the text on some shapes - emphasis next to image syntax, a long
|
|
97
|
+
* run of unclosed emphasis - and a description may be 20000 characters of
|
|
98
|
+
* them: seconds of one process's CPU, from anyone holding a form's link.
|
|
99
|
+
* Everything else here is linear, and the lexer is used only for a text of
|
|
100
|
+
* at most LEXED_TEXT_MAX_LENGTH characters. A longer one, or one the lexer
|
|
101
|
+
* fails on, is decided without it (findWithoutLexing): a "![" on an
|
|
102
|
+
* indented line or inside a code span of its own line gets the joiner, any
|
|
103
|
+
* other the backslash - and an image with no alt text still gets its
|
|
104
|
+
* address as link text when its address can be read on its line - while
|
|
105
|
+
* only a fence every renderer reads as one is renamed "text"; every other
|
|
106
|
+
* "mermaid" gets the joiner. Just as safe, and a little less tidy where a
|
|
107
|
+
* backslash lands in code.
|
|
108
|
+
*
|
|
109
|
+
* Links are left alone: a reporter linking the page that is broken is the
|
|
110
|
+
* point of a report, and a link does nothing until somebody clicks it.
|
|
111
|
+
*
|
|
112
|
+
* Pure, with no database or React imports.
|
|
113
|
+
*/
|
|
114
|
+
const WORD_JOINER = "\u2060";
|
|
115
|
+
/*
|
|
116
|
+
* Where a chat control sequence starts, as Slack reads one: "<!" and a word
|
|
117
|
+
* (<!here>, <!channel>, <!everyone>, <!subteam^ID>, <!date^...>), "<@" and
|
|
118
|
+
* a user id, "<#" and a channel id. Not an HTML comment (<!--), CDATA
|
|
119
|
+
* (<![CDATA[), or a document type or other SGML declaration (<!DOCTYPE
|
|
120
|
+
* html>, <!ENTITY ...>): none of them is a Slack sequence, and a reporter
|
|
121
|
+
* pastes them in HTML. Nor a PowerShell block comment, "<#" and a space.
|
|
122
|
+
*/
|
|
123
|
+
const CHAT_CONTROL_SEQUENCE_START_PATTERN = /<(?=[@#][a-z0-9]|!(?![-[]|(?:doctype|entity|element|attlist|notation)(?![a-z0-9])))/gi;
|
|
124
|
+
/**
|
|
125
|
+
* The text as typed, with every "<!", "<@" and "<#" that Slack could read
|
|
126
|
+
* as a mention broken by an invisible word joiner, so no chat tool reads a
|
|
127
|
+
* mention in it. Idempotent: a joiner already there is not doubled.
|
|
128
|
+
*/
|
|
129
|
+
export const neutralizeChatControlSequences = (value) => {
|
|
130
|
+
if (value === undefined || value === null) {
|
|
131
|
+
return "";
|
|
132
|
+
}
|
|
133
|
+
return String(value).replace(CHAT_CONTROL_SEQUENCE_START_PATTERN, `<${WORD_JOINER}`);
|
|
134
|
+
};
|
|
135
|
+
/*
|
|
136
|
+
* Private use characters, which nobody types and Markdown treats as plain
|
|
137
|
+
* text: MARKER_START, a number and MARKER_END tag one place in the probe.
|
|
138
|
+
* A marker only steers which change a place gets, never whether it gets
|
|
139
|
+
* one, so a reporter who does type these characters decides nothing.
|
|
140
|
+
*/
|
|
141
|
+
const MARKER_START = "\uE000";
|
|
142
|
+
const MARKER_END = "\uE001";
|
|
143
|
+
const MARKER_PATTERN = /\uE000(\d+)\uE001/g;
|
|
144
|
+
const MARKER_AT_END_PATTERN = /\uE000(\d+)\uE001$/;
|
|
145
|
+
const MARKER_AT_START_PATTERN = /^\uE000(\d+)\uE001/;
|
|
146
|
+
/*
|
|
147
|
+
* The longest text the lexer is given (see "THE LEXER ONLY READS SHORT
|
|
148
|
+
* TEXT" above). The worst shapes found take about 20 milliseconds at this
|
|
149
|
+
* length, four times that at twice it, and seconds at the 20000 characters
|
|
150
|
+
* a description may have.
|
|
151
|
+
*/
|
|
152
|
+
export const LEXED_TEXT_MAX_LENGTH = 1000;
|
|
153
|
+
/*
|
|
154
|
+
* A fence run: three or more backticks or tildes. The first one in a line
|
|
155
|
+
* is where a fenced code block's info string could begin, whatever comes
|
|
156
|
+
* before it - a block quote or a list item's marker, indentation, or text
|
|
157
|
+
* no renderer reads as a fence at all (which is only broken for nothing).
|
|
158
|
+
*/
|
|
159
|
+
const FENCE_RUN_PATTERN = /`{3,}|~{3,}/;
|
|
160
|
+
// A fence run at the very start of a line, and the info string after it.
|
|
161
|
+
const OPENING_FENCE_PATTERN = /^(?:(`{3,})[^`]*|(~{3,}).*)$/;
|
|
162
|
+
// The spaces or tabs between a fence run and its info string.
|
|
163
|
+
const FENCE_INFO_INDENT_PATTERN = /^[ \t]*/;
|
|
164
|
+
/*
|
|
165
|
+
* Raw HTML that starts a block which blank lines do not end (CommonMark's
|
|
166
|
+
* HTML blocks 1 to 5: <script>, <pre>, <style> and <textarea>, comments,
|
|
167
|
+
* processing instructions, declarations and CDATA) - anywhere in a line, to
|
|
168
|
+
* be sure of catching every one.
|
|
169
|
+
*/
|
|
170
|
+
const RAW_HTML_BLOCK_START_PATTERN = /<(?:[!?]|script|pre|style|textarea)/i;
|
|
171
|
+
const BLANK_LINE_TEXT_PATTERN = /^[ \t]*$/;
|
|
172
|
+
// What marked allows after a closing fence's run: backticks, tildes, spaces.
|
|
173
|
+
const MARKED_CLOSING_FENCE_REST_PATTERN = /^[~`]* *$/;
|
|
174
|
+
const MERMAID = "mermaid";
|
|
175
|
+
const DEMOTED_LANGUAGE = "text";
|
|
176
|
+
/*
|
|
177
|
+
* A numeric character reference - decimal or hexadecimal - as CommonMark
|
|
178
|
+
* decodes one in a fence's info string: ```mermaid is a mermaid fence
|
|
179
|
+
* to the dashboard. More digits are allowed than CommonMark allows, so a
|
|
180
|
+
* reference no renderer decodes can only be broken for nothing. Nothing
|
|
181
|
+
* else needs decoding to find every "mermaid": a named reference never
|
|
182
|
+
* stands for a letter of the English alphabet, and a backslash escape only
|
|
183
|
+
* ever stands for punctuation (reading "\m" as a reference anyway only
|
|
184
|
+
* breaks what was never a diagram).
|
|
185
|
+
*/
|
|
186
|
+
const NUMERIC_CHARACTER_REFERENCE_PATTERN = /^&#(?:[xX]([0-9a-fA-F]{1,32})|([0-9]{1,32}));/;
|
|
187
|
+
const NUMERIC_CHARACTER_REFERENCE_MAX_LENGTH = 36;
|
|
188
|
+
const REPLACEMENT_CHARACTER = "\uFFFD";
|
|
189
|
+
/*
|
|
190
|
+
* What can complete an image after its "/g;
|
|
198
|
+
/*
|
|
199
|
+
* What may come before a link reference definition's "[" on its line:
|
|
200
|
+
* indentation; the markers of block quotes and list items; a task list
|
|
201
|
+
* item's box, which marked takes off "- [ ] [a]: https://..." before it
|
|
202
|
+
* reads the rest as the item's own blocks; footnote definitions (a
|
|
203
|
+
* footnote's content, "[^1]: [a]: https://...", may itself start with
|
|
204
|
+
* one); and a byte order mark, which the dashboard's parser skips at the
|
|
205
|
+
* start of the text. A "]:" anywhere else - a Python slice, a TypeScript
|
|
206
|
+
* index signature after code, "sshd[1]:" in a log - defines nothing.
|
|
207
|
+
*/
|
|
208
|
+
const REFERENCE_DEFINITION_PREFIX_PATTERN = /^(?:[ \t>*+\-.)0-9\uFEFF]|\[[^\]\n]\][ \t]*|\[\^[^\]\n]*\]:)*/;
|
|
209
|
+
// An image link's text, when the image had no alt text: its address.
|
|
210
|
+
const IMAGE_LINK_LABEL_MAX_LENGTH = 80;
|
|
211
|
+
const IMAGE_LINK_FALLBACK_LABEL = "image";
|
|
212
|
+
/*
|
|
213
|
+
* How far past "/g;
|
|
220
|
+
// A line that could be an indented code block's.
|
|
221
|
+
const INDENTED_LINE_PATTERN = /^(?: {4}|\t)/;
|
|
222
|
+
const BACKTICK_RUN_PATTERN = /`+/g;
|
|
223
|
+
const IMAGE_OPENER_PATTERN = /!(?=\[)/g;
|
|
224
|
+
// A "]" that a link, a reference or a link definition goes on from.
|
|
225
|
+
const LINK_TAIL_OPENER_PATTERN = /\](?=[([:])/g;
|
|
226
|
+
var CandidateKind;
|
|
227
|
+
(function (CandidateKind) {
|
|
228
|
+
CandidateKind["Image"] = "image";
|
|
229
|
+
CandidateKind["Mermaid"] = "mermaid";
|
|
230
|
+
})(CandidateKind || (CandidateKind = {}));
|
|
231
|
+
const splitLines = (source) => {
|
|
232
|
+
const lines = [];
|
|
233
|
+
let start = 0;
|
|
234
|
+
for (;;) {
|
|
235
|
+
const newline = source.indexOf("\n", start);
|
|
236
|
+
if (newline === -1) {
|
|
237
|
+
lines.push({ start: start, end: source.length });
|
|
238
|
+
return lines;
|
|
239
|
+
}
|
|
240
|
+
lines.push({ start: start, end: newline });
|
|
241
|
+
start = newline + 1;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
// Whether an odd number of backslashes comes right before this character.
|
|
245
|
+
const isEscaped = (source, position) => {
|
|
246
|
+
let backslashes = 0;
|
|
247
|
+
while (position - backslashes - 1 >= 0 &&
|
|
248
|
+
source[position - backslashes - 1] === "\\") {
|
|
249
|
+
backslashes++;
|
|
250
|
+
}
|
|
251
|
+
return backslashes % 2 !== 0;
|
|
252
|
+
};
|
|
253
|
+
const isInTrustedCode = (code, position) => {
|
|
254
|
+
let low = 0;
|
|
255
|
+
let high = code.ranges.length - 1;
|
|
256
|
+
while (low <= high) {
|
|
257
|
+
const middle = (low + high) >> 1;
|
|
258
|
+
const range = code.ranges[middle];
|
|
259
|
+
if (position < range[0]) {
|
|
260
|
+
high = middle - 1;
|
|
261
|
+
}
|
|
262
|
+
else if (position >= range[1]) {
|
|
263
|
+
low = middle + 1;
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return false;
|
|
270
|
+
};
|
|
271
|
+
/*
|
|
272
|
+
* Whether a line closes a fence opened with this run, as CommonMark reads it
|
|
273
|
+
* (up to three spaces, at least as long a run of the same character, then
|
|
274
|
+
* only spaces or tabs) and as marked does (up to three spaces, the same run,
|
|
275
|
+
* then any backticks or tildes and spaces).
|
|
276
|
+
*/
|
|
277
|
+
const readClosingFence = (line, run) => {
|
|
278
|
+
let indent = 0;
|
|
279
|
+
while (indent < line.length && line[indent] === " ") {
|
|
280
|
+
indent++;
|
|
281
|
+
}
|
|
282
|
+
if (indent > 3) {
|
|
283
|
+
return { byCommonMark: false, byMarked: false };
|
|
284
|
+
}
|
|
285
|
+
let end = indent;
|
|
286
|
+
while (end < line.length && line[end] === run[0]) {
|
|
287
|
+
end++;
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
byCommonMark: end - indent >= run.length &&
|
|
291
|
+
BLANK_LINE_TEXT_PATTERN.test(line.slice(end)),
|
|
292
|
+
byMarked: line.startsWith(run, indent) &&
|
|
293
|
+
MARKED_CLOSING_FENCE_REST_PATTERN.test(line.slice(indent + run.length)),
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
/*
|
|
297
|
+
* The fenced code blocks that every renderer here reads as fenced code, and
|
|
298
|
+
* so as nothing but code: no image and no diagram can be in them.
|
|
299
|
+
*
|
|
300
|
+
* Trusted only as far as this can be sure of: a fence opened at the very
|
|
301
|
+
* start of a line (no indentation, no container) that follows a blank line,
|
|
302
|
+
* the start of the text or the close of another such fence. Nothing else
|
|
303
|
+
* can hold that line - a block quote, a list item or a footnote needs its
|
|
304
|
+
* marker or its indentation on it, and an HTML block of the kinds a blank
|
|
305
|
+
* line ends is over - except a fence or an HTML block that blank lines do
|
|
306
|
+
* not end. So trust stops for good at the first line outside such a fence
|
|
307
|
+
* that holds a fence run anywhere, or the start of such an HTML block
|
|
308
|
+
* anywhere, and at the first line that closes a fence for one renderer but
|
|
309
|
+
* not the other (marked closes "```" with "```~", CommonMark with
|
|
310
|
+
* "```\t"): after it, the renderers could pair the fences that follow
|
|
311
|
+
* differently.
|
|
312
|
+
*/
|
|
313
|
+
const findTrustedCode = (source, lines) => {
|
|
314
|
+
const code = {
|
|
315
|
+
ranges: [],
|
|
316
|
+
openingInfoStarts: new Set(),
|
|
317
|
+
};
|
|
318
|
+
let isTrusting = true;
|
|
319
|
+
// The line before was blank, closed a trusted fence, or there was none.
|
|
320
|
+
let mayOpen = true;
|
|
321
|
+
// The run the trusted fence the scan is in was opened with.
|
|
322
|
+
let openRun = null;
|
|
323
|
+
for (const line of lines) {
|
|
324
|
+
const text = source.slice(line.start, line.end);
|
|
325
|
+
if (openRun !== null) {
|
|
326
|
+
const closing = readClosingFence(text, openRun);
|
|
327
|
+
if (closing.byCommonMark || closing.byMarked) {
|
|
328
|
+
openRun = null;
|
|
329
|
+
mayOpen = true;
|
|
330
|
+
isTrusting = closing.byCommonMark && closing.byMarked;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const previous = code.ranges[code.ranges.length - 1];
|
|
334
|
+
if (previous && previous[1] + 1 === line.start) {
|
|
335
|
+
previous[1] = line.end;
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
code.ranges.push([line.start, line.end]);
|
|
339
|
+
}
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
const opening = isTrusting && mayOpen ? OPENING_FENCE_PATTERN.exec(text) : null;
|
|
343
|
+
if (opening) {
|
|
344
|
+
openRun = (opening[1] || opening[2]);
|
|
345
|
+
code.openingInfoStarts.add(line.start +
|
|
346
|
+
openRun.length +
|
|
347
|
+
FENCE_INFO_INDENT_PATTERN.exec(text.slice(openRun.length))[0].length);
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (FENCE_RUN_PATTERN.test(text) ||
|
|
351
|
+
RAW_HTML_BLOCK_START_PATTERN.test(text)) {
|
|
352
|
+
isTrusting = false;
|
|
353
|
+
}
|
|
354
|
+
mayOpen = BLANK_LINE_TEXT_PATTERN.test(text);
|
|
355
|
+
}
|
|
356
|
+
return code;
|
|
357
|
+
};
|
|
358
|
+
/*
|
|
359
|
+
* Whether any renderer could read a link reference definition in the text,
|
|
360
|
+
* which would complete any "![label]" in it however far away: a "[label]:"
|
|
361
|
+
* outside trusted code whose "[" has nothing but REFERENCE_DEFINITION_PREFIX
|
|
362
|
+
* before it on its line. Generous on purpose - it does not check what
|
|
363
|
+
* follows the colon, or that the line may start a block at all.
|
|
364
|
+
*/
|
|
365
|
+
const hasPossibleReferenceDefinition = (data) => {
|
|
366
|
+
const source = data.source;
|
|
367
|
+
/*
|
|
368
|
+
* The line the last "[" was on, and where what may come before a
|
|
369
|
+
* definition ends on it. Each "[" is after the one before (see below),
|
|
370
|
+
* so both only move forward.
|
|
371
|
+
*/
|
|
372
|
+
let lineIndex = 0;
|
|
373
|
+
let prefixEndLine = -1;
|
|
374
|
+
let prefixEnd = 0;
|
|
375
|
+
for (let colon = source.indexOf("]:"); colon !== -1; colon = source.indexOf("]:", colon + 1)) {
|
|
376
|
+
if (isEscaped(source, colon)) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
/*
|
|
380
|
+
* The label's "[": the nearest bracket before, as a label cannot hold
|
|
381
|
+
* one that is not escaped. Each search stops at the "]" of the one
|
|
382
|
+
* before it at the latest, so together they read the text once.
|
|
383
|
+
*/
|
|
384
|
+
let open = colon - 1;
|
|
385
|
+
while (open >= 0 &&
|
|
386
|
+
!((source[open] === "[" || source[open] === "]") &&
|
|
387
|
+
!isEscaped(source, open))) {
|
|
388
|
+
open--;
|
|
389
|
+
}
|
|
390
|
+
if (open < 0 ||
|
|
391
|
+
source[open] !== "[" ||
|
|
392
|
+
isInTrustedCode(data.code, open)) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
while (data.lines[lineIndex].end < open) {
|
|
396
|
+
lineIndex++;
|
|
397
|
+
}
|
|
398
|
+
if (prefixEndLine !== lineIndex) {
|
|
399
|
+
const line = data.lines[lineIndex];
|
|
400
|
+
prefixEnd =
|
|
401
|
+
line.start +
|
|
402
|
+
REFERENCE_DEFINITION_PREFIX_PATTERN.exec(source.slice(line.start, line.end))[0].length;
|
|
403
|
+
prefixEndLine = lineIndex;
|
|
404
|
+
}
|
|
405
|
+
if (open <= prefixEnd) {
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return false;
|
|
410
|
+
};
|
|
411
|
+
/*
|
|
412
|
+
* Where each "mermaid" in source[start, end) starts, read as the dashboard
|
|
413
|
+
* reads an info string - with numeric character references decoded, and
|
|
414
|
+
* any letter case. One right after a word joiner is already broken.
|
|
415
|
+
*/
|
|
416
|
+
const findMermaidWords = (source, start, end) => {
|
|
417
|
+
// The decoded characters, and where in the source each one starts.
|
|
418
|
+
const characters = [];
|
|
419
|
+
const starts = [];
|
|
420
|
+
let position = start;
|
|
421
|
+
while (position < end) {
|
|
422
|
+
const reference = source[position] === "&"
|
|
423
|
+
? NUMERIC_CHARACTER_REFERENCE_PATTERN.exec(source.slice(position, Math.min(end, position + NUMERIC_CHARACTER_REFERENCE_MAX_LENGTH)))
|
|
424
|
+
: null;
|
|
425
|
+
if (reference) {
|
|
426
|
+
const codePoint = reference[1]
|
|
427
|
+
? parseInt(reference[1], 16)
|
|
428
|
+
: parseInt(reference[2], 10);
|
|
429
|
+
characters.push(codePoint > 0 &&
|
|
430
|
+
codePoint <= 0x10ffff &&
|
|
431
|
+
!(codePoint >= 0xd800 && codePoint <= 0xdfff)
|
|
432
|
+
? String.fromCodePoint(codePoint)
|
|
433
|
+
: REPLACEMENT_CHARACTER);
|
|
434
|
+
starts.push(position);
|
|
435
|
+
position += reference[0].length;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
characters.push(source[position]);
|
|
439
|
+
starts.push(position);
|
|
440
|
+
position++;
|
|
441
|
+
}
|
|
442
|
+
const words = [];
|
|
443
|
+
for (let index = 0; index + MERMAID.length <= characters.length;) {
|
|
444
|
+
let length = 0;
|
|
445
|
+
while (length < MERMAID.length &&
|
|
446
|
+
characters[index + length].toLowerCase() === MERMAID[length]) {
|
|
447
|
+
length++;
|
|
448
|
+
}
|
|
449
|
+
if (length < MERMAID.length) {
|
|
450
|
+
index++;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (index === 0 || characters[index - 1] !== WORD_JOINER) {
|
|
454
|
+
words.push(starts[index]);
|
|
455
|
+
}
|
|
456
|
+
index += MERMAID.length;
|
|
457
|
+
}
|
|
458
|
+
return words;
|
|
459
|
+
};
|
|
460
|
+
/*
|
|
461
|
+
* Every info string with "mermaid" in it, as the dashboard decodes it: the
|
|
462
|
+
* rest of each line after its first fence run - wherever the run is, as no
|
|
463
|
+
* container before it is trusted to keep it from being a fence.
|
|
464
|
+
*/
|
|
465
|
+
const findDiagramInfoStrings = (source, lines) => {
|
|
466
|
+
const infoStrings = [];
|
|
467
|
+
for (const line of lines) {
|
|
468
|
+
const text = source.slice(line.start, line.end);
|
|
469
|
+
const run = FENCE_RUN_PATTERN.exec(text);
|
|
470
|
+
if (!run) {
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
const afterRun = run.index + run[0].length;
|
|
474
|
+
const start = line.start +
|
|
475
|
+
afterRun +
|
|
476
|
+
FENCE_INFO_INDENT_PATTERN.exec(text.slice(afterRun))[0].length;
|
|
477
|
+
const mermaidWords = findMermaidWords(source, start, line.end);
|
|
478
|
+
if (mermaidWords.length === 0) {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
let languageEnd = start;
|
|
482
|
+
while (languageEnd < line.end &&
|
|
483
|
+
source[languageEnd] !== " " &&
|
|
484
|
+
source[languageEnd] !== "\t") {
|
|
485
|
+
languageEnd++;
|
|
486
|
+
}
|
|
487
|
+
infoStrings.push({
|
|
488
|
+
start: start,
|
|
489
|
+
languageEnd: languageEnd,
|
|
490
|
+
mermaidWords: mermaidWords,
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
return infoStrings;
|
|
494
|
+
};
|
|
495
|
+
/*
|
|
496
|
+
* The options marked's own parse uses by default (GitHub flavoured, no
|
|
497
|
+
* line-break extension), given afresh each time: the lexer writes into the
|
|
498
|
+
* options object it is handed, and must not see what another caller set up
|
|
499
|
+
* with marked.use().
|
|
500
|
+
*/
|
|
501
|
+
const lex = (markdown) => {
|
|
502
|
+
return new Lexer({ gfm: true, breaks: false, pedantic: false }).lex(markdown);
|
|
503
|
+
};
|
|
504
|
+
const getChildTokens = (token) => {
|
|
505
|
+
if (token.type === "list") {
|
|
506
|
+
return token.items;
|
|
507
|
+
}
|
|
508
|
+
if (token.type === "table") {
|
|
509
|
+
const table = token;
|
|
510
|
+
const cells = [...table.header];
|
|
511
|
+
for (const row of table.rows) {
|
|
512
|
+
cells.push(...row);
|
|
513
|
+
}
|
|
514
|
+
return cells.flatMap((cell) => {
|
|
515
|
+
return cell.tokens || [];
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
const nested = token.tokens;
|
|
519
|
+
return Array.isArray(nested) ? nested : [];
|
|
520
|
+
};
|
|
521
|
+
// Every token, depth first, in the order its text appears.
|
|
522
|
+
const walkTokens = (tokens, visit) => {
|
|
523
|
+
for (const token of tokens) {
|
|
524
|
+
const children = getChildTokens(token);
|
|
525
|
+
visit(token, children.length === 0);
|
|
526
|
+
walkTokens(children, visit);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
// Where each match of a global pattern starts, in order.
|
|
530
|
+
const getMatchPositions = (source, pattern) => {
|
|
531
|
+
const positions = [];
|
|
532
|
+
for (const match of source.matchAll(pattern)) {
|
|
533
|
+
positions.push(match.index || 0);
|
|
534
|
+
}
|
|
535
|
+
return positions;
|
|
536
|
+
};
|
|
537
|
+
/*
|
|
538
|
+
* Every place to change, in order: each "![" that could open an image - its
|
|
539
|
+
* "!" not escaped (an even number of backslashes before it), not in trusted
|
|
540
|
+
* code, and something after it that could complete one (see
|
|
541
|
+
* IMAGE_COMPLETION_PATTERN) - and each info string with "mermaid" in it.
|
|
542
|
+
*/
|
|
543
|
+
const findCandidates = (data) => {
|
|
544
|
+
const source = data.source;
|
|
545
|
+
const candidates = [];
|
|
546
|
+
const mayHaveDefinition = hasPossibleReferenceDefinition(data);
|
|
547
|
+
const completions = getMatchPositions(source, IMAGE_COMPLETION_PATTERN);
|
|
548
|
+
const paragraphEnds = [
|
|
549
|
+
...getMatchPositions(source, BLANK_LINE_PATTERN),
|
|
550
|
+
source.length,
|
|
551
|
+
];
|
|
552
|
+
// Both only move forward, as the openers do.
|
|
553
|
+
let nextCompletion = 0;
|
|
554
|
+
let nextParagraphEnd = 0;
|
|
555
|
+
for (let position = source.indexOf("!["); position !== -1; position = source.indexOf("![", position + 1)) {
|
|
556
|
+
if (isEscaped(source, position) || isInTrustedCode(data.code, position)) {
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
while (nextCompletion < completions.length &&
|
|
560
|
+
completions[nextCompletion] <= position) {
|
|
561
|
+
nextCompletion++;
|
|
562
|
+
}
|
|
563
|
+
while (paragraphEnds[nextParagraphEnd] <= position) {
|
|
564
|
+
nextParagraphEnd++;
|
|
565
|
+
}
|
|
566
|
+
const isCompletable = mayHaveDefinition ||
|
|
567
|
+
(nextCompletion < completions.length &&
|
|
568
|
+
completions[nextCompletion] < paragraphEnds[nextParagraphEnd]);
|
|
569
|
+
if (isCompletable) {
|
|
570
|
+
candidates.push({ kind: CandidateKind.Image, position: position });
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
for (const info of findDiagramInfoStrings(source, data.lines)) {
|
|
574
|
+
candidates.push({
|
|
575
|
+
kind: CandidateKind.Mermaid,
|
|
576
|
+
position: info.start,
|
|
577
|
+
info: info,
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
/*
|
|
581
|
+
* A diagram candidate before an image one at the same place, so the
|
|
582
|
+
* lexer reads its marker first at the start of a code block's language.
|
|
583
|
+
*/
|
|
584
|
+
return candidates.sort((a, b) => {
|
|
585
|
+
return (a.position - b.position ||
|
|
586
|
+
Number(a.kind === CandidateKind.Image) -
|
|
587
|
+
Number(b.kind === CandidateKind.Image));
|
|
588
|
+
});
|
|
589
|
+
};
|
|
590
|
+
/*
|
|
591
|
+
* What the lexer makes of each candidate place: the text is lexed with
|
|
592
|
+
* every one of them tagged by its number.
|
|
593
|
+
*/
|
|
594
|
+
const findInProbe = (source, candidates) => {
|
|
595
|
+
const parts = [];
|
|
596
|
+
let cursor = 0;
|
|
597
|
+
candidates.forEach((candidate, index) => {
|
|
598
|
+
parts.push(source.slice(cursor, candidate.position), `${MARKER_START}${index}${MARKER_END}`);
|
|
599
|
+
cursor = candidate.position;
|
|
600
|
+
});
|
|
601
|
+
parts.push(source.slice(cursor));
|
|
602
|
+
const found = {
|
|
603
|
+
images: new Map(),
|
|
604
|
+
literal: new Set(),
|
|
605
|
+
diagrams: new Set(),
|
|
606
|
+
};
|
|
607
|
+
const markLiteral = (text) => {
|
|
608
|
+
for (const marker of (text || "").matchAll(MARKER_PATTERN)) {
|
|
609
|
+
found.literal.add(Number(marker[1]));
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
let previousLeafRaw = "";
|
|
613
|
+
walkTokens(lex(parts.join("")), (token, isLeaf) => {
|
|
614
|
+
if (token.type === "image") {
|
|
615
|
+
/*
|
|
616
|
+
* The marker sits right before the "!", so it ends the text the
|
|
617
|
+
* lexer read just before this image.
|
|
618
|
+
*/
|
|
619
|
+
const marker = MARKER_AT_END_PATTERN.exec(previousLeafRaw);
|
|
620
|
+
if (marker) {
|
|
621
|
+
found.images.set(Number(marker[1]), token.href);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
if (token.type === "code") {
|
|
625
|
+
const code = token;
|
|
626
|
+
const marker = MARKER_AT_START_PATTERN.exec((code.lang || "").trim());
|
|
627
|
+
if (marker) {
|
|
628
|
+
found.diagrams.add(Number(marker[1]));
|
|
629
|
+
}
|
|
630
|
+
// The block's content, not its info string.
|
|
631
|
+
markLiteral(code.text);
|
|
632
|
+
}
|
|
633
|
+
if (token.type === "codespan" || token.type === "html") {
|
|
634
|
+
markLiteral(token.raw);
|
|
635
|
+
}
|
|
636
|
+
if (isLeaf) {
|
|
637
|
+
previousLeafRaw = token.raw || "";
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
return found;
|
|
641
|
+
};
|
|
642
|
+
/*
|
|
643
|
+
* The code spans of one line, as [start, end) offsets: a backtick run
|
|
644
|
+
* opens one that the next run of the same length on the line closes, as
|
|
645
|
+
* CommonMark pairs them. (A span that goes on to another line is not seen.)
|
|
646
|
+
*/
|
|
647
|
+
const getLineCodeSpans = (source, line) => {
|
|
648
|
+
var _a;
|
|
649
|
+
const runs = Array.from(source.slice(line.start, line.end).matchAll(BACKTICK_RUN_PATTERN));
|
|
650
|
+
// For each run, the next run of the same length, found from the end.
|
|
651
|
+
const nextOfSameLength = [];
|
|
652
|
+
const lastByLength = new Map();
|
|
653
|
+
for (let index = runs.length - 1; index >= 0; index--) {
|
|
654
|
+
const length = runs[index][0].length;
|
|
655
|
+
nextOfSameLength[index] = (_a = lastByLength.get(length)) !== null && _a !== void 0 ? _a : -1;
|
|
656
|
+
lastByLength.set(length, index);
|
|
657
|
+
}
|
|
658
|
+
const spans = [];
|
|
659
|
+
for (let index = 0; index < runs.length;) {
|
|
660
|
+
const closer = nextOfSameLength[index];
|
|
661
|
+
if (closer === -1) {
|
|
662
|
+
index++;
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
spans.push([
|
|
666
|
+
line.start + (runs[index].index || 0),
|
|
667
|
+
line.start + (runs[closer].index || 0) + runs[closer][0].length,
|
|
668
|
+
]);
|
|
669
|
+
index = closer + 1;
|
|
670
|
+
}
|
|
671
|
+
return spans;
|
|
672
|
+
};
|
|
673
|
+
/*
|
|
674
|
+
* The address of an image whose ", then
|
|
676
|
+
* an optional title, then ")". Null when that cannot be read before limit -
|
|
677
|
+
* the image then simply gets no link text of its own.
|
|
678
|
+
*/
|
|
679
|
+
const readImageAddress = (source, start, limit) => {
|
|
680
|
+
let position = start;
|
|
681
|
+
const skipSpaces = () => {
|
|
682
|
+
while (position < limit &&
|
|
683
|
+
(source[position] === " " || source[position] === "\t")) {
|
|
684
|
+
position++;
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
// Where the character next occurs before limit, or -1.
|
|
688
|
+
const findBeforeLimit = (character, from) => {
|
|
689
|
+
for (let index = from; index < limit; index++) {
|
|
690
|
+
if (source[index] === character) {
|
|
691
|
+
return index;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return -1;
|
|
695
|
+
};
|
|
696
|
+
skipSpaces();
|
|
697
|
+
let address;
|
|
698
|
+
if (source[position] === "<") {
|
|
699
|
+
const close = findBeforeLimit(">", position + 1);
|
|
700
|
+
if (close === -1 || source.slice(position + 1, close).includes("<")) {
|
|
701
|
+
return null;
|
|
702
|
+
}
|
|
703
|
+
address = source.slice(position + 1, close);
|
|
704
|
+
position = close + 1;
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
const addressStart = position;
|
|
708
|
+
let depth = 0;
|
|
709
|
+
while (position < limit) {
|
|
710
|
+
const character = source[position];
|
|
711
|
+
if (character === " " || character === "\t") {
|
|
712
|
+
break;
|
|
713
|
+
}
|
|
714
|
+
if (character === "\\") {
|
|
715
|
+
position += 2;
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
718
|
+
if (character === "(") {
|
|
719
|
+
depth++;
|
|
720
|
+
}
|
|
721
|
+
else if (character === ")") {
|
|
722
|
+
if (depth === 0) {
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
depth--;
|
|
726
|
+
}
|
|
727
|
+
position++;
|
|
728
|
+
}
|
|
729
|
+
if (depth !== 0 || position > limit) {
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
address = source.slice(addressStart, position);
|
|
733
|
+
}
|
|
734
|
+
skipSpaces();
|
|
735
|
+
const opener = source[position];
|
|
736
|
+
if (opener === '"' || opener === "'" || opener === "(") {
|
|
737
|
+
const close = findBeforeLimit(opener === "(" ? ")" : opener, position + 1);
|
|
738
|
+
if (close === -1) {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
position = close + 1;
|
|
742
|
+
skipSpaces();
|
|
743
|
+
}
|
|
744
|
+
if (position >= limit || source[position] !== ")") {
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
return address.replace(ESCAPED_PUNCTUATION_PATTERN, "$1");
|
|
748
|
+
};
|
|
749
|
+
/*
|
|
750
|
+
* What each candidate place is taken to be when the lexer does not read the
|
|
751
|
+
* text (see "THE LEXER ONLY READS SHORT TEXT" above), in one pass: a ".
|
|
756
|
+
*/
|
|
757
|
+
const findWithoutLexing = (data) => {
|
|
758
|
+
const found = {
|
|
759
|
+
images: new Map(),
|
|
760
|
+
literal: new Set(),
|
|
761
|
+
diagrams: new Set(),
|
|
762
|
+
};
|
|
763
|
+
const images = [];
|
|
764
|
+
data.candidates.forEach((candidate, index) => {
|
|
765
|
+
if (candidate.kind === CandidateKind.Image) {
|
|
766
|
+
images.push(index);
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
/*
|
|
770
|
+
* The line of the last candidate, its code spans, and the first of them
|
|
771
|
+
* that does not end before that candidate: all only move forward, as the
|
|
772
|
+
* candidates do.
|
|
773
|
+
*/
|
|
774
|
+
let lineIndex = 0;
|
|
775
|
+
let spansOfLine = -1;
|
|
776
|
+
let spans = [];
|
|
777
|
+
let spanIndex = 0;
|
|
778
|
+
images.forEach((index, order) => {
|
|
779
|
+
const position = data.candidates[index].position;
|
|
780
|
+
while (data.lines[lineIndex].end < position) {
|
|
781
|
+
lineIndex++;
|
|
782
|
+
}
|
|
783
|
+
const line = data.lines[lineIndex];
|
|
784
|
+
if (spansOfLine !== lineIndex) {
|
|
785
|
+
spans = getLineCodeSpans(data.source, line);
|
|
786
|
+
spansOfLine = lineIndex;
|
|
787
|
+
spanIndex = 0;
|
|
788
|
+
}
|
|
789
|
+
while (spanIndex < spans.length && spans[spanIndex][1] <= position) {
|
|
790
|
+
spanIndex++;
|
|
791
|
+
}
|
|
792
|
+
const span = spans[spanIndex];
|
|
793
|
+
if (INDENTED_LINE_PATTERN.test(data.source.slice(line.start, line.end)) ||
|
|
794
|
+
(span && span[0] < position)) {
|
|
795
|
+
found.literal.add(index);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
if (!data.source.startsWith(") {
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
const next = order + 1 < images.length
|
|
802
|
+
? data.candidates[images[order + 1]]
|
|
803
|
+
: undefined;
|
|
804
|
+
const address = readImageAddress(data.source, position + 4, Math.min(line.end, next ? next.position : line.end, position + 4 + IMAGE_ADDRESS_SCAN_MAX_LENGTH));
|
|
805
|
+
if (address !== null) {
|
|
806
|
+
found.images.set(index, address);
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
return found;
|
|
810
|
+
};
|
|
811
|
+
/*
|
|
812
|
+
* The text of the link an image without alt text becomes: its address,
|
|
813
|
+
* shortened and escaped so it reads as typed, or a plain word when it has
|
|
814
|
+
* none.
|
|
815
|
+
*/
|
|
816
|
+
const getImageLinkLabel = (href) => {
|
|
817
|
+
const address = (href || "").replace(MARKER_PATTERN, "").trim();
|
|
818
|
+
if (!address) {
|
|
819
|
+
return IMAGE_LINK_FALLBACK_LABEL;
|
|
820
|
+
}
|
|
821
|
+
return escapeMarkdownInline(address.length > IMAGE_LINK_LABEL_MAX_LENGTH
|
|
822
|
+
? `${address.slice(0, IMAGE_LINK_LABEL_MAX_LENGTH)}...`
|
|
823
|
+
: address);
|
|
824
|
+
};
|
|
825
|
+
// What changes one candidate place into something that does nothing.
|
|
826
|
+
const getEdits = (data) => {
|
|
827
|
+
const position = data.candidate.position;
|
|
828
|
+
if (data.candidate.kind === CandidateKind.Mermaid) {
|
|
829
|
+
const info = data.candidate.info;
|
|
830
|
+
/*
|
|
831
|
+
* A fence the lexer found, or one every renderer reads as a fence, is
|
|
832
|
+
* given the language "text" when its language holds "mermaid"; every
|
|
833
|
+
* other "mermaid" is broken.
|
|
834
|
+
*/
|
|
835
|
+
const isRenamed = (data.found.diagrams.has(data.index) ||
|
|
836
|
+
data.code.openingInfoStarts.has(info.start)) &&
|
|
837
|
+
info.mermaidWords[0] < info.languageEnd;
|
|
838
|
+
const edits = isRenamed
|
|
839
|
+
? [
|
|
840
|
+
{
|
|
841
|
+
position: info.start,
|
|
842
|
+
deleteCount: info.languageEnd - info.start,
|
|
843
|
+
insert: DEMOTED_LANGUAGE,
|
|
844
|
+
},
|
|
845
|
+
]
|
|
846
|
+
: [];
|
|
847
|
+
for (const word of info.mermaidWords) {
|
|
848
|
+
if (!isRenamed || word >= info.languageEnd) {
|
|
849
|
+
edits.push({ position: word, deleteCount: 0, insert: WORD_JOINER });
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return edits;
|
|
853
|
+
}
|
|
854
|
+
const isImage = data.found.images.has(data.index);
|
|
855
|
+
// In code or HTML a backslash would show; the joiner cannot be seen.
|
|
856
|
+
if (!isImage && data.found.literal.has(data.index)) {
|
|
857
|
+
return [{ position: position + 1, deleteCount: 0, insert: WORD_JOINER }];
|
|
858
|
+
}
|
|
859
|
+
const edits = [
|
|
860
|
+
{ position: position, deleteCount: 0, insert: "\\" },
|
|
861
|
+
];
|
|
862
|
+
/*
|
|
863
|
+
* "![]" - an image with no alt text, whose link would have no text to
|
|
864
|
+
* see or click. Only for an image found, whose address is known.
|
|
865
|
+
*/
|
|
866
|
+
if (isImage && data.source.startsWith("![]", position)) {
|
|
867
|
+
edits.push({
|
|
868
|
+
position: position + 2,
|
|
869
|
+
deleteCount: 0,
|
|
870
|
+
insert: getImageLinkLabel(data.found.images.get(data.index)),
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
return edits;
|
|
874
|
+
};
|
|
875
|
+
/*
|
|
876
|
+
* The text with every edit made, in one pass from the start. An edit that
|
|
877
|
+
* falls inside text an earlier one replaced is dropped: that text is gone.
|
|
878
|
+
* At the same place a replacement comes first, and so wins.
|
|
879
|
+
*/
|
|
880
|
+
const applyEdits = (source, edits) => {
|
|
881
|
+
const ordered = [...edits].sort((a, b) => {
|
|
882
|
+
return a.position - b.position || b.deleteCount - a.deleteCount;
|
|
883
|
+
});
|
|
884
|
+
const parts = [];
|
|
885
|
+
let cursor = 0;
|
|
886
|
+
for (const edit of ordered) {
|
|
887
|
+
if (edit.position < cursor) {
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
parts.push(source.slice(cursor, edit.position), edit.insert);
|
|
891
|
+
cursor = edit.position + edit.deleteCount;
|
|
892
|
+
}
|
|
893
|
+
parts.push(source.slice(cursor));
|
|
894
|
+
return parts.join("");
|
|
895
|
+
};
|
|
896
|
+
/**
|
|
897
|
+
* The Markdown with every image turned into a link to the same address and
|
|
898
|
+
* every mermaid diagram into a plain code block, whatever renderer reads it
|
|
899
|
+
* (see above); everything else reads exactly as written. Text with neither
|
|
900
|
+
* comes back unchanged; otherwise its line endings come back as "\n".
|
|
901
|
+
* Linear in the text's length.
|
|
902
|
+
*/
|
|
903
|
+
export const neutralizeMarkdownImagesAndDiagrams = (markdown) => {
|
|
904
|
+
if (markdown === undefined || markdown === null) {
|
|
905
|
+
return "";
|
|
906
|
+
}
|
|
907
|
+
const original = String(markdown);
|
|
908
|
+
// As marked reads it, so a position here is a position in what it lexed.
|
|
909
|
+
const source = original.replace(/\r\n|\r/g, "\n");
|
|
910
|
+
const lines = splitLines(source);
|
|
911
|
+
const code = findTrustedCode(source, lines);
|
|
912
|
+
const candidates = findCandidates({
|
|
913
|
+
source: source,
|
|
914
|
+
lines: lines,
|
|
915
|
+
code: code,
|
|
916
|
+
});
|
|
917
|
+
// Nothing that could be an image or a diagram.
|
|
918
|
+
if (candidates.length === 0) {
|
|
919
|
+
return original;
|
|
920
|
+
}
|
|
921
|
+
let found = null;
|
|
922
|
+
if (source.length <= LEXED_TEXT_MAX_LENGTH) {
|
|
923
|
+
try {
|
|
924
|
+
found = findInProbe(source, candidates);
|
|
925
|
+
}
|
|
926
|
+
catch (_a) {
|
|
927
|
+
// Not read at all: decided as a longer text is.
|
|
928
|
+
found = null;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
if (!found) {
|
|
932
|
+
found = findWithoutLexing({
|
|
933
|
+
source: source,
|
|
934
|
+
lines: lines,
|
|
935
|
+
candidates: candidates,
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
const foundInText = found;
|
|
939
|
+
return applyEdits(source, candidates.flatMap((candidate, index) => {
|
|
940
|
+
return getEdits({
|
|
941
|
+
source: source,
|
|
942
|
+
candidate: candidate,
|
|
943
|
+
index: index,
|
|
944
|
+
found: foundInText,
|
|
945
|
+
code: code,
|
|
946
|
+
});
|
|
947
|
+
}));
|
|
948
|
+
};
|
|
949
|
+
/**
|
|
950
|
+
* Both of the above, for Markdown an outsider wrote: no image or diagram
|
|
951
|
+
* that acts on its own, and no chat mention.
|
|
952
|
+
*/
|
|
953
|
+
export const neutralizeUntrustedMarkdown = (markdown) => {
|
|
954
|
+
return neutralizeChatControlSequences(neutralizeMarkdownImagesAndDiagrams(markdown));
|
|
955
|
+
};
|
|
956
|
+
/**
|
|
957
|
+
* Plain text an outsider wrote that other code places into Markdown as it
|
|
958
|
+
* is - an incident's title, which episode titles, feed items, chat
|
|
959
|
+
* messages and note templates take up raw. Its chat control sequences are
|
|
960
|
+
* broken as above, and so, with the same invisible word joiner, is every
|
|
961
|
+
* "![", every "]" that a link or a link definition would go on from, and
|
|
962
|
+
* every "mermaid" after a fence run: wherever the text lands - even beside
|
|
963
|
+
* other Markdown - no renderer finds a mention, an image or a diagram in it,
|
|
964
|
+
* or a reference that completes one. It reads exactly as typed - in
|
|
965
|
+
* Markdown, and as plain text in an email subject or a text message.
|
|
966
|
+
* Idempotent.
|
|
967
|
+
*/
|
|
968
|
+
export const neutralizeUntrustedPlainText = (value) => {
|
|
969
|
+
if (value === undefined || value === null) {
|
|
970
|
+
return "";
|
|
971
|
+
}
|
|
972
|
+
/*
|
|
973
|
+
* Also "]" before "(", "[" or ":": joined to other Markdown - an episode
|
|
974
|
+
* template puts the title and the description side by side - a title
|
|
975
|
+
* could otherwise define the link reference an image in the description
|
|
976
|
+
* reads ("[a]: https://tracker.example/p.png"), or complete one opened
|
|
977
|
+
* there.
|
|
978
|
+
*/
|
|
979
|
+
const text = neutralizeChatControlSequences(value)
|
|
980
|
+
.replace(IMAGE_OPENER_PATTERN, `!${WORD_JOINER}`)
|
|
981
|
+
.replace(LINK_TAIL_OPENER_PATTERN, `]${WORD_JOINER}`);
|
|
982
|
+
return applyEdits(text, findDiagramInfoStrings(text, splitLines(text)).flatMap((info) => {
|
|
983
|
+
return info.mermaidWords.map((word) => {
|
|
984
|
+
return { position: word, deleteCount: 0, insert: WORD_JOINER };
|
|
985
|
+
});
|
|
986
|
+
}));
|
|
987
|
+
};
|
|
988
|
+
//# sourceMappingURL=UntrustedMarkdown.js.map
|