@oneuptime/common 14.0.2 → 14.0.5

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 (765) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/AlertFeed.ts +2 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
  4. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
  5. package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
  6. package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
  7. package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
  8. package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
  9. package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
  10. package/Models/DatabaseModels/Incident.ts +55 -0
  11. package/Models/DatabaseModels/IncidentAlert.ts +540 -0
  12. package/Models/DatabaseModels/IncidentFeed.ts +2 -0
  13. package/Models/DatabaseModels/Index.ts +18 -0
  14. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
  15. package/Models/DatabaseModels/Project.ts +60 -0
  16. package/Models/DatabaseModels/RumApplication.ts +52 -1
  17. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  18. package/Models/DatabaseModels/TelemetryException.ts +2 -0
  19. package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  25. package/Server/Middleware/MultipartFormData.ts +1 -1
  26. package/Server/Middleware/TelemetryIngest.ts +15 -8
  27. package/Server/Services/AlertReminderRuleService.ts +100 -24
  28. package/Server/Services/DatabaseServerEndpointService.ts +895 -0
  29. package/Server/Services/DatabaseServerFeedService.ts +128 -0
  30. package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
  31. package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
  32. package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
  33. package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
  34. package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
  35. package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
  36. package/Server/Services/DatabaseServerService.ts +4546 -0
  37. package/Server/Services/DatabaseService.ts +14 -8
  38. package/Server/Services/DockerResourceService.ts +43 -2
  39. package/Server/Services/IncidentAlertService.ts +1811 -0
  40. package/Server/Services/IncidentReminderRuleService.ts +103 -23
  41. package/Server/Services/IncidentService.ts +210 -10
  42. package/Server/Services/IncidentStateTimelineService.ts +24 -0
  43. package/Server/Services/Index.ts +18 -0
  44. package/Server/Services/InventoryItemService.ts +113 -5
  45. package/Server/Services/IoTDeviceService.ts +145 -37
  46. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  47. package/Server/Services/PodmanResourceService.ts +43 -2
  48. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  49. package/Server/Services/ServiceService.ts +1 -1
  50. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  51. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  52. package/Server/Services/UserService.ts +14 -1
  53. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  54. package/Server/Types/Database/QueryHelper.ts +30 -1
  55. package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
  56. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  57. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
  58. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  59. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
  60. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  61. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  62. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  63. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  64. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  65. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  66. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  67. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  68. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  69. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
  70. package/Server/Utils/StartServer.ts +26 -6
  71. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  72. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  73. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  74. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  75. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  76. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  77. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  78. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  79. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  80. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  81. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  83. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  84. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  85. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  86. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  87. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  88. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  89. package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
  90. package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
  91. package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
  92. package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
  93. package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
  94. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  95. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  96. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  97. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  98. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  99. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  100. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  101. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  102. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  103. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  104. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  105. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  106. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  107. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  108. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  109. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  110. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  111. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  112. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  113. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  114. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  115. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  116. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  117. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  118. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  119. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  120. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  121. package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
  122. package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
  123. package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
  124. package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
  125. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  126. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  127. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
  128. package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
  129. package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
  130. package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
  131. package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
  132. package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
  133. package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
  134. package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
  135. package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
  136. package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
  137. package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
  138. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
  139. package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
  140. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
  141. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
  142. package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
  143. package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
  144. package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
  145. package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
  146. package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
  147. package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
  148. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  149. package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
  150. package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
  151. package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
  152. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  153. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  154. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  155. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  156. package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
  157. package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
  158. package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
  159. package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
  160. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  161. package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
  162. package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
  163. package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
  164. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  165. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  166. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  167. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  168. package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
  169. package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
  170. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  171. package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
  172. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  173. package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
  174. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
  175. package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
  176. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  177. package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
  178. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  179. package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
  180. package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
  181. package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
  182. package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
  183. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  184. package/Tests/ClassStrings.ts +178 -0
  185. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  186. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  187. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  188. package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
  189. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  190. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
  191. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  192. package/Tests/RenderedMarkup.ts +518 -0
  193. package/Tests/ResponsiveVisibility.test.ts +490 -4
  194. package/Tests/ResponsiveVisibility.ts +505 -52
  195. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  196. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  197. package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
  198. package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
  199. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  200. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  201. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  202. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  203. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  204. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  205. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  206. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  207. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  208. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  209. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  210. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  211. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  212. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
  213. package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
  214. package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
  215. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  216. package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
  217. package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
  218. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  219. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  220. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  221. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  222. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  223. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  224. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  225. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  226. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  227. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  228. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  229. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  230. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  231. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  232. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  233. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  234. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  235. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  236. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  237. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  238. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  239. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  240. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  241. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  242. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  243. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  244. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  245. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  246. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  247. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  248. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  249. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  250. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  251. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  252. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
  253. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  254. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  255. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  256. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  257. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  258. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  259. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  260. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  261. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  262. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  263. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  264. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  265. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  266. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  267. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  268. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  269. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  270. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  271. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
  272. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  273. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  274. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  275. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  276. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  277. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  278. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  279. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  280. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  281. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  282. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  283. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  284. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  285. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  286. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  287. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  288. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  289. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  290. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  291. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  292. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  293. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
  294. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
  295. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  296. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  297. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  298. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  299. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  300. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  301. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
  302. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  303. package/Tests/Types/Rum/WebVitals.test.ts +173 -0
  304. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  305. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  306. package/Tests/UI/Components/Card.test.tsx +93 -2
  307. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  308. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  309. package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
  310. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  311. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  312. package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
  313. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  314. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  315. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
  316. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
  317. package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
  318. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  319. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  320. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  321. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  322. package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
  323. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  324. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  325. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
  326. package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
  327. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
  328. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
  329. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  330. package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
  331. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
  332. package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
  333. package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
  334. package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
  335. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
  336. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  337. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
  338. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
  339. package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
  340. package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
  341. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  342. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  343. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +80 -0
  344. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +23 -0
  345. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  346. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  347. package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
  348. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  349. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
  350. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  351. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  352. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  353. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  354. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  355. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  356. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  357. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  358. package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
  359. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  360. package/Tests/tsconfig.json +16 -0
  361. package/Types/AI/AIResourceContext.ts +7 -0
  362. package/Types/Dashboard/DashboardTemplates.ts +2 -1
  363. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  364. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  365. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  366. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  367. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  368. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  369. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  370. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  371. package/Types/Email/EmailTemplateType.ts +1 -0
  372. package/Types/Incident/IncidentAlertLink.ts +38 -0
  373. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  374. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  375. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  376. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  377. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  378. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  379. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  380. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  381. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  382. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  383. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  384. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  385. package/Types/Permission.ts +315 -0
  386. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  387. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  388. package/Types/Rules/RuleRun.ts +12 -0
  389. package/Types/Rum/SessionReplay.ts +25 -6
  390. package/Types/Rum/WebVitals.ts +52 -0
  391. package/Types/Telemetry/EntityType.ts +23 -0
  392. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  393. package/Types/Telemetry/ServiceType.ts +8 -0
  394. package/UI/Components/Banner/Banner.tsx +1 -1
  395. package/UI/Components/Card/Card.tsx +1 -1
  396. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  397. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  398. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  399. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  400. package/UI/Components/Detail/FieldLabel.tsx +8 -0
  401. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  402. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  403. package/UI/Components/Forms/BasicForm.tsx +1 -1
  404. package/UI/Components/Header/Header.tsx +1 -1
  405. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  406. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  407. package/UI/Components/InfoCard/InfoCard.tsx +47 -1
  408. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  409. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  410. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  411. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  412. package/UI/Components/ModelTable/BaseModelTable.tsx +99 -21
  413. package/UI/Components/ModelTable/Column.ts +5 -0
  414. package/UI/Components/Navbar/NavBar.tsx +9 -2
  415. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  416. package/UI/Components/Page/Page.tsx +1 -1
  417. package/UI/Components/Pagination/Pagination.tsx +3 -3
  418. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  419. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  420. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  421. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  422. package/UI/Components/Table/TableHeader.tsx +47 -2
  423. package/UI/Components/Table/Types/Column.ts +7 -0
  424. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  425. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  426. package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
  427. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  428. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  429. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  430. package/UI/Styles/Theme.css +8 -1
  431. package/UI/Utils/Navigation.ts +89 -42
  432. package/UI/Utils/PermissionGate.ts +11 -2
  433. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  434. package/UI/Utils/TelemetryService.ts +4 -3
  435. package/Utils/Incident/IncidentFromAlerts.ts +516 -0
  436. package/Utils/LabelRuleImportExport.ts +2 -0
  437. package/Utils/MetricUnitUtil.ts +103 -11
  438. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  439. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  440. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  441. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  442. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  443. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  444. package/Utils/Rum/SessionTraceState.ts +212 -0
  445. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  446. package/Utils/Telemetry/EntityKey.ts +176 -0
  447. package/Utils/ValueFormatter.ts +16 -0
  448. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  449. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  450. package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
  451. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  452. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  453. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  454. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  455. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  456. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  457. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  458. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  459. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  460. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  461. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  462. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  463. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  464. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  465. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  466. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  467. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  468. package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
  469. package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
  470. package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
  471. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  472. package/build/dist/Models/DatabaseModels/Index.js +18 -0
  473. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  474. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  475. package/build/dist/Models/DatabaseModels/Project.js +62 -0
  476. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  477. package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
  478. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  479. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  480. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  481. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  482. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  483. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  484. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  485. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
  486. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
  487. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
  488. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
  489. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  490. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  491. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  492. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  493. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  494. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  495. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  496. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  497. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  498. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  499. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  500. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  501. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  502. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  503. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  504. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  505. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  506. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  507. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  508. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  509. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  510. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  511. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  512. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  513. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  514. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  515. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  516. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  517. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  518. package/build/dist/Server/Services/DatabaseService.js +8 -4
  519. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  520. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  521. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  522. package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
  523. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
  524. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  525. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  526. package/build/dist/Server/Services/IncidentService.js +164 -12
  527. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  528. package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
  529. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  530. package/build/dist/Server/Services/Index.js +18 -0
  531. package/build/dist/Server/Services/Index.js.map +1 -1
  532. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  533. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  534. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  535. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  536. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  537. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  538. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  539. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  540. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  541. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  542. package/build/dist/Server/Services/ServiceService.js +1 -1
  543. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  544. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  545. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  546. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  547. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  548. package/build/dist/Server/Services/UserService.js +13 -1
  549. package/build/dist/Server/Services/UserService.js.map +1 -1
  550. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  551. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  552. package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
  553. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  554. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
  555. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  556. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  557. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  558. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
  559. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  560. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  561. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  562. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  563. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  564. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  565. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  566. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  567. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  568. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  569. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  570. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  571. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  572. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  573. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  574. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  575. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  576. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  577. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  578. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  579. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  580. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  581. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  582. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
  583. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  584. package/build/dist/Server/Utils/StartServer.js +20 -4
  585. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  586. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  587. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  588. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  589. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  590. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  591. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  592. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  593. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  594. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  595. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  596. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  597. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  598. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  599. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  600. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  601. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  602. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  603. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  604. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  605. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  606. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  607. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  608. package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
  609. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  610. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  611. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  612. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  613. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  614. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  615. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  616. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  617. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  618. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  619. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  620. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  621. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  622. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  623. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  624. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  625. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  626. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  627. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  628. package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
  629. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
  630. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  631. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  632. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  633. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  634. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  635. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  636. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  637. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  638. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  639. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  640. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  641. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  642. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  643. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  644. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  645. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  646. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  647. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  648. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  649. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  650. package/build/dist/Types/Permission.js +276 -0
  651. package/build/dist/Types/Permission.js.map +1 -1
  652. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  653. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  654. package/build/dist/Types/Rules/RuleRun.js +4 -0
  655. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  656. package/build/dist/Types/Rum/WebVitals.js +25 -0
  657. package/build/dist/Types/Rum/WebVitals.js.map +1 -1
  658. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  659. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  660. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  661. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  662. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  663. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  664. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  665. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  666. package/build/dist/UI/Components/Card/Card.js +1 -1
  667. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  668. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  669. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  670. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  671. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  672. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  673. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  674. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  675. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  676. package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
  677. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  678. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  679. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  680. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  681. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  682. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  683. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  684. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  685. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  686. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  687. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  688. package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
  689. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  690. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  691. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  692. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  693. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  694. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  695. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  696. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  697. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  698. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +70 -18
  699. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  700. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  701. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  702. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  703. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  704. package/build/dist/UI/Components/Page/Page.js +1 -1
  705. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  706. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  707. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  708. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  709. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  710. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  711. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  712. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  713. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  714. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  715. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  716. package/build/dist/UI/Components/Table/TableHeader.js +18 -2
  717. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  718. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  719. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  720. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  721. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  722. package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
  723. package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
  724. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  725. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  726. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  727. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  728. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  729. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  730. package/build/dist/UI/Utils/Navigation.js +66 -33
  731. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  732. package/build/dist/UI/Utils/PermissionGate.js +4 -2
  733. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  734. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  735. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  736. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  737. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  738. package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
  739. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
  740. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  741. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  742. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  743. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  744. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  745. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  746. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  747. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  748. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  749. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  750. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  751. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  752. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  753. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  754. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  755. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  756. package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
  757. package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
  758. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  759. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  760. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  761. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  762. package/build/dist/Utils/ValueFormatter.js +15 -0
  763. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  764. package/package.json +1 -1
  765. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,1407 @@
1
+ import { getDatabaseSystemDisplayName, getDatabaseSystemFamily, getDefaultDatabasePort, normalizeDatabaseSystem, trimTrailingCharacter, } from "./DatabaseSystem";
2
+ /*
3
+ * DNS suffixes that only resolve inside one network: `.local` (mDNS, and the
4
+ * `cluster.local` Kubernetes domain), `.internal` (ICANN's private-use TLD —
5
+ * `ec2.internal`, `compute.internal`, GCE's `c.<project>.internal`),
6
+ * `.home.arpa` (RFC 8375) and `.localdomain` (the placeholder domain of a
7
+ * machine with none). The same name in two VPCs or clusters can be two
8
+ * different servers, so they are qualified like private IPs.
9
+ */
10
+ export const NETWORK_SCOPED_NAME_SUFFIXES = [
11
+ ".local",
12
+ ".internal",
13
+ ".home.arpa",
14
+ ".localdomain",
15
+ ];
16
+ /*
17
+ * The attributes a SQL Server client span may name its instance in, most
18
+ * specific first: the legacy `db.mssql.instance_name`, then the instance
19
+ * half of `db.namespace` (`instance|database` for a named instance).
20
+ */
21
+ export const DATABASE_INSTANCE_NAME_ATTRIBUTE = "db.mssql.instance_name";
22
+ export const DATABASE_NAMESPACE_ATTRIBUTE = "db.namespace";
23
+ export const DATABASE_INSTANCE_ATTRIBUTES = [
24
+ DATABASE_INSTANCE_NAME_ATTRIBUTE,
25
+ DATABASE_NAMESPACE_ATTRIBUTE,
26
+ ];
27
+ const SQL_SERVER_SYSTEM = "microsoft.sql_server";
28
+ // The default instance: reached on the engine's default port, named by none.
29
+ const SQL_SERVER_DEFAULT_INSTANCE = "mssqlserver";
30
+ /*
31
+ * SQL Server instance names: at most 16 letters, digits, "_" and "$"
32
+ * (lowercased here). "#" is refused: it would end the address as a URL
33
+ * fragment, and the name could not round-trip.
34
+ */
35
+ const SQL_SERVER_INSTANCE_REGEX = /^[a-z0-9_$-]{1,16}$/;
36
+ // `scheme://`, including the JDBC `jdbc:postgresql://` spelling.
37
+ const URL_SCHEME_REGEX = /^(?:jdbc:)?[a-z][a-z0-9+.-]*:\/\//i;
38
+ /*
39
+ * Where the address part of a value ends: a path, a query, a fragment, or
40
+ * the `;property=value` list of JDBC SQL Server URLs.
41
+ */
42
+ const ADDRESS_END_REGEX = /[/?#;]/;
43
+ /*
44
+ * ADO.NET / SQL Server `tcp:host,1433` protocol prefix. Not stripped when
45
+ * what follows is only digits, so a host literally named "tcp" with a port
46
+ * ("tcp:5432") is still read as host:port.
47
+ */
48
+ const SQL_SERVER_TCP_PREFIX_REGEX = /^tcp:(?!\d+$)/i;
49
+ /*
50
+ * SQL Server spellings of "this machine": `(local)`, `.` and LocalDB. They
51
+ * are mapped to "localhost" so the loopback rule treats them like any other
52
+ * loopback address.
53
+ */
54
+ const LOCAL_MACHINE_ALIASES = new Set([
55
+ "(local)",
56
+ ".",
57
+ "(localdb)",
58
+ ]);
59
+ /*
60
+ * "localhost" and the /etc/hosts names distributions give the loopback
61
+ * address. Not `*.localhost`, but they resolve to 127.0.0.1 / ::1 on the
62
+ * caller's own machine all the same.
63
+ */
64
+ const LOOPBACK_HOST_NAMES = new Set([
65
+ "localhost",
66
+ "localhost.localdomain",
67
+ "localhost4",
68
+ "localhost4.localdomain4",
69
+ "localhost6",
70
+ "localhost6.localdomain6",
71
+ "ip6-localhost",
72
+ "ip6-loopback",
73
+ ]);
74
+ /*
75
+ * Names that resolve to the machine the caller runs on (Docker Desktop,
76
+ * Podman, kind), so like loopback they mean something different for every
77
+ * caller. Besides these, every `*.docker.internal` name and every
78
+ * `host.<tool>.internal` name (minikube, k3d, Lima, OrbStack, Rancher
79
+ * Desktop) is host-relative too (isHostRelativeDatabaseHost).
80
+ */
81
+ const HOST_RELATIVE_NAMES = new Set([
82
+ "host.docker.internal",
83
+ "host.containers.internal",
84
+ "gateway.docker.internal",
85
+ "docker.for.mac.localhost",
86
+ "kubernetes.docker.internal",
87
+ ]);
88
+ const DOCKER_DESKTOP_SUFFIX = ".docker.internal";
89
+ const EPHEMERAL_CLOUD_PLATFORMS = new Set([
90
+ "aws_ecs",
91
+ "aws_lambda",
92
+ "aws_app_runner",
93
+ "gcp_cloud_run",
94
+ "gcp_cloud_functions",
95
+ "gcp_app_engine",
96
+ "azure_container_apps",
97
+ "azure_container_instances",
98
+ "azure_functions",
99
+ ]);
100
+ const KUBERNETES_IDENTITY_ATTRIBUTES = [
101
+ "k8s.pod.name",
102
+ "k8s.namespace.name",
103
+ "k8s.cluster.name",
104
+ "k8s.node.name",
105
+ ];
106
+ const KUBERNETES_CLUSTER_DOMAIN_SUFFIX = ".svc.cluster.local";
107
+ /*
108
+ * `<a>.<b>.svc` or `<a>.<b>.svc.<any cluster domain>` (a Service), and the
109
+ * three-label `<pod>.<svc>.<ns>.svc…` form (a StatefulSet member behind a
110
+ * headless Service).
111
+ */
112
+ const KUBERNETES_SERVICE_DNS_REGEX = /^((?:[a-z0-9_-]+\.){1,2}[a-z0-9_-]+)\.svc(?:\..+)?$/;
113
+ /*
114
+ * Second labels that make a two-label name a private DNS zone rather than a
115
+ * Kubernetes `<service>.<namespace>`: `db.internal` from a pod is far more
116
+ * likely a VPC name than a Service in a namespace called "internal". Such a
117
+ * name is still network-scoped (NETWORK_SCOPED_NAME_SUFFIXES).
118
+ */
119
+ const NON_NAMESPACE_TOP_LABELS = new Set([
120
+ "local",
121
+ "internal",
122
+ "localdomain",
123
+ ]);
124
+ // RFC 1123 label, as Kubernetes validates namespace / Service / pod names.
125
+ const DNS_LABEL_REGEX = /^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$/;
126
+ const HOSTNAME_LABEL_REGEX = /^[a-z0-9_-]{1,63}$/;
127
+ const DIGITS_ONLY_REGEX = /^\d+$/;
128
+ const IPV6_CHARACTERS_REGEX = /^[0-9a-f:.]+$/;
129
+ const IPV4_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
130
+ const IPV6_GROUP_REGEX = /^[0-9a-f]{1,4}$/;
131
+ // A character a bare user name never has: a dot, colon, bracket or backslash.
132
+ const NOT_A_BARE_WORD_REGEX = /[.:[\]\\]/;
133
+ // The member number of an Atlas host: `<cluster>-shard-<NN>-<NN>`.
134
+ const ATLAS_MEMBER_NUMBER_REGEX = /^\d{2}-\d{2}$/;
135
+ const ATLAS_MEMBER_MARKER = "-shard-";
136
+ const ATLAS_DOMAIN = "mongodb.net";
137
+ const DISPLAY_NAME_MAX_LENGTH = 100;
138
+ // How much of a rejected value a message repeats back.
139
+ const MAX_ECHOED_VALUE_LENGTH = 100;
140
+ // ---- low-level parsing ---------------------------------------------------
141
+ function parseIpv4Octets(text) {
142
+ const match = IPV4_REGEX.exec(text);
143
+ if (!match) {
144
+ return null;
145
+ }
146
+ const octets = [
147
+ Number(match[1]),
148
+ Number(match[2]),
149
+ Number(match[3]),
150
+ Number(match[4]),
151
+ ];
152
+ for (const octet of octets) {
153
+ if (octet > 255) {
154
+ return null;
155
+ }
156
+ }
157
+ return octets;
158
+ }
159
+ function parseIpv4(text) {
160
+ const octets = parseIpv4Octets(text);
161
+ return octets ? octets.join(".") : null;
162
+ }
163
+ /** The eight 16-bit groups of an IPv6 literal (zone id stripped), or null. */
164
+ function parseIpv6Groups(text) {
165
+ let value = text.trim().toLowerCase();
166
+ const zoneIndex = value.indexOf("%");
167
+ if (zoneIndex >= 0) {
168
+ value = value.substring(0, zoneIndex);
169
+ }
170
+ if (!value.includes(":") || !IPV6_CHARACTERS_REGEX.test(value)) {
171
+ return null;
172
+ }
173
+ // An embedded dotted IPv4 tail ("::ffff:10.0.0.5") becomes two groups.
174
+ const lastColon = value.lastIndexOf(":");
175
+ const tail = value.substring(lastColon + 1);
176
+ if (tail.includes(".")) {
177
+ const octets = parseIpv4Octets(tail);
178
+ if (!octets) {
179
+ return null;
180
+ }
181
+ value = `${value.substring(0, lastColon + 1)}${((octets[0] << 8) |
182
+ octets[1]).toString(16)}:${((octets[2] << 8) | octets[3]).toString(16)}`;
183
+ }
184
+ const doubleColonCount = value.split("::").length - 1;
185
+ if (doubleColonCount > 1) {
186
+ return null;
187
+ }
188
+ let parts;
189
+ if (doubleColonCount === 1) {
190
+ const halves = value.split("::");
191
+ const head = halves[0] ? halves[0].split(":") : [];
192
+ const rest = halves[1] ? halves[1].split(":") : [];
193
+ const missing = 8 - head.length - rest.length;
194
+ if (missing < 1) {
195
+ return null;
196
+ }
197
+ parts = [...head, ...new Array(missing).fill("0"), ...rest];
198
+ }
199
+ else {
200
+ parts = value.split(":");
201
+ }
202
+ if (parts.length !== 8) {
203
+ return null;
204
+ }
205
+ const groups = [];
206
+ for (const part of parts) {
207
+ if (!IPV6_GROUP_REGEX.test(part)) {
208
+ return null;
209
+ }
210
+ groups.push(parseInt(part, 16));
211
+ }
212
+ return groups;
213
+ }
214
+ /*
215
+ * Canonical text form of an IPv6 literal (RFC 5952: lowercase, no leading
216
+ * zeros, the longest run of two or more zero groups compressed to "::"), or
217
+ * the dotted IPv4 address for an IPv4-mapped one (::ffff:a.b.c.d).
218
+ */
219
+ function canonicalizeIpv6(text) {
220
+ const groups = parseIpv6Groups(text);
221
+ if (!groups) {
222
+ return null;
223
+ }
224
+ const isIpv4Mapped = groups[0] === 0 &&
225
+ groups[1] === 0 &&
226
+ groups[2] === 0 &&
227
+ groups[3] === 0 &&
228
+ groups[4] === 0 &&
229
+ groups[5] === 0xffff;
230
+ if (isIpv4Mapped) {
231
+ return [
232
+ groups[6] >> 8,
233
+ groups[6] & 0xff,
234
+ groups[7] >> 8,
235
+ groups[7] & 0xff,
236
+ ].join(".");
237
+ }
238
+ let bestStart = -1;
239
+ let bestLength = 0;
240
+ let runStart = -1;
241
+ for (let index = 0; index <= groups.length; index++) {
242
+ if (index < groups.length && groups[index] === 0) {
243
+ if (runStart < 0) {
244
+ runStart = index;
245
+ }
246
+ continue;
247
+ }
248
+ if (runStart >= 0) {
249
+ const runLength = index - runStart;
250
+ if (runLength > bestLength) {
251
+ bestStart = runStart;
252
+ bestLength = runLength;
253
+ }
254
+ runStart = -1;
255
+ }
256
+ }
257
+ const hex = groups.map((group) => {
258
+ return group.toString(16);
259
+ });
260
+ if (bestLength < 2) {
261
+ return hex.join(":");
262
+ }
263
+ const head = hex.slice(0, bestStart).join(":");
264
+ const tail = hex.slice(bestStart + bestLength).join(":");
265
+ return `${head}::${tail}`;
266
+ }
267
+ function isValidHostname(host) {
268
+ if (host.length === 0 || host.length > 253) {
269
+ return false;
270
+ }
271
+ const labels = host.split(".");
272
+ for (const label of labels) {
273
+ if (!HOSTNAME_LABEL_REGEX.test(label)) {
274
+ return false;
275
+ }
276
+ }
277
+ /*
278
+ * A top-level label is never all digits (RFC 3696 §2), so "999.1.1.1" or
279
+ * "12345" is a mangled address, not a name.
280
+ */
281
+ return !DIGITS_ONLY_REGEX.test(labels[labels.length - 1]);
282
+ }
283
+ function toValidPort(value) {
284
+ let numeric;
285
+ if (typeof value === "number") {
286
+ numeric = value;
287
+ }
288
+ else if (typeof value === "string") {
289
+ const trimmed = value.trim();
290
+ if (!DIGITS_ONLY_REGEX.test(trimmed)) {
291
+ return null;
292
+ }
293
+ numeric = Number(trimmed);
294
+ }
295
+ else {
296
+ return null;
297
+ }
298
+ return Number.isInteger(numeric) && numeric >= 1 && numeric <= 65535
299
+ ? numeric
300
+ : null;
301
+ }
302
+ function canonicalClusterName(value) {
303
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
304
+ }
305
+ function canonicalDnsLabel(value) {
306
+ if (typeof value !== "string") {
307
+ return null;
308
+ }
309
+ const label = value.trim().toLowerCase();
310
+ return DNS_LABEL_REGEX.test(label) ? label : null;
311
+ }
312
+ function isNonBlankText(value) {
313
+ return typeof value === "string" && value.trim().length > 0;
314
+ }
315
+ /*
316
+ * A SQL Server instance name as it becomes part of an identity: trimmed,
317
+ * lowercased, validated; the default instance (MSSQLSERVER) is no instance.
318
+ * `undefined` for an invalid name, null for none.
319
+ */
320
+ function canonicalInstanceName(value) {
321
+ if (value === null || value === undefined) {
322
+ return null;
323
+ }
324
+ if (typeof value !== "string") {
325
+ return undefined;
326
+ }
327
+ const instance = value.trim().toLowerCase();
328
+ if (!instance) {
329
+ return null;
330
+ }
331
+ if (!SQL_SERVER_INSTANCE_REGEX.test(instance)) {
332
+ return undefined;
333
+ }
334
+ return instance === SQL_SERVER_DEFAULT_INSTANCE ? null : instance;
335
+ }
336
+ /**
337
+ * A host as stored in a DatabaseEndpoint, split into the network host and
338
+ * the SQL Server named instance it may carry (`sql1.corp\inst01` →
339
+ * `sql1.corp` + `inst01`; everything else → the host + "").
340
+ */
341
+ export function splitDatabaseHostInstance(host) {
342
+ const value = typeof host === "string" ? host : "";
343
+ const index = value.indexOf("\\");
344
+ return index >= 0
345
+ ? { host: value.substring(0, index), instance: value.substring(index + 1) }
346
+ : { host: value, instance: "" };
347
+ }
348
+ function joinHostInstance(host, instance) {
349
+ return instance ? `${host}\\${instance}` : host;
350
+ }
351
+ /*
352
+ * Where the address in a raw value is: the URL authority (scheme, userinfo
353
+ * and path dropped) or the value up to its path / query / JDBC properties,
354
+ * `tcp:` prefix dropped. May still hold a host list. Null for nothing.
355
+ */
356
+ function extractAddressText(raw) {
357
+ if (typeof raw !== "string") {
358
+ return null;
359
+ }
360
+ let value = raw.trim();
361
+ if (!value || value.startsWith("/")) {
362
+ return null;
363
+ }
364
+ const schemeMatch = URL_SCHEME_REGEX.exec(value);
365
+ if (schemeMatch) {
366
+ const afterScheme = value.substring(schemeMatch[0].length);
367
+ const authorityEnd = afterScheme.search(ADDRESS_END_REGEX);
368
+ let authority = authorityEnd >= 0 ? afterScheme.substring(0, authorityEnd) : afterScheme;
369
+ const userInfoEnd = authority.lastIndexOf("@");
370
+ if (userInfoEnd >= 0) {
371
+ authority = authority.substring(userInfoEnd + 1);
372
+ }
373
+ value = authority;
374
+ }
375
+ else {
376
+ value = value.replace(SQL_SERVER_TCP_PREFIX_REGEX, "");
377
+ const pathStart = value.search(ADDRESS_END_REGEX);
378
+ if (pathStart >= 0) {
379
+ value = value.substring(0, pathStart);
380
+ }
381
+ }
382
+ value = value.trim();
383
+ return value ? value : null;
384
+ }
385
+ /*
386
+ * One host of an address: `host`, `host:port`, `[v6]:port`, bare IPv6,
387
+ * `host\instance[:port]` and the SQL Server local-machine spellings.
388
+ * `portText` is a port found beside it (the `,1433` of SQL Server); a port
389
+ * outside 1..65535 is dropped, or — with `strictPort` — rejects the value.
390
+ */
391
+ function parseSingleHost(text, initialPortText, strictPort) {
392
+ let value = text.trim();
393
+ let portText = initialPortText;
394
+ // "host\instance" (optionally "host\instance:port"): a SQL Server named instance.
395
+ let instance = null;
396
+ const backslashIndex = value.indexOf("\\");
397
+ if (backslashIndex >= 0) {
398
+ let instanceText = value.substring(backslashIndex + 1).trim();
399
+ value = value.substring(0, backslashIndex).trim();
400
+ const colonIndex = instanceText.indexOf(":");
401
+ if (colonIndex >= 0) {
402
+ if (portText === null) {
403
+ portText = instanceText.substring(colonIndex + 1);
404
+ }
405
+ instanceText = instanceText.substring(0, colonIndex);
406
+ }
407
+ const canonical = canonicalInstanceName(instanceText);
408
+ if (canonical === undefined) {
409
+ return null;
410
+ }
411
+ instance = canonical;
412
+ }
413
+ if (!value) {
414
+ return null;
415
+ }
416
+ let host;
417
+ if (LOCAL_MACHINE_ALIASES.has(value.toLowerCase())) {
418
+ host = "localhost";
419
+ }
420
+ else if (value.startsWith("[")) {
421
+ const closing = value.indexOf("]");
422
+ if (closing < 0) {
423
+ return null;
424
+ }
425
+ const rest = value.substring(closing + 1);
426
+ if (rest) {
427
+ if (!rest.startsWith(":")) {
428
+ return null;
429
+ }
430
+ if (portText === null) {
431
+ portText = rest.substring(1);
432
+ }
433
+ }
434
+ const ipv6 = canonicalizeIpv6(value.substring(1, closing));
435
+ if (!ipv6) {
436
+ // "[REDACTED]", "[HASHED:ab12cd34]" and other bracketed non-addresses.
437
+ return null;
438
+ }
439
+ host = ipv6;
440
+ }
441
+ else {
442
+ const colonCount = (value.match(/:/g) || []).length;
443
+ if (colonCount >= 2) {
444
+ const ipv6 = canonicalizeIpv6(value);
445
+ if (!ipv6) {
446
+ return null;
447
+ }
448
+ host = ipv6;
449
+ }
450
+ else {
451
+ let hostText = value;
452
+ if (colonCount === 1) {
453
+ const colonIndex = value.indexOf(":");
454
+ hostText = value.substring(0, colonIndex);
455
+ if (portText === null) {
456
+ portText = value.substring(colonIndex + 1);
457
+ }
458
+ }
459
+ hostText = trimTrailingCharacter(hostText.trim().toLowerCase(), ".");
460
+ if (!hostText) {
461
+ return null;
462
+ }
463
+ const ipv4 = parseIpv4(hostText);
464
+ if (ipv4) {
465
+ host = ipv4;
466
+ }
467
+ else if (isValidHostname(hostText)) {
468
+ host = hostText;
469
+ }
470
+ else {
471
+ return null;
472
+ }
473
+ }
474
+ }
475
+ let port = null;
476
+ if (portText !== null && portText.trim() !== "") {
477
+ const trimmedPort = portText.trim();
478
+ if (!DIGITS_ONLY_REGEX.test(trimmedPort)) {
479
+ return null;
480
+ }
481
+ port = toValidPort(trimmedPort);
482
+ if (port === null && strictPort) {
483
+ return null;
484
+ }
485
+ }
486
+ return instance ? { host, port, instance } : { host, port };
487
+ }
488
+ // Canonical order of the hosts of a list: host, then instance, then port.
489
+ function compareParsedHosts(a, b) {
490
+ var _a, _b;
491
+ if (a.host !== b.host) {
492
+ return a.host < b.host ? -1 : 1;
493
+ }
494
+ const instanceA = a.instance || "";
495
+ const instanceB = b.instance || "";
496
+ if (instanceA !== instanceB) {
497
+ return instanceA < instanceB ? -1 : 1;
498
+ }
499
+ return ((_a = a.port) !== null && _a !== void 0 ? _a : 0) - ((_b = b.port) !== null && _b !== void 0 ? _b : 0);
500
+ }
501
+ function parseAddressHosts(raw, strictPort) {
502
+ var _a;
503
+ const address = extractAddressText(raw);
504
+ if (address === null) {
505
+ return null;
506
+ }
507
+ const parts = address.split(",");
508
+ // "host,1433": SQL Server's port separator, not a list.
509
+ if (parts.length === 2 && DIGITS_ONLY_REGEX.test(parts[1].trim())) {
510
+ const single = parseSingleHost(parts[0], parts[1].trim(), strictPort);
511
+ return single ? [single] : null;
512
+ }
513
+ const hosts = [];
514
+ const seen = new Set();
515
+ for (const part of parts) {
516
+ if (!part.trim()) {
517
+ continue;
518
+ }
519
+ const parsed = parseSingleHost(part, null, strictPort);
520
+ // A list is one logical server only when every host in it is readable.
521
+ if (!parsed) {
522
+ return null;
523
+ }
524
+ const key = `${parsed.host}\\${parsed.instance || ""}:${(_a = parsed.port) !== null && _a !== void 0 ? _a : ""}`;
525
+ if (!seen.has(key)) {
526
+ seen.add(key);
527
+ hosts.push(parsed);
528
+ }
529
+ }
530
+ if (hosts.length === 0) {
531
+ return null;
532
+ }
533
+ hosts.sort(compareParsedHosts);
534
+ return hosts;
535
+ }
536
+ /**
537
+ * Parse a raw address attribute / connection string into a canonical host
538
+ * and an optional port. Accepts `host`, `host:port`, `[v6]:port`, bare IPv6
539
+ * (zone id stripped), URLs (`scheme://user:pw@host:port/db?x` — the userinfo
540
+ * split on the LAST "@" before the first "/"; JDBC `;key=value` properties
541
+ * dropped), host lists and the SQL Server forms `tcp:host,1433`,
542
+ * `host\instance` (the instance returned beside the host; MSSQLSERVER, the
543
+ * default instance, is no instance), `(local)` and `.`.
544
+ *
545
+ * A host list (`m1:27017,m2:27017`) names ONE logical server, so it yields
546
+ * the same host whatever order a client lists the members in: the first in
547
+ * canonical order (see parseHostAndPortList). Every listed host must parse.
548
+ *
549
+ * The host must then be a valid IPv4, IPv6 or RFC 1123 hostname — anything
550
+ * else (scrubbed values, "*", whitespace, a unix socket path) is null. A
551
+ * port outside 1..65535 is dropped (null); a non-numeric port rejects the
552
+ * whole value.
553
+ */
554
+ export function parseHostAndPort(raw) {
555
+ const hosts = parseAddressHosts(raw, false);
556
+ return hosts && hosts.length > 0 ? hosts[0] : null;
557
+ }
558
+ /**
559
+ * Every host a raw address names, deduplicated and in canonical order —
560
+ * one entry for a single host, several for a host list — or null when the
561
+ * value (or any host in its list) is unparseable. The first entry is what
562
+ * parseHostAndPort returns.
563
+ */
564
+ export function parseHostAndPortList(raw) {
565
+ return parseAddressHosts(raw, false);
566
+ }
567
+ // ---- host classification -------------------------------------------------
568
+ /** True for an IPv4 or IPv6 literal (brackets and a `\instance` tolerated). */
569
+ export function isIpLiteralHost(host) {
570
+ if (typeof host !== "string") {
571
+ return false;
572
+ }
573
+ const value = splitDatabaseHostInstance(host.trim())
574
+ .host.trim()
575
+ .replace(/^\[(.*)\]$/, "$1");
576
+ if (!value) {
577
+ return false;
578
+ }
579
+ return parseIpv4(value) !== null || parseIpv6Groups(value) !== null;
580
+ }
581
+ /**
582
+ * localhost (and the distributions' /etc/hosts aliases such as
583
+ * localhost.localdomain), *.localhost, 127/8, ::1, the unspecified addresses
584
+ * (:: and 0.0.0.0) and their IPv4-mapped IPv6 spellings.
585
+ */
586
+ export function isLoopbackDatabaseHost(host) {
587
+ if (typeof host !== "string") {
588
+ return false;
589
+ }
590
+ let value = splitDatabaseHostInstance(host.trim().toLowerCase()).host.trim();
591
+ if (!value) {
592
+ return false;
593
+ }
594
+ if (LOCAL_MACHINE_ALIASES.has(value)) {
595
+ return true;
596
+ }
597
+ if (value.includes(":")) {
598
+ value = canonicalizeIpv6(value.replace(/^\[(.*)\]$/, "$1")) || value;
599
+ }
600
+ value = trimTrailingCharacter(value, ".");
601
+ if (LOOPBACK_HOST_NAMES.has(value) || value.endsWith(".localhost")) {
602
+ return true;
603
+ }
604
+ if (value === "::1" || value === "::" || value === "0.0.0.0") {
605
+ return true;
606
+ }
607
+ const octets = parseIpv4Octets(value);
608
+ return octets !== null && octets[0] === 127;
609
+ }
610
+ /*
611
+ * `host.<tool>.internal`: minikube, k3d, Lima, OrbStack, Rancher Desktop —
612
+ * the per-machine gateway name of each local Kubernetes / container tool.
613
+ * Checked with string operations (the tool label is one RFC 1123 label).
614
+ */
615
+ function isHostGatewayName(value) {
616
+ const labels = value.split(".");
617
+ return (labels.length === 3 &&
618
+ labels[0] === "host" &&
619
+ labels[2] === "internal" &&
620
+ DNS_LABEL_REGEX.test(labels[1]));
621
+ }
622
+ /**
623
+ * host.docker.internal and the other "the machine I run on" names: every
624
+ * `*.docker.internal` name, every `host.<tool>.internal` name (minikube,
625
+ * k3d, Lima, OrbStack, Rancher Desktop) and Podman's
626
+ * host.containers.internal.
627
+ */
628
+ export function isHostRelativeDatabaseHost(host) {
629
+ if (typeof host !== "string") {
630
+ return false;
631
+ }
632
+ const value = trimTrailingCharacter(splitDatabaseHostInstance(host.trim().toLowerCase()).host.trim(), ".");
633
+ return (HOST_RELATIVE_NAMES.has(value) ||
634
+ value.endsWith(DOCKER_DESKTOP_SUFFIX) ||
635
+ isHostGatewayName(value));
636
+ }
637
+ function stripBracketsAndInstance(host) {
638
+ return splitDatabaseHostInstance(host.trim())
639
+ .host.trim()
640
+ .replace(/^\[(.*)\]$/, "$1");
641
+ }
642
+ /**
643
+ * RFC 1918 (10/8, 172.16/12, 192.168/16), CGNAT (100.64/10) and IPv6 ULA
644
+ * (fc00::/7) — ranges that are reused by every cluster and VPC, so an
645
+ * address in them only identifies something together with where it was
646
+ * seen from.
647
+ */
648
+ export function isPrivateIpHost(host) {
649
+ if (typeof host !== "string") {
650
+ return false;
651
+ }
652
+ const value = stripBracketsAndInstance(host);
653
+ const octets = parseIpv4Octets(value);
654
+ if (octets) {
655
+ const first = octets[0];
656
+ const second = octets[1];
657
+ return (first === 10 ||
658
+ (first === 172 && second >= 16 && second <= 31) ||
659
+ (first === 192 && second === 168) ||
660
+ (first === 100 && second >= 64 && second <= 127));
661
+ }
662
+ const canonical = value.includes(":")
663
+ ? canonicalizeIpv6(value)
664
+ : null;
665
+ if (!canonical) {
666
+ return false;
667
+ }
668
+ if (!canonical.includes(":")) {
669
+ // IPv4-mapped: classify the unwrapped IPv4 address.
670
+ return isPrivateIpHost(canonical);
671
+ }
672
+ const groups = parseIpv6Groups(canonical);
673
+ return groups !== null && (groups[0] & 0xfe00) === 0xfc00;
674
+ }
675
+ /**
676
+ * Link-local addresses — IPv4 169.254/16 and IPv6 fe80::/10 (zone id
677
+ * dropped). Every network link has its own, so one never identifies a
678
+ * server on its own (always LOCAL scope, see getDatabaseEndpointScope).
679
+ */
680
+ export function isLinkLocalIpHost(host) {
681
+ if (typeof host !== "string") {
682
+ return false;
683
+ }
684
+ const value = stripBracketsAndInstance(host);
685
+ const octets = parseIpv4Octets(value);
686
+ if (octets) {
687
+ return octets[0] === 169 && octets[1] === 254;
688
+ }
689
+ const canonical = value.includes(":")
690
+ ? canonicalizeIpv6(value)
691
+ : null;
692
+ if (!canonical) {
693
+ return false;
694
+ }
695
+ if (!canonical.includes(":")) {
696
+ return isLinkLocalIpHost(canonical);
697
+ }
698
+ const groups = parseIpv6Groups(canonical);
699
+ return groups !== null && (groups[0] & 0xffc0) === 0xfe80;
700
+ }
701
+ function isSingleLabelName(host) {
702
+ return !host.includes(".") && !isIpLiteralHost(host);
703
+ }
704
+ /**
705
+ * True for a host that only resolves inside one Kubernetes cluster or
706
+ * private network — cluster-local DNS and the other private DNS zones
707
+ * (NETWORK_SCOPED_NAME_SUFFIXES), private IPs and link-local IPs — and so
708
+ * is qualified with the caller's cluster (`…@<cluster>`), or LOCAL scope
709
+ * without one. A `\instance` is ignored.
710
+ */
711
+ export function isClusterScopedDatabaseHost(host) {
712
+ if (typeof host !== "string") {
713
+ return false;
714
+ }
715
+ const value = trimTrailingCharacter(splitDatabaseHostInstance(host.trim().toLowerCase()).host.trim(), ".");
716
+ if (!value) {
717
+ return false;
718
+ }
719
+ for (const suffix of NETWORK_SCOPED_NAME_SUFFIXES) {
720
+ if (value.endsWith(suffix)) {
721
+ return true;
722
+ }
723
+ }
724
+ return isPrivateIpHost(value) || isLinkLocalIpHost(value);
725
+ }
726
+ /**
727
+ * True for a Kubernetes Service DNS name — `<service>.<namespace>.svc`, with
728
+ * or without its cluster domain (`.svc.cluster.local`), or
729
+ * `<pod>.<service>.<namespace>.svc…` for a StatefulSet member — which only a
730
+ * pod inside one cluster can resolve. The same test the endpoint parser
731
+ * expands such names with. Case and a trailing dot are ignored, as is a
732
+ * `\instance`; a port or `@cluster` is not part of a host.
733
+ */
734
+ export function isKubernetesServiceDnsHost(host) {
735
+ if (typeof host !== "string") {
736
+ return false;
737
+ }
738
+ const value = trimTrailingCharacter(splitDatabaseHostInstance(host.trim().toLowerCase()).host.trim(), ".");
739
+ return value.length > 0 && KUBERNETES_SERVICE_DNS_REGEX.test(value);
740
+ }
741
+ /**
742
+ * True when the caller runs in Kubernetes as far as its context tells: it
743
+ * has a namespace or a cluster (or the discovery query said so, see
744
+ * DatabaseCallerContext.runsInKubernetes).
745
+ */
746
+ export function isKubernetesDatabaseCaller(caller) {
747
+ if (!caller) {
748
+ return false;
749
+ }
750
+ return (caller.runsInKubernetes === true ||
751
+ isNonBlankText(caller.kubernetesNamespace) ||
752
+ canonicalClusterName(caller.kubernetesClusterName).length > 0);
753
+ }
754
+ /*
755
+ * `<pod>-<ordinal>.<service>`: a two-label name whose first label is a
756
+ * StatefulSet pod (`mongo-0`, `redis-node-2`) and whose second is the
757
+ * headless Service of the same release (`mongo`, `mongo-headless`,
758
+ * `redis-headless` — the same first dash-separated word) — a member in the
759
+ * caller's own namespace, not a Service in another one.
760
+ */
761
+ function isStatefulSetMemberShortName(labels) {
762
+ const pod = labels[0];
763
+ const dash = pod.lastIndexOf("-");
764
+ if (dash <= 0 || dash === pod.length - 1) {
765
+ return false;
766
+ }
767
+ if (!DIGITS_ONLY_REGEX.test(pod.substring(dash + 1))) {
768
+ return false;
769
+ }
770
+ const release = pod.split("-")[0];
771
+ return release.length > 0 && labels[1].split("-")[0] === release;
772
+ }
773
+ /*
774
+ * Rule 3 (Kubernetes DNS): any `<a>.<b>.svc[.<domain>]` (and the member form
775
+ * `<pod>.<svc>.<ns>.svc[.<domain>]`) becomes `….svc.cluster.local`, so a
776
+ * custom cluster domain and the short `.svc` form key like the FQDN; a
777
+ * single-label name from a caller in a known namespace becomes that
778
+ * namespace's Service FQDN. From a caller that runs in Kubernetes, a
779
+ * two-label name is what the pod's resolver search path makes of it:
780
+ * `<service>.<namespace>` → `<service>.<namespace>.svc.cluster.local`, and
781
+ * a StatefulSet member of the caller's own namespace
782
+ * (`mongo-0.mongo-headless`) → `mongo-0.mongo-headless.<ns>.svc.cluster.local`
783
+ * (or, with no namespace known, the Service reading). Two-label names from
784
+ * anything else — a VM, a laptop — are left alone: there they are domains.
785
+ */
786
+ function applyKubernetesDnsRules(host, kubernetesNamespace, runsInKubernetes) {
787
+ const serviceMatch = KUBERNETES_SERVICE_DNS_REGEX.exec(host);
788
+ if (serviceMatch) {
789
+ return `${serviceMatch[1]}${KUBERNETES_CLUSTER_DOMAIN_SUFFIX}`;
790
+ }
791
+ const namespace = canonicalDnsLabel(kubernetesNamespace);
792
+ if (isSingleLabelName(host)) {
793
+ if (namespace) {
794
+ return `${host}.${namespace}${KUBERNETES_CLUSTER_DOMAIN_SUFFIX}`;
795
+ }
796
+ return host;
797
+ }
798
+ if (!runsInKubernetes) {
799
+ return host;
800
+ }
801
+ const labels = host.split(".");
802
+ if (labels.length !== 2 ||
803
+ !DNS_LABEL_REGEX.test(labels[0]) ||
804
+ !DNS_LABEL_REGEX.test(labels[1]) ||
805
+ NON_NAMESPACE_TOP_LABELS.has(labels[1])) {
806
+ return host;
807
+ }
808
+ if (namespace && isStatefulSetMemberShortName(labels)) {
809
+ return `${host}.${namespace}${KUBERNETES_CLUSTER_DOMAIN_SUFFIX}`;
810
+ }
811
+ return `${host}${KUBERNETES_CLUSTER_DOMAIN_SUFFIX}`;
812
+ }
813
+ function buildEndpoint(host, port, kubernetesClusterName) {
814
+ return kubernetesClusterName
815
+ ? { host, port, kubernetesClusterName }
816
+ : { host, port };
817
+ }
818
+ // ---- caller context ------------------------------------------------------
819
+ /*
820
+ * Resource attributes are FLAT semconv keys; the `resource.`-prefixed
821
+ * spelling used by stored telemetry rows is accepted as a fallback so a
822
+ * caller holding a stored attribute map gets the same answer.
823
+ */
824
+ function readResourceAttribute(attributes, key) {
825
+ if (!attributes || typeof attributes !== "object") {
826
+ return null;
827
+ }
828
+ let value = attributes[key];
829
+ if (value === undefined || value === null || value === "") {
830
+ value = attributes[`resource.${key}`];
831
+ }
832
+ if (typeof value === "string") {
833
+ const trimmed = value.trim();
834
+ return trimmed.length > 0 ? trimmed : null;
835
+ }
836
+ if (typeof value === "number" || typeof value === "boolean") {
837
+ return String(value);
838
+ }
839
+ return null;
840
+ }
841
+ /**
842
+ * True when the resource that made a call is not a stable machine: anything
843
+ * in Kubernetes, in a container, on a FaaS or managed-container platform, or
844
+ * with no `os.type` at all (no `system` resource detector ran, so
845
+ * `host.name` is whatever the SDK guessed — usually a pod or container
846
+ * name). Its `host.name` must never become a database's identity.
847
+ */
848
+ export function isEphemeralCaller(resourceAttributes) {
849
+ const attributes = resourceAttributes && typeof resourceAttributes === "object"
850
+ ? resourceAttributes
851
+ : {};
852
+ for (const key of KUBERNETES_IDENTITY_ATTRIBUTES) {
853
+ if (readResourceAttribute(attributes, key)) {
854
+ return true;
855
+ }
856
+ }
857
+ if (readResourceAttribute(attributes, "container.id") ||
858
+ readResourceAttribute(attributes, "container.runtime")) {
859
+ return true;
860
+ }
861
+ for (const key of Object.keys(attributes)) {
862
+ const bareKey = key.startsWith("resource.")
863
+ ? key.substring("resource.".length)
864
+ : key;
865
+ if (bareKey.startsWith("faas.") && readResourceAttribute(attributes, key)) {
866
+ return true;
867
+ }
868
+ }
869
+ const cloudPlatform = readResourceAttribute(attributes, "cloud.platform");
870
+ if (cloudPlatform &&
871
+ EPHEMERAL_CLOUD_PLATFORMS.has(cloudPlatform.toLowerCase())) {
872
+ return true;
873
+ }
874
+ return readResourceAttribute(attributes, "os.type") === null;
875
+ }
876
+ /** The parts of a caller's resource that endpoint canonicalization needs. */
877
+ export function buildDatabaseCallerContext(resourceAttributes) {
878
+ return {
879
+ kubernetesNamespace: readResourceAttribute(resourceAttributes, "k8s.namespace.name"),
880
+ kubernetesClusterName: readResourceAttribute(resourceAttributes, "k8s.cluster.name"),
881
+ hostName: readResourceAttribute(resourceAttributes, "host.name"),
882
+ isEphemeral: isEphemeralCaller(resourceAttributes),
883
+ };
884
+ }
885
+ /**
886
+ * The SQL Server named instance a client span names beside its address —
887
+ * `db.mssql.instance_name`, else the instance half of a `db.namespace` of
888
+ * the form `instance|database` — or null. Only for SQL Server: other
889
+ * engines give `db.namespace` other meanings. Returned raw (untrimmed);
890
+ * canonicalizeDatabaseEndpoint validates it. Pass the result as its
891
+ * `instance`; anything that memoizes on the attributes it reads should key
892
+ * on this derived instance (as DatabaseCallEntityKeys does) or include
893
+ * DATABASE_INSTANCE_ATTRIBUTES.
894
+ */
895
+ export function readDatabaseInstanceName(input) {
896
+ if (!input || typeof input.getAttribute !== "function") {
897
+ return null;
898
+ }
899
+ if (normalizeDatabaseSystem(input.system) !== SQL_SERVER_SYSTEM) {
900
+ return null;
901
+ }
902
+ const toText = (value) => {
903
+ if (typeof value === "string") {
904
+ return value === "" ? null : value;
905
+ }
906
+ if (typeof value === "number") {
907
+ return String(value);
908
+ }
909
+ return null;
910
+ };
911
+ const instanceName = toText(input.getAttribute(DATABASE_INSTANCE_NAME_ATTRIBUTE));
912
+ if (instanceName !== null) {
913
+ return instanceName;
914
+ }
915
+ const namespace = toText(input.getAttribute(DATABASE_NAMESPACE_ATTRIBUTE));
916
+ if (namespace !== null) {
917
+ const separator = namespace.indexOf("|");
918
+ if (separator >= 0) {
919
+ return namespace.substring(0, separator);
920
+ }
921
+ }
922
+ return null;
923
+ }
924
+ // ---- canonicalization ----------------------------------------------------
925
+ /**
926
+ * Canonicalize what a caller saw into a database endpoint, or null when it
927
+ * names no identifiable server. Rules, in order:
928
+ *
929
+ * 1. parse the address; port = explicit port ?? parsed port ?? engine
930
+ * default ?? null. A SQL Server named instance (`host\instance` in the
931
+ * address, else `instance`, see readDatabaseInstanceName) is kept as
932
+ * part of the host only while no port is known — a port already names
933
+ * the instance — and then takes no default port;
934
+ * 2. loopback / host-relative: for a client call → null (a per-caller
935
+ * sidecar, proxy or dev laptop); for a collector → the collector's own
936
+ * host.name when the collector is not ephemeral, else null;
937
+ * 3. Kubernetes DNS expansion (see applyKubernetesDnsRules);
938
+ * 4. cluster-local / private-network names and private IPs are qualified
939
+ * with the caller's `k8s.cluster.name` when it has one.
940
+ */
941
+ export function canonicalizeDatabaseEndpoint(input) {
942
+ var _a, _b;
943
+ if (!input) {
944
+ return null;
945
+ }
946
+ const parsed = parseHostAndPort(input.address);
947
+ if (!parsed) {
948
+ return null;
949
+ }
950
+ const caller = input.caller || null;
951
+ const knownPort = (_a = toValidPort(input.port)) !== null && _a !== void 0 ? _a : parsed.port;
952
+ let instance = null;
953
+ if (knownPort === null) {
954
+ const reported = canonicalInstanceName(input.instance);
955
+ instance = parsed.instance || (reported ? reported : null);
956
+ }
957
+ const port = (_b = knownPort !== null && knownPort !== void 0 ? knownPort : (instance ? null : getDefaultDatabasePort(input.system))) !== null && _b !== void 0 ? _b : null;
958
+ let host = parsed.host;
959
+ if (isLoopbackDatabaseHost(host) || isHostRelativeDatabaseHost(host)) {
960
+ if (input.purpose !== "collector") {
961
+ return null;
962
+ }
963
+ if (!caller || caller.isEphemeral || !caller.hostName) {
964
+ return null;
965
+ }
966
+ const callerHost = parseHostAndPort(caller.hostName);
967
+ if (!callerHost ||
968
+ isLoopbackDatabaseHost(callerHost.host) ||
969
+ isHostRelativeDatabaseHost(callerHost.host)) {
970
+ return null;
971
+ }
972
+ host = callerHost.host;
973
+ }
974
+ host = applyKubernetesDnsRules(host, caller === null || caller === void 0 ? void 0 : caller.kubernetesNamespace, isKubernetesDatabaseCaller(caller));
975
+ const clusterName = isClusterScopedDatabaseHost(host)
976
+ ? canonicalClusterName(caller === null || caller === void 0 ? void 0 : caller.kubernetesClusterName)
977
+ : "";
978
+ return buildEndpoint(joinHostInstance(host, instance), port, clusterName);
979
+ }
980
+ /**
981
+ * "local" for an endpoint that only resolves inside one network or cluster
982
+ * and carries nothing to say which: a single-label name, cluster-local or
983
+ * private-zone DNS or a private IP without a cluster qualifier, a link-local
984
+ * IP (per link, qualified or not) and loopback / host-relative names,
985
+ * defensively. Local endpoints are still keyed (it is what the span says)
986
+ * but never create a DatabaseServer row and never auto-match an alias.
987
+ */
988
+ export function getDatabaseEndpointScope(endpoint) {
989
+ const host = endpoint && typeof endpoint.host === "string"
990
+ ? splitDatabaseHostInstance(endpoint.host.trim().toLowerCase()).host
991
+ : "";
992
+ if (!host) {
993
+ return "local";
994
+ }
995
+ if (isLoopbackDatabaseHost(host) || isHostRelativeDatabaseHost(host)) {
996
+ return "local";
997
+ }
998
+ if (isSingleLabelName(host) || isLinkLocalIpHost(host)) {
999
+ return "local";
1000
+ }
1001
+ const hasCluster = canonicalClusterName(endpoint.kubernetesClusterName).length > 0;
1002
+ if (!hasCluster && isClusterScopedDatabaseHost(host)) {
1003
+ return "local";
1004
+ }
1005
+ return "global";
1006
+ }
1007
+ /**
1008
+ * "host:port", "host" (unknown port), "[v6]:port", "host\instance"; plus
1009
+ * "@cluster" when qualified. The inverse is parseDatabaseEndpointString.
1010
+ * The cluster part is kept verbatim apart from trim + lowercase (EKS names
1011
+ * are ARNs containing ":" and "/").
1012
+ */
1013
+ export function formatDatabaseEndpoint(endpoint) {
1014
+ const value = splitDatabaseHostInstance(endpoint && typeof endpoint.host === "string"
1015
+ ? endpoint.host.trim().toLowerCase()
1016
+ : "");
1017
+ const hostPart = `${value.host.includes(":") ? `[${value.host}]` : value.host}${value.instance ? `\\${value.instance}` : ""}`;
1018
+ const port = toValidPort(endpoint === null || endpoint === void 0 ? void 0 : endpoint.port);
1019
+ const portPart = port !== null ? `:${port}` : "";
1020
+ const clusterName = canonicalClusterName(endpoint === null || endpoint === void 0 ? void 0 : endpoint.kubernetesClusterName);
1021
+ return `${hostPart}${portPart}${clusterName ? `@${clusterName}` : ""}`;
1022
+ }
1023
+ /*
1024
+ * `user@host`, not `host@cluster`: the part after the "@" reads as a server
1025
+ * (it has a port or a dot, or is an IP) while the part before it does not
1026
+ * read as an address that takes a qualifier (one with a port, an IP, a
1027
+ * cluster-local or private-zone name, a `.svc` name) — `admin@10.0.0.5:5432`,
1028
+ * `john.doe@db.example.com`. Cluster names such as `prod-eu`, and ARNs
1029
+ * (which never parse as a host), never look like a server.
1030
+ */
1031
+ function looksLikeUserInfo(beforeAt, afterAt) {
1032
+ if (!beforeAt) {
1033
+ return false;
1034
+ }
1035
+ const server = parseHostAndPort(afterAt);
1036
+ if (!server ||
1037
+ !(server.port !== null ||
1038
+ server.host.includes(".") ||
1039
+ server.host.includes(":") ||
1040
+ isIpLiteralHost(server.host))) {
1041
+ return false;
1042
+ }
1043
+ // A bare word ("admin") is a user name.
1044
+ if (!NOT_A_BARE_WORD_REGEX.test(beforeAt)) {
1045
+ return true;
1046
+ }
1047
+ const address = parseHostAndPort(beforeAt);
1048
+ if (!address) {
1049
+ return true;
1050
+ }
1051
+ return (address.port === null &&
1052
+ !isIpLiteralHost(address.host) &&
1053
+ !isClusterScopedDatabaseHost(address.host) &&
1054
+ !KUBERNETES_SERVICE_DNS_REGEX.test(address.host));
1055
+ }
1056
+ function interpretDatabaseEndpointString(value, context, strictPort) {
1057
+ var _a, _b;
1058
+ const result = {
1059
+ endpoint: null,
1060
+ problem: null,
1061
+ beforeAt: "",
1062
+ afterAt: "",
1063
+ refusedHost: "",
1064
+ };
1065
+ if (typeof value !== "string" || !value.trim()) {
1066
+ result.problem = "empty";
1067
+ return result;
1068
+ }
1069
+ const trimmed = value.trim();
1070
+ let addressPart = trimmed;
1071
+ let explicitClusterName = "";
1072
+ if (!URL_SCHEME_REGEX.test(trimmed)) {
1073
+ const atIndex = trimmed.lastIndexOf("@");
1074
+ if (atIndex >= 0) {
1075
+ addressPart = trimmed.substring(0, atIndex);
1076
+ result.beforeAt = addressPart.trim();
1077
+ result.afterAt = trimmed.substring(atIndex + 1).trim();
1078
+ explicitClusterName = canonicalClusterName(result.afterAt);
1079
+ }
1080
+ }
1081
+ if (explicitClusterName &&
1082
+ looksLikeUserInfo(result.beforeAt, result.afterAt)) {
1083
+ result.problem = "user-info";
1084
+ return result;
1085
+ }
1086
+ const hosts = parseAddressHosts(addressPart, strictPort);
1087
+ const parsed = hosts && hosts.length > 0 ? hosts[0] : null;
1088
+ if (!parsed) {
1089
+ result.problem =
1090
+ strictPort && parseHostAndPort(addressPart)
1091
+ ? "port-out-of-range"
1092
+ : "invalid";
1093
+ return result;
1094
+ }
1095
+ if (isLoopbackDatabaseHost(parsed.host) ||
1096
+ isHostRelativeDatabaseHost(parsed.host)) {
1097
+ result.problem = "loopback";
1098
+ return result;
1099
+ }
1100
+ const knownPort = (_a = toValidPort(context === null || context === void 0 ? void 0 : context.port)) !== null && _a !== void 0 ? _a : parsed.port;
1101
+ const instance = knownPort === null && parsed.instance ? parsed.instance : null;
1102
+ const port = (_b = knownPort !== null && knownPort !== void 0 ? knownPort : (instance ? null : getDefaultDatabasePort(context === null || context === void 0 ? void 0 : context.system))) !== null && _b !== void 0 ? _b : null;
1103
+ const rowClusterName = canonicalClusterName(context === null || context === void 0 ? void 0 : context.kubernetesClusterName);
1104
+ /*
1105
+ * An explicit "@cluster" says the name was seen from inside that
1106
+ * cluster, so it is read the way a pod there reads it.
1107
+ */
1108
+ const runsInKubernetes = explicitClusterName.length > 0 ||
1109
+ rowClusterName.length > 0 ||
1110
+ isNonBlankText(context === null || context === void 0 ? void 0 : context.kubernetesNamespace);
1111
+ const host = applyKubernetesDnsRules(parsed.host, context === null || context === void 0 ? void 0 : context.kubernetesNamespace, runsInKubernetes);
1112
+ const clusterScoped = isClusterScopedDatabaseHost(host);
1113
+ if (explicitClusterName && !clusterScoped) {
1114
+ result.problem = isSingleLabelName(host)
1115
+ ? "qualifier-needs-namespace"
1116
+ : "qualifier-not-allowed";
1117
+ result.refusedHost = host;
1118
+ return result;
1119
+ }
1120
+ result.endpoint = buildEndpoint(joinHostInstance(host, instance), port, clusterScoped ? explicitClusterName || rowClusterName : "");
1121
+ return result;
1122
+ }
1123
+ /**
1124
+ * Inverse of formatDatabaseEndpoint, for stored values AND user-typed
1125
+ * aliases. The cluster qualifier is split on the LAST "@" and is only valid
1126
+ * on a host that resolves inside one cluster or network
1127
+ * (isClusterScopedDatabaseHost, after the Kubernetes DNS rules): anything
1128
+ * else with an "@" — `admin@10.0.0.5:5432`, `db.example.com@prod` — is
1129
+ * null, never a silently dropped qualifier or a user name read as a host.
1130
+ * URL forms are not split: their "@" is userinfo. Kubernetes DNS rules use
1131
+ * the row's namespace for a single-label name, and read a two-label name as
1132
+ * `<service>.<namespace>` when the row (or the qualifier) is a Kubernetes
1133
+ * one; an unqualified cluster-scoped host takes the row's cluster, and the
1134
+ * port defaults from the engine. Loopback and host-relative names are null —
1135
+ * an alias must name a server.
1136
+ */
1137
+ export function parseDatabaseEndpointString(value, context) {
1138
+ return interpretDatabaseEndpointString(value, context, false).endpoint;
1139
+ }
1140
+ function echo(value) {
1141
+ return value.length > MAX_ECHOED_VALUE_LENGTH
1142
+ ? `${value.substring(0, MAX_ECHOED_VALUE_LENGTH)}…`
1143
+ : value;
1144
+ }
1145
+ const CLUSTER_QUALIFIER_EXAMPLE = "pg.shop.svc.cluster.local:5432@prod-eu";
1146
+ /**
1147
+ * The endpoint a person typed (the create form of a manually added
1148
+ * database, an alias on its Endpoints tab), with a message that says what
1149
+ * to change when it cannot be used:
1150
+ *
1151
+ * - `user@host` (`admin@10.0.0.5:5432`) is refused — the user name does
1152
+ * not belong in an endpoint;
1153
+ * - `@<cluster>` names the Kubernetes cluster of an address that only
1154
+ * resolves inside one (a cluster-local name, a `<service>.<namespace>`
1155
+ * short name, a private-zone name, a private IP) and is refused on
1156
+ * anything else;
1157
+ * - loopback and host-relative names are refused;
1158
+ * - `port` (the form's own port field) replaces any port in the address,
1159
+ * and must be 1..65535, as must a port typed in the address.
1160
+ *
1161
+ * Accepted values are canonicalized exactly like parseDatabaseEndpointString.
1162
+ * `knownClusterNames` (the project's Kubernetes cluster names) are offered
1163
+ * in the hint for an unqualified cluster-scoped endpoint.
1164
+ */
1165
+ export function parseManualDatabaseEndpoint(value, context) {
1166
+ const rejected = (error) => {
1167
+ return { endpoint: null, error: error, clusterQualifierHint: null };
1168
+ };
1169
+ const typed = typeof value === "string" ? value.trim() : "";
1170
+ const hasPortField = (context === null || context === void 0 ? void 0 : context.port) !== undefined &&
1171
+ (context === null || context === void 0 ? void 0 : context.port) !== null &&
1172
+ !(typeof context.port === "string" && context.port.trim() === "");
1173
+ let portField = null;
1174
+ if (hasPortField) {
1175
+ portField = toValidPort(context.port);
1176
+ if (portField === null) {
1177
+ return rejected("Server port must be a whole number between 1 and 65535.");
1178
+ }
1179
+ }
1180
+ const interpreted = interpretDatabaseEndpointString(value, {
1181
+ system: (context === null || context === void 0 ? void 0 : context.system) || "",
1182
+ kubernetesClusterName: context === null || context === void 0 ? void 0 : context.kubernetesClusterName,
1183
+ kubernetesNamespace: context === null || context === void 0 ? void 0 : context.kubernetesNamespace,
1184
+ port: portField,
1185
+ }, !hasPortField);
1186
+ switch (interpreted.problem) {
1187
+ case "empty":
1188
+ return rejected("Server address is required. Enter the host name or IP address applications use to reach this database, for example orders-db.example.com:5432.");
1189
+ case "user-info":
1190
+ return rejected(`"${echo(typed)}" looks like user@host. Remove "${echo(interpreted.beforeAt)}@": the database user does not belong in an endpoint. "@" is only used after an address that resolves inside one Kubernetes cluster, to name that cluster, for example ${CLUSTER_QUALIFIER_EXAMPLE}.`);
1191
+ case "qualifier-needs-namespace":
1192
+ return rejected(`"${echo(interpreted.refusedHost)}" is a single-label name, which only means one Service once its namespace is known. Enter it with the namespace, for example ${echo(interpreted.refusedHost)}.<namespace>@${echo(interpreted.afterAt)}.`);
1193
+ case "qualifier-not-allowed":
1194
+ return rejected(`"${echo(interpreted.refusedHost)}" resolves the same way everywhere, so it cannot take a Kubernetes cluster qualifier. Remove "@${echo(interpreted.afterAt)}". A cluster is only named for an address that resolves inside one cluster or private network: a cluster-local name such as pg.shop.svc.cluster.local, a <service>.<namespace> short name, a .internal or .local name, or a private IP address.`);
1195
+ case "loopback":
1196
+ return rejected(`"${echo(typed)}" is a loopback or host-local address, such as localhost or host.docker.internal. Every application reaches its own, so it cannot identify one database. Enter the host name or IP address the database is reached at from other machines.`);
1197
+ case "port-out-of-range":
1198
+ return rejected(`"${echo(typed)}" has a port outside 1-65535. Enter a port between 1 and 65535.`);
1199
+ case "invalid":
1200
+ return rejected(`"${echo(typed)}" is not a valid host[:port] endpoint. Enter a host name or IP address with an optional port, for example orders-db.example.com:5432. A SQL Server named instance is written host\\instance, and an address that resolves inside one Kubernetes cluster can name that cluster: ${CLUSTER_QUALIFIER_EXAMPLE}.`);
1201
+ default:
1202
+ break;
1203
+ }
1204
+ const endpoint = interpreted.endpoint;
1205
+ if (!endpoint) {
1206
+ return rejected(`"${echo(typed)}" is not a valid host[:port] endpoint.`);
1207
+ }
1208
+ let clusterQualifierHint = null;
1209
+ if (!endpoint.kubernetesClusterName &&
1210
+ isClusterScopedDatabaseHost(endpoint.host)) {
1211
+ const formatted = formatDatabaseEndpoint(endpoint);
1212
+ const clusters = Array.from(new Set((Array.isArray(context === null || context === void 0 ? void 0 : context.knownClusterNames)
1213
+ ? context.knownClusterNames
1214
+ : [])
1215
+ .map(canonicalClusterName)
1216
+ .filter((name) => {
1217
+ return name.length > 0;
1218
+ })));
1219
+ clusterQualifierHint = `${formatted} only resolves inside one Kubernetes cluster or private network. Applications that report their cluster (k8s.cluster.name) are matched to ${formatted}@<cluster name> instead, so name the cluster the way they report it${clusters.length > 0
1220
+ ? `, for example ${formatted}@${clusters[0]} (this project's clusters: ${clusters.join(", ")})`
1221
+ : ""}.`;
1222
+ }
1223
+ return {
1224
+ endpoint: endpoint,
1225
+ error: null,
1226
+ clusterQualifierHint: clusterQualifierHint,
1227
+ };
1228
+ }
1229
+ // ---- managed cluster members ---------------------------------------------
1230
+ /**
1231
+ * The cluster a managed-service MEMBER host belongs to, as a host name, or
1232
+ * null for anything else. Drivers of replicated databases report the member
1233
+ * that served each call, so without this every member of one cluster would
1234
+ * become a database of its own. Today: MongoDB Atlas —
1235
+ * `cluster0-shard-00-01.ab1cd.mongodb.net` → `cluster0.ab1cd.mongodb.net`
1236
+ * (the cluster's SRV name). A `\instance` or a port plays no part.
1237
+ */
1238
+ export function getDatabaseClusterHost(host) {
1239
+ if (typeof host !== "string") {
1240
+ return null;
1241
+ }
1242
+ const value = splitDatabaseHostInstance(host.trim().toLowerCase()).host;
1243
+ const labels = value.split(".");
1244
+ if (labels.length !== 4 ||
1245
+ `${labels[2]}.${labels[3]}` !== ATLAS_DOMAIN ||
1246
+ !DNS_LABEL_REGEX.test(labels[1])) {
1247
+ return null;
1248
+ }
1249
+ const member = labels[0];
1250
+ const marker = member.lastIndexOf(ATLAS_MEMBER_MARKER);
1251
+ if (marker <= 0) {
1252
+ return null;
1253
+ }
1254
+ if (!ATLAS_MEMBER_NUMBER_REGEX.test(member.substring(marker + ATLAS_MEMBER_MARKER.length))) {
1255
+ return null;
1256
+ }
1257
+ const cluster = member.substring(0, marker);
1258
+ return DNS_LABEL_REGEX.test(cluster)
1259
+ ? `${cluster}.${labels[1]}.${ATLAS_DOMAIN}`
1260
+ : null;
1261
+ }
1262
+ // ---- row identity + naming -----------------------------------------------
1263
+ /*
1264
+ * Row identifiers start with the engine FAMILY (getDatabaseSystemFamily),
1265
+ * never the engine: a fork keys like the engine it forks ("mariadb" as
1266
+ * "mysql", "valkey" as "redis"). Which of the two a database is gets
1267
+ * decided — and corrected — over its lifetime (a span says "mysql", the
1268
+ * image then says "mariadb", a version string refines "mysql" to "tidb"),
1269
+ * and that must never re-key the row or mint a second one. Engines of
1270
+ * different families still key apart. An unknown engine is its own family.
1271
+ */
1272
+ function identifierEngine(system) {
1273
+ return getDatabaseSystemFamily(system) || "";
1274
+ }
1275
+ /**
1276
+ * `${family}|${formatted endpoint}` — the identifier of an endpoint row,
1277
+ * keyed on the engine family (see identifierEngine).
1278
+ */
1279
+ export function buildDatabaseServerIdentifier(system, endpoint) {
1280
+ return `${identifierEngine(system)}|${formatDatabaseEndpoint(endpoint)}`;
1281
+ }
1282
+ /**
1283
+ * The identifier of a workload-detected row, lowercased and keyed on the
1284
+ * engine family (see identifierEngine), so a workload re-classified within
1285
+ * its family (Redis → Valkey, MySQL → MariaDB) keeps its identifier:
1286
+ * kubernetes → `${family}|kubernetes:${cluster}/${namespace}/${kind}/${name}`
1287
+ * docker / podman → `${family}|${platform}:${host}/${name}` — no kind, so
1288
+ * compose labels that appear later cannot change the identity.
1289
+ */
1290
+ export function buildWorkloadDatabaseServerIdentifier(input) {
1291
+ const segment = (value) => {
1292
+ return typeof value === "string" ? value.trim() : "";
1293
+ };
1294
+ const system = identifierEngine(input.system);
1295
+ const platform = segment(input.platform);
1296
+ const parentName = segment(input.parentName);
1297
+ const workloadName = segment(input.workloadName);
1298
+ if (platform === "kubernetes") {
1299
+ return `${system}|kubernetes:${parentName}/${segment(input.namespace)}/${segment(input.workloadKind)}/${workloadName}`.toLowerCase();
1300
+ }
1301
+ return `${system}|${platform}:${parentName}/${workloadName}`.toLowerCase();
1302
+ }
1303
+ /**
1304
+ * "PostgreSQL db.prod:5432", "Redis cache/redis-master", "MongoDB mongo" —
1305
+ * the engine then the endpoint (no "@cluster") or the workload. At most 100
1306
+ * characters.
1307
+ */
1308
+ export function buildDatabaseServerDisplayName(input) {
1309
+ const engine = getDatabaseSystemDisplayName(input === null || input === void 0 ? void 0 : input.system);
1310
+ let target = "";
1311
+ if ((input === null || input === void 0 ? void 0 : input.endpoint) && typeof input.endpoint.host === "string") {
1312
+ target = formatDatabaseEndpoint({
1313
+ host: input.endpoint.host,
1314
+ port: input.endpoint.port,
1315
+ });
1316
+ }
1317
+ else {
1318
+ const workloadName = typeof (input === null || input === void 0 ? void 0 : input.workloadName) === "string" ? input.workloadName.trim() : "";
1319
+ const namespace = typeof (input === null || input === void 0 ? void 0 : input.namespace) === "string" ? input.namespace.trim() : "";
1320
+ if (workloadName) {
1321
+ target = namespace ? `${namespace}/${workloadName}` : workloadName;
1322
+ }
1323
+ }
1324
+ const name = target ? `${engine} ${target}` : engine;
1325
+ return name.length > DISPLAY_NAME_MAX_LENGTH
1326
+ ? name.substring(0, DISPLAY_NAME_MAX_LENGTH).trimEnd()
1327
+ : name;
1328
+ }
1329
+ /**
1330
+ * The endpoint aliases of a Kubernetes-detected database, formatted:
1331
+ * - each Service × port: `${svc}.${ns}.svc.cluster.local:${port}@${cluster}`;
1332
+ * - each StatefulSet / operator member behind a headless Service:
1333
+ * `${pod}.${svc}.${ns}.svc.cluster.local:${port}@${cluster}`;
1334
+ * - the unqualified twin of each, ONLY when `includeUnqualified` (the
1335
+ * worker sets it when the project has exactly one Kubernetes cluster, so
1336
+ * an unqualified name cannot belong to anything else).
1337
+ * Ports are the engine default plus the declared container ports. No
1338
+ * two-label `${svc}.${ns}` forms are needed: a pod calling `svc.ns` is
1339
+ * canonicalized to the Service FQDN (applyKubernetesDnsRules), which is
1340
+ * already here. Invalid DNS labels are skipped. Deduped, in a stable order.
1341
+ * With a blank cluster name only the unqualified form can be produced, so
1342
+ * it is.
1343
+ */
1344
+ export function buildKubernetesDatabaseAliases(input) {
1345
+ if (!input) {
1346
+ return [];
1347
+ }
1348
+ const namespace = canonicalDnsLabel(input.namespace);
1349
+ if (!namespace) {
1350
+ return [];
1351
+ }
1352
+ const clusterName = canonicalClusterName(input.clusterName);
1353
+ const ports = [];
1354
+ const candidatePorts = [
1355
+ getDefaultDatabasePort(input.system),
1356
+ ...(Array.isArray(input.ports) ? input.ports : []),
1357
+ ];
1358
+ for (const candidate of candidatePorts) {
1359
+ const port = toValidPort(candidate);
1360
+ if (port !== null && !ports.includes(port)) {
1361
+ ports.push(port);
1362
+ }
1363
+ }
1364
+ if (ports.length === 0) {
1365
+ ports.push(null);
1366
+ }
1367
+ const aliases = [];
1368
+ const seen = new Set();
1369
+ const push = (alias) => {
1370
+ if (!seen.has(alias)) {
1371
+ seen.add(alias);
1372
+ aliases.push(alias);
1373
+ }
1374
+ };
1375
+ const addHost = (host) => {
1376
+ if (!isValidHostname(host)) {
1377
+ return;
1378
+ }
1379
+ for (const port of ports) {
1380
+ if (clusterName) {
1381
+ push(formatDatabaseEndpoint(buildEndpoint(host, port, clusterName)));
1382
+ }
1383
+ if (!clusterName || input.includeUnqualified) {
1384
+ push(formatDatabaseEndpoint(buildEndpoint(host, port, "")));
1385
+ }
1386
+ }
1387
+ };
1388
+ for (const serviceName of Array.isArray(input.serviceNames)
1389
+ ? input.serviceNames
1390
+ : []) {
1391
+ const service = canonicalDnsLabel(serviceName);
1392
+ if (service) {
1393
+ addHost(`${service}.${namespace}${KUBERNETES_CLUSTER_DOMAIN_SUFFIX}`);
1394
+ }
1395
+ }
1396
+ for (const member of Array.isArray(input.podServiceNames)
1397
+ ? input.podServiceNames
1398
+ : []) {
1399
+ const podName = canonicalDnsLabel(member === null || member === void 0 ? void 0 : member.podName);
1400
+ const serviceName = canonicalDnsLabel(member === null || member === void 0 ? void 0 : member.serviceName);
1401
+ if (podName && serviceName) {
1402
+ addHost(`${podName}.${serviceName}.${namespace}${KUBERNETES_CLUSTER_DOMAIN_SUFFIX}`);
1403
+ }
1404
+ }
1405
+ return aliases;
1406
+ }
1407
+ //# sourceMappingURL=DatabaseEndpoint.js.map