@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.
Files changed (837) hide show
  1. package/Models/DatabaseModels/AIConversation.ts +127 -1
  2. package/Models/DatabaseModels/CephCluster.ts +12 -0
  3. package/Models/DatabaseModels/CloudResource.ts +12 -0
  4. package/Models/DatabaseModels/DatabaseServer.ts +12 -0
  5. package/Models/DatabaseModels/DockerHost.ts +12 -0
  6. package/Models/DatabaseModels/DockerSwarmCluster.ts +12 -0
  7. package/Models/DatabaseModels/GlobalOidc.ts +0 -4
  8. package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
  9. package/Models/DatabaseModels/GlobalSso.ts +0 -4
  10. package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
  11. package/Models/DatabaseModels/Host.ts +12 -0
  12. package/Models/DatabaseModels/IncidentForm.ts +594 -0
  13. package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
  14. package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
  15. package/Models/DatabaseModels/Index.ts +14 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +12 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
  18. package/Models/DatabaseModels/MessageQueue.ts +1102 -0
  19. package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
  20. package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
  21. package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
  22. package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
  23. package/Models/DatabaseModels/PodmanHost.ts +12 -0
  24. package/Models/DatabaseModels/Project.ts +59 -0
  25. package/Models/DatabaseModels/ProjectOidc.ts +0 -4
  26. package/Models/DatabaseModels/ProjectSso.ts +0 -4
  27. package/Models/DatabaseModels/ProxmoxCluster.ts +12 -0
  28. package/Models/DatabaseModels/RumApplication.ts +12 -0
  29. package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
  30. package/Models/DatabaseModels/Service.ts +12 -0
  31. package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
  32. package/Models/DatabaseModels/StatusPageSso.ts +0 -4
  33. package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
  34. package/Models/DatabaseModels/VMwareVCenter.ts +12 -0
  35. package/Server/API/AIChatAPI.ts +13 -114
  36. package/Server/API/AIInvestigationAPI.ts +3 -3
  37. package/Server/API/AIInvestigationConversationAPI.ts +266 -0
  38. package/Server/API/IncidentFormAPI.ts +376 -0
  39. package/Server/API/ProjectOIDC.ts +16 -25
  40. package/Server/API/ProjectSSO.ts +16 -24
  41. package/Server/API/StatusPageAPI.ts +42 -77
  42. package/Server/Enterprise/EnterpriseEdition.ts +93 -28
  43. package/Server/Enterprise/EnterpriseFeature.ts +25 -3
  44. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
  45. package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
  46. package/Server/EnvironmentConfig.ts +1 -1
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  52. package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
  53. package/Server/Middleware/UserAuthorization.ts +16 -38
  54. package/Server/Services/AIService.ts +10 -13
  55. package/Server/Services/IncidentCustomFieldService.ts +112 -2
  56. package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
  57. package/Server/Services/IncidentEpisodeService.ts +10 -1
  58. package/Server/Services/IncidentFormService.ts +1566 -0
  59. package/Server/Services/IncidentFormSubmissionService.ts +97 -0
  60. package/Server/Services/IncidentGroupingEngineService.ts +45 -8
  61. package/Server/Services/IncidentService.ts +123 -5
  62. package/Server/Services/IncidentTemplateService.ts +22 -0
  63. package/Server/Services/Index.ts +14 -0
  64. package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
  65. package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
  66. package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
  67. package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
  68. package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
  69. package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
  70. package/Server/Services/MessageQueueService.ts +1463 -0
  71. package/Server/Services/OpenTelemetryIngestService.ts +37 -4
  72. package/Server/Services/ProjectService.ts +0 -59
  73. package/Server/Services/StatusPagePrivateUserService.ts +1 -4
  74. package/Server/Services/StatusPageService.ts +1 -51
  75. package/Server/Services/TeamComplianceSettingService.ts +163 -42
  76. package/Server/Services/UserNotificationRuleService.ts +8 -1
  77. package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
  78. package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
  79. package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
  80. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
  81. package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
  82. package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
  83. package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
  84. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
  85. package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
  86. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
  87. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  88. package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
  89. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
  90. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
  91. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
  92. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
  93. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +7 -1
  94. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +34 -14
  95. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +69 -24
  96. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +9 -0
  97. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +53 -10
  98. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +27 -10
  99. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +27 -10
  100. package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
  101. package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
  102. package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
  103. package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
  104. package/Server/Utils/EditionEnforcement.ts +19 -202
  105. package/Server/Utils/LLM/LLMService.ts +259 -63
  106. package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
  107. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  108. package/Server/Utils/SameOriginRequest.ts +203 -0
  109. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  110. package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
  111. package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
  112. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
  113. package/Server/Utils/VendorAssets.ts +3 -3
  114. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +3 -1
  115. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +3 -1
  116. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +10 -1
  117. package/Tests/App/Accounts/IncidentFormPage.test.tsx +2036 -0
  118. package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
  119. package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
  120. package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
  121. package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
  122. package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
  123. package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
  124. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
  125. package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
  126. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
  127. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
  128. package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
  129. package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
  130. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
  131. package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
  132. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +174 -12
  133. package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
  134. package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
  135. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
  136. package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
  137. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +5 -0
  138. package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
  139. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
  140. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
  141. package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
  142. package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
  143. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
  144. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
  145. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
  146. package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
  147. package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
  148. package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
  149. package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
  150. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
  151. package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
  152. package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
  153. package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
  154. package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
  155. package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
  156. package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
  157. package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
  158. package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
  159. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
  160. package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
  161. package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
  162. package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
  163. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
  164. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
  165. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
  166. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
  167. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
  168. package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
  169. package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
  170. package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
  171. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
  172. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
  173. package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
  174. package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
  175. package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
  176. package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
  177. package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
  178. package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
  179. package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
  180. package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
  181. package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
  182. package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
  183. package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
  184. package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
  185. package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
  186. package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
  187. package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
  188. package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
  189. package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
  190. package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
  191. package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
  192. package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
  193. package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
  194. package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
  195. package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
  196. package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
  197. package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
  198. package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
  199. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
  200. package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
  201. package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
  202. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
  203. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
  204. package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
  205. package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
  206. package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
  207. package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
  208. package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -0
  209. package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +555 -0
  210. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +298 -9
  211. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +453 -0
  212. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
  213. package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
  214. package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
  215. package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
  216. package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
  217. package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
  218. package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
  219. package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
  220. package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
  221. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
  222. package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
  223. package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
  224. package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
  225. package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
  226. package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
  227. package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
  228. package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
  229. package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
  230. package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
  231. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
  232. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +28 -9
  233. package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
  234. package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
  235. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  236. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
  237. package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
  238. package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
  239. package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
  240. package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
  241. package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
  242. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
  243. package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
  244. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
  245. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
  246. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
  247. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
  248. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
  249. package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
  250. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  251. package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
  252. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
  253. package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
  254. package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
  255. package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
  256. package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
  257. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
  258. package/Tests/Server/Services/IncidentCreatedFeedTitle.test.ts +212 -0
  259. package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
  260. package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
  261. package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
  262. package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
  263. package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
  264. package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
  265. package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
  266. package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
  267. package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
  268. package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
  269. package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
  270. package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
  271. package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
  272. package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
  273. package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
  274. package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
  275. package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
  276. package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
  277. package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
  278. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
  279. package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
  280. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
  281. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
  282. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
  283. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
  284. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
  285. package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
  286. package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
  287. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  288. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
  289. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
  290. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
  291. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
  292. package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
  293. package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
  294. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
  295. package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
  296. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
  297. package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
  298. package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
  299. package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
  300. package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
  301. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
  302. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
  303. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
  304. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +266 -25
  305. package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
  306. package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
  307. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
  308. package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
  309. package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
  310. package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
  311. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
  312. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +2 -0
  313. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +297 -15
  314. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +10 -6
  315. package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
  316. package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
  317. package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
  318. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
  319. package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
  320. package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
  321. package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -0
  322. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +20 -0
  323. package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
  324. package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
  325. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
  326. package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
  327. package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
  328. package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
  329. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
  330. package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
  331. package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
  332. package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
  333. package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
  334. package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
  335. package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
  336. package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
  337. package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
  338. package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
  339. package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
  340. package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
  341. package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
  342. package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
  343. package/Tests/Types/Monitor/MetricEngineFold.ts +154 -0
  344. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +5 -3
  345. package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
  346. package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
  347. package/Tests/Types/XML.test.ts +51 -0
  348. package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
  349. package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
  350. package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
  351. package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
  352. package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
  353. package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
  354. package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
  355. package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
  356. package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
  357. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
  358. package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
  359. package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
  360. package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
  361. package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
  362. package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
  363. package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
  364. package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
  365. package/Tests/UI/Components/Icon.test.tsx +32 -0
  366. package/Tests/UI/Components/Input.test.tsx +31 -0
  367. package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
  368. package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
  369. package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
  370. package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
  371. package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
  372. package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
  373. package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
  374. package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
  375. package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
  376. package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
  377. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  378. package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
  379. package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
  380. package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
  381. package/Tests/UI/Components/TextArea.test.tsx +19 -0
  382. package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
  383. package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
  384. package/Tests/UI/EsbuildConfig.test.ts +115 -39
  385. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
  386. package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
  387. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
  388. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -0
  389. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  390. package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
  391. package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
  392. package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
  393. package/Types/AI/AIAgentRunLimits.ts +146 -0
  394. package/Types/Code/CodeType.ts +2 -0
  395. package/Types/Code/JsonSyntax.ts +923 -0
  396. package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
  397. package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
  398. package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
  399. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
  400. package/Types/Icon/IconProp.ts +2 -0
  401. package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
  402. package/Types/Incident/IncidentFormPublic.ts +1145 -0
  403. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
  404. package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
  405. package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
  406. package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
  407. package/Types/MessageQueue/MessagingSystem.ts +518 -0
  408. package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
  409. package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
  410. package/Types/Permission.ts +310 -0
  411. package/Types/ResourceAiAgent/ResourceAiAccess.ts +10 -4
  412. package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
  413. package/Types/Rules/RuleRun.ts +4 -0
  414. package/Types/Team/ComplianceNotificationChannel.ts +4 -3
  415. package/Types/Team/ComplianceRule.ts +71 -18
  416. package/Types/Team/ComplianceRuleType.ts +2 -2
  417. package/Types/Team/TeamComplianceStatus.ts +6 -2
  418. package/Types/Telemetry/EntityType.ts +16 -0
  419. package/Types/Telemetry/LockedFilterDetail.ts +22 -0
  420. package/Types/XML.ts +26 -0
  421. package/UI/Components/CodeEditor/CodeEditor.css +379 -0
  422. package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
  423. package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
  424. package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
  425. package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
  426. package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
  427. package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
  428. package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
  429. package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
  430. package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
  431. package/UI/Components/Forms/Fields/FormField.tsx +8 -0
  432. package/UI/Components/Forms/Types/Field.ts +8 -0
  433. package/UI/Components/Icon/Icon.tsx +18 -0
  434. package/UI/Components/Input/Input.tsx +11 -4
  435. package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
  436. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
  437. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  438. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
  439. package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
  440. package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
  441. package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
  442. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
  443. package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
  444. package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
  445. package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
  446. package/UI/Components/Table/EmptyTableMessage.ts +81 -0
  447. package/UI/Components/Table/Table.tsx +50 -21
  448. package/UI/Components/Table/TableRow.tsx +9 -1
  449. package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
  450. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
  451. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
  452. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
  453. package/UI/Components/TextArea/TextArea.tsx +9 -2
  454. package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
  455. package/UI/Styles/Theme.css +8 -0
  456. package/UI/esbuild-config.js +2 -32
  457. package/Utils/LabelRuleImportExport.ts +2 -0
  458. package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
  459. package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
  460. package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
  461. package/Utils/Telemetry/EntityKey.ts +48 -0
  462. package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
  463. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
  464. package/build/dist/Models/DatabaseModels/CephCluster.js +12 -0
  465. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  466. package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
  467. package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
  468. package/build/dist/Models/DatabaseModels/DatabaseServer.js +12 -0
  469. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  470. package/build/dist/Models/DatabaseModels/DockerHost.js +12 -0
  471. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  472. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +12 -0
  473. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  474. package/build/dist/Models/DatabaseModels/GlobalOidc.js +0 -4
  475. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  476. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
  477. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  478. package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
  479. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  480. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
  481. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  482. package/build/dist/Models/DatabaseModels/Host.js +12 -0
  483. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  484. package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
  485. package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
  486. package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
  487. package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
  488. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
  489. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  490. package/build/dist/Models/DatabaseModels/Index.js +14 -0
  491. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  492. package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
  493. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  494. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
  495. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  496. package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
  497. package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
  498. package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
  499. package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
  500. package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
  501. package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
  502. package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
  503. package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
  504. package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
  505. package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
  506. package/build/dist/Models/DatabaseModels/PodmanHost.js +12 -0
  507. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  508. package/build/dist/Models/DatabaseModels/Project.js +61 -0
  509. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  510. package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
  511. package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
  512. package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
  513. package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
  514. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +12 -0
  515. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  516. package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
  517. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  518. package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
  519. package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
  520. package/build/dist/Models/DatabaseModels/Service.js +12 -0
  521. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  522. package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
  523. package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
  524. package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
  525. package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
  526. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
  527. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  528. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +12 -0
  529. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  530. package/build/dist/Server/API/AIChatAPI.js +9 -103
  531. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  532. package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
  533. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  534. package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
  535. package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
  536. package/build/dist/Server/API/IncidentFormAPI.js +245 -0
  537. package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
  538. package/build/dist/Server/API/ProjectOIDC.js +16 -24
  539. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  540. package/build/dist/Server/API/ProjectSSO.js +16 -24
  541. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  542. package/build/dist/Server/API/StatusPageAPI.js +42 -75
  543. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  544. package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
  545. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
  546. package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
  547. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
  548. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
  549. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
  550. package/build/dist/Server/EnvironmentConfig.js +1 -1
  551. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js +63 -0
  552. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
  553. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
  554. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
  555. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
  556. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
  557. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
  558. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js.map +1 -0
  559. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  560. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  561. package/build/dist/Server/Middleware/IncidentFormRateLimit.js +559 -0
  562. package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
  563. package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
  564. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  565. package/build/dist/Server/Services/AIService.js +10 -13
  566. package/build/dist/Server/Services/AIService.js.map +1 -1
  567. package/build/dist/Server/Services/IncidentCustomFieldService.js +83 -0
  568. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  569. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
  570. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  571. package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
  572. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  573. package/build/dist/Server/Services/IncidentFormService.js +1202 -0
  574. package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
  575. package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
  576. package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
  577. package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
  578. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  579. package/build/dist/Server/Services/IncidentService.js +106 -4
  580. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  581. package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
  582. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  583. package/build/dist/Server/Services/Index.js +14 -0
  584. package/build/dist/Server/Services/Index.js.map +1 -1
  585. package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
  586. package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
  587. package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
  588. package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
  589. package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
  590. package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
  591. package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
  592. package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
  593. package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
  594. package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
  595. package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
  596. package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
  597. package/build/dist/Server/Services/MessageQueueService.js +1140 -0
  598. package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
  599. package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
  600. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  601. package/build/dist/Server/Services/ProjectService.js +0 -54
  602. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  603. package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
  604. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  605. package/build/dist/Server/Services/StatusPageService.js +0 -46
  606. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  607. package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
  608. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  609. package/build/dist/Server/Services/UserNotificationRuleService.js +8 -1
  610. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  611. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +12 -3
  612. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
  613. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
  614. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  615. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
  616. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  617. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
  618. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  619. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
  620. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
  621. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  622. package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
  623. package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
  624. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
  625. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  626. package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
  627. package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
  628. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
  629. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  630. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  631. package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
  632. package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
  633. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
  634. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  635. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
  636. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  637. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
  638. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  639. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
  640. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  641. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +7 -2
  642. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  643. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +29 -14
  644. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  645. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +38 -14
  646. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -1
  647. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +2 -0
  648. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -1
  649. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +40 -10
  650. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  651. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +19 -7
  652. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  653. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +19 -7
  654. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  655. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
  656. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  657. package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
  658. package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
  659. package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
  660. package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
  661. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
  662. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
  663. package/build/dist/Server/Utils/EditionEnforcement.js +20 -158
  664. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
  665. package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
  666. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  667. package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
  668. package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
  669. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  670. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  671. package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
  672. package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
  673. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  674. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  675. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
  676. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  677. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
  678. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
  679. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
  680. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  681. package/build/dist/Server/Utils/VendorAssets.js +3 -3
  682. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +3 -1
  683. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  684. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +3 -1
  685. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  686. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +10 -1
  687. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  688. package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
  689. package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
  690. package/build/dist/Types/Code/CodeType.js +2 -0
  691. package/build/dist/Types/Code/CodeType.js.map +1 -1
  692. package/build/dist/Types/Code/JsonSyntax.js +604 -0
  693. package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
  694. package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
  695. package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
  696. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
  697. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
  698. package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
  699. package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
  700. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
  701. package/build/dist/Types/Icon/IconProp.js +2 -0
  702. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  703. package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
  704. package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
  705. package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
  706. package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
  707. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
  708. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  709. package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
  710. package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
  711. package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
  712. package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
  713. package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
  714. package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
  715. package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
  716. package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
  717. package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
  718. package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
  719. package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
  720. package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
  721. package/build/dist/Types/Permission.js +274 -0
  722. package/build/dist/Types/Permission.js.map +1 -1
  723. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +10 -4
  724. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -1
  725. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
  726. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  727. package/build/dist/Types/Rules/RuleRun.js +4 -0
  728. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  729. package/build/dist/Types/Team/ComplianceNotificationChannel.js +4 -3
  730. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
  731. package/build/dist/Types/Team/ComplianceRule.js +48 -14
  732. package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
  733. package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
  734. package/build/dist/Types/Telemetry/EntityType.js +16 -0
  735. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  736. package/build/dist/Types/XML.js +23 -0
  737. package/build/dist/Types/XML.js.map +1 -1
  738. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
  739. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  740. package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
  741. package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
  742. package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
  743. package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
  744. package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
  745. package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
  746. package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
  747. package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
  748. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
  749. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
  750. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
  751. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
  752. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
  753. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  754. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
  755. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
  756. package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
  757. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  758. package/build/dist/UI/Components/Icon/Icon.js +8 -0
  759. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  760. package/build/dist/UI/Components/Input/Input.js +11 -3
  761. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  762. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
  763. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  764. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
  765. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  766. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  767. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  768. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
  769. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  770. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
  771. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
  772. package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
  773. package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
  774. package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
  775. package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
  776. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
  777. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  778. package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
  779. package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
  780. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
  781. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  782. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
  783. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
  784. package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
  785. package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
  786. package/build/dist/UI/Components/Table/Table.js +30 -11
  787. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  788. package/build/dist/UI/Components/Table/TableRow.js +9 -2
  789. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  790. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
  791. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
  792. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
  793. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  794. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
  795. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
  796. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
  797. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  798. package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
  799. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  800. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
  801. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
  802. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  803. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  804. package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
  805. package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
  806. package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
  807. package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
  808. package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
  809. package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
  810. package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
  811. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  812. package/package.json +1 -3
  813. package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
  814. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
  815. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
  816. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
  817. package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
  818. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
  819. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
  820. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
  821. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
  822. package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
  823. package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
  824. package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
  825. package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
  826. package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
  827. package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
  828. package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
  829. package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
  830. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
  831. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
  832. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
  833. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
  834. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
  835. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
  836. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
  837. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
@@ -0,0 +1,1362 @@
1
+ /*
2
+ * Indenting and outdenting list items, in both of the MarkdownEditor's modes,
3
+ * and the list buttons' clean-up of bullet characters typed as text.
4
+ *
5
+ * Visual mode works on the contenteditable DOM directly: the selected items
6
+ * are moved under the item before them (indent) or out beside their parent
7
+ * (outdent). document.execCommand("indent") is no substitute -- Chromium,
8
+ * Firefox and WebKit all answer it with a <ul> directly inside a <ul>, which
9
+ * is not a list item at all, and the serializer drops that item on save.
10
+ *
11
+ * Markdown mode works on the source lines. A nested item has to start at its
12
+ * parent's content column -- two columns in under "- ", three under "1. ",
13
+ * four under "10. " -- or CommonMark (and the email renderer, marked) reads
14
+ * it as a sibling rather than a child, so indenting moves a line to the
15
+ * content column of the item above it rather than by a fixed width.
16
+ *
17
+ * Both return whether they changed anything. The editor only claims the Tab
18
+ * key when they did, so Tab still moves focus out of the editor everywhere
19
+ * else -- a list's first item, a top-level item on Shift+Tab, a paragraph --
20
+ * and a keyboard user is never trapped inside the field.
21
+ */
22
+
23
+ /*
24
+ * Characters other apps put in front of a list item as plain text: Word and
25
+ * Outlook ("•", and "·" / U+F0B7 from the Symbol font), Slack ("•", "◦",
26
+ * "▪"), Google Docs and PowerPoint (the squares, diamonds and arrows), and
27
+ * the dashes many people type by hand. Word's second and third levels are
28
+ * "o" and "§" (U+F0A7 from Wingdings), recognised only before a tab so that
29
+ * a sentence starting with the word "o" is left alone.
30
+ */
31
+ export const TEXT_BULLET_GLYPHS: string = "•◦▪▫‣⁃∙·●○■□◆◇➢➤►▶–—\uF0B7\uF0A7";
32
+
33
+ // Word's level-two and level-three bullets, which only count before a tab.
34
+ export const TAB_ONLY_BULLET_GLYPHS: string = "o§";
35
+
36
+ /*
37
+ * A marker at the start of a list item's own text that the list itself now
38
+ * draws: a bullet character followed by a space or tab (or on its own),
39
+ * Word's "o" / "§" before a tab, a "- " left behind as text, or a number the
40
+ * way Word and Outlook write one into plain text -- "1." followed by a tab
41
+ * or a run of spaces. A number followed by a single space is left alone:
42
+ * "2021. was a good year" is a sentence. So is a line whose text merely
43
+ * starts with one of the characters -- the dash in "–5°C overnight low" is a
44
+ * minus sign, and "—Mark Twain" an attribution -- which the paste's own
45
+ * bullet rule (MarkdownPaste) leaves alone too.
46
+ * \u00a0 is included because Word and browsers write the space after a
47
+ * marker as a non-breaking one.
48
+ */
49
+ const RE_LEADING_TEXT_MARKER: RegExp = new RegExp(
50
+ `^[ \\t\\u00a0]*(?:[${TEXT_BULLET_GLYPHS}](?:[ \\t\\u00a0]+|$)|[${TAB_ONLY_BULLET_GLYPHS}]\\t[ \\t\\u00a0]*|[-*+][ \\t\\u00a0]+|\\d{1,9}[.)](?:\\t|[ \\u00a0]{2,})[ \\t\\u00a0]*)`,
51
+ );
52
+
53
+ // A tab advances to the next multiple of four columns, as in CommonMark.
54
+ const TAB_WIDTH: number = 4;
55
+
56
+ /*
57
+ * ---------------------------------------------------------------------------
58
+ * Visual mode: the contenteditable DOM
59
+ * ---------------------------------------------------------------------------
60
+ */
61
+
62
+ const tagOf: (node: Node | null | undefined) => string = (
63
+ node: Node | null | undefined,
64
+ ): string => {
65
+ if (!node || node.nodeType !== Node.ELEMENT_NODE) {
66
+ return "";
67
+ }
68
+ return (node as Element).localName.toLowerCase();
69
+ };
70
+
71
+ const isList: (node: Node | null | undefined) => boolean = (
72
+ node: Node | null | undefined,
73
+ ): boolean => {
74
+ const tag: string = tagOf(node);
75
+ return tag === "ul" || tag === "ol";
76
+ };
77
+
78
+ const isListItem: (node: Node | null | undefined) => boolean = (
79
+ node: Node | null | undefined,
80
+ ): boolean => {
81
+ return tagOf(node) === "li";
82
+ };
83
+
84
+ interface SelectionInRoot {
85
+ selection: Selection;
86
+ range: Range;
87
+ }
88
+
89
+ const getSelectionInRoot: (root: HTMLElement) => SelectionInRoot | null = (
90
+ root: HTMLElement,
91
+ ): SelectionInRoot | null => {
92
+ const selection: Selection | null = root.ownerDocument.getSelection();
93
+ if (!selection || selection.rangeCount === 0) {
94
+ return null;
95
+ }
96
+ const range: Range = selection.getRangeAt(0);
97
+ if (!root.contains(range.startContainer)) {
98
+ return null;
99
+ }
100
+ return { selection, range };
101
+ };
102
+
103
+ /*
104
+ * The nearest <li> at or above `node`, without leaving `root`. None from
105
+ * inside a code block, even one in a list item: Tab there is not a list
106
+ * edit, as the source mode skips the lines of a fenced block.
107
+ */
108
+ const closestListItem: (
109
+ node: Node | null,
110
+ root: HTMLElement,
111
+ ) => HTMLElement | null = (
112
+ node: Node | null,
113
+ root: HTMLElement,
114
+ ): HTMLElement | null => {
115
+ let current: Node | null = node;
116
+ while (current && current !== root) {
117
+ if (isListItem(current)) {
118
+ return current as HTMLElement;
119
+ }
120
+ if (tagOf(current) === "pre") {
121
+ return null;
122
+ }
123
+ current = current.parentNode;
124
+ }
125
+ return null;
126
+ };
127
+
128
+ /*
129
+ * The <li> the selection starts in. A boundary that sits on a list itself,
130
+ * or in the whitespace between two of its items, belongs to the item after
131
+ * it.
132
+ */
133
+ const listItemAtSelectionStart: (
134
+ range: Range,
135
+ root: HTMLElement,
136
+ ) => HTMLElement | null = (
137
+ range: Range,
138
+ root: HTMLElement,
139
+ ): HTMLElement | null => {
140
+ let node: Node = range.startContainer;
141
+ if (node.nodeType === Node.ELEMENT_NODE) {
142
+ const child: ChildNode | undefined = node.childNodes[range.startOffset];
143
+ if (child) {
144
+ node = child;
145
+ }
146
+ }
147
+ if (isList(node)) {
148
+ const firstItem: Element | null = (node as Element).querySelector(
149
+ ":scope > li",
150
+ );
151
+ if (firstItem) {
152
+ node = firstItem;
153
+ }
154
+ } else if (!isListItem(node) && isList(node.parentNode)) {
155
+ let next: Node | null = node.nextSibling;
156
+ while (next && !isListItem(next)) {
157
+ next = next.nextSibling;
158
+ }
159
+ if (next) {
160
+ node = next;
161
+ }
162
+ }
163
+ return closestListItem(node, root);
164
+ };
165
+
166
+ /*
167
+ * Whether the range selects any of `item` -- not merely touches it. A
168
+ * selection dragged down to the very start of the next item (which is what
169
+ * a triple click leaves behind) does not take that item along, the same way
170
+ * a textarea selection ending at column 0 does not take that line.
171
+ */
172
+ const rangeSelectsInto: (range: Range, item: HTMLElement) => boolean = (
173
+ range: Range,
174
+ item: HTMLElement,
175
+ ): boolean => {
176
+ if (!range.intersectsNode(item)) {
177
+ return false;
178
+ }
179
+ if (!item.contains(range.endContainer)) {
180
+ return true;
181
+ }
182
+ const head: Range = item.ownerDocument.createRange();
183
+ head.setStart(item, 0);
184
+ head.setEnd(range.endContainer, range.endOffset);
185
+ return head.toString().length > 0;
186
+ };
187
+
188
+ /*
189
+ * The items an indent or outdent moves: the one the selection starts in,
190
+ * plus the siblings after it that the selection reaches. Items at other
191
+ * levels move along with these (as their children) rather than on their own.
192
+ */
193
+ const selectedSiblingItems: (
194
+ range: Range,
195
+ root: HTMLElement,
196
+ ) => Array<HTMLElement> = (
197
+ range: Range,
198
+ root: HTMLElement,
199
+ ): Array<HTMLElement> => {
200
+ const first: HTMLElement | null = listItemAtSelectionStart(range, root);
201
+ if (!first || !isList(first.parentNode)) {
202
+ return [];
203
+ }
204
+ const items: Array<HTMLElement> = [first];
205
+ let sibling: Element | null = first.nextElementSibling;
206
+ while (
207
+ sibling &&
208
+ isListItem(sibling) &&
209
+ rangeSelectsInto(range, sibling as HTMLElement)
210
+ ) {
211
+ items.push(sibling as HTMLElement);
212
+ sibling = sibling.nextElementSibling;
213
+ }
214
+ return items;
215
+ };
216
+
217
+ interface SavedSelection {
218
+ anchorNode: Node;
219
+ anchorOffset: number;
220
+ focusNode: Node;
221
+ focusOffset: number;
222
+ }
223
+
224
+ const saveSelection: (selection: Selection) => SavedSelection | null = (
225
+ selection: Selection,
226
+ ): SavedSelection | null => {
227
+ if (!selection.anchorNode || !selection.focusNode) {
228
+ return null;
229
+ }
230
+ return {
231
+ anchorNode: selection.anchorNode,
232
+ anchorOffset: selection.anchorOffset,
233
+ focusNode: selection.focusNode,
234
+ focusOffset: selection.focusOffset,
235
+ };
236
+ };
237
+
238
+ const nodeLength: (node: Node) => number = (node: Node): number => {
239
+ if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.COMMENT_NODE) {
240
+ return (node as CharacterData).length;
241
+ }
242
+ return node.childNodes.length;
243
+ };
244
+
245
+ /*
246
+ * Moving a node collapses any selection inside it to the spot it was moved
247
+ * from, so the selection is put back by hand. The nodes it was anchored in
248
+ * move rather than get recreated, so the same boundary points still name the
249
+ * same characters.
250
+ */
251
+ const restoreSelection: (
252
+ selection: Selection,
253
+ saved: SavedSelection | null,
254
+ root: HTMLElement,
255
+ fallback: HTMLElement,
256
+ ) => void = (
257
+ selection: Selection,
258
+ saved: SavedSelection | null,
259
+ root: HTMLElement,
260
+ fallback: HTMLElement,
261
+ ): void => {
262
+ try {
263
+ if (
264
+ saved &&
265
+ root.contains(saved.anchorNode) &&
266
+ root.contains(saved.focusNode)
267
+ ) {
268
+ selection.setBaseAndExtent(
269
+ saved.anchorNode,
270
+ Math.min(saved.anchorOffset, nodeLength(saved.anchorNode)),
271
+ saved.focusNode,
272
+ Math.min(saved.focusOffset, nodeLength(saved.focusNode)),
273
+ );
274
+ return;
275
+ }
276
+ const caret: Range = root.ownerDocument.createRange();
277
+ caret.setStart(fallback, 0);
278
+ caret.collapse(true);
279
+ selection.removeAllRanges();
280
+ selection.addRange(caret);
281
+ } catch {
282
+ // Leave the selection where the browser put it rather than fail the edit.
283
+ }
284
+ };
285
+
286
+ // The list an item's children sit in, created (like `list`) when it has none.
287
+ const trailingSublist: (item: HTMLElement, like: HTMLElement) => HTMLElement = (
288
+ item: HTMLElement,
289
+ like: HTMLElement,
290
+ ): HTMLElement => {
291
+ const last: Element | null = item.lastElementChild;
292
+ if (last && isList(last)) {
293
+ return last as HTMLElement;
294
+ }
295
+ const sublist: HTMLElement = item.ownerDocument.createElement(tagOf(like));
296
+ if (like.classList.contains("task-list")) {
297
+ sublist.className = "task-list";
298
+ }
299
+ item.appendChild(sublist);
300
+ return sublist;
301
+ };
302
+
303
+ /*
304
+ * Indent: the selected items become the last children of the item before
305
+ * them, joining its nested list when it has one (and taking that list's kind)
306
+ * or starting a new one of their own list's kind. Their own nested items move
307
+ * with them. The first item of a list has nothing to nest under, so it is left
308
+ * alone and this returns false.
309
+ */
310
+ export const sinkListItems: (root: HTMLElement) => boolean = (
311
+ root: HTMLElement,
312
+ ): boolean => {
313
+ const context: SelectionInRoot | null = getSelectionInRoot(root);
314
+ if (!context) {
315
+ return false;
316
+ }
317
+ const items: Array<HTMLElement> = selectedSiblingItems(context.range, root);
318
+ const first: HTMLElement | undefined = items[0];
319
+ if (!first) {
320
+ return false;
321
+ }
322
+ const previous: Element | null = first.previousElementSibling;
323
+ if (!previous || !isListItem(previous)) {
324
+ return false;
325
+ }
326
+ const list: HTMLElement = first.parentNode as HTMLElement;
327
+ const saved: SavedSelection | null = saveSelection(context.selection);
328
+
329
+ const target: HTMLElement = trailingSublist(previous as HTMLElement, list);
330
+ for (const item of items) {
331
+ target.appendChild(item);
332
+ }
333
+
334
+ restoreSelection(context.selection, saved, root, first);
335
+ return true;
336
+ };
337
+
338
+ /*
339
+ * Outdent: the selected items move out of their list to sit right after the
340
+ * item that held it. The items that followed them in that list stay below
341
+ * them, so they become the last moved item's children -- as in Google Docs
342
+ * and Word, the text keeps its order -- and so does whatever that item held
343
+ * after the list: a paragraph that goes on below the nested items, or a
344
+ * nested list of the other kind. Left in place, those came out above the
345
+ * moved items. The markdown-source outdent keeps the same order. A top-level
346
+ * item has nowhere to go, so this returns false for it (and never lifts an
347
+ * item out of `root` itself).
348
+ */
349
+ export const liftListItems: (root: HTMLElement) => boolean = (
350
+ root: HTMLElement,
351
+ ): boolean => {
352
+ const context: SelectionInRoot | null = getSelectionInRoot(root);
353
+ if (!context) {
354
+ return false;
355
+ }
356
+ const items: Array<HTMLElement> = selectedSiblingItems(context.range, root);
357
+ const first: HTMLElement | undefined = items[0];
358
+ const last: HTMLElement | undefined = items[items.length - 1];
359
+ if (!first || !last) {
360
+ return false;
361
+ }
362
+ const list: HTMLElement = first.parentNode as HTMLElement;
363
+ const parentItem: Node | null = list.parentNode;
364
+ const outerList: ParentNode | null = parentItem
365
+ ? parentItem.parentNode
366
+ : null;
367
+ if (
368
+ !parentItem ||
369
+ !outerList ||
370
+ !isListItem(parentItem) ||
371
+ parentItem === root ||
372
+ !root.contains(parentItem)
373
+ ) {
374
+ return false;
375
+ }
376
+ const saved: SavedSelection | null = saveSelection(context.selection);
377
+
378
+ const trailing: Array<Element> = [];
379
+ let next: Element | null = last.nextElementSibling;
380
+ while (next) {
381
+ trailing.push(next);
382
+ next = next.nextElementSibling;
383
+ }
384
+ if (trailing.length > 0) {
385
+ const sublist: HTMLElement = trailingSublist(last, list);
386
+ for (const item of trailing) {
387
+ sublist.appendChild(item);
388
+ }
389
+ }
390
+ /*
391
+ * After the items that followed, not before: a nested list of the other
392
+ * kind moved in first would be taken for the last item's own sublist, and
393
+ * the followers would go into it.
394
+ */
395
+ let after: ChildNode | null = list.nextSibling;
396
+ while (after) {
397
+ const following: ChildNode | null = after.nextSibling;
398
+ last.appendChild(after);
399
+ after = following;
400
+ }
401
+
402
+ let anchor: Node = parentItem;
403
+ for (const item of items) {
404
+ outerList.insertBefore(item, anchor.nextSibling);
405
+ anchor = item;
406
+ }
407
+ if (list.children.length === 0) {
408
+ list.remove();
409
+ }
410
+
411
+ restoreSelection(context.selection, saved, root, first);
412
+ return true;
413
+ };
414
+
415
+ // The text nodes that make up an item's own text, in order -- not its sublists'.
416
+ const ownTextNodes: (item: HTMLElement) => Array<Text> = (
417
+ item: HTMLElement,
418
+ ): Array<Text> => {
419
+ const texts: Array<Text> = [];
420
+ const walk: (node: Node) => void = (node: Node): void => {
421
+ for (const child of Array.from(node.childNodes)) {
422
+ if (child.nodeType === Node.TEXT_NODE) {
423
+ texts.push(child as Text);
424
+ } else if (child.nodeType === Node.ELEMENT_NODE && !isList(child)) {
425
+ walk(child);
426
+ }
427
+ }
428
+ };
429
+ walk(item);
430
+ return texts;
431
+ };
432
+
433
+ const INLINE_CONTENT_SELECTOR: string = "img, br, input";
434
+
435
+ /*
436
+ * Removes the marker at the start of one item's text. The marker can be
437
+ * split over several text nodes -- "•" in a <span>, the space after it
438
+ * outside -- so the leading text is matched as one string and then trimmed
439
+ * node by node. Inline elements the marker leaves empty go too, or an empty
440
+ * <strong> would come back as "****".
441
+ */
442
+ const stripLeadingMarker: (item: HTMLElement) => boolean = (
443
+ item: HTMLElement,
444
+ ): boolean => {
445
+ const texts: Array<Text> = ownTextNodes(item);
446
+ const leading: string = texts
447
+ .map((text: Text): string => {
448
+ return text.data;
449
+ })
450
+ .join("");
451
+ const match: RegExpMatchArray | null = leading.match(RE_LEADING_TEXT_MARKER);
452
+ if (!match || match[0].length === 0) {
453
+ return false;
454
+ }
455
+ let remaining: number = match[0].length;
456
+ for (const text of texts) {
457
+ if (remaining === 0) {
458
+ break;
459
+ }
460
+ const take: number = Math.min(remaining, text.data.length);
461
+ remaining -= take;
462
+ text.data = text.data.slice(take);
463
+ if (text.data.length > 0) {
464
+ continue;
465
+ }
466
+ let emptied: Node | null = text.parentNode;
467
+ text.remove();
468
+ while (
469
+ emptied &&
470
+ emptied !== item &&
471
+ emptied.nodeType === Node.ELEMENT_NODE &&
472
+ (emptied.textContent || "").length === 0 &&
473
+ !(emptied as Element).querySelector(INLINE_CONTENT_SELECTOR)
474
+ ) {
475
+ const parent: Node | null = emptied.parentNode;
476
+ (emptied as Element).remove();
477
+ emptied = parent;
478
+ }
479
+ }
480
+ return true;
481
+ };
482
+
483
+ /*
484
+ * The list buttons turn lines into list items with execCommand, which keeps
485
+ * whatever the lines started with. Text pasted from Word or Slack that still
486
+ * begins with "•" or "o" therefore showed two bullets -- the list's own and
487
+ * the character -- and saved as "- •\tService down". This strips such a
488
+ * marker from every item the selection reaches.
489
+ */
490
+ export const stripTextListMarkers: (root: HTMLElement) => boolean = (
491
+ root: HTMLElement,
492
+ ): boolean => {
493
+ const context: SelectionInRoot | null = getSelectionInRoot(root);
494
+ if (!context) {
495
+ return false;
496
+ }
497
+ const saved: SavedSelection | null = saveSelection(context.selection);
498
+ let changed: boolean = false;
499
+ const items: Array<HTMLElement> = Array.from(
500
+ root.querySelectorAll("li"),
501
+ ).filter((item: HTMLLIElement): boolean => {
502
+ return context.range.intersectsNode(item);
503
+ });
504
+ for (const item of items) {
505
+ if (stripLeadingMarker(item)) {
506
+ changed = true;
507
+ }
508
+ }
509
+ const first: HTMLElement | undefined = items[0];
510
+ if (changed && first) {
511
+ restoreSelection(context.selection, saved, root, first);
512
+ }
513
+ return changed;
514
+ };
515
+
516
+ /*
517
+ * ---------------------------------------------------------------------------
518
+ * Markdown mode: the source text
519
+ * ---------------------------------------------------------------------------
520
+ */
521
+
522
+ export interface MarkdownTextEdit {
523
+ text: string;
524
+ selectionStart: number;
525
+ selectionEnd: number;
526
+ }
527
+
528
+ interface ListMarker {
529
+ // "-", "*", "+", "1.", "10)".
530
+ marker: string;
531
+ ordered: boolean;
532
+ // The item's number; 0 for a bullet.
533
+ number: number;
534
+ // "." or ")" for an ordered item, the bullet character otherwise.
535
+ delimiter: string;
536
+ // The whitespace between the marker and the item's text, as written.
537
+ spacing: string;
538
+ // Everything after that whitespace.
539
+ rest: string;
540
+ contentColumn: number;
541
+ }
542
+
543
+ interface SourceLine {
544
+ blank: boolean;
545
+ indent: number;
546
+ // A fence line, or a line inside a fenced code block.
547
+ fenced: boolean;
548
+ // Null for anything that is not a list item, and for every fenced line.
549
+ item: ListMarker | null;
550
+ }
551
+
552
+ const RE_SOURCE_LIST_ITEM: RegExp =
553
+ /^([ \t]*)([-*+]|\d{1,9}[.)])([ \t]+|$)(.*)$/;
554
+ const RE_BULLET_MARKER: RegExp = /^[-*+]$/;
555
+ const RE_FENCE_OPEN: RegExp = /^[ \t]*(`{3,}|~{3,})/;
556
+ const RE_LEADING_WHITESPACE: RegExp = /^[ \t]*/;
557
+ const RE_BLANK: RegExp = /^[ \t]*$/;
558
+
559
+ // How many columns `text` covers when it starts at column `start`.
560
+ const columnsOf: (text: string, start: number) => number = (
561
+ text: string,
562
+ start: number,
563
+ ): number => {
564
+ let column: number = start;
565
+ for (const ch of text) {
566
+ column += ch === "\t" ? TAB_WIDTH - (column % TAB_WIDTH) : 1;
567
+ }
568
+ return column - start;
569
+ };
570
+
571
+ const leadingWhitespace: (line: string) => string = (line: string): string => {
572
+ const match: RegExpMatchArray | null = line.match(RE_LEADING_WHITESPACE);
573
+ return match ? match[0] : "";
574
+ };
575
+
576
+ /*
577
+ * CommonMark's content column: the marker's indent, plus the marker, plus the
578
+ * spaces after it -- unless there are none (an empty item) or five or more
579
+ * (the text is indented code), in which case one space counts.
580
+ */
581
+ const contentColumnOf: (
582
+ indent: number,
583
+ marker: string,
584
+ spacing: string,
585
+ ) => number = (indent: number, marker: string, spacing: string): number => {
586
+ const markerEnd: number = indent + marker.length;
587
+ const spacingWidth: number = columnsOf(spacing, markerEnd);
588
+ if (spacingWidth === 0 || spacingWidth > 4) {
589
+ return markerEnd + 1;
590
+ }
591
+ return markerEnd + spacingWidth;
592
+ };
593
+
594
+ const parseSourceLines: (lines: Array<string>) => Array<SourceLine> = (
595
+ lines: Array<string>,
596
+ ): Array<SourceLine> => {
597
+ const parsed: Array<SourceLine> = [];
598
+ let openFence: string | null = null;
599
+ for (const line of lines) {
600
+ const indent: number = columnsOf(leadingWhitespace(line), 0);
601
+ const blank: boolean = RE_BLANK.test(line);
602
+ const fence: RegExpMatchArray | null = line.match(RE_FENCE_OPEN);
603
+ if (openFence !== null) {
604
+ const fenceRun: string = fence ? fence[1] || "" : "";
605
+ const closes: boolean =
606
+ fenceRun.length >= openFence.length &&
607
+ fenceRun.charAt(0) === openFence.charAt(0) &&
608
+ RE_BLANK.test(line.slice(line.indexOf(fenceRun) + fenceRun.length));
609
+ parsed.push({ blank, indent, fenced: true, item: null });
610
+ if (closes) {
611
+ openFence = null;
612
+ }
613
+ continue;
614
+ }
615
+ if (fence) {
616
+ openFence = fence[1] || "```";
617
+ parsed.push({ blank, indent, fenced: true, item: null });
618
+ continue;
619
+ }
620
+ const match: RegExpMatchArray | null = line.match(RE_SOURCE_LIST_ITEM);
621
+ if (!match) {
622
+ parsed.push({ blank, indent, fenced: false, item: null });
623
+ continue;
624
+ }
625
+ const marker: string = match[2] || "";
626
+ const ordered: boolean = !RE_BULLET_MARKER.test(marker);
627
+ const spacing: string = match[3] || "";
628
+ parsed.push({
629
+ blank,
630
+ indent,
631
+ fenced: false,
632
+ item: {
633
+ marker,
634
+ ordered,
635
+ number: ordered ? parseInt(marker, 10) : 0,
636
+ delimiter: ordered ? marker.slice(-1) : marker,
637
+ spacing,
638
+ rest: match[4] || "",
639
+ contentColumn: contentColumnOf(indent, marker, spacing),
640
+ },
641
+ });
642
+ }
643
+ return parsed;
644
+ };
645
+
646
+ /*
647
+ * Whether `offset` in the source is inside a fenced code block: on one of
648
+ * its fence lines, between them, or anywhere after a fence that is never
649
+ * closed. The editor pastes there as the browser would, text as it is --
650
+ * the same fences Tab and the list buttons leave alone.
651
+ */
652
+ export const isInFencedCodeBlock: (text: string, offset: number) => boolean = (
653
+ text: string,
654
+ offset: number,
655
+ ): boolean => {
656
+ const line: number =
657
+ text.slice(0, Math.max(0, offset)).split("\n").length - 1;
658
+ return parseSourceLines(text.split("\n"))[line]?.fenced === true;
659
+ };
660
+
661
+ /*
662
+ * The end (exclusive) of the block that starts at `index`: the item's own
663
+ * line and everything indented deeper than it below -- its continuation
664
+ * lines, its nested items, a fenced block inside it -- up to the next line
665
+ * that is not.
666
+ */
667
+ const blockEnd: (parsed: Array<SourceLine>, index: number) => number = (
668
+ parsed: Array<SourceLine>,
669
+ index: number,
670
+ ): number => {
671
+ const own: number = parsed[index]?.indent ?? 0;
672
+ let end: number = index + 1;
673
+ let j: number = index + 1;
674
+ while (j < parsed.length) {
675
+ const line: SourceLine = parsed[j] as SourceLine;
676
+ if (!line.blank) {
677
+ if (line.indent <= own) {
678
+ break;
679
+ }
680
+ end = j + 1;
681
+ }
682
+ j++;
683
+ }
684
+ return end;
685
+ };
686
+
687
+ // The innermost list item whose block holds line `index`, or -1.
688
+ const itemHoldingLine: (parsed: Array<SourceLine>, index: number) => number = (
689
+ parsed: Array<SourceLine>,
690
+ index: number,
691
+ ): number => {
692
+ for (let k: number = index; k >= 0; k--) {
693
+ const line: SourceLine = parsed[k] as SourceLine;
694
+ if (line.item && (k === index || blockEnd(parsed, k) > index)) {
695
+ return k;
696
+ }
697
+ if (k < index && !line.blank && line.indent === 0 && !line.item) {
698
+ return -1;
699
+ }
700
+ }
701
+ return -1;
702
+ };
703
+
704
+ // The item line `index` is nested in, or -1 for a top-level item.
705
+ const parentItemOf: (parsed: Array<SourceLine>, index: number) => number = (
706
+ parsed: Array<SourceLine>,
707
+ index: number,
708
+ ): number => {
709
+ const indent: number = parsed[index]?.indent ?? 0;
710
+ for (let k: number = index - 1; k >= 0; k--) {
711
+ const line: SourceLine = parsed[k] as SourceLine;
712
+ if (
713
+ line.item &&
714
+ line.indent < indent &&
715
+ line.item.contentColumn <= indent &&
716
+ blockEnd(parsed, k) > index
717
+ ) {
718
+ return k;
719
+ }
720
+ if (!line.blank && line.indent === 0 && k < index && !line.item) {
721
+ return -1;
722
+ }
723
+ }
724
+ return -1;
725
+ };
726
+
727
+ /*
728
+ * The item before `index` in the same list: the nearest item above it at
729
+ * the same level, with nothing shallower in between.
730
+ */
731
+ const previousSiblingOf: (
732
+ parsed: Array<SourceLine>,
733
+ index: number,
734
+ ) => number = (parsed: Array<SourceLine>, index: number): number => {
735
+ const indent: number = parsed[index]?.indent ?? 0;
736
+ for (let k: number = index - 1; k >= 0; k--) {
737
+ const line: SourceLine = parsed[k] as SourceLine;
738
+ if (line.blank || line.indent > indent) {
739
+ continue;
740
+ }
741
+ if (line.item && indent < line.item.contentColumn) {
742
+ return k;
743
+ }
744
+ return -1;
745
+ }
746
+ return -1;
747
+ };
748
+
749
+ /*
750
+ * The items after `index` in the same list, up to line `lastLine`. A marker
751
+ * of the other kind at the same indent starts a list of its own, so it ends
752
+ * the run.
753
+ */
754
+ const followingSiblingsOf: (
755
+ parsed: Array<SourceLine>,
756
+ index: number,
757
+ lastLine: number,
758
+ ) => Array<number> = (
759
+ parsed: Array<SourceLine>,
760
+ index: number,
761
+ lastLine: number,
762
+ ): Array<number> => {
763
+ const start: SourceLine | undefined = parsed[index];
764
+ const siblings: Array<number> = [];
765
+ if (!start || !start.item) {
766
+ return siblings;
767
+ }
768
+ let j: number = blockEnd(parsed, index);
769
+ while (j < parsed.length && j <= lastLine) {
770
+ const line: SourceLine = parsed[j] as SourceLine;
771
+ if (line.blank) {
772
+ j++;
773
+ continue;
774
+ }
775
+ if (
776
+ !line.item ||
777
+ line.indent !== start.indent ||
778
+ line.item.ordered !== start.item.ordered
779
+ ) {
780
+ break;
781
+ }
782
+ siblings.push(j);
783
+ j = blockEnd(parsed, j);
784
+ }
785
+ return siblings;
786
+ };
787
+
788
+ /*
789
+ * The lines a selection covers. A selection that ends at column 0 of a line
790
+ * -- what dragging to the end of the previous line or selecting whole lines
791
+ * leaves -- does not include that line.
792
+ */
793
+ const selectedLineRange: (
794
+ text: string,
795
+ selectionStart: number,
796
+ selectionEnd: number,
797
+ ) => { first: number; last: number } = (
798
+ text: string,
799
+ selectionStart: number,
800
+ selectionEnd: number,
801
+ ): { first: number; last: number } => {
802
+ const start: number = Math.max(0, Math.min(selectionStart, text.length));
803
+ let end: number = Math.max(start, Math.min(selectionEnd, text.length));
804
+ if (end > start && text.charAt(end - 1) === "\n") {
805
+ end--;
806
+ }
807
+ const lineOf: (offset: number) => number = (offset: number): number => {
808
+ return text.slice(0, offset).split("\n").length - 1;
809
+ };
810
+ return { first: lineOf(start), last: lineOf(end) };
811
+ };
812
+
813
+ /*
814
+ * The item an indent or outdent starts from: the one holding the first
815
+ * non-blank selected line. Nothing, when that line is in a fenced code block
816
+ * or is not in a list at all.
817
+ */
818
+ const startItemOf: (
819
+ parsed: Array<SourceLine>,
820
+ first: number,
821
+ last: number,
822
+ ) => number = (
823
+ parsed: Array<SourceLine>,
824
+ first: number,
825
+ last: number,
826
+ ): number => {
827
+ let line: number = first;
828
+ while (line <= last && parsed[line]?.blank) {
829
+ line++;
830
+ }
831
+ const at: SourceLine | undefined = parsed[line];
832
+ if (line > last || !at || at.fenced) {
833
+ return -1;
834
+ }
835
+ return itemHoldingLine(parsed, line);
836
+ };
837
+
838
+ const withIndent: (line: string, columns: number) => string = (
839
+ line: string,
840
+ columns: number,
841
+ ): string => {
842
+ return `${" ".repeat(Math.max(0, columns))}${line.slice(leadingWhitespace(line).length)}`;
843
+ };
844
+
845
+ /*
846
+ * Rewrites item `index` to start at column `indent` with `marker`, and moves
847
+ * every line of its block by as much as its content column moved, so the
848
+ * lines nested in it stay nested in it -- including when the new marker is
849
+ * wider or narrower than the old one ("9." becoming "10.").
850
+ */
851
+ const moveItem: (
852
+ lines: Array<string>,
853
+ parsed: Array<SourceLine>,
854
+ index: number,
855
+ indent: number,
856
+ marker: string,
857
+ ) => void = (
858
+ lines: Array<string>,
859
+ parsed: Array<SourceLine>,
860
+ index: number,
861
+ indent: number,
862
+ marker: string,
863
+ ): void => {
864
+ const item: ListMarker | null = parsed[index]?.item || null;
865
+ if (!item) {
866
+ return;
867
+ }
868
+ const end: number = blockEnd(parsed, index);
869
+ // Tabs in the spacing would change width with the column; write spaces.
870
+ const oldMarkerEnd: number =
871
+ (parsed[index]?.indent ?? 0) + item.marker.length;
872
+ const spacing: string = item.spacing.includes("\t")
873
+ ? " ".repeat(columnsOf(item.spacing, oldMarkerEnd))
874
+ : item.spacing;
875
+ lines[index] = `${" ".repeat(indent)}${marker}${spacing}${item.rest}`;
876
+ const shift: number =
877
+ contentColumnOf(indent, marker, spacing) - item.contentColumn;
878
+ for (let j: number = index + 1; j < end; j++) {
879
+ const line: SourceLine = parsed[j] as SourceLine;
880
+ if (!line.blank) {
881
+ lines[j] = withIndent(lines[j] || "", line.indent + shift);
882
+ }
883
+ }
884
+ };
885
+
886
+ const markerAfter: (item: ListMarker, number: number) => string = (
887
+ item: ListMarker,
888
+ number: number,
889
+ ): string => {
890
+ return item.ordered ? `${number}${item.delimiter}` : item.marker;
891
+ };
892
+
893
+ /*
894
+ * Numbers an ordered list's items one after another, from `startNumber`, so
895
+ * the source reads the way the visual editor would write it. CommonMark only
896
+ * takes a list's first number, so this changes what the text says rather than
897
+ * how it renders -- except for the first item, whose number is the list's
898
+ * start.
899
+ */
900
+ const renumberList: (
901
+ lines: Array<string>,
902
+ firstItem: number,
903
+ startNumber: number,
904
+ ) => void = (
905
+ lines: Array<string>,
906
+ firstItem: number,
907
+ startNumber: number,
908
+ ): void => {
909
+ let parsed: Array<SourceLine> = parseSourceLines(lines);
910
+ const first: ListMarker | null = parsed[firstItem]?.item || null;
911
+ if (!first || !first.ordered) {
912
+ return;
913
+ }
914
+ const items: Array<number> = [
915
+ firstItem,
916
+ ...followingSiblingsOf(parsed, firstItem, lines.length),
917
+ ];
918
+ let number: number = startNumber;
919
+ for (const index of items) {
920
+ const item: ListMarker | null = parsed[index]?.item || null;
921
+ if (item) {
922
+ const marker: string = `${number}${item.delimiter}`;
923
+ if (marker !== item.marker) {
924
+ moveItem(lines, parsed, index, parsed[index]?.indent ?? 0, marker);
925
+ parsed = parseSourceLines(lines);
926
+ }
927
+ }
928
+ number++;
929
+ }
930
+ };
931
+
932
+ /*
933
+ * Where an offset in the old text lands in the new one. Only the start of a
934
+ * line (its indent and marker) ever changes, so a position in the text after
935
+ * that moves with it; a position inside the part that changed stays put, or
936
+ * moves back to the new line's end if it would pass it. A non-empty selection
937
+ * that started at column 0 keeps starting there, so whole lines stay selected
938
+ * and a second Tab indents them again.
939
+ */
940
+ const mapOffset: (
941
+ before: Array<string>,
942
+ after: Array<string>,
943
+ offset: number,
944
+ keepLineStart: boolean,
945
+ ) => number = (
946
+ before: Array<string>,
947
+ after: Array<string>,
948
+ offset: number,
949
+ keepLineStart: boolean,
950
+ ): number => {
951
+ let remaining: number = offset;
952
+ let line: number = 0;
953
+ while (line < before.length - 1 && remaining > (before[line] || "").length) {
954
+ remaining -= (before[line] || "").length + 1;
955
+ line++;
956
+ }
957
+ const oldLine: string = before[line] || "";
958
+ const newLine: string = after[line] || "";
959
+ let column: number = Math.max(0, Math.min(remaining, oldLine.length));
960
+ if (!(keepLineStart && column === 0)) {
961
+ // Everything after the changed start of the line is shared by both.
962
+ const unchanged: number = commonSuffixLength(oldLine, newLine);
963
+ const oldChangedEnd: number = oldLine.length - unchanged;
964
+ const newChangedEnd: number = newLine.length - unchanged;
965
+ column =
966
+ column >= oldChangedEnd
967
+ ? column - oldChangedEnd + newChangedEnd
968
+ : Math.min(column, newChangedEnd);
969
+ column = Math.max(0, Math.min(column, newLine.length));
970
+ }
971
+ let result: number = 0;
972
+ for (let k: number = 0; k < line; k++) {
973
+ result += (after[k] || "").length + 1;
974
+ }
975
+ return result + column;
976
+ };
977
+
978
+ const commonSuffixLength: (a: string, b: string) => number = (
979
+ a: string,
980
+ b: string,
981
+ ): number => {
982
+ let length: number = 0;
983
+ while (
984
+ length < a.length &&
985
+ length < b.length &&
986
+ a.charAt(a.length - 1 - length) === b.charAt(b.length - 1 - length)
987
+ ) {
988
+ length++;
989
+ }
990
+ return length;
991
+ };
992
+
993
+ const finishEdit: (
994
+ before: Array<string>,
995
+ after: Array<string>,
996
+ selectionStart: number,
997
+ selectionEnd: number,
998
+ ) => MarkdownTextEdit | null = (
999
+ before: Array<string>,
1000
+ after: Array<string>,
1001
+ selectionStart: number,
1002
+ selectionEnd: number,
1003
+ ): MarkdownTextEdit | null => {
1004
+ const text: string = after.join("\n");
1005
+ if (text === before.join("\n")) {
1006
+ return null;
1007
+ }
1008
+ const collapsed: boolean = selectionStart === selectionEnd;
1009
+ const start: number = mapOffset(before, after, selectionStart, !collapsed);
1010
+ const end: number = collapsed
1011
+ ? start
1012
+ : Math.max(start, mapOffset(before, after, selectionEnd, false));
1013
+ return { text, selectionStart: start, selectionEnd: end };
1014
+ };
1015
+
1016
+ /*
1017
+ * Indent in the source: the selected items move to the content column of the
1018
+ * item before them, and everything nested in them moves by the same amount.
1019
+ * An item that becomes the first child starts a new list (an ordered one is
1020
+ * renumbered from 1, or it would render as start="2"); one that joins
1021
+ * existing children takes their kind of marker and the next number. The list
1022
+ * the items left is renumbered. Returns null when there is nothing to indent
1023
+ * -- the caret is not in a list, the item is its list's first, or the line is
1024
+ * in a fenced code block.
1025
+ */
1026
+ export const indentMarkdownLines: (
1027
+ text: string,
1028
+ selectionStart: number,
1029
+ selectionEnd: number,
1030
+ ) => MarkdownTextEdit | null = (
1031
+ text: string,
1032
+ selectionStart: number,
1033
+ selectionEnd: number,
1034
+ ): MarkdownTextEdit | null => {
1035
+ const before: Array<string> = text.split("\n");
1036
+ const lines: Array<string> = before.slice();
1037
+ let parsed: Array<SourceLine> = parseSourceLines(lines);
1038
+ const range: { first: number; last: number } = selectedLineRange(
1039
+ text,
1040
+ selectionStart,
1041
+ selectionEnd,
1042
+ );
1043
+ const start: number = startItemOf(parsed, range.first, range.last);
1044
+ if (start === -1) {
1045
+ return null;
1046
+ }
1047
+ const previous: number = previousSiblingOf(parsed, start);
1048
+ const previousItem: ListMarker | null = parsed[previous]?.item || null;
1049
+ if (previous === -1 || !previousItem) {
1050
+ return null;
1051
+ }
1052
+ const items: Array<number> = [
1053
+ start,
1054
+ ...followingSiblingsOf(parsed, start, range.last),
1055
+ ];
1056
+ const column: number = previousItem.contentColumn;
1057
+
1058
+ for (const index of items) {
1059
+ const item: ListMarker | null = parsed[index]?.item || null;
1060
+ if (!item) {
1061
+ continue;
1062
+ }
1063
+ let joins: number = -1;
1064
+ for (let k: number = index - 1; k > previous; k--) {
1065
+ if (parsed[k]?.item && parentItemOf(parsed, k) === previous) {
1066
+ joins = k;
1067
+ break;
1068
+ }
1069
+ }
1070
+ const joined: ListMarker | null = parsed[joins]?.item || null;
1071
+ let marker: string;
1072
+ if (joined) {
1073
+ marker = markerAfter(joined, joined.number + 1);
1074
+ } else {
1075
+ marker = item.ordered ? `1${item.delimiter}` : item.marker;
1076
+ }
1077
+ moveItem(lines, parsed, index, column, marker);
1078
+ parsed = parseSourceLines(lines);
1079
+ }
1080
+
1081
+ if (previousItem.ordered) {
1082
+ renumberList(lines, previous, previousItem.number);
1083
+ }
1084
+ return finishEdit(before, lines, selectionStart, selectionEnd);
1085
+ };
1086
+
1087
+ /*
1088
+ * Outdent in the source: the selected items move out to their parent's
1089
+ * column and take the parent list's kind of marker, numbered on from the
1090
+ * parent (otherwise "1. a\n - b\n2. c" would come out as three separate
1091
+ * lists). The items that followed them at their old level stay where they
1092
+ * are, which now nests them in the last moved item -- re-indented to its
1093
+ * content column if its marker is wider -- and they start a new list, so an
1094
+ * ordered one is renumbered from 1. Returns null for a top-level item, a line
1095
+ * outside any list, or one in a fenced code block.
1096
+ */
1097
+ export const outdentMarkdownLines: (
1098
+ text: string,
1099
+ selectionStart: number,
1100
+ selectionEnd: number,
1101
+ ) => MarkdownTextEdit | null = (
1102
+ text: string,
1103
+ selectionStart: number,
1104
+ selectionEnd: number,
1105
+ ): MarkdownTextEdit | null => {
1106
+ const before: Array<string> = text.split("\n");
1107
+ const lines: Array<string> = before.slice();
1108
+ let parsed: Array<SourceLine> = parseSourceLines(lines);
1109
+ const range: { first: number; last: number } = selectedLineRange(
1110
+ text,
1111
+ selectionStart,
1112
+ selectionEnd,
1113
+ );
1114
+ const start: number = startItemOf(parsed, range.first, range.last);
1115
+ if (start === -1) {
1116
+ return null;
1117
+ }
1118
+ const parent: number = parentItemOf(parsed, start);
1119
+ const parentItem: ListMarker | null = parsed[parent]?.item || null;
1120
+ if (parent === -1 || !parentItem) {
1121
+ return null;
1122
+ }
1123
+ const items: Array<number> = [
1124
+ start,
1125
+ ...followingSiblingsOf(parsed, start, range.last),
1126
+ ];
1127
+ const lastMoved: number = items[items.length - 1] ?? start;
1128
+ const oldIndent: number = parsed[start]?.indent ?? 0;
1129
+ const trailing: Array<number> = followingSiblingsOf(
1130
+ parsed,
1131
+ lastMoved,
1132
+ lines.length,
1133
+ );
1134
+ const firstTrailing: number | undefined = trailing[0];
1135
+ const lastTrailing: number | undefined = trailing[trailing.length - 1];
1136
+ const trailingEnd: number =
1137
+ lastTrailing === undefined ? -1 : blockEnd(parsed, lastTrailing);
1138
+ const newIndent: number = parsed[parent]?.indent ?? 0;
1139
+
1140
+ let number: number = parentItem.number;
1141
+ for (const index of items) {
1142
+ number++;
1143
+ moveItem(lines, parsed, index, newIndent, markerAfter(parentItem, number));
1144
+ parsed = parseSourceLines(lines);
1145
+ }
1146
+
1147
+ if (firstTrailing !== undefined) {
1148
+ const moved: ListMarker | null = parsed[lastMoved]?.item || null;
1149
+ const shortfall: number = moved ? moved.contentColumn - oldIndent : 0;
1150
+ if (shortfall > 0) {
1151
+ for (let j: number = firstTrailing; j < trailingEnd; j++) {
1152
+ const line: SourceLine = parsed[j] as SourceLine;
1153
+ if (!line.blank) {
1154
+ lines[j] = withIndent(lines[j] || "", line.indent + shortfall);
1155
+ }
1156
+ }
1157
+ parsed = parseSourceLines(lines);
1158
+ }
1159
+ renumberList(lines, firstTrailing, 1);
1160
+ }
1161
+
1162
+ if (parentItem.ordered) {
1163
+ renumberList(lines, parent, parentItem.number);
1164
+ }
1165
+ return finishEdit(before, lines, selectionStart, selectionEnd);
1166
+ };
1167
+
1168
+ export type MarkdownListKind = "bullet" | "ordered" | "task";
1169
+
1170
+ const RE_TASK_LINE: RegExp = /^[-*+][ \t]+\[([ xX])\](?:[ \t]|$)/;
1171
+ const RE_BULLET_LINE: RegExp = /^[-*+](?:[ \t]|$)/;
1172
+ const RE_ORDERED_LINE: RegExp = /^\d{1,9}[.)](?:[ \t]|$)/;
1173
+ /*
1174
+ * A marker at the start of a source line's text. As in the visual editor, a
1175
+ * bullet character only counts before a space or tab (or on its own):
1176
+ * "–5°C" keeps its minus sign, and "- –5°C" is an item, not a double bullet.
1177
+ */
1178
+ const RE_SOURCE_MARKER: RegExp = new RegExp(
1179
+ `^(?:[-*+][ \\t]+(?:\\[[ xX]\\][ \\t]+)?|\\d{1,9}[.)][ \\t]+|[${TEXT_BULLET_GLYPHS}](?:[ \\t\\u00a0]+|$)|[${TAB_ONLY_BULLET_GLYPHS}]\\t[ \\t]*)`,
1180
+ );
1181
+
1182
+ /*
1183
+ * The kind of item a line is. A line whose text still starts with a second
1184
+ * marker after its own -- the "- •\tService down" a double bullet saved as
1185
+ * -- counts as none, so the button repairs it instead of taking the list off.
1186
+ */
1187
+ const listKindOf: (body: string) => MarkdownListKind | null = (
1188
+ body: string,
1189
+ ): MarkdownListKind | null => {
1190
+ let kind: MarkdownListKind | null = null;
1191
+ if (RE_TASK_LINE.test(body)) {
1192
+ kind = "task";
1193
+ } else if (RE_BULLET_LINE.test(body)) {
1194
+ kind = "bullet";
1195
+ } else if (RE_ORDERED_LINE.test(body)) {
1196
+ kind = "ordered";
1197
+ }
1198
+ const own: RegExpMatchArray | null = body.match(RE_SOURCE_MARKER);
1199
+ if (kind && own && RE_SOURCE_MARKER.test(body.slice(own[0].length))) {
1200
+ return null;
1201
+ }
1202
+ return kind;
1203
+ };
1204
+
1205
+ // Every marker a line starts with -- "- •\tx" (a double bullet) loses both.
1206
+ const stripSourceMarkers: (body: string) => string = (body: string): string => {
1207
+ let stripped: string = body;
1208
+ for (let pass: number = 0; pass < 3; pass++) {
1209
+ const match: RegExpMatchArray | null = stripped.match(RE_SOURCE_MARKER);
1210
+ if (!match || match[0].length === 0) {
1211
+ break;
1212
+ }
1213
+ stripped = stripped.slice(match[0].length);
1214
+ }
1215
+ return stripped;
1216
+ };
1217
+
1218
+ /*
1219
+ * The number an item gets from the Numbered List button: 1 when it starts a
1220
+ * list of its own, otherwise one on from the item before it at its level --
1221
+ * counted per list, so a nested list starts again at 1 rather than carrying
1222
+ * on from its parent's numbers.
1223
+ */
1224
+ const nextListNumber: (
1225
+ parsed: Array<SourceLine>,
1226
+ index: number,
1227
+ counters: Map<number, number>,
1228
+ ) => number = (
1229
+ parsed: Array<SourceLine>,
1230
+ index: number,
1231
+ counters: Map<number, number>,
1232
+ ): number => {
1233
+ const parent: number = parentItemOf(parsed, index);
1234
+ const previous: number = previousSiblingOf(parsed, index);
1235
+ let number: number = 1;
1236
+ if (previous !== -1) {
1237
+ const counted: number | undefined = counters.get(parent);
1238
+ const previousItem: ListMarker | null = parsed[previous]?.item || null;
1239
+ if (counted !== undefined) {
1240
+ number = counted + 1;
1241
+ } else if (previousItem && previousItem.ordered) {
1242
+ number = previousItem.number + 1;
1243
+ }
1244
+ }
1245
+ counters.set(parent, number);
1246
+ return number;
1247
+ };
1248
+
1249
+ /*
1250
+ * The Bullet List, Numbered List and Task List buttons in the source. Every
1251
+ * selected line that has text becomes an item of that kind: whatever marker
1252
+ * it already had -- another kind's, or a bullet character pasted as text --
1253
+ * is replaced rather than kept beside the new one, and numbered lines count
1254
+ * 1, 2, 3 down each list they are in. When every one of those lines already
1255
+ * is an item of that kind, the button takes the markers off instead. A task
1256
+ * item keeps its checked state. With no text selected, the caret's own line
1257
+ * is used even when it is empty, to start a list there. Returns null when
1258
+ * nothing changed (the caret is inside a fenced code block).
1259
+ */
1260
+ export const toggleMarkdownList: (
1261
+ text: string,
1262
+ selectionStart: number,
1263
+ selectionEnd: number,
1264
+ kind: MarkdownListKind,
1265
+ ) => MarkdownTextEdit | null = (
1266
+ text: string,
1267
+ selectionStart: number,
1268
+ selectionEnd: number,
1269
+ kind: MarkdownListKind,
1270
+ ): MarkdownTextEdit | null => {
1271
+ const before: Array<string> = text.split("\n");
1272
+ const lines: Array<string> = before.slice();
1273
+ const parsed: Array<SourceLine> = parseSourceLines(lines);
1274
+ const range: { first: number; last: number } = selectedLineRange(
1275
+ text,
1276
+ selectionStart,
1277
+ selectionEnd,
1278
+ );
1279
+ let targets: Array<number> = [];
1280
+ for (let index: number = range.first; index <= range.last; index++) {
1281
+ const line: SourceLine | undefined = parsed[index];
1282
+ if (line && !line.blank && !line.fenced) {
1283
+ targets.push(index);
1284
+ }
1285
+ }
1286
+ if (targets.length === 0 && range.first === range.last) {
1287
+ if (parsed[range.first]?.fenced) {
1288
+ return null;
1289
+ }
1290
+ targets = [range.first];
1291
+ }
1292
+ if (targets.length === 0) {
1293
+ return null;
1294
+ }
1295
+
1296
+ const bodies: Array<{ indent: string; body: string }> = targets.map(
1297
+ (index: number): { indent: string; body: string } => {
1298
+ const line: string = lines[index] || "";
1299
+ const indent: string = leadingWhitespace(line);
1300
+ return { indent, body: line.slice(indent.length) };
1301
+ },
1302
+ );
1303
+ const allOfKind: boolean = bodies.every(
1304
+ (entry: { indent: string; body: string }): boolean => {
1305
+ return listKindOf(entry.body) === kind;
1306
+ },
1307
+ );
1308
+
1309
+ if (allOfKind) {
1310
+ targets.forEach((index: number, position: number): void => {
1311
+ const entry: { indent: string; body: string } | undefined =
1312
+ bodies[position];
1313
+ if (entry) {
1314
+ lines[index] = `${entry.indent}${stripSourceMarkers(entry.body)}`;
1315
+ }
1316
+ });
1317
+ return finishEdit(before, lines, selectionStart, selectionEnd);
1318
+ }
1319
+
1320
+ /*
1321
+ * Top down, re-reading the text after each line. "1. " is wider than
1322
+ * "- ", so an item's text starts a column further in once it is numbered
1323
+ * -- and the lines nested in it (its sub-items, a code block in it) move
1324
+ * with it, or " - b" under a new "1. a" would fall out of the item: the
1325
+ * button turned "- a\n - b\n- c" into the flat list "1. a\n 2. b\n3. c".
1326
+ * A line's own indent can have moved with its parent before it is reached.
1327
+ */
1328
+ let current: Array<SourceLine> = parsed;
1329
+ const counters: Map<number, number> = new Map<number, number>();
1330
+ for (const index of targets) {
1331
+ const line: string = lines[index] || "";
1332
+ const indent: string = leadingWhitespace(line);
1333
+ const body: string = line.slice(indent.length);
1334
+ let prefix: string;
1335
+ if (kind === "ordered") {
1336
+ prefix = `${nextListNumber(current, index, counters)}. `;
1337
+ } else if (kind === "task") {
1338
+ const task: RegExpMatchArray | null = body.match(RE_TASK_LINE);
1339
+ const checked: boolean = Boolean(task && (task[1] || "").trim());
1340
+ prefix = checked ? "- [x] " : "- [ ] ";
1341
+ } else {
1342
+ prefix = "- ";
1343
+ }
1344
+ lines[index] = `${indent}${prefix}${stripSourceMarkers(body)}`;
1345
+ const item: ListMarker | null = current[index]?.item || null;
1346
+ if (item) {
1347
+ // A task's "[ ] " is the item's text, which starts after "- ".
1348
+ const width: number = kind === "ordered" ? prefix.length : 2;
1349
+ const shift: number = columnsOf(indent, 0) + width - item.contentColumn;
1350
+ const end: number = blockEnd(current, index);
1351
+ for (let j: number = index + 1; j < end && shift !== 0; j++) {
1352
+ const nested: SourceLine = current[j] as SourceLine;
1353
+ if (!nested.blank) {
1354
+ lines[j] = withIndent(lines[j] || "", nested.indent + shift);
1355
+ }
1356
+ }
1357
+ }
1358
+ current = parseSourceLines(lines);
1359
+ }
1360
+
1361
+ return finishEdit(before, lines, selectionStart, selectionEnd);
1362
+ };