@oneuptime/common 14.0.3 → 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 (617) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
  3. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
  4. package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
  5. package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
  6. package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
  7. package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
  8. package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
  9. package/Models/DatabaseModels/Incident.ts +55 -0
  10. package/Models/DatabaseModels/Index.ts +16 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
  12. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  13. package/Models/DatabaseModels/TelemetryException.ts +2 -0
  14. package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  18. package/Server/Middleware/MultipartFormData.ts +1 -1
  19. package/Server/Middleware/TelemetryIngest.ts +15 -8
  20. package/Server/Services/AlertReminderRuleService.ts +100 -24
  21. package/Server/Services/DatabaseServerEndpointService.ts +895 -0
  22. package/Server/Services/DatabaseServerFeedService.ts +128 -0
  23. package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
  24. package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
  25. package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
  26. package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
  27. package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
  28. package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
  29. package/Server/Services/DatabaseServerService.ts +4546 -0
  30. package/Server/Services/DatabaseService.ts +14 -8
  31. package/Server/Services/DockerResourceService.ts +43 -2
  32. package/Server/Services/IncidentReminderRuleService.ts +103 -23
  33. package/Server/Services/Index.ts +16 -0
  34. package/Server/Services/InventoryItemService.ts +113 -5
  35. package/Server/Services/IoTDeviceService.ts +145 -37
  36. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  37. package/Server/Services/PodmanResourceService.ts +43 -2
  38. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  39. package/Server/Services/ServiceService.ts +1 -1
  40. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  41. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  42. package/Server/Services/UserService.ts +14 -1
  43. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  44. package/Server/Types/Database/QueryHelper.ts +30 -1
  45. package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
  46. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  47. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
  48. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  49. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
  50. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  51. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  52. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  53. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  54. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  55. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  56. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  57. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  58. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  59. package/Server/Utils/StartServer.ts +26 -6
  60. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  61. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  62. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  63. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  64. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  65. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  66. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  67. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  68. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  69. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  70. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  71. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  72. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  73. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  74. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  75. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  76. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  77. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  78. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  79. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  80. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  81. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  82. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  83. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  84. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  85. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  86. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  87. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  88. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  89. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  90. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  91. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  92. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  93. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  94. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  95. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  96. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  97. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  98. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  99. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  100. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  101. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  102. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  103. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  104. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  105. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  106. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  107. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  108. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  109. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  110. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  111. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  112. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  113. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  114. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  115. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  116. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  117. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  118. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  119. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  120. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  121. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  122. package/Tests/ClassStrings.ts +178 -0
  123. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  124. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  125. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  126. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  127. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  128. package/Tests/RenderedMarkup.ts +518 -0
  129. package/Tests/ResponsiveVisibility.test.ts +490 -4
  130. package/Tests/ResponsiveVisibility.ts +505 -52
  131. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  132. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  133. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  134. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  135. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  136. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  137. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  138. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  139. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  140. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  141. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  142. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  143. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  144. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  145. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  146. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  147. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  148. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  149. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  150. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  151. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  152. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  153. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  154. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  155. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  156. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  157. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  158. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  159. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  160. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  161. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  162. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  163. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  164. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  165. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  166. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  167. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  168. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  169. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  170. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  171. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  172. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  173. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  174. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  175. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  176. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  177. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  178. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  179. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  180. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  181. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
  182. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  183. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  184. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  185. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  186. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  187. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  188. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  189. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  190. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  191. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  192. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  193. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  194. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  195. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  196. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  197. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  198. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  199. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  200. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  201. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  202. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  203. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  205. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  206. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  207. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  208. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  209. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  210. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  211. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  212. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  213. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  214. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  215. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  216. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  217. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  218. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  219. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  220. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  221. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
  222. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
  223. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  224. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  225. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  226. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  227. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  228. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  229. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
  230. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  231. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  232. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  233. package/Tests/UI/Components/Card.test.tsx +93 -2
  234. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  235. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  236. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  237. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  238. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  239. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  240. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  241. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  242. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  243. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  244. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  245. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  246. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  247. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  248. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  249. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  250. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +70 -0
  251. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +21 -0
  252. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  253. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  254. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  255. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  256. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  257. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  258. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  259. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  260. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  261. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  262. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  263. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  264. package/Tests/tsconfig.json +16 -0
  265. package/Types/AI/AIResourceContext.ts +7 -0
  266. package/Types/Dashboard/DashboardTemplates.ts +2 -1
  267. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  268. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  269. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  270. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  271. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  272. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  273. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  274. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  275. package/Types/Email/EmailTemplateType.ts +1 -0
  276. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  277. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  278. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  279. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  280. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  281. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  282. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  283. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  284. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  285. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  286. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  287. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  288. package/Types/Permission.ts +267 -0
  289. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  290. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  291. package/Types/Rules/RuleRun.ts +12 -0
  292. package/Types/Telemetry/EntityType.ts +23 -0
  293. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  294. package/Types/Telemetry/ServiceType.ts +8 -0
  295. package/UI/Components/Banner/Banner.tsx +1 -1
  296. package/UI/Components/Card/Card.tsx +1 -1
  297. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  298. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  299. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  300. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  301. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  302. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  303. package/UI/Components/Forms/BasicForm.tsx +1 -1
  304. package/UI/Components/Header/Header.tsx +1 -1
  305. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  306. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  307. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  308. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  309. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  310. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  311. package/UI/Components/ModelTable/BaseModelTable.tsx +4 -4
  312. package/UI/Components/Navbar/NavBar.tsx +9 -2
  313. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  314. package/UI/Components/Page/Page.tsx +1 -1
  315. package/UI/Components/Pagination/Pagination.tsx +3 -3
  316. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  317. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  318. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  319. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  320. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  321. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  322. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  323. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  324. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  325. package/UI/Styles/Theme.css +8 -1
  326. package/UI/Utils/Navigation.ts +89 -42
  327. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  328. package/UI/Utils/TelemetryService.ts +4 -3
  329. package/Utils/LabelRuleImportExport.ts +2 -0
  330. package/Utils/MetricUnitUtil.ts +103 -11
  331. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  332. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  333. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  334. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  335. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  336. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  337. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  338. package/Utils/Telemetry/EntityKey.ts +176 -0
  339. package/Utils/ValueFormatter.ts +16 -0
  340. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  341. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  342. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  343. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  344. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  345. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  346. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  347. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  348. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  349. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  350. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  351. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  352. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  353. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  354. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  355. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  356. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  357. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  358. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  359. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  360. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  362. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  366. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  367. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  368. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  369. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  370. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  371. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  372. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  373. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  374. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  375. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  376. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  377. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  378. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  379. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  380. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  381. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  382. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  383. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  384. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  385. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  386. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  387. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  388. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  389. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  390. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  391. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  392. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  393. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  394. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  395. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  396. package/build/dist/Server/Services/DatabaseService.js +8 -4
  397. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  398. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  399. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  400. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  401. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  402. package/build/dist/Server/Services/Index.js +16 -0
  403. package/build/dist/Server/Services/Index.js.map +1 -1
  404. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  405. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  406. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  407. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  408. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  409. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  410. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  411. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  412. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  413. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  414. package/build/dist/Server/Services/ServiceService.js +1 -1
  415. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  416. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  417. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  418. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  419. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  420. package/build/dist/Server/Services/UserService.js +13 -1
  421. package/build/dist/Server/Services/UserService.js.map +1 -1
  422. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  423. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  424. package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
  425. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  426. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
  427. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  428. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  429. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  430. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
  431. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  433. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  435. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  437. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  439. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  440. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  441. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  442. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  443. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  444. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  445. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  446. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  447. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  448. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  449. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  450. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  451. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  452. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  453. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  454. package/build/dist/Server/Utils/StartServer.js +20 -4
  455. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  456. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  457. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  458. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  459. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  460. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  461. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  462. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  463. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  464. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  465. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  466. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  467. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  468. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  469. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  470. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  471. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  472. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  473. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  474. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  475. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  476. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  477. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  478. package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
  479. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  480. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  481. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  482. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  483. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  484. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  485. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  486. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  487. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  488. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  489. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  490. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  491. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  492. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  493. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  494. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  495. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  496. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  497. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  498. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  499. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  500. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  501. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  502. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  503. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  504. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  505. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  506. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  507. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  508. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  509. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  510. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  511. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  512. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  513. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  514. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  515. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  516. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  517. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  518. package/build/dist/Types/Permission.js +234 -0
  519. package/build/dist/Types/Permission.js.map +1 -1
  520. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  521. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  522. package/build/dist/Types/Rules/RuleRun.js +4 -0
  523. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  524. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  525. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  526. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  527. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  528. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  529. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  530. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  531. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  532. package/build/dist/UI/Components/Card/Card.js +1 -1
  533. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  534. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  535. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  536. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  537. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  538. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  539. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  540. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  541. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  542. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  543. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  544. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  545. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  546. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  547. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  548. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  549. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  550. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  551. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  552. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  553. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  554. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  555. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  556. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  557. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  558. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  559. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  560. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +4 -4
  561. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  562. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  563. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  564. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  565. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  566. package/build/dist/UI/Components/Page/Page.js +1 -1
  567. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  568. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  569. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  570. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  571. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  572. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  573. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  574. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  575. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  576. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  577. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  578. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  579. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  580. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  581. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  582. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  583. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  584. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  585. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  586. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  587. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  588. package/build/dist/UI/Utils/Navigation.js +66 -33
  589. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  590. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  591. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  592. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  593. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  594. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  595. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  596. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  597. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  598. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  599. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  600. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  601. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  602. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  603. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  604. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  605. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  606. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  607. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  608. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  609. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  610. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  611. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  612. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  613. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  614. package/build/dist/Utils/ValueFormatter.js +15 -0
  615. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  616. package/package.json +1 -1
  617. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,994 @@
1
+ import "@testing-library/jest-dom";
2
+ import {
3
+ act,
4
+ fireEvent,
5
+ render,
6
+ screen,
7
+ waitFor,
8
+ } from "@testing-library/react";
9
+ import {
10
+ beforeAll,
11
+ beforeEach,
12
+ describe,
13
+ expect,
14
+ jest,
15
+ test,
16
+ } from "@jest/globals";
17
+ import fs from "fs";
18
+ import path from "path";
19
+ import * as React from "react";
20
+ import { JSONObject } from "../../../Types/JSON";
21
+ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
22
+ import HTTPResponse from "../../../Types/API/HTTPResponse";
23
+ import IconProp from "../../../Types/Icon/IconProp";
24
+ import {
25
+ ClassCandidate,
26
+ collapseWhitespace,
27
+ collectClassCandidates,
28
+ describeCandidate,
29
+ } from "../../ClassStrings";
30
+ import {
31
+ isSrOnlyUnhidingToken,
32
+ listScanRoots,
33
+ listSourceFiles,
34
+ toRelativePath,
35
+ } from "../../ForeignHiddenRuleGuard";
36
+ import {
37
+ NON_WIDTH_MEDIA_VARIANTS,
38
+ PHONE_WIDTH_IN_PX,
39
+ ScreenReaderOnlyOptions,
40
+ TAILWIND_BREAKPOINTS_IN_PX,
41
+ WIDE_DESKTOP_WIDTH_IN_PX,
42
+ isVisuallyCollapsed,
43
+ splitVariants,
44
+ } from "../../ResponsiveVisibility";
45
+
46
+ /*
47
+ * The foreign `.hidden` rule has a sibling. Bootstrap 3 and HTML5
48
+ * Boilerplate - the same two stylesheets that ship
49
+ * `.hidden{display:none !important}` - also ship `.sr-only`, the
50
+ * visually-hidden pattern, and a browser that carries one carries the other.
51
+ * Appended after Tailwind's <style>, the foreign `.sr-only` has the same
52
+ * specificity as `.sm\:not-sr-only` and comes later, so it wins: a label
53
+ * written `sr-only sm:not-sr-only` - visible from sm up, read-only to screen
54
+ * readers below it - collapses to a 1px clip at every width. That is how the
55
+ * screenshot dock's "Copy image" and "Download", the Send Test badges, the
56
+ * session replay's collapsible action labels and the feed's "Filter & Sort"
57
+ * would have become icon-only on a wide screen. The fix wrote them
58
+ * `max-sm:sr-only sm:not-sr-only` (max-xl for the feed), which behaves the
59
+ * same everywhere and never carries the class the foreign rule targets.
60
+ *
61
+ * Skip links keep `sr-only focus:not-sr-only` on purpose. They must be
62
+ * hidden at EVERY width until focused, so a max-width form would be wrong,
63
+ * and they do not need one: `.focus\:not-sr-only:focus` is a class plus a
64
+ * pseudo-class, (0,2,0), and beats an appended `.sr-only`, (0,1,0), whatever
65
+ * the order. Unfocused, the foreign rule and Tailwind agree the link is
66
+ * hidden. The one case that would still break them - a foreign `.sr-only`
67
+ * marked !important - is not what either library ships (their `.hidden` is
68
+ * !important; their `.sr-only` is not), and the resolver's own tests pin
69
+ * that boundary.
70
+ *
71
+ * jsdom has no layout and no stylesheet, so "is this label collapsed at
72
+ * 1917px?" is answered by the sr-only resolver in ResponsiveVisibility.ts
73
+ * (isVisuallyCollapsed, beside resolveDisplay), which has its own unit tests
74
+ * in ResponsiveVisibility.test.ts. The labels are read from the real
75
+ * components where rendering them is cheap; the status page's skip link and
76
+ * the static sites' skip links are read from source. A sweep of every browser
77
+ * module and every EJS view then checks that no class string anywhere lets
78
+ * the foreign rule change what is on screen - and a last test holds that
79
+ * sweep and ForeignHiddenRuleGuard to the same answer.
80
+ */
81
+
82
+ /* ------------------------------------------------------------------------ */
83
+ /* The resolver, across widths */
84
+ /* ------------------------------------------------------------------------ */
85
+
86
+ const MAX_WIDTH_SR_ONLY_CLASS: RegExp = /^max-(sm|md|lg|xl|2xl):sr-only$/;
87
+
88
+ // `min-[900px]:` / `max-[900px]:` inside a class token: an arbitrary screen.
89
+ const ARBITRARY_PIXEL_SCREEN: RegExp = /\b(?:min|max)-\[(\d+(?:\.\d+)?)px\]:/g;
90
+
91
+ function tokensOf(classText: string | null | undefined): Array<string> {
92
+ return (classText || "").split(/\s+/).filter(Boolean);
93
+ }
94
+
95
+ // Every breakpoint and the pixel below it, plus a phone and a wide desktop.
96
+ const CHECK_WIDTHS_IN_PX: Array<number> = Array.from(
97
+ new Set<number>([
98
+ PHONE_WIDTH_IN_PX,
99
+ ...Object.values(TAILWIND_BREAKPOINTS_IN_PX).flatMap(
100
+ (breakpointInPx: number): Array<number> => {
101
+ return [breakpointInPx - 1, breakpointInPx];
102
+ },
103
+ ),
104
+ WIDE_DESKTOP_WIDTH_IN_PX,
105
+ ]),
106
+ ).sort((first: number, second: number): number => {
107
+ return first - second;
108
+ });
109
+
110
+ /*
111
+ * "375px collapsed, 639px collapsed, 640px shown, ..." - a failure then
112
+ * reads as the widths that went wrong.
113
+ */
114
+ function describeCollapse(
115
+ classAttribute: string | null | undefined,
116
+ options?: ScreenReaderOnlyOptions,
117
+ ): string {
118
+ return CHECK_WIDTHS_IN_PX.map((widthInPx: number): string => {
119
+ return `${widthInPx}px ${
120
+ isVisuallyCollapsed(classAttribute, widthInPx, options)
121
+ ? "collapsed"
122
+ : "shown"
123
+ }`;
124
+ }).join(", ");
125
+ }
126
+
127
+ function collapsedBelow(breakpoint: string): string {
128
+ const breakpointInPx: number = TAILWIND_BREAKPOINTS_IN_PX[breakpoint]!;
129
+
130
+ return CHECK_WIDTHS_IN_PX.map((widthInPx: number): string => {
131
+ return `${widthInPx}px ${widthInPx < breakpointInPx ? "collapsed" : "shown"}`;
132
+ }).join(", ");
133
+ }
134
+
135
+ function collapsedEverywhere(): string {
136
+ return CHECK_WIDTHS_IN_PX.map((widthInPx: number): string => {
137
+ return `${widthInPx}px collapsed`;
138
+ }).join(", ");
139
+ }
140
+
141
+ function shownEverywhere(): string {
142
+ return CHECK_WIDTHS_IN_PX.map((widthInPx: number): string => {
143
+ return `${widthInPx}px shown`;
144
+ }).join(", ");
145
+ }
146
+
147
+ /*
148
+ * The media conditions worth resolving a class under: none (a screen with
149
+ * default preferences), then every combination of the non-width media
150
+ * variants it names, so `print:not-sr-only` is also resolved as it prints.
151
+ */
152
+ function mediaEnvironmentsFor(classAttribute: string): Array<Array<string>> {
153
+ const named: Array<string> = NON_WIDTH_MEDIA_VARIANTS.filter(
154
+ (variant: string): boolean => {
155
+ return tokensOf(classAttribute).some((token: string): boolean => {
156
+ return splitVariants(token).slice(0, -1).includes(variant);
157
+ });
158
+ },
159
+ );
160
+ let environments: Array<Array<string>> = [[]];
161
+
162
+ for (const variant of named) {
163
+ environments = environments.flatMap(
164
+ (environment: Array<string>): Array<Array<string>> => {
165
+ return [environment, [...environment, variant]];
166
+ },
167
+ );
168
+ }
169
+
170
+ return environments;
171
+ }
172
+
173
+ // The checked widths, plus both sides of any arbitrary screen the class names.
174
+ function widthsFor(classAttribute: string): Array<number> {
175
+ const widths: Set<number> = new Set<number>(CHECK_WIDTHS_IN_PX);
176
+
177
+ for (const screen of classAttribute.matchAll(ARBITRARY_PIXEL_SCREEN)) {
178
+ const widthInPx: number = parseFloat(screen[1]!);
179
+ widths.add(widthInPx - 1);
180
+ widths.add(widthInPx);
181
+ }
182
+
183
+ return Array.from(widths);
184
+ }
185
+
186
+ /*
187
+ * Whether a foreign `.sr-only` changes what is on screen for this class at
188
+ * any width where its screens change, focused or not, under any media
189
+ * condition it names.
190
+ */
191
+ function isForeignSrOnlyHazard(classAttribute: string): boolean {
192
+ const widths: Array<number> = widthsFor(classAttribute);
193
+
194
+ return mediaEnvironmentsFor(classAttribute).some(
195
+ (mediaConditions: Array<string>): boolean => {
196
+ return [false, true].some((isFocused: boolean): boolean => {
197
+ const clean: ScreenReaderOnlyOptions = {
198
+ isFocused: isFocused,
199
+ mediaConditions: mediaConditions,
200
+ };
201
+
202
+ return widths.some((widthInPx: number): boolean => {
203
+ return (
204
+ isVisuallyCollapsed(classAttribute, widthInPx, {
205
+ ...clean,
206
+ withForeignSrOnlyRule: true,
207
+ }) !== isVisuallyCollapsed(classAttribute, widthInPx, clean)
208
+ );
209
+ });
210
+ });
211
+ },
212
+ );
213
+ }
214
+
215
+ /*
216
+ * Put the pre-fix idiom back: every `max-<bp>:sr-only` becomes the bare
217
+ * `sr-only` it replaced. Nothing used a max-width sr-only before the fix,
218
+ * so this rebuilds the old class exactly.
219
+ */
220
+ function restorePreFixSrOnly(classText: string | null): string {
221
+ return tokensOf(classText)
222
+ .map((token: string): string => {
223
+ return MAX_WIDTH_SR_ONLY_CLASS.test(token) ? "sr-only" : token;
224
+ })
225
+ .join(" ");
226
+ }
227
+
228
+ /* ------------------------------------------------------------------------ */
229
+ /* Component seams */
230
+ /* ------------------------------------------------------------------------ */
231
+
232
+ /*
233
+ * SendTestNotificationButton posts through API and reads its headers from
234
+ * ModelAPI; both are stood in for the same way its own suite does, with the
235
+ * answer decided per test.
236
+ */
237
+ type PostResult = HTTPResponse<JSONObject> | HTTPErrorResponse;
238
+
239
+ let apiPost: () => Promise<PostResult> = async (): Promise<PostResult> => {
240
+ return new HTTPResponse<JSONObject>(200, {}, {});
241
+ };
242
+
243
+ jest.mock("../../../UI/Utils/API/API", () => {
244
+ return {
245
+ __esModule: true,
246
+ default: {
247
+ post: (): Promise<PostResult> => {
248
+ return apiPost();
249
+ },
250
+ getFriendlyErrorMessage: (error: unknown): string => {
251
+ return error instanceof Error ? error.message : "Request failed.";
252
+ },
253
+ },
254
+ };
255
+ });
256
+
257
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
258
+ return {
259
+ __esModule: true,
260
+ default: {
261
+ getCommonHeaders: (): Record<string, string> => {
262
+ return { tenantid: "project-under-test" };
263
+ },
264
+ },
265
+ };
266
+ });
267
+
268
+ import { DEFAULT_FEED_OPTIONS } from "../../../UI/Components/Feed/FeedOptions";
269
+ import FeedOptionsButton from "../../../UI/Components/Feed/FeedOptionsButton";
270
+ import MasterPage from "../../../UI/Components/MasterPage/MasterPage";
271
+ import { ReplayToolButton } from "../../../../App/FeatureSet/Dashboard/src/Components/SessionReplay/ReplayUi";
272
+ import ReplayScreenshotActions from "../../../../App/FeatureSet/Dashboard/src/Components/SessionReplay/ReplayScreenshotActions";
273
+ import { ReplayScreenshot } from "../../../../App/FeatureSet/Dashboard/src/Components/SessionReplay/ReplayScreenshot";
274
+ import SendTestNotificationButton from "../../../../App/FeatureSet/Dashboard/src/Components/Workspace/SendTestNotificationButton";
275
+
276
+ function noop(): void {
277
+ /* Handlers the assertions do not care about. */
278
+ }
279
+
280
+ /*
281
+ * The one element whose own text is exactly the label: the <span>, not the
282
+ * button around it that shares the text.
283
+ */
284
+ function getLabelElement(container: HTMLElement, text: string): HTMLElement {
285
+ const matches: Array<HTMLElement> = Array.from(
286
+ container.querySelectorAll<HTMLElement>("*"),
287
+ ).filter((element: HTMLElement): boolean => {
288
+ return (
289
+ element.textContent === text &&
290
+ Array.from(element.children).every((child: Element): boolean => {
291
+ return child.textContent !== text;
292
+ })
293
+ );
294
+ });
295
+
296
+ expect(matches).toHaveLength(1);
297
+ return matches[0]!;
298
+ }
299
+
300
+ function renderScreenshotDock(): void {
301
+ render(
302
+ <ReplayScreenshotActions
303
+ onCapture={(): Promise<ReplayScreenshot> => {
304
+ return Promise.resolve({
305
+ blob: new Blob(["png-bytes"], { type: "image/png" }),
306
+ fileName: "session-replay-frame.png",
307
+ width: 1440,
308
+ height: 900,
309
+ });
310
+ }}
311
+ copyToClipboard={async (): Promise<void> => {
312
+ /* The dock is only rendered, never clicked. */
313
+ }}
314
+ download={noop}
315
+ clipboardSupport="supported"
316
+ fit="contain"
317
+ frameKey="1:41200"
318
+ />,
319
+ );
320
+ }
321
+
322
+ async function renderSendTestOutcome(
323
+ outcome: "sent" | "failed",
324
+ ): Promise<HTMLElement> {
325
+ if (outcome === "failed") {
326
+ apiPost = async (): Promise<PostResult> => {
327
+ return new HTTPErrorResponse(400, { message: "Channel not found." }, {});
328
+ };
329
+ }
330
+
331
+ render(
332
+ <SendTestNotificationButton
333
+ route="/slack/channels/test"
334
+ requestBody={{ channelId: "C0123ALERTS" }}
335
+ destinationName="#alerts"
336
+ workspaceName="Slack"
337
+ />,
338
+ );
339
+
340
+ await act(async (): Promise<void> => {
341
+ fireEvent.click(
342
+ screen.getByRole("button", {
343
+ name: "Send test notification to #alerts",
344
+ }),
345
+ );
346
+ });
347
+
348
+ const testId: string = `send-test-notification-${outcome}`;
349
+
350
+ await waitFor(() => {
351
+ expect(screen.getByTestId(testId)).toBeInTheDocument();
352
+ });
353
+
354
+ return getLabelElement(
355
+ screen.getByTestId(testId),
356
+ outcome === "sent" ? "Sent" : "Failed",
357
+ );
358
+ }
359
+
360
+ interface CollapsibleLabelCase {
361
+ name: string;
362
+ // Drawn from this breakpoint up; read to screen readers only below it.
363
+ breakpoint: string;
364
+ // The class this label carried before the fix (git 9bda7b343d).
365
+ preFixClass: string;
366
+ renderLabel: () => Promise<HTMLElement>;
367
+ }
368
+
369
+ const COLLAPSIBLE_LABELS: Array<CollapsibleLabelCase> = [
370
+ {
371
+ name: 'FeedOptionsButton "Filter & Sort"',
372
+ breakpoint: "xl",
373
+ preFixClass: "sr-only xl:not-sr-only",
374
+ renderLabel: async (): Promise<HTMLElement> => {
375
+ render(
376
+ <FeedOptionsButton
377
+ value={DEFAULT_FEED_OPTIONS}
378
+ eventTypeOptions={[]}
379
+ onChange={noop}
380
+ />,
381
+ );
382
+
383
+ return screen.getByTestId("feed-options-label");
384
+ },
385
+ },
386
+ {
387
+ name: "ReplayToolButton collapsible action label",
388
+ breakpoint: "sm",
389
+ preFixClass: "sr-only sm:not-sr-only",
390
+ renderLabel: async (): Promise<HTMLElement> => {
391
+ render(
392
+ <ReplayToolButton
393
+ label="Details"
394
+ icon={IconProp.Info}
395
+ collapseLabelOnSmallScreens={true}
396
+ onClick={noop}
397
+ />,
398
+ );
399
+
400
+ return getLabelElement(
401
+ screen.getByRole("button", { name: "Details" }),
402
+ "Details",
403
+ );
404
+ },
405
+ },
406
+ {
407
+ name: 'ReplayScreenshotActions "Copy image"',
408
+ breakpoint: "sm",
409
+ preFixClass: "sr-only sm:not-sr-only",
410
+ renderLabel: async (): Promise<HTMLElement> => {
411
+ renderScreenshotDock();
412
+
413
+ return getLabelElement(
414
+ screen.getByTestId("replay-screenshot-copy"),
415
+ "Copy image",
416
+ );
417
+ },
418
+ },
419
+ {
420
+ name: 'ReplayScreenshotActions "Download"',
421
+ breakpoint: "sm",
422
+ preFixClass: "sr-only sm:not-sr-only",
423
+ renderLabel: async (): Promise<HTMLElement> => {
424
+ renderScreenshotDock();
425
+
426
+ return getLabelElement(
427
+ screen.getByTestId("replay-screenshot-download"),
428
+ "Download",
429
+ );
430
+ },
431
+ },
432
+ {
433
+ name: 'SendTestNotificationButton "Sent" badge',
434
+ breakpoint: "sm",
435
+ preFixClass: "sr-only sm:not-sr-only",
436
+ renderLabel: async (): Promise<HTMLElement> => {
437
+ return renderSendTestOutcome("sent");
438
+ },
439
+ },
440
+ {
441
+ name: 'SendTestNotificationButton "Failed" badge',
442
+ breakpoint: "sm",
443
+ preFixClass: "sr-only sm:not-sr-only",
444
+ renderLabel: async (): Promise<HTMLElement> => {
445
+ return renderSendTestOutcome("failed");
446
+ },
447
+ },
448
+ ];
449
+
450
+ /*
451
+ * The contract for a label that is drawn from `breakpoint` up: the
452
+ * max-width form, never the bare class, and - by the resolver - collapsed
453
+ * below the breakpoint and on screen from it, identically with and without
454
+ * a foreign `.sr-only` on the page.
455
+ */
456
+ function expectCollapsedOnlyBelow(element: Element, breakpoint: string): void {
457
+ const classAttribute: string = element.getAttribute("class") || "";
458
+ const tokens: Array<string> = tokensOf(classAttribute);
459
+
460
+ expect(tokens).toContain(`max-${breakpoint}:sr-only`);
461
+ expect(tokens).toContain(`${breakpoint}:not-sr-only`);
462
+ expect(tokens).not.toContain("sr-only");
463
+
464
+ expect(describeCollapse(classAttribute)).toBe(collapsedBelow(breakpoint));
465
+ expect(
466
+ describeCollapse(classAttribute, { withForeignSrOnlyRule: true }),
467
+ ).toBe(collapsedBelow(breakpoint));
468
+ }
469
+
470
+ /* ------------------------------------------------------------------------ */
471
+ /* Source */
472
+ /* ------------------------------------------------------------------------ */
473
+
474
+ // packages/Common/Tests/UI/Components -> the repository root.
475
+ const REPOSITORY_ROOT: string = path.resolve(
476
+ __dirname,
477
+ "..",
478
+ "..",
479
+ "..",
480
+ "..",
481
+ "..",
482
+ );
483
+
484
+ // The static sites render EJS views, which the TypeScript walk never reads.
485
+ const EJS_VIEW_ROOTS: Array<string> = [
486
+ path.join(REPOSITORY_ROOT, "packages", "Home", "Views"),
487
+ path.join(REPOSITORY_ROOT, "packages", "App", "FeatureSet", "Docs", "Views"),
488
+ path.join(
489
+ REPOSITORY_ROOT,
490
+ "packages",
491
+ "App",
492
+ "FeatureSet",
493
+ "APIReference",
494
+ "views",
495
+ ),
496
+ ];
497
+
498
+ const COMMON_MASTER_PAGE_FILE: string =
499
+ "packages/Common/UI/Components/MasterPage/MasterPage.tsx";
500
+ const STATUS_PAGE_MASTER_PAGE_FILE: string =
501
+ "packages/App/FeatureSet/StatusPage/src/Components/MasterPage/MasterPage.tsx";
502
+ const HOME_NAV_VIEW_FILE: string = "packages/Home/Views/nav.ejs";
503
+ const API_REFERENCE_INDEX_VIEW_FILE: string =
504
+ "packages/App/FeatureSet/APIReference/views/pages/index.ejs";
505
+
506
+ const SKIP_LINK_FILES: Array<string> = [
507
+ COMMON_MASTER_PAGE_FILE,
508
+ STATUS_PAGE_MASTER_PAGE_FILE,
509
+ HOME_NAV_VIEW_FILE,
510
+ API_REFERENCE_INDEX_VIEW_FILE,
511
+ ];
512
+
513
+ // The modules whose labels the fix converted.
514
+ const CONVERTED_LABEL_FILES: Array<string> = [
515
+ "packages/Common/UI/Components/Feed/FeedOptionsButton.tsx",
516
+ "packages/App/FeatureSet/Dashboard/src/Components/SessionReplay/ReplayUi.tsx",
517
+ "packages/App/FeatureSet/Dashboard/src/Components/SessionReplay/ReplayScreenshotActions.tsx",
518
+ "packages/App/FeatureSet/Dashboard/src/Components/Workspace/SendTestNotificationButton.tsx",
519
+ ];
520
+
521
+ /*
522
+ * The static class attributes of an EJS view. Everything inside <% %> is
523
+ * blanked first (newlines kept, so line numbers hold): only the text the
524
+ * browser receives verbatim is read.
525
+ */
526
+ function collectViewCandidates(
527
+ relativePath: string,
528
+ viewText: string,
529
+ ): Array<ClassCandidate> {
530
+ const staticText: string = viewText.replace(
531
+ /<%[\s\S]*?%>/g,
532
+ (tag: string): string => {
533
+ return tag.replace(/[^\n]/g, " ");
534
+ },
535
+ );
536
+ const candidates: Array<ClassCandidate> = [];
537
+
538
+ for (const match of staticText.matchAll(
539
+ /\bclass\s*=\s*(?:"([^"]*)"|'([^']*)')/g,
540
+ )) {
541
+ candidates.push({
542
+ file: relativePath,
543
+ line: staticText.slice(0, match.index).split("\n").length,
544
+ classText: collapseWhitespace(match[1] ?? match[2] ?? ""),
545
+ });
546
+ }
547
+
548
+ return candidates;
549
+ }
550
+
551
+ function listViewFiles(directory: string): Array<string> {
552
+ const found: Array<string> = [];
553
+
554
+ if (!fs.existsSync(directory)) {
555
+ return found;
556
+ }
557
+
558
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
559
+ const fullPath: string = path.join(directory, entry.name);
560
+
561
+ if (entry.isDirectory()) {
562
+ found.push(...listViewFiles(fullPath));
563
+ } else if (entry.isFile() && entry.name.endsWith(".ejs")) {
564
+ found.push(fullPath);
565
+ }
566
+ }
567
+
568
+ return found;
569
+ }
570
+
571
+ interface SrOnlySweep {
572
+ // Every class string that mentions sr-only, TypeScript and EJS alike.
573
+ candidates: Array<ClassCandidate>;
574
+ filesRead: number;
575
+ }
576
+
577
+ function sweepSrOnlyClassStrings(): SrOnlySweep {
578
+ const candidates: Array<ClassCandidate> = [];
579
+ let filesRead: number = 0;
580
+
581
+ const read: (
582
+ filePath: string,
583
+ collect: (relativePath: string, text: string) => Array<ClassCandidate>,
584
+ ) => void = (
585
+ filePath: string,
586
+ collect: (relativePath: string, text: string) => Array<ClassCandidate>,
587
+ ): void => {
588
+ filesRead++;
589
+ const text: string = fs.readFileSync(filePath, "utf8");
590
+
591
+ if (!text.includes("sr-only")) {
592
+ return;
593
+ }
594
+
595
+ for (const candidate of collect(
596
+ toRelativePath(REPOSITORY_ROOT, filePath),
597
+ text,
598
+ )) {
599
+ if (candidate.classText.includes("sr-only")) {
600
+ candidates.push(candidate);
601
+ }
602
+ }
603
+ };
604
+
605
+ for (const root of listScanRoots(REPOSITORY_ROOT)) {
606
+ for (const filePath of listSourceFiles(root)) {
607
+ read(filePath, collectClassCandidates);
608
+ }
609
+ }
610
+
611
+ for (const root of EJS_VIEW_ROOTS) {
612
+ for (const filePath of listViewFiles(root)) {
613
+ read(filePath, collectViewCandidates);
614
+ }
615
+ }
616
+
617
+ return { candidates: candidates, filesRead: filesRead };
618
+ }
619
+
620
+ let sweep: SrOnlySweep = { candidates: [], filesRead: 0 };
621
+
622
+ /*
623
+ * Parsing ~3,300 files takes seconds. Doing it in beforeAll rather than at
624
+ * module scope keeps it under a timeout and reports a failure as a failed
625
+ * test instead of a suite that could not even be collected.
626
+ */
627
+ beforeAll(() => {
628
+ sweep = sweepSrOnlyClassStrings();
629
+ }, 180000);
630
+
631
+ function skipLinkClassIn(file: string): ClassCandidate {
632
+ const skipLinks: Array<ClassCandidate> = sweep.candidates.filter(
633
+ (candidate: ClassCandidate): boolean => {
634
+ return (
635
+ candidate.file === file &&
636
+ tokensOf(candidate.classText).includes("focus:not-sr-only")
637
+ );
638
+ },
639
+ );
640
+
641
+ expect({ file: file, skipLinks: skipLinks.length }).toEqual({
642
+ file: file,
643
+ skipLinks: 1,
644
+ });
645
+
646
+ return skipLinks[0]!;
647
+ }
648
+
649
+ /*
650
+ * The contract for a skip link: collapsed at every width until focused and
651
+ * on screen at every width once focused - with a foreign `.sr-only` on the
652
+ * page as much as without one.
653
+ */
654
+ function expectSkipLinkContract(classAttribute: string): void {
655
+ const tokens: Array<string> = tokensOf(classAttribute);
656
+
657
+ expect(tokens).toContain("sr-only");
658
+ expect(tokens).toContain("focus:not-sr-only");
659
+
660
+ for (const withForeignSrOnlyRule of [false, true]) {
661
+ expect(
662
+ describeCollapse(classAttribute, {
663
+ withForeignSrOnlyRule: withForeignSrOnlyRule,
664
+ }),
665
+ ).toBe(collapsedEverywhere());
666
+ expect(
667
+ describeCollapse(classAttribute, {
668
+ withForeignSrOnlyRule: withForeignSrOnlyRule,
669
+ isFocused: true,
670
+ }),
671
+ ).toBe(shownEverywhere());
672
+ }
673
+ }
674
+
675
+ /* ------------------------------------------------------------------------ */
676
+
677
+ beforeEach(() => {
678
+ apiPost = async (): Promise<PostResult> => {
679
+ return new HTTPResponse<JSONObject>(200, {}, {});
680
+ };
681
+ });
682
+
683
+ /*
684
+ * The resolver itself is unit-tested beside it, in ResponsiveVisibility.test.ts.
685
+ * These cover what this file builds on top of it for the sweep.
686
+ */
687
+ describe("sweep helpers", () => {
688
+ test("isForeignSrOnlyHazard flags exactly the shapes the foreign rule changes", () => {
689
+ expect(isForeignSrOnlyHazard("sr-only sm:not-sr-only")).toBe(true);
690
+ expect(isForeignSrOnlyHazard("sr-only xl:not-sr-only")).toBe(true);
691
+ expect(isForeignSrOnlyHazard("sr-only max-md:not-sr-only")).toBe(true);
692
+ expect(isForeignSrOnlyHazard("max-sm:sr-only sm:not-sr-only")).toBe(false);
693
+ expect(isForeignSrOnlyHazard("sr-only")).toBe(false);
694
+ expect(isForeignSrOnlyHazard("sr-only focus:not-sr-only")).toBe(false);
695
+ expect(isForeignSrOnlyHazard("sr-only group-hover:not-sr-only")).toBe(
696
+ false,
697
+ );
698
+ });
699
+
700
+ test("isForeignSrOnlyHazard resolves the media conditions and arbitrary screens a class names", () => {
701
+ // Only while printing, and only between screens no named breakpoint marks.
702
+ expect(isForeignSrOnlyHazard("sr-only print:not-sr-only")).toBe(true);
703
+ expect(isForeignSrOnlyHazard("sr-only md:print:not-sr-only")).toBe(true);
704
+ expect(isForeignSrOnlyHazard("sr-only min-[3000px]:not-sr-only")).toBe(
705
+ true,
706
+ );
707
+ expect(isForeignSrOnlyHazard("sr-only max-[100px]:not-sr-only")).toBe(true);
708
+ expect(mediaEnvironmentsFor("sr-only print:not-sr-only")).toEqual([
709
+ [],
710
+ ["print"],
711
+ ]);
712
+ expect(widthsFor("sr-only min-[900px]:not-sr-only")).toEqual(
713
+ expect.arrayContaining([899, 900]),
714
+ );
715
+ });
716
+
717
+ test("restorePreFixSrOnly rebuilds the pre-fix class", () => {
718
+ expect(restorePreFixSrOnly("max-sm:sr-only sm:not-sr-only")).toBe(
719
+ "sr-only sm:not-sr-only",
720
+ );
721
+ expect(restorePreFixSrOnly("max-xl:sr-only xl:not-sr-only")).toBe(
722
+ "sr-only xl:not-sr-only",
723
+ );
724
+ expect(restorePreFixSrOnly("sr-only focus:not-sr-only")).toBe(
725
+ "sr-only focus:not-sr-only",
726
+ );
727
+ });
728
+ });
729
+
730
+ describe("labels drawn from a breakpoint up survive a foreign .sr-only", () => {
731
+ test.each(COLLAPSIBLE_LABELS)(
732
+ "$name is collapsed only below $breakpoint",
733
+ async (labelCase: CollapsibleLabelCase) => {
734
+ const label: HTMLElement = await labelCase.renderLabel();
735
+
736
+ expectCollapsedOnlyBelow(label, labelCase.breakpoint);
737
+ },
738
+ );
739
+
740
+ /*
741
+ * The same rendered label, its class put back to what it was before the
742
+ * fix. The assertion above must fail on it: on a clean page the old class
743
+ * looked right, and only the foreign rule collapsed it on a wide screen.
744
+ */
745
+ test.each(COLLAPSIBLE_LABELS)(
746
+ "control: $name fails the same check with its pre-fix class",
747
+ async (labelCase: CollapsibleLabelCase) => {
748
+ const label: HTMLElement = await labelCase.renderLabel();
749
+ const preFixClass: string = restorePreFixSrOnly(
750
+ label.getAttribute("class"),
751
+ );
752
+
753
+ expect(preFixClass).toBe(labelCase.preFixClass);
754
+
755
+ label.setAttribute("class", preFixClass);
756
+
757
+ expect(() => {
758
+ expectCollapsedOnlyBelow(label, labelCase.breakpoint);
759
+ }).toThrow();
760
+ expect(isVisuallyCollapsed(preFixClass, WIDE_DESKTOP_WIDTH_IN_PX)).toBe(
761
+ false,
762
+ );
763
+ expect(
764
+ isVisuallyCollapsed(preFixClass, WIDE_DESKTOP_WIDTH_IN_PX, {
765
+ withForeignSrOnlyRule: true,
766
+ }),
767
+ ).toBe(true);
768
+ },
769
+ );
770
+ });
771
+
772
+ describe("skip links keep `sr-only focus:not-sr-only`", () => {
773
+ test("the Common MasterPage skip link, rendered and focused", () => {
774
+ render(
775
+ <MasterPage isLoading={false} error="">
776
+ <div>Children</div>
777
+ </MasterPage>,
778
+ );
779
+
780
+ const skipLink: HTMLElement = screen.getByRole("link", {
781
+ name: "Skip to main content",
782
+ });
783
+ const classAttribute: string = skipLink.getAttribute("class") || "";
784
+
785
+ expectSkipLinkContract(classAttribute);
786
+
787
+ // The focused half of the contract, on the real element.
788
+ expect(
789
+ isVisuallyCollapsed(classAttribute, WIDE_DESKTOP_WIDTH_IN_PX, {
790
+ withForeignSrOnlyRule: true,
791
+ isFocused: document.activeElement === skipLink,
792
+ }),
793
+ ).toBe(true);
794
+
795
+ act(() => {
796
+ skipLink.focus();
797
+ });
798
+
799
+ expect(document.activeElement).toBe(skipLink);
800
+ expect(
801
+ isVisuallyCollapsed(classAttribute, WIDE_DESKTOP_WIDTH_IN_PX, {
802
+ withForeignSrOnlyRule: true,
803
+ isFocused: document.activeElement === skipLink,
804
+ }),
805
+ ).toBe(false);
806
+ });
807
+
808
+ test.each(SKIP_LINK_FILES)("%s: the skip link in source", (file: string) => {
809
+ expectSkipLinkContract(skipLinkClassIn(file).classText);
810
+ });
811
+
812
+ test("control: a skip link converted to the max-width form would show on wide screens", () => {
813
+ /*
814
+ * Why the codemod left them alone: `max-sm:sr-only` is right for a label
815
+ * that belongs on screen from sm up, and wrong for a link that belongs
816
+ * on screen only while focused.
817
+ */
818
+ expect(() => {
819
+ expectSkipLinkContract("max-sm:sr-only sm:not-sr-only focus:not-sr-only");
820
+ }).toThrow();
821
+ });
822
+ });
823
+
824
+ describe("no class string anywhere lets a foreign .sr-only change the page", () => {
825
+ test("the sweep read every tree and found the converted labels and the skip links", () => {
826
+ // A broken walk must not let the main assertion pass over nothing.
827
+ expect(sweep.filesRead).toBeGreaterThan(1000);
828
+
829
+ const files: Set<string> = new Set<string>(
830
+ sweep.candidates
831
+ .filter((candidate: ClassCandidate): boolean => {
832
+ return candidate.classText.includes("not-sr-only");
833
+ })
834
+ .map((candidate: ClassCandidate): string => {
835
+ return candidate.file;
836
+ }),
837
+ );
838
+
839
+ for (const file of [...CONVERTED_LABEL_FILES, ...SKIP_LINK_FILES]) {
840
+ expect({ file: file, read: files.has(file) }).toEqual({
841
+ file: file,
842
+ read: true,
843
+ });
844
+ }
845
+ });
846
+
847
+ test("every converted module carries the max-width form and no bare sr-only undone by a screen", () => {
848
+ for (const file of CONVERTED_LABEL_FILES) {
849
+ const labels: Array<ClassCandidate> = sweep.candidates.filter(
850
+ (candidate: ClassCandidate): boolean => {
851
+ return (
852
+ candidate.file === file &&
853
+ tokensOf(candidate.classText).some((token: string): boolean => {
854
+ return MAX_WIDTH_SR_ONLY_CLASS.test(token);
855
+ })
856
+ );
857
+ },
858
+ );
859
+
860
+ expect({ file: file, hasMaxWidthLabel: labels.length > 0 }).toEqual({
861
+ file: file,
862
+ hasMaxWidthLabel: true,
863
+ });
864
+ }
865
+ });
866
+
867
+ test("the foreign rule changes nothing on screen, at any width, focused or not", () => {
868
+ const hazards: Array<string> = sweep.candidates
869
+ .filter((candidate: ClassCandidate): boolean => {
870
+ return isForeignSrOnlyHazard(candidate.classText);
871
+ })
872
+ .map(describeCandidate);
873
+
874
+ expect(hazards).toEqual([]);
875
+ });
876
+
877
+ test("control: the same sweep over the pre-fix class strings finds every converted label", () => {
878
+ const hazardFiles: Set<string> = new Set<string>(
879
+ sweep.candidates
880
+ .filter((candidate: ClassCandidate): boolean => {
881
+ return isForeignSrOnlyHazard(
882
+ restorePreFixSrOnly(candidate.classText),
883
+ );
884
+ })
885
+ .map((candidate: ClassCandidate): string => {
886
+ return candidate.file;
887
+ }),
888
+ );
889
+
890
+ expect(Array.from(hazardFiles).sort()).toEqual(
891
+ [...CONVERTED_LABEL_FILES].sort(),
892
+ );
893
+ });
894
+
895
+ test("the view reader sees static class text only", () => {
896
+ const candidates: Array<string> = collectViewCandidates(
897
+ "fixture.ejs",
898
+ [
899
+ '<a class="sr-only focus:not-sr-only">Skip</a>',
900
+ "<span class='max-sm:sr-only sm:not-sr-only'>Label</span>",
901
+ '<p class="<%= isOpen ? "sr-only sm:not-sr-only" : "" %> text-sm">x</p>',
902
+ ].join("\n"),
903
+ ).map((candidate: ClassCandidate): string => {
904
+ return candidate.classText;
905
+ });
906
+
907
+ expect(candidates).toEqual([
908
+ "sr-only focus:not-sr-only",
909
+ "max-sm:sr-only sm:not-sr-only",
910
+ "text-sm",
911
+ ]);
912
+ });
913
+
914
+ test("the source reader joins a template's static text and its branches", () => {
915
+ const candidates: Array<string> = collectClassCandidates(
916
+ "Fixture.tsx",
917
+ 'const e = <span className={`sr-only ${wide ? "sm:not-sr-only" : ""}`} />;',
918
+ ).map((candidate: ClassCandidate): string => {
919
+ return candidate.classText;
920
+ });
921
+
922
+ expect(candidates).toContain("sr-only sm:not-sr-only");
923
+ expect(isForeignSrOnlyHazard("sr-only sm:not-sr-only")).toBe(true);
924
+ });
925
+
926
+ test("the sweep and ForeignHiddenRuleGuard agree on which not-sr-only a foreign .sr-only beats", () => {
927
+ /*
928
+ * Two checks read the same hazard: the guard flags `sr-only
929
+ * <variants>:not-sr-only` when every variant is a media query, and this
930
+ * sweep calls a class a hazard when the resolver says the foreign rule
931
+ * changes what is on screen. Both take "is a media query" from
932
+ * isMediaQueryVariant in ResponsiveVisibility.ts, the source of truth, so
933
+ * they must name the same variants - named screens and arbitrary ones,
934
+ * the other media queries, stacks, and none of the state variants that
935
+ * out-specify the foreign class.
936
+ */
937
+ const mediaQueries: Array<string> = [
938
+ "sm",
939
+ "md",
940
+ "lg",
941
+ "xl",
942
+ "2xl",
943
+ "max-sm",
944
+ "max-md",
945
+ "max-lg",
946
+ "max-xl",
947
+ "max-2xl",
948
+ "min-[900px]",
949
+ "max-[900px]",
950
+ "print",
951
+ "motion-safe",
952
+ "motion-reduce",
953
+ "contrast-more",
954
+ "contrast-less",
955
+ "portrait",
956
+ "landscape",
957
+ "forced-colors",
958
+ "md:print",
959
+ "sm:max-lg",
960
+ ];
961
+ const states: Array<string> = [
962
+ "focus",
963
+ "focus-visible",
964
+ "focus-within",
965
+ "hover",
966
+ "group-hover",
967
+ "group-focus",
968
+ "peer-checked",
969
+ "aria-expanded",
970
+ "data-[state=open]",
971
+ "dark",
972
+ "[&.is-open]",
973
+ "group-[.is-open]",
974
+ "lg:group-hover",
975
+ "sm:focus",
976
+ "md:hover",
977
+ ];
978
+
979
+ const verdicts: Array<string> = [...mediaQueries, ...states].map(
980
+ (variants: string): string => {
981
+ return `${variants}: guard ${isSrOnlyUnhidingToken(`${variants}:not-sr-only`)}, sweep ${isForeignSrOnlyHazard(`sr-only ${variants}:not-sr-only`)}`;
982
+ },
983
+ );
984
+
985
+ expect(verdicts).toEqual([
986
+ ...mediaQueries.map((variants: string): string => {
987
+ return `${variants}: guard true, sweep true`;
988
+ }),
989
+ ...states.map((variants: string): string => {
990
+ return `${variants}: guard false, sweep false`;
991
+ }),
992
+ ]);
993
+ });
994
+ });