@oneuptime/common 12.0.34 → 13.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Alert.ts +55 -0
- package/Models/DatabaseModels/CloudResource.ts +45 -7
- package/Models/DatabaseModels/CodeRepository.ts +85 -0
- package/Models/DatabaseModels/GlobalConfig.ts +12 -12
- package/Models/DatabaseModels/GoogleSecOpsConnection.ts +57 -7
- package/Models/DatabaseModels/GoogleSecOpsConnectionRun.ts +263 -0
- package/Models/DatabaseModels/Incident.ts +55 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/InventoryItem.ts +44 -1
- package/Models/DatabaseModels/NetworkDevice.ts +126 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
- package/Models/DatabaseModels/User.ts +51 -2
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +43 -2
- package/Models/DatabaseModels/UserWebAuthn.ts +17 -0
- package/Models/DatabaseModels/VMwareResource.ts +1149 -0
- package/Models/DatabaseModels/VMwareVCenter.ts +1122 -0
- package/Models/DatabaseModels/VMwareVCenterFeed.ts +625 -0
- package/Models/DatabaseModels/VMwareVCenterLabelRule.ts +514 -0
- package/Models/DatabaseModels/VMwareVCenterOwnerRule.ts +596 -0
- package/Models/DatabaseModels/VMwareVCenterOwnerTeam.ts +485 -0
- package/Models/DatabaseModels/VMwareVCenterOwnerUser.ts +484 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +22 -1
- package/Server/API/AIAgentDataAPI.ts +79 -4
- package/Server/API/AIAgentGitHubAPI.ts +523 -0
- package/Server/API/AIChatAPI.ts +20 -1
- package/Server/API/BillingAPI.ts +33 -0
- package/Server/API/DashboardAPI.ts +10 -0
- package/Server/API/GitHubAPI.ts +47 -5
- package/Server/API/GoogleSecOpsConnectionAPI.ts +79 -0
- package/Server/API/UserWebAuthnAPI.ts +21 -1
- package/Server/API/VMwareResourceAPI.ts +143 -0
- package/Server/EnvironmentConfig.ts +47 -16
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.ts +68 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.ts +636 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.ts +83 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
- package/Server/Infrastructure/Redis.ts +8 -8
- package/Server/Infrastructure/Status.ts +10 -4
- package/Server/Middleware/IdentityRateLimit.ts +101 -0
- package/Server/Services/AIRunService.ts +13 -0
- package/Server/Services/BillingPaymentMethodService.ts +99 -28
- package/Server/Services/BillingService.ts +287 -20
- package/Server/Services/CloudResourceInstanceService.ts +70 -0
- package/Server/Services/DatabaseService.ts +65 -13
- package/Server/Services/ExceptionAggregationService.ts +1 -0
- package/Server/Services/GoogleSecOpsConnectionRunService.ts +10 -0
- package/Server/Services/GoogleSecOpsConnectionService.ts +12 -0
- package/Server/Services/Index.ts +16 -0
- package/Server/Services/InventoryItemService.ts +31 -1
- package/Server/Services/LogAggregationService.ts +1 -0
- package/Server/Services/MetricAggregationService.ts +1 -0
- package/Server/Services/MobilePasskeyLoginService.ts +216 -0
- package/Server/Services/MonitorService.ts +51 -1
- package/Server/Services/MonitorTemplateService.ts +218 -35
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +481 -42
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +176 -2
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +87 -2
- package/Server/Services/NetworkDeviceService.ts +69 -0
- package/Server/Services/OpenTelemetryIngestService.ts +17 -0
- package/Server/Services/PayAsYouGoBillingService.ts +446 -0
- package/Server/Services/ProjectService.ts +46 -2
- package/Server/Services/ServerlessFunctionInstanceService.ts +71 -0
- package/Server/Services/TeamMemberService.ts +96 -36
- package/Server/Services/TelemetryIngestionKeyService.ts +80 -10
- package/Server/Services/TelemetryUsageBillingService.ts +95 -5
- package/Server/Services/TraceAggregationService.ts +5 -4
- package/Server/Services/UserNotificationRuleService.ts +76 -25
- package/Server/Services/UserWebAuthnService.ts +592 -133
- package/Server/Services/VMwareResourceService.ts +648 -0
- package/Server/Services/VMwareVCenterFeedService.ts +99 -0
- package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +240 -0
- package/Server/Services/VMwareVCenterLabelRuleService.ts +14 -0
- package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +252 -0
- package/Server/Services/VMwareVCenterOwnerRuleService.ts +14 -0
- package/Server/Services/VMwareVCenterOwnerTeamService.ts +139 -0
- package/Server/Services/VMwareVCenterOwnerUserService.ts +133 -0
- package/Server/Services/VMwareVCenterService.ts +629 -0
- package/Server/Services/WorkflowVariableService.ts +203 -0
- package/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.ts +17 -0
- package/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.ts +31 -1
- package/Server/Types/Database/Permissions/ReadPermission.ts +45 -5
- package/Server/Types/Database/QueryUtil.ts +56 -0
- package/Server/Types/Markdown.ts +93 -1
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +7 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.ts +341 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.ts +274 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.ts +375 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubConversation.ts +846 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.ts +360 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubRunReply.ts +421 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.ts +140 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.ts +906 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +225 -17
- package/Server/Utils/DataSource/EgressGuard.ts +160 -15
- package/Server/Utils/Database/TruncateColumnValue.ts +1 -1
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +12 -1
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +35 -2
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +44 -0
- package/Server/Utils/LogRedaction.ts +2 -1
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +82 -35
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +31 -5
- package/Server/Utils/Monitor/MonitorAlert.ts +1 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +502 -38
- package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +82 -9
- package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +16 -7
- package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +29 -17
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +107 -48
- package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +26 -4
- package/Server/Utils/Monitor/MonitorResourceContext.ts +5 -3
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +14 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
- package/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.ts +158 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +27 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +26 -0
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +28 -5
- package/Server/Utils/ResourceFeed/ResourceFeedUtil.ts +3 -3
- package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +14 -9
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +116 -84
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +594 -195
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +466 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +16 -1
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +2 -1
- package/Server/Utils/Telemetry/TelemetryEntity.ts +264 -10
- package/Server/Utils/Telemetry/VMwareSnapshotScan.ts +1352 -0
- package/Tests/App/Accounts/LoginPasskey.test.tsx +529 -0
- package/Tests/App/Accounts/MobilePasskey.test.tsx +620 -0
- package/Tests/App/Accounts/PasswordRequirements.test.tsx +254 -0
- package/Tests/App/Accounts/RegisterPassword.test.tsx +553 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +32 -0
- package/Tests/App/Dashboard/AdoptedDeviceDrawer.test.tsx +374 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +224 -0
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +432 -0
- package/Tests/App/Dashboard/BackupCodes.test.tsx +414 -0
- package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +530 -0
- package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +195 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +199 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +198 -0
- package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +215 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +183 -0
- package/Tests/App/Dashboard/CloudFleetSummaryComponent.test.tsx +248 -0
- package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +215 -0
- package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +3 -0
- package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +441 -0
- package/Tests/App/Dashboard/DashboardLabelVariables.test.tsx +580 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +458 -0
- package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +438 -0
- package/Tests/App/Dashboard/DashboardToolbarPopupLayering.test.tsx +566 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +5 -2
- package/Tests/App/Dashboard/DeviceAttachmentCard.test.tsx +273 -0
- package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +505 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +376 -0
- package/Tests/App/Dashboard/DiscoveryScanLiveUpdates.test.tsx +642 -0
- package/Tests/App/Dashboard/DiscoveryScanProgress.test.tsx +267 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +69 -231
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +163 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +244 -0
- package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +724 -0
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +401 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +232 -0
- package/Tests/App/Dashboard/InventoryItems.test.tsx +201 -0
- package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +798 -0
- package/Tests/App/Dashboard/MonitorTemplateSyncFields.test.tsx +539 -0
- package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +320 -0
- package/Tests/App/Dashboard/NetworkTopologyToolbar.test.tsx +275 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedEmptyState.test.tsx +975 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +63 -0
- package/Tests/App/Dashboard/OnCallLayerCardOverrides.test.tsx +24 -7
- package/Tests/App/Dashboard/OnCallOverridePresentation.test.ts +496 -0
- package/Tests/App/Dashboard/OnCallScheduleOverrideClarity.test.tsx +677 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +31 -3
- package/Tests/App/Dashboard/PaidUsageConsent.test.tsx +180 -0
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +1220 -0
- package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +176 -275
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +380 -233
- package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +3 -23
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +1 -0
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +626 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +348 -0
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +331 -0
- package/Tests/App/Dashboard/TwoFactorStatus.test.tsx +260 -0
- package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +603 -0
- package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +324 -0
- package/Tests/App/Dashboard/VMwareDashboardWidgets.test.ts +573 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
- package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +768 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +13 -4
- package/Tests/App/StatusPage/StatusPageOidcOrigin.test.tsx +223 -0
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +532 -40
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +19 -2
- package/Tests/Fixtures/MobilePasskeyUser.json +8 -0
- package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +25 -6
- package/Tests/Models/DatabaseModels/VMwareModels.test.ts +1134 -0
- package/Tests/Models/InventoryItemStatus.test.ts +147 -0
- package/Tests/Models/NetworkDeviceMacAddressColumn.test.ts +294 -0
- package/Tests/Models/RunnerVersionLabel.test.ts +4 -2
- package/Tests/Server/API/AIChatProvidersAIEnabled.test.ts +259 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +31 -2
- package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +116 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +158 -1
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +13 -2
- package/Tests/Server/API/GitHubWebhookSignature.test.ts +368 -0
- package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +248 -0
- package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +330 -0
- package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +172 -0
- package/Tests/Server/API/VMwareResourceAPI.test.ts +546 -0
- package/Tests/Server/EnvironmentConfigValkey.test.ts +227 -0
- package/Tests/Server/Infrastructure/Postgres/AddMacAddressToNetworkDeviceMigration.test.ts +365 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +62 -23
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupMetadataMigration.test.ts +85 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +34 -3
- package/Tests/Server/Infrastructure/ValkeyDeploymentConfig.test.ts +265 -0
- package/Tests/Server/Middleware/HttpMetricsMiddleware.test.ts +382 -0
- package/Tests/Server/Middleware/PasskeyRateLimit.test.ts +141 -0
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +525 -0
- package/Tests/Server/Services/AutoImportRuleRearmRecentScans.test.ts +343 -0
- package/Tests/Server/Services/AutoImportRuleWriteRearmsScans.test.ts +381 -0
- package/Tests/Server/Services/BillingPaymentMethodServiceSync.test.ts +175 -0
- package/Tests/Server/Services/BillingService.test.ts +26 -11
- package/Tests/Server/Services/BillingServiceMeteredPaymentAuthorization.test.ts +245 -0
- package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +362 -0
- package/Tests/Server/Services/CloudResourceInstanceStalePrune.test.ts +188 -0
- package/Tests/Server/Services/DatabaseServiceAggregateBy.test.ts +291 -56
- package/Tests/Server/Services/DatabaseServiceSortTiebreaker.test.ts +151 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +16 -2
- package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +153 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +13 -0
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +105 -0
- package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +183 -0
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +36 -0
- package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +151 -0
- package/Tests/Server/Services/MobilePasskeyLoginIntegration.test.ts +231 -0
- package/Tests/Server/Services/MobilePasskeyLoginService.test.ts +315 -0
- package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +302 -0
- package/Tests/Server/Services/MonitorTemplateServiceCustomFieldSync.test.ts +502 -0
- package/Tests/Server/Services/MonitorTemplateServiceFieldSync.test.ts +994 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1133 -81
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +22 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanRegistration.test.ts +520 -0
- package/Tests/Server/Services/NetworkDeviceMacAddressNormalization.test.ts +572 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
- package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +857 -0
- package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +379 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +99 -1
- package/Tests/Server/Services/ProjectServiceSubscriptionSeats.test.ts +134 -0
- package/Tests/Server/Services/ResourceFeedServices.test.ts +3 -2
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +32 -6
- package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +363 -175
- package/Tests/Server/Services/ServerlessFunctionInstanceStalePrune.test.ts +200 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +3 -0
- package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +762 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +3 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +72 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +17 -4
- package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +355 -0
- package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +41 -4
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +37 -0
- package/Tests/Server/Services/UserWebAuthnPasskeyIntegration.test.ts +401 -0
- package/Tests/Server/Services/UserWebAuthnPasskeyService.test.ts +769 -0
- package/Tests/Server/Services/UserWebAuthnUserVerification.test.ts +649 -0
- package/Tests/Server/Services/VMwareResourceService.test.ts +945 -0
- package/Tests/Server/Services/VMwareVCenterService.test.ts +722 -0
- package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +842 -0
- package/Tests/Server/TestingUtils/PasskeyHttpIntegration.ts +102 -0
- package/Tests/Server/TestingUtils/SecurityKey.ts +464 -0
- package/Tests/Server/TestingUtils/WebAuthnServiceMocks.ts +60 -0
- package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +573 -0
- package/Tests/Server/Types/Database/InventoryStatusPostgres.test.ts +368 -0
- package/Tests/Server/Types/Database/Permissions/ProjectCustomerSupportAccessColumn.test.ts +261 -0
- package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +261 -14
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +95 -0
- package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroups.test.ts +169 -0
- package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroupsPostgres.test.ts +297 -0
- package/Tests/Server/Types/Markdown.test.ts +194 -1
- package/Tests/Server/Types/Workflow/Components/IncomingWebhookUtils.test.ts +279 -0
- package/Tests/Server/Types/Workflow/Components/TextToJson.test.ts +212 -0
- package/Tests/Server/Utils/CodeRepository/GitHubAgentTaskTrigger.test.ts +2101 -0
- package/Tests/Server/Utils/CodeRepository/GitHubCommandAuthorizer.test.ts +883 -0
- package/Tests/Server/Utils/CodeRepository/GitHubCommandParser.test.ts +1474 -0
- package/Tests/Server/Utils/CodeRepository/GitHubConversation.test.ts +1526 -0
- package/Tests/Server/Utils/CodeRepository/GitHubReplyComposer.test.ts +1389 -0
- package/Tests/Server/Utils/CodeRepository/GitHubRunReply.test.ts +1707 -0
- package/Tests/Server/Utils/CodeRepository/GitHubWebhookHandler.test.ts +2202 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingRegistry.test.ts +436 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +559 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +896 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
- package/Tests/Server/Utils/EmailRollup/EmailRollupMetadataIntegration.test.ts +246 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +309 -4
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +6 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +185 -0
- package/Tests/Server/Utils/EventLoop.test.ts +359 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +30 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +33 -0
- package/Tests/Server/Utils/Monitor/CapturedMetricAttributeUtil.test.ts +2 -1
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +242 -0
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +13 -7
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +29 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +30 -6
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +246 -0
- package/Tests/Server/Utils/Monitor/Criteria/TelemetryStepMetricAlias.test.ts +10 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +66 -1
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEmailEvalLogAgreement.test.ts +280 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +586 -10
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +570 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +30 -5
- package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +68 -21
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +36 -19
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +60 -1
- package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +60 -0
- package/Tests/Server/Utils/Monitor/MonitorRootCauseTargetResolution.test.ts +423 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +6 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.test.ts +573 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +317 -0
- package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +46 -2
- package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +81 -45
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +711 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClickhouseIntegration.test.ts +223 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +69 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +838 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsErrorHandling.test.ts +241 -28
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsHttpIntegration.test.ts +651 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +11 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +13 -12
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +112 -127
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsRequestContract.test.ts +12 -18
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsResponseParsing.test.ts +43 -0
- package/Tests/Server/Utils/Telemetry/ContextSpanProcessor.test.ts +281 -0
- package/Tests/Server/Utils/Telemetry/InventoryDuplicateIdentity.test.ts +316 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +691 -8
- package/Tests/Server/Utils/Telemetry/VMwareSnapshotScan.test.ts +1748 -0
- package/Tests/Types/Cloud/CloudPlatform.test.ts +574 -0
- package/Tests/Types/Database/IncludesAnyOfGroups.test.ts +106 -0
- package/Tests/Types/JSONFunctions.test.ts +40 -0
- package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +2 -0
- package/Tests/Types/Monitor/MonitorCriteriaMetricVariables.test.ts +9 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorStepInfraMonitorUtils.test.ts +53 -8
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +97 -0
- package/Tests/Types/Monitor/MonitorStepMetricViewConfigUtil.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorStepTemplateSyncFields.test.ts +107 -0
- package/Tests/Types/Monitor/MonitorTemplateSyncField.test.ts +172 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +2 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +1 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +9 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +131 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +10 -0
- package/Tests/Types/Monitor/VMwareAlertTemplates.test.ts +1608 -0
- package/Tests/Types/Monitor/VMwareMetricCatalog.test.ts +488 -0
- package/Tests/Types/NetworkAutomation/AutoImportRunMerge.test.ts +235 -0
- package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +66 -0
- package/Tests/Types/NetworkAutomation/RuleRunResultDescribe.test.ts +309 -1
- package/Tests/Types/OnCallDutyPolicy/OverrideProvenance.test.ts +295 -0
- package/Tests/Types/Runner/RunnerLiveStatus.test.ts +2 -2
- package/Tests/Types/SignupPassword.test.ts +205 -0
- package/Tests/Types/StatusPage/StatusPageLanguage.test.ts +44 -0
- package/Tests/Types/SupportedLanguages.test.ts +119 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +19 -0
- package/Tests/Types/Telemetry/InventoryLiveness.test.ts +99 -0
- package/Tests/UI/ColorPickerBuild.test.ts +86 -0
- package/Tests/UI/Components/Breadcrumbs.test.tsx +32 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +160 -0
- package/Tests/UI/Components/Forms/ModelFormPreservesUserInput.test.tsx +937 -0
- package/Tests/UI/Components/Forms/ModelFormWriteOnlyColumnSelect.test.tsx +230 -0
- package/Tests/UI/Components/Forms/ValidationFormSteps.test.ts +3 -4
- package/Tests/UI/Components/LabelRuleImportExport.test.tsx +907 -0
- package/Tests/UI/Components/ModelTable/ModelTableCreateAfterEdit.test.tsx +514 -0
- package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +301 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +2 -1
- package/Tests/UI/Components/TooltipLazyContent.test.tsx +373 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsMessagingEndpointGuidance.test.tsx +43 -12
- package/Tests/UI/ReactDomBuild.test.ts +104 -0
- package/Tests/UI/ReactRouterSingletonBuild.test.ts +143 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +10 -2
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +514 -0
- package/Tests/UI/Rum/ReplayTimeFormat.test.ts +94 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +559 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +153 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +30 -0
- package/Tests/UI/Utils/DashboardStackingLayers.test.ts +197 -0
- package/Tests/UI/Utils/LabelRuleImportExport.test.ts +546 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +109 -2
- package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +7 -2
- package/Tests/UI/Utils/UserEmailRegistrationStatus.test.tsx +295 -0
- package/Tests/UI/Utils/WebAuthn.test.ts +265 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +5 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +11 -1
- package/Tests/Utils/Dashboard/Components/DashboardVMwareListComponents.test.ts +548 -0
- package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +17 -3
- package/Tests/Utils/Dashboard/LabelVariable.test.ts +257 -0
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +144 -14
- package/Tests/Utils/LabelRuleImportExport.test.ts +583 -0
- package/Tests/Utils/MetricUnitUtil.test.ts +81 -0
- package/Tests/Utils/Monitor/DeviceMacLearningUtil.test.ts +497 -0
- package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +546 -0
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/MonitorTemplateCustomFieldUtil.test.ts +218 -0
- package/Tests/Utils/Monitor/MonitorTemplateSyncUtil.test.ts +590 -0
- package/Tests/Utils/Monitor/NetworkTopologyEndpointAdoption.test.ts +1755 -0
- package/Tests/Utils/NetworkAutomation/AutoImportRunChain.test.ts +320 -0
- package/Tests/Utils/RequestFailedDetails.test.ts +325 -0
- package/Tests/Utils/Telemetry/CloudInstanceIdentity.test.ts +255 -0
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +167 -0
- package/Tests/Utils/WebAuthnTestUtil.ts +79 -0
- package/Tests/__mocks__/simplewebauthn.js +33 -4
- package/Types/AI/CodeFixTaskContext.ts +122 -0
- package/Types/AI/CodeFixTaskType.ts +62 -0
- package/Types/Accounts/AccountsLanguage.ts +1 -0
- package/Types/AdminDashboard/AdminDashboardLanguage.ts +1 -0
- package/Types/BaseDatabase/IncludesAnyOfGroups.ts +77 -0
- package/Types/Calendar/CalendarEvent.ts +16 -0
- package/Types/Cloud/CloudPlatform.ts +372 -0
- package/Types/CodeRepository/GitHubCommand.ts +69 -0
- package/Types/Dashboard/DashboardComponentType.ts +2 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +2 -0
- package/Types/Dashboard/DashboardComponents/DashboardMonitorListComponent.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.ts +23 -0
- package/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.ts +30 -0
- package/Types/Dashboard/DashboardLanguage.ts +1 -0
- package/Types/Dashboard/DashboardTemplates.ts +314 -0
- package/Types/Dashboard/DashboardVariable.ts +8 -0
- package/Types/Docs/DocsLanguage.ts +1 -0
- package/Types/Exception/EgressGuardException.ts +65 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSON.ts +4 -0
- package/Types/JSONFunctions.ts +16 -0
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +36 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +1 -0
- package/Types/Monitor/MonitorStep.ts +78 -17
- package/Types/Monitor/MonitorStepMetricViewConfigUtil.ts +1 -0
- package/Types/Monitor/MonitorStepVMwareMonitor.ts +127 -0
- package/Types/Monitor/MonitorTemplateSyncField.ts +291 -0
- package/Types/Monitor/MonitorType.ts +24 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +33 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +2 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +3 -0
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +158 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +61 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
- package/Types/Monitor/VMwareAlertTemplates.ts +1070 -0
- package/Types/Monitor/VMwareMetricCatalog.ts +914 -0
- package/Types/NetworkAutomation/RuleRunResult.ts +402 -13
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +29 -0
- package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +16 -0
- package/Types/Password.ts +84 -5
- package/Types/Permission.ts +265 -0
- package/Types/Probe/RequestFailedDetails.ts +7 -0
- package/Types/Runner/RunnerLiveStatus.ts +1 -1
- package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +56 -0
- package/Types/SerializableObjectDictionary.ts +4 -0
- package/Types/StatusPage/StatusPageLanguage.ts +1 -0
- package/Types/Telemetry/EntityType.ts +21 -0
- package/Types/Telemetry/InventoryLiveness.ts +56 -0
- package/Types/Telemetry/ServiceType.ts +1 -0
- package/Typings/Index.d.ts +63 -0
- package/UI/Components/Breadcrumbs/Breadcrumbs.tsx +2 -2
- package/UI/Components/CSVFileUpload/CSVFileUpload.tsx +9 -2
- package/UI/Components/Calendar/Calendar.css +78 -0
- package/UI/Components/Calendar/Calendar.tsx +28 -3
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +46 -21
- package/UI/Components/Dashboard/DashboardVariableControl.tsx +285 -0
- package/UI/Components/Forms/BasicForm.tsx +44 -2
- package/UI/Components/Forms/Fields/ColorPicker.tsx +2 -1
- package/UI/Components/Forms/Fields/FormField.tsx +16 -3
- package/UI/Components/Forms/ModelForm.tsx +159 -5
- package/UI/Components/Forms/Types/Field.ts +8 -1
- package/UI/Components/Graphs/DayUptimeGraph.tsx +8 -10
- package/UI/Components/Icon/Icon.tsx +16 -0
- package/UI/Components/Input/Input.tsx +42 -7
- package/UI/Components/LabelRule/ImportLabelRulesModal.tsx +441 -0
- package/UI/Components/LabelRule/LabelRuleTable.tsx +142 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +22 -5
- package/UI/Components/ModelTable/ModelTable.tsx +14 -6
- package/UI/Components/MonitorGraphs/Uptime.tsx +17 -27
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +3 -1
- package/UI/Components/Tooltip/Tooltip.tsx +52 -6
- package/UI/Utils/DashboardStackingLayers.ts +85 -0
- package/UI/Utils/LabelRuleImportExport.ts +310 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +4 -3
- package/UI/Utils/TelemetryService.ts +4 -3
- package/UI/Utils/UseDashboardGridDnd.ts +4 -1
- package/UI/Utils/UserEmailRegistrationStatus.ts +33 -5
- package/UI/Utils/WebAuthn.ts +220 -0
- package/UI/esbuild-config.js +10 -0
- package/Utils/API.ts +34 -0
- package/Utils/Dashboard/Components/DashboardMonitorListComponent.ts +12 -1
- package/Utils/Dashboard/Components/DashboardVMwareHostListComponent.ts +38 -0
- package/Utils/Dashboard/Components/DashboardVMwareResourceListShared.ts +70 -0
- package/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.ts +76 -0
- package/Utils/Dashboard/Components/Index.ts +16 -0
- package/Utils/Dashboard/LabelVariable.ts +152 -0
- package/Utils/Dashboard/VariableUrlState.ts +27 -5
- package/Utils/LabelRuleImportExport.ts +496 -0
- package/Utils/MetricUnitUtil.ts +34 -0
- package/Utils/Monitor/DeviceMacLearningUtil.ts +177 -0
- package/Utils/Monitor/MetricValueFormatter.ts +342 -0
- package/Utils/Monitor/MonitorTemplateCustomFieldUtil.ts +124 -0
- package/Utils/Monitor/MonitorTemplateSyncUtil.ts +164 -0
- package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +7 -2
- package/Utils/Monitor/NetworkTopologyUtil.ts +693 -0
- package/Utils/NetworkAutomation/AutoImportRunChain.ts +138 -0
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +8 -0
- package/Utils/Telemetry/CloudInstanceIdentity.ts +94 -0
- package/Utils/Telemetry/EntityKey.ts +19 -0
- package/Utils/Telemetry/EntityRelationship.ts +19 -0
- package/build/dist/Models/DatabaseModels/Alert.js +54 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResource.js +44 -7
- package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +87 -0
- package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +12 -12
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +60 -7
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js +287 -0
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Incident.js +54 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.js +34 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +128 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +57 -4
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +47 -2
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js +18 -0
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareResource.js +1201 -0
- package/build/dist/Models/DatabaseModels/VMwareResource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +1149 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterFeed.js +648 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js +503 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js +502 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +22 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +63 -3
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentGitHubAPI.js +363 -0
- package/build/dist/Server/API/AIAgentGitHubAPI.js.map +1 -0
- package/build/dist/Server/API/AIChatAPI.js +19 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/BillingAPI.js +22 -0
- package/build/dist/Server/API/BillingAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +10 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GitHubAPI.js +33 -5
- package/build/dist/Server/API/GitHubAPI.js.map +1 -1
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +56 -0
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +1 -0
- package/build/dist/Server/API/UserWebAuthnAPI.js +17 -1
- package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
- package/build/dist/Server/API/VMwareResourceAPI.js +106 -0
- package/build/dist/Server/API/VMwareResourceAPI.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +44 -12
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.js +241 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Redis.js +8 -8
- package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
- package/build/dist/Server/Infrastructure/Status.js +10 -4
- package/build/dist/Server/Infrastructure/Status.js.map +1 -1
- package/build/dist/Server/Middleware/IdentityRateLimit.js +80 -0
- package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +14 -1
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/BillingPaymentMethodService.js +71 -21
- package/build/dist/Server/Services/BillingPaymentMethodService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +210 -22
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceInstanceService.js +66 -0
- package/build/dist/Server/Services/CloudResourceInstanceService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +58 -13
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +1 -0
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js +9 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +1 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +7 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +16 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +28 -1
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +1 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +1 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MobilePasskeyLoginService.js +137 -0
- package/build/dist/Server/Services/MobilePasskeyLoginService.js.map +1 -0
- package/build/dist/Server/Services/MonitorService.js +34 -1
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +167 -30
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +394 -38
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +142 -2
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +65 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +54 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +28 -13
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PayAsYouGoBillingService.js +297 -0
- package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -0
- package/build/dist/Server/Services/ProjectService.js +38 -2
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionInstanceService.js +66 -0
- package/build/dist/Server/Services/ServerlessFunctionInstanceService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +85 -28
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +61 -10
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +62 -5
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +5 -4
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +60 -25
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserWebAuthnService.js +345 -113
- package/build/dist/Server/Services/UserWebAuthnService.js.map +1 -1
- package/build/dist/Server/Services/VMwareResourceService.js +395 -0
- package/build/dist/Server/Services/VMwareResourceService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterFeedService.js +89 -0
- package/build/dist/Server/Services/VMwareVCenterFeedService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +197 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleService.js +13 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +214 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerTeamService.js +129 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerUserService.js +122 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterService.js +533 -0
- package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -0
- package/build/dist/Server/Services/WorkflowVariableService.js +169 -0
- package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.js +12 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.js.map +1 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.js +25 -2
- package/build/dist/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +29 -4
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryUtil.js +36 -0
- package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +75 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.js +275 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.js +226 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.js +297 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubConversation.js +582 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubConversation.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.js +275 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubRunReply.js +365 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubRunReply.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.js +103 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.js +661 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +166 -18
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +99 -15
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +12 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +20 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +31 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +2 -1
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +58 -35
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +29 -5
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +382 -36
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +58 -9
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +9 -3
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +26 -12
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +74 -33
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +12 -4
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +5 -3
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +22 -9
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js +114 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +25 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +21 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +21 -6
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/ResourceFeed/ResourceFeedUtil.js +3 -3
- package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +9 -9
- package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +92 -71
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +428 -143
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +376 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +14 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +206 -14
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/VMwareSnapshotScan.js +933 -0
- package/build/dist/Server/Utils/Telemetry/VMwareSnapshotScan.js.map +1 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js +40 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
- package/build/dist/Types/AI/CodeFixTaskType.js +57 -0
- package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -1
- package/build/dist/Types/Accounts/AccountsLanguage.js +1 -0
- package/build/dist/Types/Accounts/AccountsLanguage.js.map +1 -1
- package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js +1 -0
- package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js.map +1 -1
- package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js +54 -0
- package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js.map +1 -0
- package/build/dist/Types/Cloud/CloudPlatform.js +277 -0
- package/build/dist/Types/Cloud/CloudPlatform.js.map +1 -0
- package/build/dist/Types/CodeRepository/GitHubCommand.js +52 -0
- package/build/dist/Types/CodeRepository/GitHubCommand.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardLanguage.js +1 -0
- package/build/dist/Types/Dashboard/DashboardLanguage.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js +286 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardVariable.js +1 -0
- package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -1
- package/build/dist/Types/Docs/DocsLanguage.js +1 -0
- package/build/dist/Types/Docs/DocsLanguage.js.map +1 -1
- package/build/dist/Types/Exception/EgressGuardException.js +59 -0
- package/build/dist/Types/Exception/EgressGuardException.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSON.js +1 -0
- package/build/dist/Types/JSON.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +13 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +61 -18
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricViewConfigUtil.js +1 -0
- package/build/dist/Types/Monitor/MonitorStepMetricViewConfigUtil.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepVMwareMonitor.js +71 -0
- package/build/dist/Types/Monitor/MonitorStepVMwareMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorTemplateSyncField.js +211 -0
- package/build/dist/Types/Monitor/MonitorTemplateSyncField.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +23 -0
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +28 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +2 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +120 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +60 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
- package/build/dist/Types/Monitor/VMwareAlertTemplates.js +775 -0
- package/build/dist/Types/Monitor/VMwareAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/VMwareMetricCatalog.js +799 -0
- package/build/dist/Types/Monitor/VMwareMetricCatalog.js.map +1 -0
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js +291 -6
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +25 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +5 -0
- package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
- package/build/dist/Types/Password.js +63 -5
- package/build/dist/Types/Password.js.map +1 -1
- package/build/dist/Types/Permission.js +234 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Probe/RequestFailedDetails.js +7 -0
- package/build/dist/Types/Probe/RequestFailedDetails.js.map +1 -1
- package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +2 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +1 -0
- package/build/dist/Types/SerializableObjectDictionary.js +4 -0
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/StatusPage/StatusPageLanguage.js +1 -0
- package/build/dist/Types/StatusPage/StatusPageLanguage.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +21 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/InventoryLiveness.js +37 -0
- package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js +2 -2
- package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js +7 -0
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js.map +1 -1
- package/build/dist/UI/Components/Calendar/Calendar.js +24 -4
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +9 -2
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +137 -0
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -0
- package/build/dist/UI/Components/Forms/BasicForm.js +28 -3
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +89 -6
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +5 -6
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +14 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +37 -8
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js +228 -0
- package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js.map +1 -0
- package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +102 -0
- package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +15 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js +13 -5
- package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +14 -15
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +2 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +33 -4
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Utils/DashboardStackingLayers.js +44 -0
- package/build/dist/UI/Utils/DashboardStackingLayers.js.map +1 -0
- package/build/dist/UI/Utils/LabelRuleImportExport.js +195 -0
- package/build/dist/UI/Utils/LabelRuleImportExport.js.map +1 -0
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +4 -4
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/TelemetryService.js +3 -2
- package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
- package/build/dist/UI/Utils/UseDashboardGridDnd.js +2 -1
- package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -1
- package/build/dist/UI/Utils/UserEmailRegistrationStatus.js +21 -4
- package/build/dist/UI/Utils/UserEmailRegistrationStatus.js.map +1 -1
- package/build/dist/UI/Utils/WebAuthn.js +121 -0
- package/build/dist/UI/Utils/WebAuthn.js.map +1 -0
- package/build/dist/Utils/API.js +29 -0
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js +9 -1
- package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareHostListComponent.js +33 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareHostListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareResourceListShared.js +54 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareResourceListShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.js +60 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +8 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/Dashboard/LabelVariable.js +96 -0
- package/build/dist/Utils/Dashboard/LabelVariable.js.map +1 -0
- package/build/dist/Utils/Dashboard/VariableUrlState.js +19 -4
- package/build/dist/Utils/Dashboard/VariableUrlState.js.map +1 -1
- package/build/dist/Utils/LabelRuleImportExport.js +356 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -0
- package/build/dist/Utils/MetricUnitUtil.js +26 -0
- package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js +112 -0
- package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +276 -0
- package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js +101 -0
- package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorTemplateSyncUtil.js +110 -0
- package/build/dist/Utils/Monitor/MonitorTemplateSyncUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +7 -2
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +484 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js +59 -0
- package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +6 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -1
- package/build/dist/Utils/Telemetry/CloudInstanceIdentity.js +88 -0
- package/build/dist/Utils/Telemetry/CloudInstanceIdentity.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +15 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +13 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/test-setup.sh +9 -9
- package/tsconfig.json +51 -11
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +0 -399
|
@@ -0,0 +1,1474 @@
|
|
|
1
|
+
import GitHubCommandParser from "../../../../Server/Utils/CodeRepository/GitHub/GitHubCommandParser";
|
|
2
|
+
import GitHubCommandType, {
|
|
3
|
+
GitHubCommand,
|
|
4
|
+
GitHubCommandSurface,
|
|
5
|
+
isConversationalCommand,
|
|
6
|
+
} from "../../../../Types/CodeRepository/GitHubCommand";
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* ---------------------------------------------------------------------------
|
|
11
|
+
* GitHubCommandParser is the gate between arbitrary text written by anyone
|
|
12
|
+
* with comment access to a connected repository and a paid, write-capable
|
|
13
|
+
* agent run. Nothing downstream re-checks whether the app was actually
|
|
14
|
+
* addressed: if parse() returns a command, work is enqueued.
|
|
15
|
+
*
|
|
16
|
+
* So these tests are written around four invariants rather than around the
|
|
17
|
+
* grammar:
|
|
18
|
+
*
|
|
19
|
+
* 1. NO MENTION, NO COMMAND. The overwhelmingly common case is a comment
|
|
20
|
+
* that has nothing to do with this app, and it must cost nothing and
|
|
21
|
+
* return null.
|
|
22
|
+
*
|
|
23
|
+
* 2. NO LOOPS. GitHub's "Quote reply" button copies the parent comment into
|
|
24
|
+
* a `>` block verbatim, so a mention inside a quote, a fenced code block
|
|
25
|
+
* or an inline code span must NOT be a command. Without this, every
|
|
26
|
+
* reply to one of the app's own comments re-triggers it and the two talk
|
|
27
|
+
* to each other until the fix budget is gone.
|
|
28
|
+
*
|
|
29
|
+
* 3. WHOLE-WORD MENTIONS, BOUNDED BY AN ALLOW-LIST. `@oneuptime-staging` is
|
|
30
|
+
* a different GitHub App and `support@oneuptime.com` is an email
|
|
31
|
+
* address. Neither may command this installation. The character BEFORE
|
|
32
|
+
* the at-sign is checked against a list of what may appear there —
|
|
33
|
+
* nothing, whitespace, or wrapping punctuation — rather than against a
|
|
34
|
+
* list of what may not, because "not an ASCII word character" silently
|
|
35
|
+
* admits every non-ASCII local part on earth.
|
|
36
|
+
*
|
|
37
|
+
* 4. NOTHING IS SILENTLY DROPPED. An unrecognized verb is not an error —
|
|
38
|
+
* the surface decides (pull request -> Revise, issue -> Implement) — and
|
|
39
|
+
* a verb aimed at the wrong surface still parses, so the webhook handler
|
|
40
|
+
* can answer with a real explanation instead of ignoring the user.
|
|
41
|
+
*
|
|
42
|
+
* The module is pure: no IO, no environment, nothing mocked. Every assertion
|
|
43
|
+
* below is a statement about (body, appSlug, surface) alone.
|
|
44
|
+
* ---------------------------------------------------------------------------
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
const APP_SLUG: string = "oneuptime";
|
|
48
|
+
|
|
49
|
+
function parseOnPullRequest(
|
|
50
|
+
body: string | null | undefined,
|
|
51
|
+
): GitHubCommand | null {
|
|
52
|
+
return GitHubCommandParser.parse({
|
|
53
|
+
body: body,
|
|
54
|
+
appSlug: APP_SLUG,
|
|
55
|
+
surface: GitHubCommandSurface.PullRequest,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function parseOnIssue(body: string | null | undefined): GitHubCommand | null {
|
|
60
|
+
return GitHubCommandParser.parse({
|
|
61
|
+
body: body,
|
|
62
|
+
appSlug: APP_SLUG,
|
|
63
|
+
surface: GitHubCommandSurface.Issue,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function parseWithSlug(
|
|
68
|
+
body: string | null | undefined,
|
|
69
|
+
appSlug: string | null | undefined,
|
|
70
|
+
): GitHubCommand | null {
|
|
71
|
+
return GitHubCommandParser.parse({
|
|
72
|
+
body: body,
|
|
73
|
+
appSlug: appSlug,
|
|
74
|
+
surface: GitHubCommandSurface.PullRequest,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Non-null variants. A test that means "this text IS a command" should fail
|
|
80
|
+
* on the null itself rather than on a confusing property read of null.
|
|
81
|
+
*/
|
|
82
|
+
function commandOnPullRequest(body: string): GitHubCommand {
|
|
83
|
+
const command: GitHubCommand | null = parseOnPullRequest(body);
|
|
84
|
+
|
|
85
|
+
if (!command) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Expected a command on a pull request from ${JSON.stringify(body)}, got null`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return command;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function commandOnIssue(body: string): GitHubCommand {
|
|
95
|
+
const command: GitHubCommand | null = parseOnIssue(body);
|
|
96
|
+
|
|
97
|
+
if (!command) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Expected a command on an issue from ${JSON.stringify(body)}, got null`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return command;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Multi-line comment bodies read far better as lines than as escaped strings.
|
|
107
|
+
function body(...lines: Array<string>): string {
|
|
108
|
+
return lines.join("\n");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const FENCE: string = "```";
|
|
112
|
+
const TILDE_FENCE: string = "~~~";
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* A four-character fence. CommonMark lets an author open with a LONGER fence
|
|
116
|
+
* precisely so the block can contain the ordinary three-backtick one — which
|
|
117
|
+
* is exactly the shape of a comment that shows someone how to talk to this
|
|
118
|
+
* app, and therefore the shape most likely to contain a mention.
|
|
119
|
+
*/
|
|
120
|
+
const LONG_FENCE: string = "````";
|
|
121
|
+
const LONG_TILDE_FENCE: string = "~~~~";
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
* The parser is pure and mocks nothing, but the house convention is kept so
|
|
125
|
+
* that a spy added to this file later cannot leak into a neighbouring test in
|
|
126
|
+
* the same worker.
|
|
127
|
+
*/
|
|
128
|
+
beforeEach(() => {
|
|
129
|
+
jest.restoreAllMocks();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
afterEach(() => {
|
|
133
|
+
jest.restoreAllMocks();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe("GitHubCommandParser.parse", () => {
|
|
137
|
+
describe("comments that do not address the app", () => {
|
|
138
|
+
test("returns null for an ordinary review comment", () => {
|
|
139
|
+
expect(
|
|
140
|
+
parseOnPullRequest("LGTM, shipping this once CI goes green."),
|
|
141
|
+
).toBeNull();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("returns null when the app is named but not mentioned with an @", () => {
|
|
145
|
+
expect(
|
|
146
|
+
parseOnPullRequest(
|
|
147
|
+
"we should ask oneuptime to review this at some point",
|
|
148
|
+
),
|
|
149
|
+
).toBeNull();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test("returns null when a different app is being commanded", () => {
|
|
153
|
+
expect(parseOnPullRequest("@dependabot rebase")).toBeNull();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("returns null for a long comment with no mention anywhere in it", () => {
|
|
157
|
+
expect(parseOnIssue("x".repeat(5000))).toBeNull();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("a bare mention", () => {
|
|
162
|
+
/*
|
|
163
|
+
* Orientation, not a licence to start work on whatever the thread happens
|
|
164
|
+
* to be about. A bare "@oneuptime" on a 400-comment issue must not be
|
|
165
|
+
* read as "implement all of that".
|
|
166
|
+
*/
|
|
167
|
+
test("is Help with an empty instruction, not the surface default", () => {
|
|
168
|
+
const command: GitHubCommand = commandOnIssue("@oneuptime");
|
|
169
|
+
|
|
170
|
+
expect(command.commandType).toBe(GitHubCommandType.Help);
|
|
171
|
+
expect(command.instruction).toBe("");
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("is Help on a pull request too", () => {
|
|
175
|
+
expect(commandOnPullRequest("@oneuptime").commandType).toBe(
|
|
176
|
+
GitHubCommandType.Help,
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("is still Help when only whitespace and blank lines follow", () => {
|
|
181
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
182
|
+
body("", "", "@oneuptime ", "", "\t"),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
expect(command.commandType).toBe(GitHubCommandType.Help);
|
|
186
|
+
expect(command.instruction).toBe("");
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test("is Help for the [bot]-suffixed form GitHub renders", () => {
|
|
190
|
+
const command: GitHubCommand = commandOnPullRequest("@oneuptime[bot]");
|
|
191
|
+
|
|
192
|
+
expect(command.commandType).toBe(GitHubCommandType.Help);
|
|
193
|
+
expect(command.instruction).toBe("");
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
describe("explicit verbs", () => {
|
|
198
|
+
describe("Review, on a pull request", () => {
|
|
199
|
+
test.each([
|
|
200
|
+
"review",
|
|
201
|
+
"code review",
|
|
202
|
+
"please review",
|
|
203
|
+
"can you review",
|
|
204
|
+
"review this",
|
|
205
|
+
])("'@oneuptime %s' asks for a Review", (phrase: string) => {
|
|
206
|
+
expect(commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
207
|
+
GitHubCommandType.Review,
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
/*
|
|
212
|
+
* "code review" must not be shadowed by the shorter "review" landing on
|
|
213
|
+
* a different command type — they happen to agree today, and this test
|
|
214
|
+
* is what keeps them agreeing if the phrase list is reordered.
|
|
215
|
+
*/
|
|
216
|
+
test("'code review' is a Review even though 'review' is not its first word", () => {
|
|
217
|
+
expect(commandOnPullRequest("@oneuptime code review").commandType).toBe(
|
|
218
|
+
GitHubCommandType.Review,
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe("Revise, on a pull request", () => {
|
|
224
|
+
test.each([
|
|
225
|
+
"revise",
|
|
226
|
+
"revise this",
|
|
227
|
+
"please revise",
|
|
228
|
+
"rework",
|
|
229
|
+
"rework this",
|
|
230
|
+
"redo",
|
|
231
|
+
"redo this",
|
|
232
|
+
])("'@oneuptime %s' asks for a Revise", (phrase: string) => {
|
|
233
|
+
expect(commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
234
|
+
GitHubCommandType.Revise,
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe("Implement, on an issue", () => {
|
|
240
|
+
test.each([
|
|
241
|
+
"implement",
|
|
242
|
+
"implement this",
|
|
243
|
+
"please implement",
|
|
244
|
+
"work on this",
|
|
245
|
+
"work on it",
|
|
246
|
+
"pick this up",
|
|
247
|
+
"take this",
|
|
248
|
+
])("'@oneuptime %s' asks for an Implement", (phrase: string) => {
|
|
249
|
+
expect(commandOnIssue(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
250
|
+
GitHubCommandType.Implement,
|
|
251
|
+
);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe("the conversational verbs, on either surface", () => {
|
|
256
|
+
test.each(["help", "commands", "usage", "what can you do"])(
|
|
257
|
+
"'@oneuptime %s' asks for Help",
|
|
258
|
+
(phrase: string) => {
|
|
259
|
+
expect(
|
|
260
|
+
commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType,
|
|
261
|
+
).toBe(GitHubCommandType.Help);
|
|
262
|
+
expect(commandOnIssue(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
263
|
+
GitHubCommandType.Help,
|
|
264
|
+
);
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
test.each(["status", "progress"])(
|
|
269
|
+
"'@oneuptime %s' asks for Status",
|
|
270
|
+
(phrase: string) => {
|
|
271
|
+
expect(
|
|
272
|
+
commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType,
|
|
273
|
+
).toBe(GitHubCommandType.Status);
|
|
274
|
+
expect(commandOnIssue(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
275
|
+
GitHubCommandType.Status,
|
|
276
|
+
);
|
|
277
|
+
},
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
test.each(["cancel", "stop", "abort"])(
|
|
281
|
+
"'@oneuptime %s' asks for Cancel",
|
|
282
|
+
(phrase: string) => {
|
|
283
|
+
expect(
|
|
284
|
+
commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType,
|
|
285
|
+
).toBe(GitHubCommandType.Cancel);
|
|
286
|
+
expect(commandOnIssue(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
287
|
+
GitHubCommandType.Cancel,
|
|
288
|
+
);
|
|
289
|
+
},
|
|
290
|
+
);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
/*
|
|
294
|
+
* A verb overrides the surface default even when the surface cannot carry
|
|
295
|
+
* it out. Downgrading a misplaced "review" on an issue into the issue
|
|
296
|
+
* default would open a pull request nobody asked for; parsing it as a
|
|
297
|
+
* Review lets the handler say why it cannot be done.
|
|
298
|
+
*/
|
|
299
|
+
test("a Review asked for on an issue still parses as a Review", () => {
|
|
300
|
+
expect(commandOnIssue("@oneuptime review").commandType).toBe(
|
|
301
|
+
GitHubCommandType.Review,
|
|
302
|
+
);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test("an Implement asked for on a pull request still parses as an Implement", () => {
|
|
306
|
+
expect(
|
|
307
|
+
commandOnPullRequest("@oneuptime implement this").commandType,
|
|
308
|
+
).toBe(GitHubCommandType.Implement);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
describe("case insensitivity", () => {
|
|
312
|
+
test("an all-caps comment is still parsed as its verb", () => {
|
|
313
|
+
expect(commandOnPullRequest("@ONEUPTIME CODE REVIEW").commandType).toBe(
|
|
314
|
+
GitHubCommandType.Review,
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
test("a mixed-case verb is still parsed as its verb", () => {
|
|
319
|
+
expect(commandOnPullRequest("@oneuptime Review This").commandType).toBe(
|
|
320
|
+
GitHubCommandType.Review,
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
test("the [bot] suffix matches in any case", () => {
|
|
325
|
+
expect(commandOnPullRequest("@ONEUPTIME[BOT] status").commandType).toBe(
|
|
326
|
+
GitHubCommandType.Status,
|
|
327
|
+
);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
test("a slug configured in a different case still matches the comment", () => {
|
|
331
|
+
const command: GitHubCommand | null = parseWithSlug(
|
|
332
|
+
"@oneuptime review",
|
|
333
|
+
"OneUptime",
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
expect(command?.commandType).toBe(GitHubCommandType.Review);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
/*
|
|
340
|
+
* The instruction is NOT lower-cased on its way out. Only the verb match
|
|
341
|
+
* is case-insensitive; the text the agent reads is what the human typed,
|
|
342
|
+
* including any identifier whose case is load-bearing.
|
|
343
|
+
*/
|
|
344
|
+
test("does not lower-case the instruction it hands on", () => {
|
|
345
|
+
expect(commandOnPullRequest("@oneuptime CODE REVIEW").instruction).toBe(
|
|
346
|
+
"CODE REVIEW",
|
|
347
|
+
);
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
describe("punctuation around the verb", () => {
|
|
353
|
+
test.each(["review:", "review :", "review,", "review.", "review!"])(
|
|
354
|
+
"'@oneuptime %s' is still a Review",
|
|
355
|
+
(phrase: string) => {
|
|
356
|
+
expect(commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
357
|
+
GitHubCommandType.Review,
|
|
358
|
+
);
|
|
359
|
+
},
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
test("'@oneuptime help!' is Help", () => {
|
|
363
|
+
expect(commandOnPullRequest("@oneuptime help!").commandType).toBe(
|
|
364
|
+
GitHubCommandType.Help,
|
|
365
|
+
);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
test("'@oneuptime status?' is Status", () => {
|
|
369
|
+
expect(commandOnPullRequest("@oneuptime status?").commandType).toBe(
|
|
370
|
+
GitHubCommandType.Status,
|
|
371
|
+
);
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
test("'@oneuptime abort!' is Cancel", () => {
|
|
375
|
+
expect(commandOnPullRequest("@oneuptime abort!").commandType).toBe(
|
|
376
|
+
GitHubCommandType.Cancel,
|
|
377
|
+
);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// "@oneuptime: review" — the colon belongs to the mention, not the verb.
|
|
381
|
+
test("a colon straight after the mention does not hide the verb", () => {
|
|
382
|
+
expect(commandOnPullRequest("@oneuptime: review").commandType).toBe(
|
|
383
|
+
GitHubCommandType.Review,
|
|
384
|
+
);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
test("a leading list dash does not hide the verb", () => {
|
|
388
|
+
expect(
|
|
389
|
+
commandOnIssue("@oneuptime - please implement this").commandType,
|
|
390
|
+
).toBe(GitHubCommandType.Implement);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test("a verb on the line after the mention is still the verb", () => {
|
|
394
|
+
expect(
|
|
395
|
+
commandOnPullRequest(body("@oneuptime", "please review this diff"))
|
|
396
|
+
.commandType,
|
|
397
|
+
).toBe(GitHubCommandType.Review);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
describe("the instruction handed to the agent", () => {
|
|
402
|
+
/*
|
|
403
|
+
* The verb is kept in the instruction rather than stripped. Every consumer
|
|
404
|
+
* quotes this text into a prompt as the user's own words, and removing the
|
|
405
|
+
* first line of them changes what was asked for.
|
|
406
|
+
*/
|
|
407
|
+
test("keeps the verb itself, not only the words after it", () => {
|
|
408
|
+
expect(
|
|
409
|
+
commandOnPullRequest(
|
|
410
|
+
"@oneuptime review this and check perf on the hot path",
|
|
411
|
+
).instruction,
|
|
412
|
+
).toBe("review this and check perf on the hot path");
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test("keeps trailing punctuation and the rest of the sentence", () => {
|
|
416
|
+
expect(
|
|
417
|
+
commandOnPullRequest("@oneuptime review: focus on the retry loop")
|
|
418
|
+
.instruction,
|
|
419
|
+
).toBe("review: focus on the retry loop");
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
test("keeps everything after a mention written mid-sentence", () => {
|
|
423
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
424
|
+
"Hey @oneuptime review this when you get a sec",
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
expect(command.commandType).toBe(GitHubCommandType.Review);
|
|
428
|
+
expect(command.instruction).toBe("review this when you get a sec");
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
test("does not include the mention token itself", () => {
|
|
432
|
+
expect(
|
|
433
|
+
commandOnPullRequest("@oneuptime[bot] revise this").instruction,
|
|
434
|
+
).not.toContain("@oneuptime");
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
test("collapses the whitespace between the mention and the instruction", () => {
|
|
438
|
+
expect(commandOnPullRequest("@oneuptime status").instruction).toBe(
|
|
439
|
+
"status",
|
|
440
|
+
);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
test("preserves non-ASCII text byte for byte", () => {
|
|
444
|
+
expect(
|
|
445
|
+
commandOnPullRequest(
|
|
446
|
+
"@oneuptime revise this — the café loader 🚀 drops frames",
|
|
447
|
+
).instruction,
|
|
448
|
+
).toBe("revise this — the café loader 🚀 drops frames");
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
/*
|
|
452
|
+
* Inline code is blanked only to LOCATE the mention — the instruction is
|
|
453
|
+
* sliced out of the ORIGINAL text at the same index. Removing the span
|
|
454
|
+
* instead would hand the agent "revise this to use " and leave it to
|
|
455
|
+
* guess what to use, on the very requests where the person was most
|
|
456
|
+
* precise: the ones where they typed the identifier out.
|
|
457
|
+
*/
|
|
458
|
+
test("keeps an inline code span the person typed", () => {
|
|
459
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
460
|
+
"@oneuptime revise this to use `Array<T>`",
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
464
|
+
expect(command.instruction).toBe("revise this to use `Array<T>`");
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
test("keeps an inline code span in the middle of the instruction", () => {
|
|
468
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
469
|
+
"@oneuptime revise this: `retryCount` must be capped at 5",
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
473
|
+
expect(command.instruction).toBe(
|
|
474
|
+
"revise this: `retryCount` must be capped at 5",
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test("keeps several inline code spans and the text between them", () => {
|
|
479
|
+
expect(
|
|
480
|
+
commandOnIssue(
|
|
481
|
+
"@oneuptime implement this: `parseAll()` should call `parseOne()` per row",
|
|
482
|
+
).instruction,
|
|
483
|
+
).toBe("implement this: `parseAll()` should call `parseOne()` per row");
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
/*
|
|
487
|
+
* The blanking is what keeps the two strings index-aligned. A span BEFORE
|
|
488
|
+
* the mention is the case that would go wrong if the span were removed
|
|
489
|
+
* rather than blanked: every index after it would shift, and the
|
|
490
|
+
* instruction would be sliced from the wrong place.
|
|
491
|
+
*/
|
|
492
|
+
test("an inline code span before the mention does not shift the slice", () => {
|
|
493
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
494
|
+
"`retryCount` is wrong — @oneuptime revise this: cap it at 5",
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
498
|
+
expect(command.instruction).toBe("revise this: cap it at 5");
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
test("carries a multi-line instruction through to the end of the comment", () => {
|
|
502
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
503
|
+
body(
|
|
504
|
+
"@oneuptime revise this",
|
|
505
|
+
"because the retry loop is wrong",
|
|
506
|
+
"> quoted from an older comment",
|
|
507
|
+
"also fix the log line",
|
|
508
|
+
),
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
512
|
+
expect(command.instruction).toBe(
|
|
513
|
+
body(
|
|
514
|
+
"revise this",
|
|
515
|
+
"because the retry loop is wrong",
|
|
516
|
+
"also fix the log line",
|
|
517
|
+
),
|
|
518
|
+
);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
/*
|
|
522
|
+
* The quoted half of a reply is history, not instruction. Letting it
|
|
523
|
+
* through would feed the app its own earlier output back as a request.
|
|
524
|
+
*/
|
|
525
|
+
test("drops quoted lines from the instruction, keeping only the new text", () => {
|
|
526
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
527
|
+
body(
|
|
528
|
+
"> @oneuptime review",
|
|
529
|
+
"> looks good to me",
|
|
530
|
+
"",
|
|
531
|
+
"@oneuptime revise this: add the null check",
|
|
532
|
+
),
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
536
|
+
expect(command.instruction).toBe("revise this: add the null check");
|
|
537
|
+
expect(command.instruction).not.toContain("looks good to me");
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
describe("surface defaults when no verb is recognized", () => {
|
|
542
|
+
/*
|
|
543
|
+
* "@oneuptime the retry loop here looks wrong" is the most natural way to
|
|
544
|
+
* ask for a change. Rejecting it as unparseable would make the app feel
|
|
545
|
+
* broken; guessing Implement on a pull request would open a second PR.
|
|
546
|
+
*/
|
|
547
|
+
test("unrecognized text on a pull request is a Revise", () => {
|
|
548
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
549
|
+
"@oneuptime the retry loop here looks wrong",
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
553
|
+
expect(command.instruction).toBe("the retry loop here looks wrong");
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
test("the same text on an issue is an Implement", () => {
|
|
557
|
+
const command: GitHubCommand = commandOnIssue(
|
|
558
|
+
"@oneuptime the retry loop here looks wrong",
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
expect(command.commandType).toBe(GitHubCommandType.Implement);
|
|
562
|
+
expect(command.instruction).toBe("the retry loop here looks wrong");
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
/*
|
|
566
|
+
* The composition that matters: whatever the default is, it has to be
|
|
567
|
+
* something the surface it came from can actually carry out, or free-text
|
|
568
|
+
* mentions would dead-end in "not supported here".
|
|
569
|
+
*/
|
|
570
|
+
test("the default is always supported on the surface it came from", () => {
|
|
571
|
+
const onPullRequest: GitHubCommand = commandOnPullRequest(
|
|
572
|
+
"@oneuptime this needs a null check",
|
|
573
|
+
);
|
|
574
|
+
const onIssue: GitHubCommand = commandOnIssue(
|
|
575
|
+
"@oneuptime this needs a null check",
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
expect(
|
|
579
|
+
GitHubCommandParser.isSupportedOnSurface({
|
|
580
|
+
commandType: onPullRequest.commandType,
|
|
581
|
+
surface: GitHubCommandSurface.PullRequest,
|
|
582
|
+
}),
|
|
583
|
+
).toBe(true);
|
|
584
|
+
|
|
585
|
+
expect(
|
|
586
|
+
GitHubCommandParser.isSupportedOnSurface({
|
|
587
|
+
commandType: onIssue.commandType,
|
|
588
|
+
surface: GitHubCommandSurface.Issue,
|
|
589
|
+
}),
|
|
590
|
+
).toBe(true);
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
/*
|
|
595
|
+
* A verb is a verb only at the START of the instruction. Scanning the whole
|
|
596
|
+
* instruction for the word would turn ordinary prose that happens to mention
|
|
597
|
+
* reviewing into a review run, and — worse — would let a comment ending in
|
|
598
|
+
* "...so I stopped" cancel someone else's in-flight work.
|
|
599
|
+
*/
|
|
600
|
+
describe("a word that is not the verb", () => {
|
|
601
|
+
test("'the reviewer asked for a null check' is not a Review", () => {
|
|
602
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
603
|
+
"@oneuptime the reviewer asked for a null check",
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
test.each([
|
|
610
|
+
"reviews are failing on main",
|
|
611
|
+
"helpme with the flaky spec",
|
|
612
|
+
"stopping the poller mid-flight leaks a handle",
|
|
613
|
+
"cancelled the deploy last night",
|
|
614
|
+
"implementation is wrong here",
|
|
615
|
+
"statuses should be paginated",
|
|
616
|
+
])(
|
|
617
|
+
"'@oneuptime %s' falls through to the surface default",
|
|
618
|
+
(phrase: string) => {
|
|
619
|
+
expect(commandOnPullRequest(`@${APP_SLUG} ${phrase}`).commandType).toBe(
|
|
620
|
+
GitHubCommandType.Revise,
|
|
621
|
+
);
|
|
622
|
+
},
|
|
623
|
+
);
|
|
624
|
+
|
|
625
|
+
test("a verb buried in the middle of a sentence does not win", () => {
|
|
626
|
+
expect(
|
|
627
|
+
commandOnPullRequest(
|
|
628
|
+
"@oneuptime can we get someone to review and merge",
|
|
629
|
+
).commandType,
|
|
630
|
+
).toBe(GitHubCommandType.Revise);
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
/*
|
|
635
|
+
* -------------------------------------------------------------------------
|
|
636
|
+
* More than one mention in one comment.
|
|
637
|
+
*
|
|
638
|
+
* "@oneuptime[bot] said it was flaky, so @oneuptime review this again" is
|
|
639
|
+
* ordinary English, and it is what people write when they are replying to
|
|
640
|
+
* the app and giving it an order in the same breath. Reading only the FIRST
|
|
641
|
+
* mention turns the order into a fragment of an instruction string nobody
|
|
642
|
+
* wrote — and picks the surface default instead of the verb the person
|
|
643
|
+
* actually used, which is the difference between answering a question and
|
|
644
|
+
* pushing a commit.
|
|
645
|
+
*
|
|
646
|
+
* So every mention is scanned, and the precedence is: the first mention
|
|
647
|
+
* followed by a recognized VERB wins; failing that, the first mention that
|
|
648
|
+
* says anything at all; failing that, Help.
|
|
649
|
+
* -------------------------------------------------------------------------
|
|
650
|
+
*/
|
|
651
|
+
describe("several mentions in one comment", () => {
|
|
652
|
+
test("a verb on a later mention beats free text on an earlier one", () => {
|
|
653
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
654
|
+
"@oneuptime[bot] said it was flaky, so @oneuptime status",
|
|
655
|
+
);
|
|
656
|
+
|
|
657
|
+
expect(command.commandType).toBe(GitHubCommandType.Status);
|
|
658
|
+
expect(command.instruction).toBe("status");
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
test("the verb wins even when the earlier mention would default to Revise", () => {
|
|
662
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
663
|
+
"@oneuptime the CI is red, so @oneuptime review this",
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
expect(command.commandType).toBe(GitHubCommandType.Review);
|
|
667
|
+
expect(command.instruction).toBe("review this");
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
test("the same precedence holds on an issue", () => {
|
|
671
|
+
expect(
|
|
672
|
+
commandOnIssue("@oneuptime this is still open, @oneuptime cancel")
|
|
673
|
+
.commandType,
|
|
674
|
+
).toBe(GitHubCommandType.Cancel);
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
/*
|
|
678
|
+
* With no verb anywhere, the FIRST substantive mention is the request —
|
|
679
|
+
* later ones are the person addressing the app again inside their own
|
|
680
|
+
* sentence, not a second command.
|
|
681
|
+
*/
|
|
682
|
+
test("with no verb anywhere the first substantive mention wins", () => {
|
|
683
|
+
const command: GitHubCommand = commandOnIssue(
|
|
684
|
+
"@oneuptime the CSV export drops the last row, cc @oneuptime",
|
|
685
|
+
);
|
|
686
|
+
|
|
687
|
+
expect(command.commandType).toBe(GitHubCommandType.Implement);
|
|
688
|
+
expect(command.instruction).toBe(
|
|
689
|
+
"the CSV export drops the last row, cc @oneuptime",
|
|
690
|
+
);
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
/*
|
|
694
|
+
* An earlier mention with nothing after it must not consume the comment:
|
|
695
|
+
* before the scan, a leading bare mention returned Help and the order on
|
|
696
|
+
* the next line was never read.
|
|
697
|
+
*/
|
|
698
|
+
test("a bare mention on its own line does not eat the order below it", () => {
|
|
699
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
700
|
+
body("@oneuptime", "", "@oneuptime code review"),
|
|
701
|
+
);
|
|
702
|
+
|
|
703
|
+
expect(command.commandType).toBe(GitHubCommandType.Review);
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
test("two verbs in one comment resolve to the first of them", () => {
|
|
707
|
+
expect(
|
|
708
|
+
commandOnPullRequest("@oneuptime review this, @oneuptime cancel")
|
|
709
|
+
.commandType,
|
|
710
|
+
).toBe(GitHubCommandType.Review);
|
|
711
|
+
});
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
/*
|
|
715
|
+
* -------------------------------------------------------------------------
|
|
716
|
+
* A mention with no WORD after it.
|
|
717
|
+
*
|
|
718
|
+
* "@oneuptime 👍" is applause, not a work order. It is not the empty string
|
|
719
|
+
* either, so a bare truthiness check on the instruction sent it to the
|
|
720
|
+
* surface default and spent a full agent run — a write-capable one on a
|
|
721
|
+
* pull request — on a thumbs-up. Substance means at least one alphanumeric
|
|
722
|
+
* character.
|
|
723
|
+
* -------------------------------------------------------------------------
|
|
724
|
+
*/
|
|
725
|
+
describe("a mention with no word after it", () => {
|
|
726
|
+
test.each(["👍", "🎉 🚀", "!!", "...", "??", "— —", "🙏"])(
|
|
727
|
+
"'@oneuptime %s' is Help, not a paid run",
|
|
728
|
+
(trailer: string) => {
|
|
729
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
730
|
+
`@${APP_SLUG} ${trailer}`,
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
expect(command.commandType).toBe(GitHubCommandType.Help);
|
|
734
|
+
expect(command.instruction).toBe("");
|
|
735
|
+
},
|
|
736
|
+
);
|
|
737
|
+
|
|
738
|
+
test("an emoji-only mention on an issue is Help too, not an Implement", () => {
|
|
739
|
+
expect(commandOnIssue("@oneuptime 👍").commandType).toBe(
|
|
740
|
+
GitHubCommandType.Help,
|
|
741
|
+
);
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
test("a single letter after the mention IS substance", () => {
|
|
745
|
+
const command: GitHubCommand = commandOnPullRequest("@oneuptime k");
|
|
746
|
+
|
|
747
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
748
|
+
expect(command.instruction).toBe("k");
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
/*
|
|
752
|
+
* Substance is about the presence of a word, not about dropping the
|
|
753
|
+
* decoration around it — the agent still reads the emoji the person sent.
|
|
754
|
+
*/
|
|
755
|
+
test("an emoji beside a real instruction does not suppress it", () => {
|
|
756
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
757
|
+
"@oneuptime 🙏 revise this: cap the retries",
|
|
758
|
+
);
|
|
759
|
+
|
|
760
|
+
expect(command.commandType).toBe(GitHubCommandType.Revise);
|
|
761
|
+
expect(command.instruction).toBe("🙏 revise this: cap the retries");
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
test("a thumbs-up before a real order still runs the order", () => {
|
|
765
|
+
expect(
|
|
766
|
+
commandOnPullRequest("@oneuptime 👍 and @oneuptime status").commandType,
|
|
767
|
+
).toBe(GitHubCommandType.Status);
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
/*
|
|
772
|
+
* ---------------------------------------------------------------------
|
|
773
|
+
* Loop prevention. Each of these bodies is text the app itself could have
|
|
774
|
+
* written and a human could have quoted back. Any one of them returning a
|
|
775
|
+
* command is a comment loop that spends the project's fix budget.
|
|
776
|
+
* ---------------------------------------------------------------------
|
|
777
|
+
*/
|
|
778
|
+
describe("loop prevention: quoted regions are not commands", () => {
|
|
779
|
+
test("a mention inside a blockquote is not a command", () => {
|
|
780
|
+
expect(parseOnPullRequest("> @oneuptime review")).toBeNull();
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
test("a mention inside GitHub's nested quote-reply form is not a command", () => {
|
|
784
|
+
expect(parseOnPullRequest("> > @oneuptime review this")).toBeNull();
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
test("an indented quote is still a quote", () => {
|
|
788
|
+
expect(parseOnPullRequest(" > @oneuptime review")).toBeNull();
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
test("a tab-indented quote is still a quote", () => {
|
|
792
|
+
expect(parseOnPullRequest("\t> @oneuptime review")).toBeNull();
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
test("a quote that appears after other text is still a quote", () => {
|
|
796
|
+
expect(
|
|
797
|
+
parseOnPullRequest(
|
|
798
|
+
body("Thanks, that helped!", "", "> @oneuptime review"),
|
|
799
|
+
),
|
|
800
|
+
).toBeNull();
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
// The exact shape GitHub's "Quote reply" button produces.
|
|
804
|
+
test("quote-replying to the app's own comment does not re-trigger it", () => {
|
|
805
|
+
expect(
|
|
806
|
+
parseOnPullRequest(
|
|
807
|
+
body(
|
|
808
|
+
"> **@oneuptime[bot]** commented:",
|
|
809
|
+
"> ",
|
|
810
|
+
"> @oneuptime review",
|
|
811
|
+
"",
|
|
812
|
+
"Thanks, looks good.",
|
|
813
|
+
),
|
|
814
|
+
),
|
|
815
|
+
).toBeNull();
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
test("a genuine mention below the quoted history is still a command", () => {
|
|
819
|
+
expect(
|
|
820
|
+
commandOnPullRequest(
|
|
821
|
+
body("> @oneuptime review", "", "@oneuptime status"),
|
|
822
|
+
).commandType,
|
|
823
|
+
).toBe(GitHubCommandType.Status);
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
/*
|
|
827
|
+
* The stripping has to stay line-anchored. A ">" written mid-sentence is
|
|
828
|
+
* a comparison, and dropping that line would silently swallow the command
|
|
829
|
+
* on it.
|
|
830
|
+
*/
|
|
831
|
+
test("a '>' in the middle of a line does not make the line a quote", () => {
|
|
832
|
+
expect(
|
|
833
|
+
commandOnPullRequest("if a > b then @oneuptime review this")
|
|
834
|
+
.commandType,
|
|
835
|
+
).toBe(GitHubCommandType.Review);
|
|
836
|
+
});
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
describe("loop prevention: fenced code blocks are not commands", () => {
|
|
840
|
+
test("a mention inside a backtick fence is not a command", () => {
|
|
841
|
+
expect(
|
|
842
|
+
parseOnPullRequest(body(FENCE, "@oneuptime review", FENCE)),
|
|
843
|
+
).toBeNull();
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
test("a mention inside a fence with an info string is not a command", () => {
|
|
847
|
+
expect(
|
|
848
|
+
parseOnPullRequest(
|
|
849
|
+
body(`${FENCE}suggestion`, "@oneuptime review", FENCE),
|
|
850
|
+
),
|
|
851
|
+
).toBeNull();
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
test("a mention inside a tilde fence is not a command", () => {
|
|
855
|
+
expect(
|
|
856
|
+
parseOnPullRequest(body(TILDE_FENCE, "@oneuptime review", TILDE_FENCE)),
|
|
857
|
+
).toBeNull();
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
test("a mention inside a tilde fence with an info string is not a command", () => {
|
|
861
|
+
expect(
|
|
862
|
+
parseOnPullRequest(
|
|
863
|
+
body(`${TILDE_FENCE}text`, "@oneuptime review", TILDE_FENCE),
|
|
864
|
+
),
|
|
865
|
+
).toBeNull();
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
/*
|
|
869
|
+
* The case a lazy regex gets wrong. Pasted logs very often end without a
|
|
870
|
+
* closing fence, and everything after the opener is code as far as GitHub
|
|
871
|
+
* renders it — so it must be code as far as this parser reads it too.
|
|
872
|
+
*/
|
|
873
|
+
test("an unclosed fence swallows the rest of the comment", () => {
|
|
874
|
+
expect(
|
|
875
|
+
parseOnPullRequest(
|
|
876
|
+
body(
|
|
877
|
+
"Here is the log:",
|
|
878
|
+
FENCE,
|
|
879
|
+
"@oneuptime review",
|
|
880
|
+
"more log lines",
|
|
881
|
+
),
|
|
882
|
+
),
|
|
883
|
+
).toBeNull();
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
test("an unclosed tilde fence swallows the rest of the comment", () => {
|
|
887
|
+
expect(
|
|
888
|
+
parseOnIssue(body(TILDE_FENCE, "@oneuptime implement this")),
|
|
889
|
+
).toBeNull();
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
test("a backtick fence is not closed by a tilde fence", () => {
|
|
893
|
+
expect(
|
|
894
|
+
parseOnPullRequest(
|
|
895
|
+
body(FENCE, "@oneuptime review", TILDE_FENCE, "@oneuptime status"),
|
|
896
|
+
),
|
|
897
|
+
).toBeNull();
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
test("a mention after a CLOSED fence is a command again", () => {
|
|
901
|
+
expect(
|
|
902
|
+
commandOnPullRequest(
|
|
903
|
+
body(FENCE, "@oneuptime help", FENCE, "@oneuptime review"),
|
|
904
|
+
).commandType,
|
|
905
|
+
).toBe(GitHubCommandType.Review);
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test("a quote marker inside a fence does not end the fence early", () => {
|
|
909
|
+
expect(
|
|
910
|
+
parseOnPullRequest(
|
|
911
|
+
body(FENCE, "> @oneuptime review", "@oneuptime cancel", FENCE),
|
|
912
|
+
),
|
|
913
|
+
).toBeNull();
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
test("backticks inside a fence do not re-open it as an inline span", () => {
|
|
917
|
+
expect(
|
|
918
|
+
parseOnPullRequest(
|
|
919
|
+
body(FENCE, "`@oneuptime`", "@oneuptime cancel", FENCE),
|
|
920
|
+
),
|
|
921
|
+
).toBeNull();
|
|
922
|
+
});
|
|
923
|
+
|
|
924
|
+
test("a CRLF comment is stripped the same way as an LF one", () => {
|
|
925
|
+
expect(
|
|
926
|
+
parseOnPullRequest("log:\r\n```\r\n@oneuptime review\r\n```\r\n"),
|
|
927
|
+
).toBeNull();
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
/*
|
|
931
|
+
* Fence LENGTH, per CommonMark: a fence closes only on a run of the same
|
|
932
|
+
* character that is AT LEAST as long as the opener. Comparing only the
|
|
933
|
+
* character is the loop guard failing open on the one comment shape most
|
|
934
|
+
* likely to contain a mention — someone using a four-backtick block to
|
|
935
|
+
* show a colleague what a three-backtick example looks like. The inner
|
|
936
|
+
* ``` does not close the ```` block, so the mention beneath it is still
|
|
937
|
+
* code, not an order.
|
|
938
|
+
*/
|
|
939
|
+
test("a short fence inside a longer one does not close it", () => {
|
|
940
|
+
expect(
|
|
941
|
+
commandOnPullRequest(
|
|
942
|
+
body(
|
|
943
|
+
LONG_FENCE,
|
|
944
|
+
FENCE,
|
|
945
|
+
"@oneuptime review",
|
|
946
|
+
FENCE,
|
|
947
|
+
LONG_FENCE,
|
|
948
|
+
"@oneuptime status",
|
|
949
|
+
),
|
|
950
|
+
).commandType,
|
|
951
|
+
).toBe(GitHubCommandType.Status);
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
test("a short fence inside an unclosed longer one swallows the rest", () => {
|
|
955
|
+
expect(
|
|
956
|
+
parseOnPullRequest(
|
|
957
|
+
body(LONG_FENCE, "@oneuptime review", FENCE, "@oneuptime cancel"),
|
|
958
|
+
),
|
|
959
|
+
).toBeNull();
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
test("a short tilde fence inside a longer one does not close it", () => {
|
|
963
|
+
expect(
|
|
964
|
+
parseOnPullRequest(
|
|
965
|
+
body(
|
|
966
|
+
LONG_TILDE_FENCE,
|
|
967
|
+
"@oneuptime review",
|
|
968
|
+
TILDE_FENCE,
|
|
969
|
+
"@oneuptime cancel",
|
|
970
|
+
),
|
|
971
|
+
),
|
|
972
|
+
).toBeNull();
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
/*
|
|
976
|
+
* The other direction is allowed by the same rule: a longer run closes a
|
|
977
|
+
* shorter opener, so a comment that ends its block with extra backticks
|
|
978
|
+
* is not left permanently open.
|
|
979
|
+
*/
|
|
980
|
+
test("a longer fence does close a shorter one", () => {
|
|
981
|
+
expect(
|
|
982
|
+
commandOnPullRequest(
|
|
983
|
+
body(FENCE, "@oneuptime review", LONG_FENCE, "@oneuptime status"),
|
|
984
|
+
).commandType,
|
|
985
|
+
).toBe(GitHubCommandType.Status);
|
|
986
|
+
});
|
|
987
|
+
|
|
988
|
+
test("an exactly matching long fence closes the block", () => {
|
|
989
|
+
expect(
|
|
990
|
+
commandOnPullRequest(
|
|
991
|
+
body(LONG_FENCE, "@oneuptime review", LONG_FENCE, "@oneuptime help"),
|
|
992
|
+
).commandType,
|
|
993
|
+
).toBe(GitHubCommandType.Help);
|
|
994
|
+
});
|
|
995
|
+
});
|
|
996
|
+
|
|
997
|
+
describe("loop prevention: inline code spans are not commands", () => {
|
|
998
|
+
test("a mention inside an inline span is not a command", () => {
|
|
999
|
+
expect(
|
|
1000
|
+
parseOnPullRequest("`@oneuptime review` is how you ask for one"),
|
|
1001
|
+
).toBeNull();
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
test("a real mention beside a documented one is still a command", () => {
|
|
1005
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
1006
|
+
"Use `@oneuptime review` — @oneuptime help",
|
|
1007
|
+
);
|
|
1008
|
+
|
|
1009
|
+
expect(command.commandType).toBe(GitHubCommandType.Help);
|
|
1010
|
+
expect(command.instruction).toBe("help");
|
|
1011
|
+
});
|
|
1012
|
+
|
|
1013
|
+
test("an inline span inside a quote is not a command either", () => {
|
|
1014
|
+
expect(
|
|
1015
|
+
parseOnPullRequest(body("> `@oneuptime review`", "nothing to do here")),
|
|
1016
|
+
).toBeNull();
|
|
1017
|
+
});
|
|
1018
|
+
|
|
1019
|
+
/*
|
|
1020
|
+
* An UNMATCHED backtick renders literally on GitHub, so the mention after
|
|
1021
|
+
* it is really addressed to the app. Swallowing to end-of-line here would
|
|
1022
|
+
* let a stray backtick silently drop a genuine command.
|
|
1023
|
+
*/
|
|
1024
|
+
test("a single unmatched backtick does not swallow the command", () => {
|
|
1025
|
+
expect(commandOnPullRequest("`@oneuptime review").commandType).toBe(
|
|
1026
|
+
GitHubCommandType.Review,
|
|
1027
|
+
);
|
|
1028
|
+
});
|
|
1029
|
+
});
|
|
1030
|
+
|
|
1031
|
+
describe("the mention must be a whole word", () => {
|
|
1032
|
+
/*
|
|
1033
|
+
* A DIFFERENT GitHub App. `\b` sits happily between "oneuptime" and the
|
|
1034
|
+
* "-", which is exactly why the parser uses a negative lookahead instead.
|
|
1035
|
+
*/
|
|
1036
|
+
test("@oneuptime-staging does not command @oneuptime", () => {
|
|
1037
|
+
expect(parseOnPullRequest("@oneuptime-staging review")).toBeNull();
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
test.each([
|
|
1041
|
+
"@oneuptimebot review",
|
|
1042
|
+
"@oneuptime_bot review",
|
|
1043
|
+
"@oneuptime2 review",
|
|
1044
|
+
])("'%s' does not command @oneuptime", (text: string) => {
|
|
1045
|
+
expect(parseOnPullRequest(text)).toBeNull();
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
test("an email address ending in the slug is not a mention", () => {
|
|
1049
|
+
expect(
|
|
1050
|
+
parseOnPullRequest("ping support@oneuptime.com if CI is stuck"),
|
|
1051
|
+
).toBeNull();
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
test("an at-sign preceded by a word character is never a mention", () => {
|
|
1055
|
+
expect(
|
|
1056
|
+
parseOnPullRequest("email@oneuptime and see what happens"),
|
|
1057
|
+
).toBeNull();
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
test("a slug inside a URL path is not a mention", () => {
|
|
1061
|
+
expect(
|
|
1062
|
+
parseOnPullRequest("see https://example.com/@oneuptime for the docs"),
|
|
1063
|
+
).toBeNull();
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
test("a doubled at-sign is not a mention", () => {
|
|
1067
|
+
expect(parseOnPullRequest("@@oneuptime review")).toBeNull();
|
|
1068
|
+
});
|
|
1069
|
+
|
|
1070
|
+
test("the [bot] form GitHub renders IS a mention", () => {
|
|
1071
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
1072
|
+
"@oneuptime[bot] review",
|
|
1073
|
+
);
|
|
1074
|
+
|
|
1075
|
+
expect(command.commandType).toBe(GitHubCommandType.Review);
|
|
1076
|
+
expect(command.instruction).toBe("review");
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
test("the [bot] form falls through to the surface default like any other", () => {
|
|
1080
|
+
expect(
|
|
1081
|
+
commandOnPullRequest("@oneuptime[bot] the retry loop is wrong")
|
|
1082
|
+
.commandType,
|
|
1083
|
+
).toBe(GitHubCommandType.Revise);
|
|
1084
|
+
});
|
|
1085
|
+
|
|
1086
|
+
test("a mention at the very start of a later line is a mention", () => {
|
|
1087
|
+
expect(
|
|
1088
|
+
commandOnPullRequest(
|
|
1089
|
+
body("Hi team.", "", "@oneuptime review this diff"),
|
|
1090
|
+
).commandType,
|
|
1091
|
+
).toBe(GitHubCommandType.Review);
|
|
1092
|
+
});
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
/*
|
|
1096
|
+
* -------------------------------------------------------------------------
|
|
1097
|
+
* The character immediately BEFORE the at-sign.
|
|
1098
|
+
*
|
|
1099
|
+
* This is an ALLOW-LIST, and the whole describe block exists to pin that it
|
|
1100
|
+
* stays one. The obvious rule — "the preceding character must not be a word
|
|
1101
|
+
* character" — is written in ASCII and is therefore wrong everywhere else:
|
|
1102
|
+
* "é" is not an ASCII word character, so `café@oneuptime.com` parsed as a
|
|
1103
|
+
* mention and an EMAIL ADDRESS in the body of a comment started a paid,
|
|
1104
|
+
* write-capable agent run. There is no finite list of characters an email
|
|
1105
|
+
* local part may end with, so the only sound rule names what MAY precede a
|
|
1106
|
+
* mention instead: the start of the text, whitespace, or the punctuation
|
|
1107
|
+
* people genuinely wrap a mention in.
|
|
1108
|
+
*
|
|
1109
|
+
* Each character is asserted on its own rather than as a class, because a
|
|
1110
|
+
* single character dropped from — or added to — the class is invisible in a
|
|
1111
|
+
* diff and changes what can spend money.
|
|
1112
|
+
* -------------------------------------------------------------------------
|
|
1113
|
+
*/
|
|
1114
|
+
describe("the character before the mention is an allow-list", () => {
|
|
1115
|
+
/*
|
|
1116
|
+
* Each accepted character is tested with a letter in front of it, so that
|
|
1117
|
+
* a passing case proves the CHARACTER was accepted rather than the
|
|
1118
|
+
* start-of-text alternative matching.
|
|
1119
|
+
*/
|
|
1120
|
+
test.each([
|
|
1121
|
+
{ name: "a space", character: " " },
|
|
1122
|
+
{ name: "a tab", character: "\t" },
|
|
1123
|
+
{ name: "a newline", character: "\n" },
|
|
1124
|
+
{ name: "an opening parenthesis", character: "(" },
|
|
1125
|
+
{ name: "an opening square bracket", character: "[" },
|
|
1126
|
+
{ name: "an opening brace", character: "{" },
|
|
1127
|
+
{ name: "an asterisk, as in *@oneuptime*", character: "*" },
|
|
1128
|
+
{ name: "an underscore, as in _@oneuptime_", character: "_" },
|
|
1129
|
+
{ name: "a tilde, as in ~@oneuptime~", character: "~" },
|
|
1130
|
+
{ name: "a double quote", character: '"' },
|
|
1131
|
+
{ name: "a single quote", character: "'" },
|
|
1132
|
+
{ name: "a lone backtick", character: "`" },
|
|
1133
|
+
])(
|
|
1134
|
+
"$name before the at-sign still leaves a mention",
|
|
1135
|
+
({ character }: { name: string; character: string }) => {
|
|
1136
|
+
expect(
|
|
1137
|
+
commandOnPullRequest(`hi${character}@${APP_SLUG} review`).commandType,
|
|
1138
|
+
).toBe(GitHubCommandType.Review);
|
|
1139
|
+
},
|
|
1140
|
+
);
|
|
1141
|
+
|
|
1142
|
+
test("the very start of the comment is a mention position", () => {
|
|
1143
|
+
expect(commandOnPullRequest("@oneuptime review").commandType).toBe(
|
|
1144
|
+
GitHubCommandType.Review,
|
|
1145
|
+
);
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
/*
|
|
1149
|
+
* Everything else. A hyphen, a slash and a dot are the characters that
|
|
1150
|
+
* make a mention out of a handle in a URL, a path or a domain; a letter
|
|
1151
|
+
* and a digit are the ordinary end of an email local part; and "é" is the
|
|
1152
|
+
* one that used to get through, which is the reason this list is an
|
|
1153
|
+
* allow-list at all.
|
|
1154
|
+
*/
|
|
1155
|
+
test.each([
|
|
1156
|
+
{ name: "a letter", character: "x" },
|
|
1157
|
+
{ name: "a digit", character: "7" },
|
|
1158
|
+
{ name: "a hyphen", character: "-" },
|
|
1159
|
+
{ name: "a slash", character: "/" },
|
|
1160
|
+
{ name: "a dot", character: "." },
|
|
1161
|
+
{ name: "a non-ASCII letter", character: "é" },
|
|
1162
|
+
])(
|
|
1163
|
+
"$name before the at-sign is not a mention position",
|
|
1164
|
+
({ character }: { name: string; character: string }) => {
|
|
1165
|
+
expect(
|
|
1166
|
+
parseOnPullRequest(`${character}@${APP_SLUG} review`),
|
|
1167
|
+
).toBeNull();
|
|
1168
|
+
},
|
|
1169
|
+
);
|
|
1170
|
+
|
|
1171
|
+
/*
|
|
1172
|
+
* The case that actually happened. Every part of this body is innocent —
|
|
1173
|
+
* someone pasting a contact address into a thread — and it must cost
|
|
1174
|
+
* nothing at all.
|
|
1175
|
+
*/
|
|
1176
|
+
test("an email address with a non-ASCII local part is not a mention", () => {
|
|
1177
|
+
expect(
|
|
1178
|
+
parseOnPullRequest("write to café@oneuptime.com if CI is stuck"),
|
|
1179
|
+
).toBeNull();
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
test("a bare non-ASCII address is not a mention either", () => {
|
|
1183
|
+
expect(parseOnIssue("café@oneuptime.com")).toBeNull();
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
/*
|
|
1187
|
+
* A domain with no local part in front of it. The leading guard cannot
|
|
1188
|
+
* catch this one — a space precedes the at-sign — so the trailing guard
|
|
1189
|
+
* has to.
|
|
1190
|
+
*/
|
|
1191
|
+
test("a bare @slug followed by a domain suffix is not a mention", () => {
|
|
1192
|
+
expect(parseOnPullRequest("we host this at @oneuptime.com")).toBeNull();
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
test.each([
|
|
1196
|
+
"@oneuptime.com is our site",
|
|
1197
|
+
"see @oneuptime.dev for the docs",
|
|
1198
|
+
"docs live at @oneuptime.io/docs",
|
|
1199
|
+
])("'%s' is not a mention", (text: string) => {
|
|
1200
|
+
expect(parseOnPullRequest(text)).toBeNull();
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
/*
|
|
1204
|
+
* ...but the dot guard must only refuse a dot that starts something
|
|
1205
|
+
* DOMAIN-shaped. A mention at the end of a sentence is how most people
|
|
1206
|
+
* write, and refusing it would silently drop ordinary commands.
|
|
1207
|
+
*/
|
|
1208
|
+
test("a sentence-ending period after the mention is still a mention", () => {
|
|
1209
|
+
const command: GitHubCommand = commandOnPullRequest("thanks @oneuptime.");
|
|
1210
|
+
|
|
1211
|
+
expect(command.commandType).toBe(GitHubCommandType.Help);
|
|
1212
|
+
expect(command.instruction).toBe("");
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1215
|
+
test("a period between the mention and the verb does not hide the verb", () => {
|
|
1216
|
+
const command: GitHubCommand = commandOnPullRequest(
|
|
1217
|
+
"thanks @oneuptime. please review this",
|
|
1218
|
+
);
|
|
1219
|
+
|
|
1220
|
+
expect(command.commandType).toBe(GitHubCommandType.Review);
|
|
1221
|
+
// The instruction is the text as typed; only the verb match normalizes.
|
|
1222
|
+
expect(command.instruction).toBe(". please review this");
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
test("a comma after the mention is untouched by the dot guard", () => {
|
|
1226
|
+
expect(
|
|
1227
|
+
commandOnPullRequest("@oneuptime, please review this").commandType,
|
|
1228
|
+
).toBe(GitHubCommandType.Review);
|
|
1229
|
+
});
|
|
1230
|
+
});
|
|
1231
|
+
|
|
1232
|
+
/*
|
|
1233
|
+
* The slug comes from configuration, so a metacharacter in it is a
|
|
1234
|
+
* correctness bug rather than an injection — but an unescaped "[" throws a
|
|
1235
|
+
* SyntaxError that takes down every webhook for that installation, and an
|
|
1236
|
+
* unescaped "+" or "*" quietly widens what counts as a mention.
|
|
1237
|
+
*/
|
|
1238
|
+
describe("app slugs containing regex metacharacters", () => {
|
|
1239
|
+
test("a dot in the slug matches only a literal dot", () => {
|
|
1240
|
+
expect(parseWithSlug("@oneXuptime review", "one.uptime")).toBeNull();
|
|
1241
|
+
expect(
|
|
1242
|
+
parseWithSlug("@one.uptime review", "one.uptime")?.commandType,
|
|
1243
|
+
).toBe(GitHubCommandType.Review);
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
test("a plus in the slug is not read as a repetition", () => {
|
|
1247
|
+
expect(parseWithSlug("@oneeeuptime review", "one+uptime")).toBeNull();
|
|
1248
|
+
expect(
|
|
1249
|
+
parseWithSlug("@one+uptime review", "one+uptime")?.commandType,
|
|
1250
|
+
).toBe(GitHubCommandType.Review);
|
|
1251
|
+
});
|
|
1252
|
+
|
|
1253
|
+
test("a star in the slug is not read as a repetition", () => {
|
|
1254
|
+
expect(parseWithSlug("@onuptime review", "one*uptime")).toBeNull();
|
|
1255
|
+
});
|
|
1256
|
+
|
|
1257
|
+
test("a dollar in the slug is not read as an end anchor", () => {
|
|
1258
|
+
expect(
|
|
1259
|
+
parseWithSlug("@one$uptime review", "one$uptime")?.commandType,
|
|
1260
|
+
).toBe(GitHubCommandType.Review);
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
test("an unbalanced bracket in the slug does not throw", () => {
|
|
1264
|
+
expect(() => {
|
|
1265
|
+
return parseWithSlug("nothing to see here", "one[uptime");
|
|
1266
|
+
}).not.toThrow();
|
|
1267
|
+
|
|
1268
|
+
expect(parseWithSlug("nothing to see here", "one[uptime")).toBeNull();
|
|
1269
|
+
expect(parseWithSlug("@one[uptime help", "one[uptime")?.commandType).toBe(
|
|
1270
|
+
GitHubCommandType.Help,
|
|
1271
|
+
);
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
test("a parenthesised slug is matched literally", () => {
|
|
1275
|
+
expect(parseWithSlug("@a(b) review", "a(b)")?.commandType).toBe(
|
|
1276
|
+
GitHubCommandType.Review,
|
|
1277
|
+
);
|
|
1278
|
+
});
|
|
1279
|
+
|
|
1280
|
+
test("a slug stored with surrounding whitespace still matches", () => {
|
|
1281
|
+
expect(
|
|
1282
|
+
parseWithSlug("@oneuptime review", " oneuptime ")?.commandType,
|
|
1283
|
+
).toBe(GitHubCommandType.Review);
|
|
1284
|
+
});
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
describe("missing or empty input", () => {
|
|
1288
|
+
test("a null body is not a command", () => {
|
|
1289
|
+
expect(parseOnPullRequest(null)).toBeNull();
|
|
1290
|
+
});
|
|
1291
|
+
|
|
1292
|
+
test("an undefined body is not a command", () => {
|
|
1293
|
+
expect(parseOnIssue(undefined)).toBeNull();
|
|
1294
|
+
});
|
|
1295
|
+
|
|
1296
|
+
test("an empty body is not a command", () => {
|
|
1297
|
+
expect(parseOnPullRequest("")).toBeNull();
|
|
1298
|
+
});
|
|
1299
|
+
|
|
1300
|
+
test("a whitespace-only body is not a command", () => {
|
|
1301
|
+
expect(parseOnPullRequest(" \n\t \n")).toBeNull();
|
|
1302
|
+
});
|
|
1303
|
+
|
|
1304
|
+
/*
|
|
1305
|
+
* An unconfigured slug must never fall back to matching everything: with
|
|
1306
|
+
* an empty pattern, "@" alone — or any text at all — would start a run.
|
|
1307
|
+
*/
|
|
1308
|
+
test("a null app slug is not a command", () => {
|
|
1309
|
+
expect(parseWithSlug("@oneuptime review", null)).toBeNull();
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
test("an undefined app slug is not a command", () => {
|
|
1313
|
+
expect(parseWithSlug("@oneuptime review", undefined)).toBeNull();
|
|
1314
|
+
});
|
|
1315
|
+
|
|
1316
|
+
test("an empty app slug is not a command", () => {
|
|
1317
|
+
expect(parseWithSlug("@oneuptime review", "")).toBeNull();
|
|
1318
|
+
});
|
|
1319
|
+
|
|
1320
|
+
test("a whitespace-only app slug is not a command", () => {
|
|
1321
|
+
expect(parseWithSlug("@oneuptime review", " ")).toBeNull();
|
|
1322
|
+
});
|
|
1323
|
+
});
|
|
1324
|
+
});
|
|
1325
|
+
|
|
1326
|
+
/*
|
|
1327
|
+
* The surface matrix. Review and Revise both need a diff and a head branch;
|
|
1328
|
+
* Implement needs an issue to close. Getting one of these wrong does not
|
|
1329
|
+
* fail loudly — it runs the WRONG kind of agent, so the pairs below are
|
|
1330
|
+
* asserted in both directions.
|
|
1331
|
+
*/
|
|
1332
|
+
describe("GitHubCommandParser.isSupportedOnSurface", () => {
|
|
1333
|
+
function isSupported(
|
|
1334
|
+
commandType: GitHubCommandType,
|
|
1335
|
+
surface: GitHubCommandSurface,
|
|
1336
|
+
): boolean {
|
|
1337
|
+
return GitHubCommandParser.isSupportedOnSurface({
|
|
1338
|
+
commandType: commandType,
|
|
1339
|
+
surface: surface,
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
describe("Review", () => {
|
|
1344
|
+
test("is supported on a pull request", () => {
|
|
1345
|
+
expect(
|
|
1346
|
+
isSupported(GitHubCommandType.Review, GitHubCommandSurface.PullRequest),
|
|
1347
|
+
).toBe(true);
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
test("is NOT supported on an issue, which has no diff to read", () => {
|
|
1351
|
+
expect(
|
|
1352
|
+
isSupported(GitHubCommandType.Review, GitHubCommandSurface.Issue),
|
|
1353
|
+
).toBe(false);
|
|
1354
|
+
});
|
|
1355
|
+
});
|
|
1356
|
+
|
|
1357
|
+
describe("Revise", () => {
|
|
1358
|
+
test("is supported on a pull request, whose head branch it pushes to", () => {
|
|
1359
|
+
expect(
|
|
1360
|
+
isSupported(GitHubCommandType.Revise, GitHubCommandSurface.PullRequest),
|
|
1361
|
+
).toBe(true);
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
test("is NOT supported on an issue, which has no head branch", () => {
|
|
1365
|
+
expect(
|
|
1366
|
+
isSupported(GitHubCommandType.Revise, GitHubCommandSurface.Issue),
|
|
1367
|
+
).toBe(false);
|
|
1368
|
+
});
|
|
1369
|
+
});
|
|
1370
|
+
|
|
1371
|
+
describe("Implement", () => {
|
|
1372
|
+
test("is supported on an issue", () => {
|
|
1373
|
+
expect(
|
|
1374
|
+
isSupported(GitHubCommandType.Implement, GitHubCommandSurface.Issue),
|
|
1375
|
+
).toBe(true);
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
/*
|
|
1379
|
+
* Implement opens a NEW pull request that closes an issue. Allowing it on
|
|
1380
|
+
* a pull request would open a second PR against the same work instead of
|
|
1381
|
+
* revising the one being commented on.
|
|
1382
|
+
*/
|
|
1383
|
+
test("is NOT supported on a pull request", () => {
|
|
1384
|
+
expect(
|
|
1385
|
+
isSupported(
|
|
1386
|
+
GitHubCommandType.Implement,
|
|
1387
|
+
GitHubCommandSurface.PullRequest,
|
|
1388
|
+
),
|
|
1389
|
+
).toBe(false);
|
|
1390
|
+
});
|
|
1391
|
+
});
|
|
1392
|
+
|
|
1393
|
+
describe("the conversational commands", () => {
|
|
1394
|
+
test.each([
|
|
1395
|
+
GitHubCommandType.Help,
|
|
1396
|
+
GitHubCommandType.Status,
|
|
1397
|
+
GitHubCommandType.Cancel,
|
|
1398
|
+
])("%s is supported on both surfaces", (commandType: GitHubCommandType) => {
|
|
1399
|
+
expect(isSupported(commandType, GitHubCommandSurface.PullRequest)).toBe(
|
|
1400
|
+
true,
|
|
1401
|
+
);
|
|
1402
|
+
expect(isSupported(commandType, GitHubCommandSurface.Issue)).toBe(true);
|
|
1403
|
+
});
|
|
1404
|
+
});
|
|
1405
|
+
|
|
1406
|
+
/*
|
|
1407
|
+
* The catch-all. A command type added to the enum without a line in
|
|
1408
|
+
* isSupportedOnSurface falls into the `return true` at the bottom and is
|
|
1409
|
+
* silently allowed everywhere — so the count is asserted too, to make a new
|
|
1410
|
+
* type fail HERE, next to the matrix it needs a decision in.
|
|
1411
|
+
*/
|
|
1412
|
+
test("every command type is supported on at least one surface", () => {
|
|
1413
|
+
const commandTypes: Array<GitHubCommandType> =
|
|
1414
|
+
Object.values(GitHubCommandType);
|
|
1415
|
+
|
|
1416
|
+
expect(commandTypes.length).toBe(6);
|
|
1417
|
+
|
|
1418
|
+
for (const commandType of commandTypes) {
|
|
1419
|
+
expect(
|
|
1420
|
+
isSupported(commandType, GitHubCommandSurface.PullRequest) ||
|
|
1421
|
+
isSupported(commandType, GitHubCommandSurface.Issue),
|
|
1422
|
+
).toBe(true);
|
|
1423
|
+
}
|
|
1424
|
+
});
|
|
1425
|
+
});
|
|
1426
|
+
|
|
1427
|
+
/*
|
|
1428
|
+
* The parser and this predicate together decide whether a comment costs
|
|
1429
|
+
* money. Anything conversational is answered inline by the webhook and never
|
|
1430
|
+
* enqueues an agent run, so a command type moving across this line changes
|
|
1431
|
+
* the billing behaviour of the whole integration.
|
|
1432
|
+
*/
|
|
1433
|
+
describe("commands that never start an agent run", () => {
|
|
1434
|
+
test.each([
|
|
1435
|
+
GitHubCommandType.Help,
|
|
1436
|
+
GitHubCommandType.Status,
|
|
1437
|
+
GitHubCommandType.Cancel,
|
|
1438
|
+
])("%s is conversational", (commandType: GitHubCommandType) => {
|
|
1439
|
+
expect(isConversationalCommand(commandType)).toBe(true);
|
|
1440
|
+
});
|
|
1441
|
+
|
|
1442
|
+
test.each([
|
|
1443
|
+
GitHubCommandType.Review,
|
|
1444
|
+
GitHubCommandType.Revise,
|
|
1445
|
+
GitHubCommandType.Implement,
|
|
1446
|
+
])("%s is NOT conversational", (commandType: GitHubCommandType) => {
|
|
1447
|
+
expect(isConversationalCommand(commandType)).toBe(false);
|
|
1448
|
+
});
|
|
1449
|
+
|
|
1450
|
+
// The bare mention is the one that fires most often by accident.
|
|
1451
|
+
test("a bare mention is conversational, so it cannot cost a run", () => {
|
|
1452
|
+
const command: GitHubCommand = commandOnIssue("@oneuptime");
|
|
1453
|
+
|
|
1454
|
+
expect(isConversationalCommand(command.commandType)).toBe(true);
|
|
1455
|
+
});
|
|
1456
|
+
|
|
1457
|
+
/*
|
|
1458
|
+
* The other one that fires by accident, and the more expensive of the two:
|
|
1459
|
+
* a thumbs-up on a pull request would have started a WRITE-capable Revise.
|
|
1460
|
+
*/
|
|
1461
|
+
test("a thumbs-up mention is conversational, so it cannot cost a run", () => {
|
|
1462
|
+
const command: GitHubCommand = commandOnPullRequest("@oneuptime 👍");
|
|
1463
|
+
|
|
1464
|
+
expect(isConversationalCommand(command.commandType)).toBe(true);
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
test("free text on an issue is NOT conversational, and does cost a run", () => {
|
|
1468
|
+
const command: GitHubCommand = commandOnIssue(
|
|
1469
|
+
"@oneuptime the CSV export drops the last row",
|
|
1470
|
+
);
|
|
1471
|
+
|
|
1472
|
+
expect(isConversationalCommand(command.commandType)).toBe(false);
|
|
1473
|
+
});
|
|
1474
|
+
});
|