@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,1005 @@
1
+ import {
2
+ FOREIGN_HIDDEN_RULE_CSS,
3
+ LAPTOP_WIDTH_IN_PX,
4
+ PHONE_WIDTH_IN_PX,
5
+ TABLET_WIDTH_IN_PX,
6
+ TAILWIND_BREAKPOINTS_IN_PX,
7
+ WIDE_DESKTOP_WIDTH_IN_PX,
8
+ resolveDisplay,
9
+ splitVariants,
10
+ } from "../ResponsiveVisibility";
11
+ import {
12
+ afterAll,
13
+ beforeAll,
14
+ describe,
15
+ expect,
16
+ jest,
17
+ test,
18
+ } from "@jest/globals";
19
+ import { waitFor } from "@testing-library/react";
20
+ import fs from "fs";
21
+ import path from "path";
22
+
23
+ /*
24
+ * The fix for the missing navigation bar swapped every `hidden md:flex` for
25
+ * `max-md:hidden md:flex`. The two only paint the same if Tailwind emits the
26
+ * max-width variant the way we think it does: `display:none` below the
27
+ * breakpoint, nothing from the breakpoint up, in a block the `md:flex` rule
28
+ * still comes after. Nothing else in the suite checks that. Every frontend
29
+ * styles itself at runtime with the Play CDN (index.ejs serves the vendored
30
+ * tailwind-3.4.5.js), so there is no build output to inspect, and jsdom has no
31
+ * stylesheet at all: the suites that guard the navigation read class
32
+ * attributes through ResponsiveVisibility.ts, which carries its own model of
33
+ * Tailwind's cascade.
34
+ *
35
+ * This file holds that model to the real thing. It runs the vendored script in
36
+ * jsdom the way the page does - a classic <script>, then `tailwind.config` as
37
+ * index.ejs sets it - hands it the class strings the fix depends on, and
38
+ * asserts on the CSS the CDN writes. If a Tailwind upgrade moves a media
39
+ * query, reorders the blocks or rewrites an arbitrary-variant selector, this
40
+ * file fails before ResponsiveVisibility.ts starts quietly approving markup a
41
+ * browser would hide.
42
+ */
43
+
44
+ const PLAY_CDN_PATH: string = path.resolve(
45
+ __dirname,
46
+ "..",
47
+ "..",
48
+ "Server",
49
+ "Static",
50
+ "Vendor",
51
+ "tailwind",
52
+ "tailwind-3.4.5.js",
53
+ );
54
+
55
+ const FEATURE_SET_ROOT: string = path.resolve(
56
+ __dirname,
57
+ "..",
58
+ "..",
59
+ "..",
60
+ "App",
61
+ "FeatureSet",
62
+ );
63
+
64
+ const DASHBOARD_INDEX_VIEW: string = path.join(
65
+ FEATURE_SET_ROOT,
66
+ "Dashboard",
67
+ "views",
68
+ "index.ejs",
69
+ );
70
+
71
+ // The inline config in the Dashboard's index.ejs (checked below).
72
+ const INDEX_VIEW_TAILWIND_CONFIG: Record<string, unknown> = {
73
+ darkMode: "class",
74
+ theme: {
75
+ extend: {
76
+ fontFamily: {
77
+ display: ["Inter", "sans-serif"],
78
+ body: ["Inter", "sans-serif"],
79
+ },
80
+ },
81
+ },
82
+ };
83
+
84
+ const BREAKPOINTS: Array<string> = Object.keys(TAILWIND_BREAKPOINTS_IN_PX);
85
+
86
+ /*
87
+ * The order ResponsiveVisibility.ts ranks display utilities in (its
88
+ * maxVariantPrecedence / minVariantPrecedence). If the CDN stops emitting the
89
+ * blocks in this order, it is the helper that is wrong, not this list.
90
+ */
91
+ const EMIT_ORDER_ASSUMED_BY_RESPONSIVE_VISIBILITY: Array<string> = [
92
+ "unprefixed",
93
+ "max-2xl",
94
+ "max-xl",
95
+ "max-lg",
96
+ "max-md",
97
+ "max-sm",
98
+ "sm",
99
+ "md",
100
+ "lg",
101
+ "xl",
102
+ "2xl",
103
+ ];
104
+
105
+ /*
106
+ * The two class names the facet rows and the runbook execution view moved to,
107
+ * and the selectors Tailwind 3.4.5 is expected to write for them.
108
+ */
109
+ const GROUP_NOT_HOVER_HIDDEN: string = "group-[:not(:hover)]:hidden";
110
+ const GROUP_NOT_HOVER_HIDDEN_SELECTOR: string =
111
+ ".group:not(:hover) .group-\\[\\:not\\(\\:hover\\)\\]\\:hidden";
112
+ const DETAILS_CLOSED_HIDDEN: string = "[details:not([open])>summary>&]:hidden";
113
+ const DETAILS_CLOSED_HIDDEN_SELECTOR: string =
114
+ "details:not([open])>summary>.\\[details\\:not\\(\\[open\\]\\)\\>summary\\>\\&\\]\\:hidden";
115
+
116
+ /*
117
+ * Not every foreign rule is !important. A plain `.hidden{display:none}` in a
118
+ * sheet appended after Tailwind's <style> ties on specificity and wins on
119
+ * source order, which is just as fatal to `hidden md:flex`.
120
+ */
121
+ const APPENDED_PLAIN_HIDDEN_RULE_CSS: string = ".hidden{display:none}";
122
+
123
+ interface ConvertedClassString {
124
+ where: string;
125
+ before: string;
126
+ after: string;
127
+ }
128
+
129
+ // Real before/after pairs from the fix, at least one per breakpoint.
130
+ const CONVERTED_CLASS_STRINGS: Array<ConvertedClassString> = [
131
+ {
132
+ where: "NavBar desktop row",
133
+ before: "bg-white flex text-center items-center lg:py-2 hidden md:flex",
134
+ after:
135
+ "bg-white flex text-center items-center lg:py-2 max-md:hidden md:flex",
136
+ },
137
+ {
138
+ where: "Dashboard header search rail",
139
+ before: "hidden items-center gap-2 lg:flex",
140
+ after: "max-lg:hidden items-center gap-2 lg:flex",
141
+ },
142
+ {
143
+ where: "Home side menu",
144
+ before: "hidden md:block w-56 lg:w-64 flex-shrink-0 mb-10",
145
+ after: "max-md:hidden md:block w-56 lg:w-64 flex-shrink-0 mb-10",
146
+ },
147
+ {
148
+ where: "Pagination page button",
149
+ before: "hidden sm:flex",
150
+ after: "max-sm:hidden sm:flex",
151
+ },
152
+ {
153
+ where: "Page header actions",
154
+ before:
155
+ "hidden sm:flex sm:flex-wrap sm:items-center sm:justify-end sm:gap-3",
156
+ after:
157
+ "max-sm:hidden sm:flex sm:flex-wrap sm:items-center sm:justify-end sm:gap-3",
158
+ },
159
+ {
160
+ where: "Workflow query builder column headings",
161
+ before:
162
+ "hidden border-b border-gray-100 bg-gray-50/60 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.08em] text-gray-400 sm:grid sm:grid-cols-[minmax(0,1fr)_minmax(0,0.85fr)_minmax(0,1.3fr)_auto] sm:gap-2",
163
+ after:
164
+ "max-sm:hidden border-b border-gray-100 bg-gray-50/60 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.08em] text-gray-400 sm:grid sm:grid-cols-[minmax(0,1fr)_minmax(0,0.85fr)_minmax(0,1.3fr)_auto] sm:gap-2",
165
+ },
166
+ {
167
+ where: "AI insight skeleton column",
168
+ before: "hidden w-36 flex-shrink-0 xl:block",
169
+ after: "max-xl:hidden w-36 flex-shrink-0 xl:block",
170
+ },
171
+ {
172
+ where: "Session replay timestamp",
173
+ before: "hidden text-gray-400 2xl:inline",
174
+ after: "max-2xl:hidden text-gray-400 2xl:inline",
175
+ },
176
+ ];
177
+
178
+ /*
179
+ * Strings whose answer turns on a precedence rule rather than on one
180
+ * breakpoint: max-* over unprefixed, the narrower max-* over the wider, a
181
+ * min-width variant over a max-width one, and the order display utilities
182
+ * keep inside one block (`hidden` last, `grid` after `flex` after `block`).
183
+ */
184
+ const PRECEDENCE_PROBES: Array<string> = [
185
+ "flex max-lg:hidden",
186
+ "max-xl:hidden max-md:block",
187
+ "max-lg:hidden sm:block",
188
+ "hidden flex",
189
+ "block inline-flex",
190
+ "contents grid inline-block",
191
+ "md:grid md:flex md:block",
192
+ "max-md:hidden md:inline-flex",
193
+ "max-sm:hidden sm:inline-block",
194
+ "max-sm:hidden sm:inline",
195
+ "text-sm font-medium",
196
+ ];
197
+
198
+ /*
199
+ * Every display utility Tailwind 3.4.5 has, alphabetically: the order that
200
+ * matters is the one the CDN emits them in, and that is read from its output.
201
+ */
202
+ const EVERY_DISPLAY_UTILITY: string =
203
+ "block contents flex flow-root grid hidden inline inline-block inline-flex inline-grid inline-table list-item table table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group";
204
+
205
+ // Named viewports; every breakpoint edge the CDN emits is added on top.
206
+ const ASSERTED_WIDTHS_IN_PX: Array<number> = [
207
+ PHONE_WIDTH_IN_PX,
208
+ 640,
209
+ 767,
210
+ TABLET_WIDTH_IN_PX,
211
+ 1024,
212
+ LAPTOP_WIDTH_IN_PX,
213
+ WIDE_DESKTOP_WIDTH_IN_PX,
214
+ ];
215
+
216
+ interface PlayCdnGlobal {
217
+ config: Record<string, unknown>;
218
+ defaultTheme: { screens: Record<string, string> };
219
+ }
220
+
221
+ interface EmittedRule {
222
+ order: number;
223
+ // Enclosing at-rule preludes, outermost first: "@media (min-width: 640px)".
224
+ atRules: Array<string>;
225
+ selector: string;
226
+ declarations: string;
227
+ }
228
+
229
+ interface DisplayDeclaration {
230
+ value: string;
231
+ important: boolean;
232
+ }
233
+
234
+ function playCdn(): PlayCdnGlobal | undefined {
235
+ return (window as unknown as { tailwind?: PlayCdnGlobal }).tailwind;
236
+ }
237
+
238
+ // The <style> the CDN appends to <head>, recognised by its license banner.
239
+ function playCdnCss(): string {
240
+ const style: HTMLStyleElement | undefined = Array.from(
241
+ document.head.querySelectorAll("style"),
242
+ ).find((element: HTMLStyleElement) => {
243
+ return (element.textContent || "").includes("tailwindcss v");
244
+ });
245
+
246
+ return style?.textContent || "";
247
+ }
248
+
249
+ /*
250
+ * A small parser for the stylesheet the CDN writes: comments dropped, quoted
251
+ * strings and backslash escapes kept intact (Tailwind escapes `:`, `[`, `(`
252
+ * and friends in class names), and every style rule recorded with the at-rules
253
+ * around it and its position in the sheet.
254
+ */
255
+ function parseStylesheet(css: string): Array<EmittedRule> {
256
+ const rules: Array<EmittedRule> = [];
257
+ const atRules: Array<string> = [];
258
+ let selector: string | null = null;
259
+ let buffer: string = "";
260
+ let index: number = 0;
261
+
262
+ while (index < css.length) {
263
+ const character: string = css[index]!;
264
+
265
+ if (character === "\\") {
266
+ buffer += css.slice(index, index + 2);
267
+ index += 2;
268
+ continue;
269
+ }
270
+
271
+ if (character === "/" && css[index + 1] === "*") {
272
+ const commentEnd: number = css.indexOf("*/", index + 2);
273
+ index = commentEnd === -1 ? css.length : commentEnd + 2;
274
+ continue;
275
+ }
276
+
277
+ if (character === '"' || character === "'") {
278
+ let stringEnd: number = index + 1;
279
+
280
+ while (stringEnd < css.length && css[stringEnd] !== character) {
281
+ stringEnd += css[stringEnd] === "\\" ? 2 : 1;
282
+ }
283
+
284
+ buffer += css.slice(index, stringEnd + 1);
285
+ index = stringEnd + 1;
286
+ continue;
287
+ }
288
+
289
+ if (character === "{") {
290
+ const prelude: string = buffer.trim();
291
+
292
+ if (prelude.startsWith("@")) {
293
+ atRules.push(prelude);
294
+ } else {
295
+ selector = prelude;
296
+ }
297
+
298
+ buffer = "";
299
+ } else if (character === "}") {
300
+ if (selector !== null) {
301
+ rules.push({
302
+ order: rules.length,
303
+ atRules: [...atRules],
304
+ selector: selector,
305
+ declarations: buffer.trim(),
306
+ });
307
+ selector = null;
308
+ } else {
309
+ atRules.pop();
310
+ }
311
+
312
+ buffer = "";
313
+ } else {
314
+ buffer += character;
315
+ }
316
+
317
+ index++;
318
+ }
319
+
320
+ return rules;
321
+ }
322
+
323
+ const HEX_DIGIT_FIRST: RegExp = /^[0-9a-fA-F]/;
324
+ const LONE_CLASS_SELECTOR: RegExp =
325
+ /^\.((?:\\[0-9a-fA-F]{1,6}\s?|\\[\s\S]|[\w-])+)$/;
326
+ const DISPLAY_DECLARATION: RegExp =
327
+ /(?:^|;)\s*display\s*:\s*([^;!]+?)\s*(!\s*important)?\s*(?:;|$)/;
328
+ const TAILWIND_CONFIG_ASSIGNMENT: RegExp =
329
+ /tailwind\.config\s*=\s*([\s\S]*?)<\/script>/;
330
+
331
+ // `\:` -> `:`, `\32xl` -> `2xl`, `\2c ` -> `,` (CSS identifier escapes).
332
+ function unescapeCssIdentifier(escaped: string): string {
333
+ return escaped.replace(
334
+ /\\([0-9a-fA-F]{1,6}\s?|[\s\S])/g,
335
+ (_escape: string, sequence: string): string => {
336
+ if (HEX_DIGIT_FIRST.test(sequence)) {
337
+ return String.fromCodePoint(parseInt(sequence.trim(), 16));
338
+ }
339
+
340
+ return sequence;
341
+ },
342
+ );
343
+ }
344
+
345
+ /*
346
+ * The class name when the selector is one lone class (`.max-md\:hidden`,
347
+ * `.\32xl\:flex`) and null otherwise. Lone-class rules are the ones
348
+ * ResponsiveVisibility.ts models, and they all share one specificity, so
349
+ * source order alone decides between them.
350
+ */
351
+ function loneClassName(selector: string): string | null {
352
+ const match: RegExpExecArray | null = LONE_CLASS_SELECTOR.exec(selector);
353
+
354
+ return match ? unescapeCssIdentifier(match[1]!) : null;
355
+ }
356
+
357
+ function displayDeclaration(declarations: string): DisplayDeclaration | null {
358
+ const match: RegExpExecArray | null = DISPLAY_DECLARATION.exec(declarations);
359
+
360
+ if (!match) {
361
+ return null;
362
+ }
363
+
364
+ return { value: match[1]!, important: Boolean(match[2]) };
365
+ }
366
+
367
+ const MIN_WIDTH_MEDIA: RegExp = /^@media \(min-width: (\d+)px\)$/;
368
+ const BELOW_WIDTH_MEDIA: RegExp = /^@media not all and \(min-width: (\d+)px\)$/;
369
+
370
+ /*
371
+ * Whether a rule's media applies at a viewport width, read from the px in the
372
+ * emitted query rather than from the helper's breakpoint table. Anything but
373
+ * the two forms ResponsiveVisibility.ts models is an error, not a guess.
374
+ */
375
+ function appliesAtWidth(rule: EmittedRule, viewportWidthInPx: number): boolean {
376
+ if (rule.atRules.length === 0) {
377
+ return true;
378
+ }
379
+
380
+ if (rule.atRules.length === 1) {
381
+ const minWidth: RegExpExecArray | null = MIN_WIDTH_MEDIA.exec(
382
+ rule.atRules[0]!,
383
+ );
384
+
385
+ if (minWidth) {
386
+ return viewportWidthInPx >= Number(minWidth[1]);
387
+ }
388
+
389
+ const belowWidth: RegExpExecArray | null = BELOW_WIDTH_MEDIA.exec(
390
+ rule.atRules[0]!,
391
+ );
392
+
393
+ if (belowWidth) {
394
+ return viewportWidthInPx < Number(belowWidth[1]);
395
+ }
396
+ }
397
+
398
+ throw new Error(
399
+ `${rule.selector} is emitted inside ${JSON.stringify(
400
+ rule.atRules,
401
+ )}; ResponsiveVisibility.ts only models "(min-width: Npx)" and "not all and (min-width: Npx)", so it needs updating for this Tailwind output`,
402
+ );
403
+ }
404
+
405
+ /*
406
+ * The display a browser would compute from these rules for an element carrying
407
+ * `classAttribute`: the last applicable declaration wins, unless an earlier
408
+ * one is !important and it is not. Returned in utility terms (`none` reads as
409
+ * `hidden`) so it compares directly with resolveDisplay.
410
+ */
411
+ function cascadeDisplay(
412
+ rules: Array<EmittedRule>,
413
+ classAttribute: string,
414
+ viewportWidthInPx: number,
415
+ ): string | null {
416
+ const tokens: Set<string> = new Set(
417
+ classAttribute.split(/\s+/).filter(Boolean),
418
+ );
419
+ let winner: DisplayDeclaration | null = null;
420
+
421
+ for (const rule of rules) {
422
+ const className: string | null = loneClassName(rule.selector);
423
+
424
+ if (className === null || !tokens.has(className)) {
425
+ continue;
426
+ }
427
+
428
+ const display: DisplayDeclaration | null = displayDeclaration(
429
+ rule.declarations,
430
+ );
431
+
432
+ if (!display || !appliesAtWidth(rule, viewportWidthInPx)) {
433
+ continue;
434
+ }
435
+
436
+ if (!winner || display.important || !winner.important) {
437
+ winner = display;
438
+ }
439
+ }
440
+
441
+ if (!winner) {
442
+ return null;
443
+ }
444
+
445
+ return winner.value === "none" ? "hidden" : winner.value;
446
+ }
447
+
448
+ // The object literal assigned to `tailwind.config` in an index.ejs, if any.
449
+ function tailwindConfigSource(indexView: string): string | null {
450
+ const match: RegExpExecArray | null =
451
+ TAILWIND_CONFIG_ASSIGNMENT.exec(indexView);
452
+
453
+ return match ? match[1]! : null;
454
+ }
455
+
456
+ /*
457
+ * Whitespace, quotes and trailing commas stripped, so an object literal in
458
+ * index.ejs and JSON.stringify of the same object compare equal.
459
+ */
460
+ function normalizeObjectLiteral(source: string): string {
461
+ return source
462
+ .replace(/[\s'"]/g, "")
463
+ .replace(/;$/, "")
464
+ .replace(/,([}\]])/g, "$1");
465
+ }
466
+
467
+ function rulesForClass(
468
+ rules: Array<EmittedRule>,
469
+ className: string,
470
+ ): Array<EmittedRule> {
471
+ return rules.filter((rule: EmittedRule) => {
472
+ return loneClassName(rule.selector) === className;
473
+ });
474
+ }
475
+
476
+ function rulesForSelector(
477
+ rules: Array<EmittedRule>,
478
+ selector: string,
479
+ ): Array<EmittedRule> {
480
+ return rules.filter((rule: EmittedRule) => {
481
+ return rule.selector === selector;
482
+ });
483
+ }
484
+
485
+ function everyFixtureClassString(): Array<string> {
486
+ return [
487
+ ...CONVERTED_CLASS_STRINGS.flatMap((pair: ConvertedClassString) => {
488
+ return [pair.before, pair.after];
489
+ }),
490
+ ...PRECEDENCE_PROBES,
491
+ EVERY_DISPLAY_UTILITY,
492
+ ...BREAKPOINTS.map((breakpoint: string) => {
493
+ return `max-${breakpoint}:hidden ${breakpoint}:flex`;
494
+ }),
495
+ ];
496
+ }
497
+
498
+ /*
499
+ * The CDN keeps two MutationObservers on the document for the life of the page
500
+ * and exposes neither. jsdom empties the document when the file finishes, the
501
+ * observers fire into a window that no longer has one, and the worker dies on
502
+ * a TypeError. Recording them as they are built lets afterAll disconnect them.
503
+ */
504
+ const OriginalMutationObserver: typeof MutationObserver =
505
+ window.MutationObserver;
506
+ const playCdnObservers: Array<MutationObserver> = [];
507
+
508
+ class RecordingMutationObserver extends OriginalMutationObserver {
509
+ public constructor(callback: MutationCallback) {
510
+ super(callback);
511
+ playCdnObservers.push(this);
512
+ }
513
+ }
514
+
515
+ // Carried by the fixture container only, so its rule marks the fixture build.
516
+ const FIXTURE_SENTINEL_CLASS: string = "isolate";
517
+
518
+ let emittedCss: string = "";
519
+ let emittedRules: Array<EmittedRule> = [];
520
+ let detailsFixture: HTMLDetailsElement;
521
+ let detailsFixtureLabel: HTMLSpanElement;
522
+
523
+ beforeAll(async () => {
524
+ window.MutationObserver = RecordingMutationObserver;
525
+
526
+ // The CDN announces itself on console.warn; that is noise here, not news.
527
+ const warn: ReturnType<typeof jest.spyOn> = jest
528
+ .spyOn(console, "warn")
529
+ .mockImplementation(() => {});
530
+
531
+ const script: HTMLScriptElement = document.createElement("script");
532
+ script.textContent = fs.readFileSync(PLAY_CDN_PATH, "utf-8");
533
+ document.head.appendChild(script);
534
+
535
+ warn.mockRestore();
536
+
537
+ const cdn: PlayCdnGlobal | undefined = playCdn();
538
+
539
+ if (!cdn) {
540
+ throw new Error(
541
+ "the vendored Play CDN did not run: jest-environment-jsdom must execute <script> elements (runScripts: 'dangerously')",
542
+ );
543
+ }
544
+
545
+ cdn.config = INDEX_VIEW_TAILWIND_CONFIG;
546
+
547
+ /*
548
+ * Setting the config starts a full build. Let it land before adding the
549
+ * fixture, so it cannot finish late and overwrite the build that follows.
550
+ */
551
+ await waitFor(
552
+ () => {
553
+ expect(playCdnCss()).not.toBe("");
554
+ },
555
+ { timeout: 30000 },
556
+ );
557
+
558
+ const fixture: HTMLDivElement = document.createElement("div");
559
+ fixture.className = FIXTURE_SENTINEL_CLASS;
560
+
561
+ for (const classAttribute of everyFixtureClassString()) {
562
+ const element: HTMLDivElement = document.createElement("div");
563
+ element.className = classAttribute;
564
+ fixture.appendChild(element);
565
+ }
566
+
567
+ // The facet row's remove button, inside its `group` row.
568
+ const facetRow: HTMLDivElement = document.createElement("div");
569
+ facetRow.className = "group flex";
570
+ const removeButton: HTMLButtonElement = document.createElement("button");
571
+ removeButton.className = `flex h-5 w-5 items-center ${GROUP_NOT_HOVER_HIDDEN}`;
572
+ facetRow.appendChild(removeButton);
573
+ fixture.appendChild(facetRow);
574
+
575
+ // The runbook step label, in the details > summary > span shape it ships in.
576
+ detailsFixture = document.createElement("details");
577
+ const summary: HTMLElement = document.createElement("summary");
578
+ detailsFixtureLabel = document.createElement("span");
579
+ detailsFixtureLabel.className = `inline ${DETAILS_CLOSED_HIDDEN}`;
580
+ summary.appendChild(detailsFixtureLabel);
581
+ detailsFixture.appendChild(summary);
582
+ fixture.appendChild(detailsFixture);
583
+
584
+ document.body.appendChild(fixture);
585
+
586
+ /*
587
+ * The fixture goes in with one append and the CDN collects every class in
588
+ * the document in one pass, so once the container's own class is in the
589
+ * sheet the rest of the fixture is too. Waiting on that, not on the rules
590
+ * under test, lets a changed rule fail its own test with its own message.
591
+ */
592
+ await waitFor(
593
+ () => {
594
+ expect(
595
+ rulesForClass(parseStylesheet(playCdnCss()), FIXTURE_SENTINEL_CLASS),
596
+ ).toHaveLength(1);
597
+ },
598
+ { timeout: 30000 },
599
+ );
600
+
601
+ emittedCss = playCdnCss();
602
+ emittedRules = parseStylesheet(emittedCss);
603
+ }, 60000);
604
+
605
+ afterAll(() => {
606
+ for (const observer of playCdnObservers) {
607
+ observer.disconnect();
608
+ }
609
+
610
+ window.MutationObserver = OriginalMutationObserver;
611
+ });
612
+
613
+ describe("vendored Tailwind Play CDN output", () => {
614
+ test("is the 3.4.5 build, and its screens are the breakpoints ResponsiveVisibility.ts assumes", () => {
615
+ expect(emittedCss).toContain("tailwindcss v3.4.5");
616
+
617
+ const expectedScreens: Record<string, string> = {};
618
+
619
+ for (const breakpoint of BREAKPOINTS) {
620
+ expectedScreens[breakpoint] =
621
+ `${TAILWIND_BREAKPOINTS_IN_PX[breakpoint]}px`;
622
+ }
623
+
624
+ expect(playCdn()!.defaultTheme.screens).toEqual(expectedScreens);
625
+ });
626
+
627
+ test("is configured here exactly as the Dashboard's index.ejs configures it", () => {
628
+ const source: string | null = tailwindConfigSource(
629
+ fs.readFileSync(DASHBOARD_INDEX_VIEW, "utf8"),
630
+ );
631
+
632
+ expect(source).not.toBeNull();
633
+ expect(normalizeObjectLiteral(source!)).toBe(
634
+ normalizeObjectLiteral(JSON.stringify(INDEX_VIEW_TAILWIND_CONFIG)),
635
+ );
636
+ });
637
+
638
+ test("no frontend that loads it redefines the screens", () => {
639
+ /*
640
+ * A `screens` entry would move the breakpoints the helper and this file
641
+ * assume, and Tailwind 3 only generates max-* variants while every screen
642
+ * is a plain min-width - a customised one can make them vanish, and the
643
+ * fix with them.
644
+ */
645
+ const viewsLoadingTheCdn: Array<string> = [];
646
+ const viewsRedefiningScreens: Array<string> = [];
647
+
648
+ for (const featureSet of fs.readdirSync(FEATURE_SET_ROOT)) {
649
+ const indexViewPath: string = path.join(
650
+ FEATURE_SET_ROOT,
651
+ featureSet,
652
+ "views",
653
+ "index.ejs",
654
+ );
655
+
656
+ if (!fs.existsSync(indexViewPath)) {
657
+ continue;
658
+ }
659
+
660
+ const indexView: string = fs.readFileSync(indexViewPath, "utf8");
661
+
662
+ if (!indexView.includes("tailwind-3.4.5.js")) {
663
+ continue;
664
+ }
665
+
666
+ viewsLoadingTheCdn.push(featureSet);
667
+
668
+ if ((tailwindConfigSource(indexView) || "").includes("screens")) {
669
+ viewsRedefiningScreens.push(featureSet);
670
+ }
671
+ }
672
+
673
+ expect(viewsLoadingTheCdn).toEqual(
674
+ expect.arrayContaining([
675
+ "Accounts",
676
+ "AdminDashboard",
677
+ "Dashboard",
678
+ "PublicDashboard",
679
+ "StatusPage",
680
+ ]),
681
+ );
682
+ expect(viewsRedefiningScreens).toEqual([]);
683
+ });
684
+
685
+ test.each(BREAKPOINTS)(
686
+ "max-%s:hidden is display:none below the breakpoint and nothing from it up",
687
+ (breakpoint: string) => {
688
+ const rules: Array<EmittedRule> = rulesForClass(
689
+ emittedRules,
690
+ `max-${breakpoint}:hidden`,
691
+ );
692
+
693
+ expect(
694
+ rules.map((rule: EmittedRule) => {
695
+ return { atRules: rule.atRules, declarations: rule.declarations };
696
+ }),
697
+ ).toEqual([
698
+ {
699
+ atRules: [
700
+ `@media not all and (min-width: ${TAILWIND_BREAKPOINTS_IN_PX[breakpoint]}px)`,
701
+ ],
702
+ declarations: "display:none",
703
+ },
704
+ ]);
705
+ },
706
+ );
707
+
708
+ test.each(BREAKPOINTS)(
709
+ "%s:flex, the counterpart that shows the element again, applies from the breakpoint up",
710
+ (breakpoint: string) => {
711
+ const rules: Array<EmittedRule> = rulesForClass(
712
+ emittedRules,
713
+ `${breakpoint}:flex`,
714
+ );
715
+
716
+ expect(
717
+ rules.map((rule: EmittedRule) => {
718
+ return { atRules: rule.atRules, declarations: rule.declarations };
719
+ }),
720
+ ).toEqual([
721
+ {
722
+ atRules: [
723
+ `@media (min-width: ${TAILWIND_BREAKPOINTS_IN_PX[breakpoint]}px)`,
724
+ ],
725
+ declarations: "display:flex",
726
+ },
727
+ ]);
728
+ },
729
+ );
730
+
731
+ test("every responsive display rule sits in the media query its variant names", () => {
732
+ const misplaced: Array<string> = [];
733
+ let responsiveDisplayRules: number = 0;
734
+
735
+ for (const rule of emittedRules) {
736
+ const className: string | null = loneClassName(rule.selector);
737
+
738
+ if (className === null || !displayDeclaration(rule.declarations)) {
739
+ continue;
740
+ }
741
+
742
+ const parts: Array<string> = splitVariants(className);
743
+
744
+ if (parts.length !== 2) {
745
+ continue;
746
+ }
747
+
748
+ const variant: string = parts[0]!;
749
+ const isMaxVariant: boolean = variant.startsWith("max-");
750
+ const breakpoint: string = isMaxVariant ? variant.slice(4) : variant;
751
+ const breakpointInPx: number | undefined =
752
+ TAILWIND_BREAKPOINTS_IN_PX[breakpoint];
753
+
754
+ if (breakpointInPx === undefined) {
755
+ continue;
756
+ }
757
+
758
+ responsiveDisplayRules++;
759
+
760
+ const expectedMedia: string = isMaxVariant
761
+ ? `@media not all and (min-width: ${breakpointInPx}px)`
762
+ : `@media (min-width: ${breakpointInPx}px)`;
763
+
764
+ if (rule.atRules.length !== 1 || rule.atRules[0] !== expectedMedia) {
765
+ misplaced.push(`${rule.selector} in ${JSON.stringify(rule.atRules)}`);
766
+ }
767
+ }
768
+
769
+ expect(misplaced).toEqual([]);
770
+ // sm..2xl in both directions at the very least, so the loop did look.
771
+ expect(responsiveDisplayRules).toBeGreaterThanOrEqual(
772
+ 2 * BREAKPOINTS.length,
773
+ );
774
+ });
775
+
776
+ test("display blocks come out in the order ResponsiveVisibility.ts ranks them", () => {
777
+ /*
778
+ * Every lone-class display rule, labelled with its variant, in sheet
779
+ * order, with runs of the same label collapsed. A block that is split up
780
+ * or out of place shows up as a repeated or misplaced label.
781
+ */
782
+ const emittedOrder: Array<string> = [];
783
+
784
+ for (const rule of emittedRules) {
785
+ const className: string | null = loneClassName(rule.selector);
786
+
787
+ if (className === null || !displayDeclaration(rule.declarations)) {
788
+ continue;
789
+ }
790
+
791
+ const parts: Array<string> = splitVariants(className);
792
+ const group: string = parts.length === 1 ? "unprefixed" : parts[0]!;
793
+
794
+ if (emittedOrder[emittedOrder.length - 1] !== group) {
795
+ emittedOrder.push(group);
796
+ }
797
+ }
798
+
799
+ expect(emittedOrder).toEqual(EMIT_ORDER_ASSUMED_BY_RESPONSIVE_VISIBILITY);
800
+ });
801
+
802
+ test("inside a block, the display utility emitted later is the one ResponsiveVisibility.ts lets win", () => {
803
+ const everyDisplayUtility: Array<string> = EVERY_DISPLAY_UTILITY.split(" ");
804
+ const emittedDisplayOrder: Array<string> = emittedRules
805
+ .map((rule: EmittedRule) => {
806
+ return loneClassName(rule.selector);
807
+ })
808
+ .filter((className: string | null): className is string => {
809
+ return className !== null && everyDisplayUtility.includes(className);
810
+ });
811
+
812
+ expect([...emittedDisplayOrder].sort()).toEqual(
813
+ [...everyDisplayUtility].sort(),
814
+ );
815
+
816
+ /*
817
+ * Adjacent pairs are enough: the model ranks utilities on one list, so
818
+ * agreeing on every neighbour means agreeing on the whole order.
819
+ */
820
+ const disagreements: Array<string> = [];
821
+
822
+ for (let index: number = 1; index < emittedDisplayOrder.length; index++) {
823
+ const earlier: string = emittedDisplayOrder[index - 1]!;
824
+ const later: string = emittedDisplayOrder[index]!;
825
+ const modelWinner: string | null = resolveDisplay(
826
+ `${later} ${earlier}`,
827
+ LAPTOP_WIDTH_IN_PX,
828
+ );
829
+
830
+ if (modelWinner !== later) {
831
+ disagreements.push(
832
+ `${earlier} is emitted before ${later}, but the model picks ${modelWinner}`,
833
+ );
834
+ }
835
+ }
836
+
837
+ expect(disagreements).toEqual([]);
838
+ });
839
+
840
+ test("group-[:not(:hover)]:hidden emits the selector the facet rows rely on", () => {
841
+ const rules: Array<EmittedRule> = rulesForSelector(
842
+ emittedRules,
843
+ GROUP_NOT_HOVER_HIDDEN_SELECTOR,
844
+ );
845
+
846
+ expect(rules).toHaveLength(1);
847
+ expect(rules[0]!.atRules).toEqual([]);
848
+ expect(rules[0]!.declarations).toBe("display:none");
849
+
850
+ /*
851
+ * It has to beat the unprefixed `flex` on the same button. It outranks it
852
+ * on specificity and it also comes later, so it wins either way.
853
+ */
854
+ const flex: EmittedRule = rulesForClass(emittedRules, "flex")[0]!;
855
+ expect(rules[0]!.order).toBeGreaterThan(flex.order);
856
+ });
857
+
858
+ test("[details:not([open])>summary>&]:hidden emits the selector the runbook view relies on, and it lets go of an open <details>", () => {
859
+ const rules: Array<EmittedRule> = rulesForSelector(
860
+ emittedRules,
861
+ DETAILS_CLOSED_HIDDEN_SELECTOR,
862
+ );
863
+
864
+ expect(rules).toHaveLength(1);
865
+ expect(rules[0]!.atRules).toEqual([]);
866
+ expect(rules[0]!.declarations).toBe("display:none");
867
+
868
+ const inline: EmittedRule = rulesForClass(emittedRules, "inline")[0]!;
869
+ expect(rules[0]!.order).toBeGreaterThan(inline.order);
870
+
871
+ // `&` became the element's own class, so it selects the label itself ...
872
+ expect(detailsFixtureLabel.matches(rules[0]!.selector)).toBe(true);
873
+
874
+ // ... and only while the disclosure is closed.
875
+ detailsFixture.open = true;
876
+
877
+ try {
878
+ expect(detailsFixtureLabel.matches(rules[0]!.selector)).toBe(false);
879
+ } finally {
880
+ detailsFixture.open = false;
881
+ }
882
+ });
883
+ });
884
+
885
+ describe("the emitted cascade agrees with resolveDisplay", () => {
886
+ /*
887
+ * Each breakpoint's last hidden pixel and first shown pixel, read from the
888
+ * media queries the CDN actually wrote, on top of the named viewports.
889
+ */
890
+ function widthsToCheck(): Array<number> {
891
+ const widths: Set<number> = new Set(ASSERTED_WIDTHS_IN_PX);
892
+
893
+ for (const rule of emittedRules) {
894
+ for (const atRule of rule.atRules) {
895
+ const media: RegExpExecArray | null =
896
+ MIN_WIDTH_MEDIA.exec(atRule) || BELOW_WIDTH_MEDIA.exec(atRule);
897
+
898
+ if (media) {
899
+ widths.add(Number(media[1]) - 1);
900
+ widths.add(Number(media[1]));
901
+ }
902
+ }
903
+ }
904
+
905
+ return Array.from(widths).sort((left: number, right: number) => {
906
+ return left - right;
907
+ });
908
+ }
909
+
910
+ function cascadeAcrossWidths(
911
+ rules: Array<EmittedRule>,
912
+ classAttribute: string,
913
+ ): Array<string> {
914
+ return widthsToCheck().map((width: number) => {
915
+ return `${width}px: ${cascadeDisplay(rules, classAttribute, width)}`;
916
+ });
917
+ }
918
+
919
+ function modelAcrossWidths(
920
+ classAttribute: string,
921
+ withForeignHiddenRule: boolean,
922
+ ): Array<string> {
923
+ return widthsToCheck().map((width: number) => {
924
+ return `${width}px: ${resolveDisplay(classAttribute, width, {
925
+ withForeignHiddenRule,
926
+ })}`;
927
+ });
928
+ }
929
+
930
+ test("the widths checked include every breakpoint edge", () => {
931
+ const widths: Array<number> = widthsToCheck();
932
+
933
+ for (const breakpoint of BREAKPOINTS) {
934
+ const breakpointInPx: number = TAILWIND_BREAKPOINTS_IN_PX[breakpoint]!;
935
+ expect(widths).toEqual(
936
+ expect.arrayContaining([breakpointInPx - 1, breakpointInPx]),
937
+ );
938
+ }
939
+ });
940
+
941
+ test.each(everyFixtureClassString())(
942
+ '"%s" resolves the same from the real CSS as from the model, with and without a foreign .hidden rule',
943
+ (classAttribute: string) => {
944
+ expect(cascadeAcrossWidths(emittedRules, classAttribute)).toEqual(
945
+ modelAcrossWidths(classAttribute, false),
946
+ );
947
+
948
+ // Appended after Tailwind's <style>, as an extension or user sheet is.
949
+ for (const foreignCss of [
950
+ FOREIGN_HIDDEN_RULE_CSS,
951
+ APPENDED_PLAIN_HIDDEN_RULE_CSS,
952
+ ]) {
953
+ expect(
954
+ cascadeAcrossWidths(
955
+ parseStylesheet(emittedCss + foreignCss),
956
+ classAttribute,
957
+ ),
958
+ ).toEqual(modelAcrossWidths(classAttribute, true));
959
+ }
960
+ },
961
+ );
962
+
963
+ test.each(CONVERTED_CLASS_STRINGS)(
964
+ "$where: the new classes paint exactly as the old ones did, and a foreign .hidden rule no longer removes them",
965
+ ({ before, after }: ConvertedClassString) => {
966
+ // Display-equivalent at every width, by the real stylesheet.
967
+ expect(cascadeAcrossWidths(emittedRules, after)).toEqual(
968
+ cascadeAcrossWidths(emittedRules, before),
969
+ );
970
+
971
+ for (const foreignCss of [
972
+ FOREIGN_HIDDEN_RULE_CSS,
973
+ APPENDED_PLAIN_HIDDEN_RULE_CSS,
974
+ ]) {
975
+ const withForeignRule: Array<EmittedRule> = parseStylesheet(
976
+ emittedCss + foreignCss,
977
+ );
978
+
979
+ // Immune: the foreign rule changes nothing for the new classes ...
980
+ expect(cascadeAcrossWidths(withForeignRule, after)).toEqual(
981
+ cascadeAcrossWidths(emittedRules, after),
982
+ );
983
+
984
+ /*
985
+ * ... while the same check fails for the old ones. At the customer's
986
+ * 1917px the old classes were on screen and the foreign rule took
987
+ * them off it - the missing navigation bar, reproduced from the real
988
+ * CSS.
989
+ */
990
+ expect(cascadeAcrossWidths(withForeignRule, before)).not.toEqual(
991
+ cascadeAcrossWidths(emittedRules, before),
992
+ );
993
+ expect(
994
+ cascadeDisplay(emittedRules, before, WIDE_DESKTOP_WIDTH_IN_PX),
995
+ ).not.toBe("hidden");
996
+ expect(
997
+ cascadeDisplay(withForeignRule, before, WIDE_DESKTOP_WIDTH_IN_PX),
998
+ ).toBe("hidden");
999
+ expect(
1000
+ cascadeDisplay(withForeignRule, after, WIDE_DESKTOP_WIDTH_IN_PX),
1001
+ ).not.toBe("hidden");
1002
+ }
1003
+ },
1004
+ );
1005
+ });