@oneuptime/common 12.0.7 → 12.0.9
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/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +1 -1
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
- package/Models/DatabaseModels/AIConversation.ts +32 -0
- package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
- package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
- package/Models/DatabaseModels/Index.ts +12 -4
- package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +184 -9
- package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
- package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +33 -7
- package/Models/DatabaseModels/NetworkDevice.ts +141 -0
- package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
- package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
- package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
- package/Models/DatabaseModels/Project.ts +78 -0
- package/Models/DatabaseModels/UserCall.ts +42 -0
- package/Models/DatabaseModels/UserEmail.ts +44 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
- package/Models/DatabaseModels/UserPush.ts +49 -0
- package/Models/DatabaseModels/UserSMS.ts +43 -0
- package/Models/DatabaseModels/UserTelegram.ts +59 -0
- package/Models/DatabaseModels/UserWebhook.ts +52 -0
- package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
- package/Models/DatabaseModels/WorkflowLog.ts +38 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
- package/Server/API/AIChatAPI.ts +315 -1
- package/Server/API/DashboardAPI.ts +217 -1
- package/Server/API/OnCallReadinessAPI.ts +841 -0
- package/Server/API/TeamComplianceAPI.ts +69 -17
- package/Server/API/TelemetryAPI.ts +220 -12
- package/Server/API/UserAPI.ts +16 -1
- package/Server/EnvironmentConfig.ts +52 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +24 -0
- package/Server/Infrastructure/Queue.ts +78 -13
- package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
- package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
- package/Server/Services/AIService.ts +7 -0
- package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/AlertSeverityService.ts +63 -0
- package/Server/Services/DashboardService.ts +9 -10
- package/Server/Services/DatabaseService.ts +32 -2
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/IncidentSeverityService.ts +76 -0
- package/Server/Services/Index.ts +12 -4
- package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
- package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +7 -4
- package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +203 -21
- package/Server/Services/LogAggregationService.ts +45 -8
- package/Server/Services/MetricAggregationService.ts +121 -0
- package/Server/Services/MetricService.ts +7 -7
- package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
- package/Server/Services/NetworkDeviceLinkService.ts +84 -0
- package/Server/Services/NetworkDeviceService.ts +140 -0
- package/Server/Services/NetworkSiteService.ts +77 -25
- package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
- package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
- package/Server/Services/OnCallReadinessService.ts +2803 -0
- package/Server/Services/OnCallSetupReminderService.ts +955 -0
- package/Server/Services/ProfileAggregationService.ts +123 -0
- package/Server/Services/StatusPageService.ts +9 -10
- package/Server/Services/TeamComplianceService.ts +429 -252
- package/Server/Services/UserCallService.ts +26 -1
- package/Server/Services/UserEmailService.ts +26 -1
- package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
- package/Server/Services/UserNotificationRuleService.ts +3812 -333
- package/Server/Services/UserOnCallLogService.ts +561 -48
- package/Server/Services/UserPushService.ts +29 -0
- package/Server/Services/UserService.ts +11 -0
- package/Server/Services/UserSmsService.ts +26 -1
- package/Server/Services/UserTelegramService.ts +24 -1
- package/Server/Services/UserWebhookService.ts +28 -1
- package/Server/Services/UserWhatsAppService.ts +24 -1
- package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
- package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
- package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
- package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
- package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
- package/Server/Types/Workflow/Components/API/Get.ts +1 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
- package/Server/Types/Workflow/Components/API/Post.ts +1 -1
- package/Server/Types/Workflow/Components/API/Put.ts +1 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
- package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
- package/Server/Types/Workflow/Components/Email.ts +25 -7
- package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
- package/Server/Types/Workflow/TriggerCode.ts +12 -0
- package/Server/Types/Workflow/Workflow.ts +5 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
- package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
- package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
- package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
- package/Server/Utils/AI/Toolbox/Index.ts +48 -0
- package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
- package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
- package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
- package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
- package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
- package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
- package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
- package/Server/Utils/ClientIp.ts +221 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
- package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
- package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
- package/Server/Utils/Express.ts +12 -17
- package/Server/Utils/LLM/LLMService.ts +85 -8
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
- package/Server/Utils/SSRFProtection.ts +98 -23
- package/Server/Utils/StartServer.ts +12 -3
- package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
- package/Server/Utils/VM/VMAPI.ts +56 -8
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
- package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
- package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
- package/Tests/Models/InventoryItemModel.test.ts +174 -0
- package/Tests/Models/InventoryItemNaming.test.ts +302 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
- package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
- package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
- package/Tests/Server/API/Helpers.ts +24 -15
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
- package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
- package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
- package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
- package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
- package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
- package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +248 -0
- package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
- package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
- package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
- package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
- package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
- package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
- package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
- package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
- package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
- package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
- package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
- package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
- package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
- package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
- package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
- package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
- package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
- package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
- package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
- package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
- package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
- package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
- package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
- package/Tests/Server/Utils/ClientIp.test.ts +438 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
- package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
- package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
- package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
- package/Tests/Types/IP/IP.test.ts +263 -0
- package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
- package/Tests/Types/IP/IPv6.test.ts +12 -1
- package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
- package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
- package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
- package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
- package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
- package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +491 -0
- package/Tests/Types/Workflow/Templates.test.ts +1218 -0
- package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
- package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
- package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
- package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
- package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
- package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
- package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
- package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
- package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
- package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
- package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +893 -0
- package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +522 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +193 -0
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +388 -0
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +210 -0
- package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
- package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
- package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
- package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
- package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
- package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
- package/Tests/UI/EsbuildConfig.test.ts +607 -0
- package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
- package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
- package/Tests/UI/Utils/Platform.test.ts +147 -0
- package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +727 -0
- package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
- package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
- package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
- package/Tests/__mocks__/bullmq.js +55 -0
- package/Types/AI/AIChatMessageStatus.ts +8 -1
- package/Types/AI/AIChatTypes.ts +12 -0
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
- package/Types/Exception/ExceptionCode.ts +2 -0
- package/Types/Exception/ServiceUnavailableException.ts +8 -0
- package/Types/Exception/TooManyRequestsException.ts +8 -0
- package/Types/IP/IP.ts +93 -47
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +80 -3
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
- package/Types/OnCallDutyPolicy/Layer.ts +203 -149
- package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
- package/Types/Permission.ts +193 -0
- package/Types/SerializableObjectDictionary.ts +133 -39
- package/Types/Telemetry/EntityRelationshipType.ts +1 -1
- package/Types/Telemetry/EntitySource.ts +40 -0
- package/Types/Telemetry/EntityType.ts +28 -1
- package/Types/Telemetry/EntityTypeGroups.ts +65 -0
- package/Types/Workflow/Component.ts +29 -0
- package/Types/Workflow/Components/API.ts +35 -0
- package/Types/Workflow/Components/BaseModel.ts +77 -27
- package/Types/Workflow/Components/Discord.ts +1 -0
- package/Types/Workflow/Components/Email.ts +12 -3
- package/Types/Workflow/Components/JavaScript.ts +7 -0
- package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
- package/Types/Workflow/Components/Slack.ts +1 -0
- package/Types/Workflow/Components/Telegram.ts +1 -0
- package/Types/Workflow/StepTrace.ts +181 -0
- package/Types/Workflow/TemplateSyntax.ts +543 -0
- package/Types/Workflow/Templates.ts +2368 -0
- package/UI/Components/Calendar/Calendar.css +43 -0
- package/UI/Components/Calendar/Calendar.tsx +8 -0
- package/UI/Components/Card/Card.tsx +2 -2
- package/UI/Components/Checkbox/Checkbox.tsx +16 -0
- package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
- package/UI/Components/Dictionary/Dictionary.tsx +71 -15
- package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
- package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
- package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
- package/UI/Components/Forms/Types/Field.ts +7 -0
- package/UI/Components/Forms/Validation.ts +63 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
- package/UI/Components/Input/Input.tsx +32 -3
- package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
- package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
- package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
- package/UI/Components/LogsViewer/types.ts +23 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
- package/UI/Components/Modal/Modal.tsx +37 -4
- package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
- package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
- package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
- package/UI/Components/Table/Table.tsx +49 -16
- package/UI/Components/Table/TableBody.tsx +53 -28
- package/UI/Components/Table/TableHeader.tsx +13 -0
- package/UI/Components/Table/TableRow.tsx +58 -26
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
- package/UI/Components/Workflow/ArgumentsForm.tsx +341 -8
- package/UI/Components/Workflow/Component.tsx +28 -26
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +79 -9
- package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
- package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
- package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
- package/UI/Components/Workflow/GraphLint.ts +628 -0
- package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +528 -0
- package/UI/Components/Workflow/ModelSchema.ts +278 -0
- package/UI/Components/Workflow/RunForm.tsx +41 -7
- package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
- package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
- package/UI/Components/Workflow/UseRunWatch.ts +212 -0
- package/UI/Components/Workflow/Utils.ts +93 -1
- package/UI/Components/Workflow/VariableModal.tsx +6 -2
- package/UI/Components/Workflow/Workflow.tsx +126 -7
- package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
- package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
- package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
- package/UI/Types/LayeredDismissal.ts +31 -0
- package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
- package/UI/Utils/Platform.ts +149 -0
- package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
- package/UI/esbuild-config.js +22 -1
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +917 -155
- package/Utils/Telemetry/CrossSignalScope.ts +502 -0
- package/Utils/Telemetry/EntityKey.ts +71 -5
- package/Utils/Telemetry/EntityRelationship.ts +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +12 -4
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +212 -29
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
- package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +52 -25
- package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +80 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
- package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +237 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +165 -13
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
- package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
- package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +129 -18
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +16 -1
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +45 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +72 -13
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AIService.js +1 -0
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +54 -0
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/DashboardService.js +10 -9
- package/build/dist/Server/Services/DashboardService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +24 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +12 -4
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +9 -6
- package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +158 -23
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
- package/build/dist/Server/Services/LogAggregationService.js +27 -8
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +80 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +6 -6
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +53 -13
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
- package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
- package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
- package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +11 -10
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceService.js +312 -160
- package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +24 -1
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +24 -1
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
- package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +26 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +24 -1
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +22 -1
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +25 -1
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
- package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
- package/build/dist/Server/Utils/ClientIp.js +137 -0
- package/build/dist/Server/Utils/ClientIp.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
- package/build/dist/Server/Utils/Express.js +12 -12
- package/build/dist/Server/Utils/Express.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +82 -21
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +12 -4
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatTypes.js +12 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js +2 -0
- package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
- package/build/dist/Types/IP/IP.js +87 -43
- package/build/dist/Types/IP/IP.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/Permission.js +174 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +133 -39
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +39 -0
- package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +28 -1
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
- package/build/dist/Types/Workflow/Component.js +21 -0
- package/build/dist/Types/Workflow/Component.js.map +1 -1
- package/build/dist/Types/Workflow/Components/API.js +35 -0
- package/build/dist/Types/Workflow/Components/API.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +68 -26
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Discord.js +1 -0
- package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Email.js +12 -3
- package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
- package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Slack.js +1 -0
- package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
- package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
- package/build/dist/Types/Workflow/StepTrace.js +104 -0
- package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js +338 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +2111 -0
- package/build/dist/Types/Workflow/Templates.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js +47 -17
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +44 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +13 -4
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +31 -5
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +27 -15
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +24 -18
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +9 -1
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +29 -21
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +261 -14
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +20 -19
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +35 -7
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +425 -0
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +320 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js +156 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
- package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
- package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Utils.js +73 -1
- package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
- package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
- package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +92 -7
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
- package/build/dist/UI/Types/LayeredDismissal.js +21 -0
- package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Platform.js +118 -0
- package/build/dist/UI/Utils/Platform.js.map +1 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +661 -126
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +57 -5
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
- package/jest.config.json +1 -0
- package/package.json +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
|
@@ -0,0 +1,1218 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Every shipped template is checked against the real component registry and
|
|
3
|
+
* against the same linter the builder runs.
|
|
4
|
+
*
|
|
5
|
+
* A template is the first workflow a lot of people will ever see, so one with
|
|
6
|
+
* a mistyped argument id, a reference to a return value that does not exist,
|
|
7
|
+
* or an edge leaving a port the component does not have would be worse than
|
|
8
|
+
* shipping no templates at all — it teaches the wrong thing and looks broken
|
|
9
|
+
* on arrival. Writing these tests caught exactly that: the Log component's
|
|
10
|
+
* argument is "value" (not "log-message"), the Schedule trigger's is
|
|
11
|
+
* "schedule" (not "schedule-at"), the Manual trigger leaves by "success" and
|
|
12
|
+
* the Schedule trigger by "execute" (neither is "out").
|
|
13
|
+
*
|
|
14
|
+
* Two things here are load-bearing and easy to get wrong when extending this
|
|
15
|
+
* file:
|
|
16
|
+
*
|
|
17
|
+
* 1. The registry is the MERGED one (loadComponentsAndCategories), not the
|
|
18
|
+
* static Components array. Templates use database-model components like
|
|
19
|
+
* `incident-on-create`, which only exist in the merged registry. Against
|
|
20
|
+
* the static array those nodes get `metadata: undefined`, the linter's
|
|
21
|
+
* isRealNode silently drops them, and the lint test passes on a graph it
|
|
22
|
+
* never checked.
|
|
23
|
+
*
|
|
24
|
+
* 2. References are classified with parseReferencePath rather than by
|
|
25
|
+
* assuming every {{...}} is local.components.*. Templates now also carry
|
|
26
|
+
* {{local.variables.*}}, and a test that assumes otherwise fails on
|
|
27
|
+
* correct templates.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
WORKFLOW_TEMPLATE_VARIABLE_NAME_REGEX,
|
|
32
|
+
WorkflowTemplate,
|
|
33
|
+
WorkflowTemplateCategories,
|
|
34
|
+
WorkflowTemplateCategory,
|
|
35
|
+
WorkflowTemplateVariable,
|
|
36
|
+
buildGraphForTemplate,
|
|
37
|
+
getTemplateGraphSpec,
|
|
38
|
+
getWorkflowTemplate,
|
|
39
|
+
getWorkflowTemplates,
|
|
40
|
+
getWorkflowTemplatesByCategory,
|
|
41
|
+
} from "../../../Types/Workflow/Templates";
|
|
42
|
+
import ComponentMetadata, {
|
|
43
|
+
Argument,
|
|
44
|
+
ComponentType,
|
|
45
|
+
NodeDataProp,
|
|
46
|
+
Port,
|
|
47
|
+
ReturnValue,
|
|
48
|
+
} from "../../../Types/Workflow/Component";
|
|
49
|
+
import { JSONObject, JSONValue } from "../../../Types/JSON";
|
|
50
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
51
|
+
import {
|
|
52
|
+
LintGraphEdge,
|
|
53
|
+
LintGraphNode,
|
|
54
|
+
WorkflowLintIssue,
|
|
55
|
+
WorkflowLintResult,
|
|
56
|
+
WorkflowLintSeverity,
|
|
57
|
+
lintWorkflowGraph,
|
|
58
|
+
} from "../../../UI/Components/Workflow/GraphLint";
|
|
59
|
+
import { loadComponentsAndCategories } from "../../../UI/Components/Workflow/Utils";
|
|
60
|
+
import {
|
|
61
|
+
ParsedReferencePath,
|
|
62
|
+
ReferenceRootType,
|
|
63
|
+
TemplateExpression,
|
|
64
|
+
TemplateExpressionKind,
|
|
65
|
+
parseReferencePath,
|
|
66
|
+
parseTemplateExpressions,
|
|
67
|
+
} from "../../../Types/Workflow/TemplateSyntax";
|
|
68
|
+
import { describe, expect, test } from "@jest/globals";
|
|
69
|
+
import ComponentID from "../../../Types/Workflow/ComponentID";
|
|
70
|
+
import CronTab from "../../../Utils/CronTab";
|
|
71
|
+
|
|
72
|
+
const templates: Array<WorkflowTemplate> = getWorkflowTemplates();
|
|
73
|
+
|
|
74
|
+
/*
|
|
75
|
+
* The same registry the builder loads: static components plus one set per
|
|
76
|
+
* database model. Built once — it walks every entity in the models index.
|
|
77
|
+
*/
|
|
78
|
+
const registry: Array<ComponentMetadata> =
|
|
79
|
+
loadComponentsAndCategories().components;
|
|
80
|
+
|
|
81
|
+
type FindMetadataFunction = (
|
|
82
|
+
metadataId: string,
|
|
83
|
+
) => ComponentMetadata | undefined;
|
|
84
|
+
|
|
85
|
+
const findMetadata: FindMetadataFunction = (
|
|
86
|
+
metadataId: string,
|
|
87
|
+
): ComponentMetadata | undefined => {
|
|
88
|
+
return registry.find((component: ComponentMetadata) => {
|
|
89
|
+
return component.id === metadataId;
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
let idCounter: number = 0;
|
|
94
|
+
|
|
95
|
+
type GenerateIdFunction = () => string;
|
|
96
|
+
|
|
97
|
+
const generateId: GenerateIdFunction = (): string => {
|
|
98
|
+
idCounter++;
|
|
99
|
+
return `generated-${idCounter}`;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
interface TemplateNodeSpec {
|
|
103
|
+
componentId: string;
|
|
104
|
+
metadataId: string;
|
|
105
|
+
componentType: ComponentType;
|
|
106
|
+
args?: JSONObject | undefined;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface TemplateEdgeSpec {
|
|
110
|
+
fromComponentId: string;
|
|
111
|
+
toComponentId: string;
|
|
112
|
+
fromPort: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
interface TemplateSpec {
|
|
116
|
+
nodes: Array<TemplateNodeSpec>;
|
|
117
|
+
edges: Array<TemplateEdgeSpec>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
type SpecOfFunction = (templateId: string) => TemplateSpec;
|
|
121
|
+
|
|
122
|
+
const specOf: SpecOfFunction = (templateId: string): TemplateSpec => {
|
|
123
|
+
return getTemplateGraphSpec(templateId) as unknown as TemplateSpec;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Build a template's graph and hydrate each node with its real metadata, the
|
|
128
|
+
* way the builder does on load. Without the metadata the linter cannot check
|
|
129
|
+
* arguments or return values.
|
|
130
|
+
*/
|
|
131
|
+
type HydrateFunction = (templateId: string) => {
|
|
132
|
+
nodes: Array<LintGraphNode>;
|
|
133
|
+
edges: Array<LintGraphEdge>;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const hydrate: HydrateFunction = (
|
|
137
|
+
templateId: string,
|
|
138
|
+
): { nodes: Array<LintGraphNode>; edges: Array<LintGraphEdge> } => {
|
|
139
|
+
const graph: JSONObject = buildGraphForTemplate(
|
|
140
|
+
templateId,
|
|
141
|
+
generateId,
|
|
142
|
+
) as JSONObject;
|
|
143
|
+
|
|
144
|
+
const rawNodes: Array<JSONObject> = graph["nodes"] as Array<JSONObject>;
|
|
145
|
+
const rawEdges: Array<JSONObject> = graph["edges"] as Array<JSONObject>;
|
|
146
|
+
|
|
147
|
+
const nodes: Array<LintGraphNode> = rawNodes.map(
|
|
148
|
+
(node: JSONObject): LintGraphNode => {
|
|
149
|
+
const data: JSONObject = node["data"] as JSONObject;
|
|
150
|
+
const metadata: ComponentMetadata | undefined = findMetadata(
|
|
151
|
+
data["metadataId"] as string,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
id: node["id"] as string,
|
|
156
|
+
data: {
|
|
157
|
+
...(data as unknown as NodeDataProp),
|
|
158
|
+
metadata: metadata as ComponentMetadata,
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const edges: Array<LintGraphEdge> = rawEdges.map(
|
|
165
|
+
(edge: JSONObject): LintGraphEdge => {
|
|
166
|
+
return {
|
|
167
|
+
source: edge["source"] as string,
|
|
168
|
+
target: edge["target"] as string,
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
return { nodes: nodes, edges: edges };
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/** Every string an argument holds, including strings nested inside JSON objects. */
|
|
177
|
+
type CollectStringsFunction = (value: JSONValue | undefined) => Array<string>;
|
|
178
|
+
|
|
179
|
+
const collectStrings: CollectStringsFunction = (
|
|
180
|
+
value: JSONValue | undefined,
|
|
181
|
+
): Array<string> => {
|
|
182
|
+
if (typeof value === "string") {
|
|
183
|
+
return [value];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (Array.isArray(value)) {
|
|
187
|
+
return value.flatMap((entry: JSONValue) => {
|
|
188
|
+
return collectStrings(entry);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (value && typeof value === "object") {
|
|
193
|
+
return Object.values(value as JSONObject).flatMap((entry: JSONValue) => {
|
|
194
|
+
return collectStrings(entry);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return [];
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
interface TemplateReference {
|
|
202
|
+
/** The full {{...}} text. */
|
|
203
|
+
raw: string;
|
|
204
|
+
inner: string;
|
|
205
|
+
parsed: ParsedReferencePath;
|
|
206
|
+
/** The component id the argument lives on. */
|
|
207
|
+
onComponentId: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
type ReferencesOfFunction = (templateId: string) => Array<TemplateReference>;
|
|
211
|
+
|
|
212
|
+
const referencesOf: ReferencesOfFunction = (
|
|
213
|
+
templateId: string,
|
|
214
|
+
): Array<TemplateReference> => {
|
|
215
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
216
|
+
const references: Array<TemplateReference> = [];
|
|
217
|
+
|
|
218
|
+
for (const node of spec.nodes) {
|
|
219
|
+
for (const value of Object.values(node.args || {})) {
|
|
220
|
+
for (const text of collectStrings(value as JSONValue)) {
|
|
221
|
+
const expressions: Array<TemplateExpression> =
|
|
222
|
+
parseTemplateExpressions(text);
|
|
223
|
+
|
|
224
|
+
for (const expression of expressions) {
|
|
225
|
+
if (expression.kind !== TemplateExpressionKind.Reference) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
references.push({
|
|
230
|
+
raw: expression.raw,
|
|
231
|
+
inner: expression.inner,
|
|
232
|
+
parsed: parseReferencePath(expression.inner),
|
|
233
|
+
onComponentId: node.componentId,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return references;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Whether a trigger's `select` argument actually asks for the field a
|
|
245
|
+
* reference reads. The runtime only hydrates what `select` names, so
|
|
246
|
+
* {{…returnValues.model.title}} against a select without `title` resolves to
|
|
247
|
+
* nothing — and an unresolved reference is not an error, it just ships the
|
|
248
|
+
* literal braces.
|
|
249
|
+
*/
|
|
250
|
+
type SelectCoversFunction = (
|
|
251
|
+
select: JSONValue | undefined,
|
|
252
|
+
path: Array<string>,
|
|
253
|
+
) => boolean;
|
|
254
|
+
|
|
255
|
+
const selectCovers: SelectCoversFunction = (
|
|
256
|
+
select: JSONValue | undefined,
|
|
257
|
+
path: Array<string>,
|
|
258
|
+
): boolean => {
|
|
259
|
+
if (path.length === 0) {
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/*
|
|
264
|
+
* ObjectID, Email, Phone and Date values are serialized for workflow storage
|
|
265
|
+
* as { _type, value }. Selecting the database column selects that wrapper;
|
|
266
|
+
* `.value` is a serialization detail rather than another database column.
|
|
267
|
+
*/
|
|
268
|
+
if (path.length === 1 && path[0] === "value" && Boolean(select)) {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// The runtime always adds _id to the select it issues.
|
|
273
|
+
if (path.length === 1 && (path[0] === "_id" || path[0] === "id")) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!select || typeof select !== "object" || Array.isArray(select)) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const head: string = path[0] as string;
|
|
282
|
+
const branch: JSONValue | undefined = (select as JSONObject)[head];
|
|
283
|
+
|
|
284
|
+
if (branch === undefined) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (path.length === 1) {
|
|
289
|
+
return Boolean(branch);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return selectCovers(branch, path.slice(1));
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
describe("workflow templates", () => {
|
|
296
|
+
test("there are plenty to choose from", () => {
|
|
297
|
+
expect(templates.length).toBeGreaterThan(10);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test("each has a unique id", () => {
|
|
301
|
+
const ids: Array<string> = templates.map((template: WorkflowTemplate) => {
|
|
302
|
+
return template.id;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test("each id is dash-cased, so it is safe in a URL and in a test name", () => {
|
|
309
|
+
for (const template of templates) {
|
|
310
|
+
expect(template.id).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test("each suggests a distinct workflow name", () => {
|
|
315
|
+
const names: Array<string> = templates.map((template: WorkflowTemplate) => {
|
|
316
|
+
return template.workflowName;
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
expect(new Set(names).size).toBe(names.length);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
test("each is described well enough to choose between them", () => {
|
|
323
|
+
for (const template of templates) {
|
|
324
|
+
expect(template.name.length).toBeGreaterThan(0);
|
|
325
|
+
expect(template.description.length).toBeGreaterThan(0);
|
|
326
|
+
expect(template.teaches.length).toBeGreaterThan(0);
|
|
327
|
+
expect(template.workflowName.length).toBeGreaterThan(0);
|
|
328
|
+
expect(template.workflowDescription.length).toBeGreaterThan(0);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
test("each belongs to a category the picker knows how to show", () => {
|
|
333
|
+
for (const template of templates) {
|
|
334
|
+
expect(WorkflowTemplateCategories).toContain(template.category);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test("each category in the picker has at least one template", () => {
|
|
339
|
+
for (const category of WorkflowTemplateCategories) {
|
|
340
|
+
expect(getWorkflowTemplatesByCategory(category).length).toBeGreaterThan(
|
|
341
|
+
0,
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
test("grouping by category accounts for every template exactly once", () => {
|
|
347
|
+
const grouped: Array<WorkflowTemplate> = WorkflowTemplateCategories.flatMap(
|
|
348
|
+
(category: WorkflowTemplateCategory) => {
|
|
349
|
+
return getWorkflowTemplatesByCategory(category);
|
|
350
|
+
},
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
expect(grouped).toHaveLength(templates.length);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("each has an icon that exists", () => {
|
|
357
|
+
const iconValues: Array<string> = Object.values(IconProp);
|
|
358
|
+
|
|
359
|
+
for (const template of templates) {
|
|
360
|
+
expect(iconValues).toContain(template.icon);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test("getWorkflowTemplate finds each one, and nothing else", () => {
|
|
365
|
+
for (const template of templates) {
|
|
366
|
+
expect(getWorkflowTemplate(template.id)?.name).toBe(template.name);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
expect(getWorkflowTemplate("does-not-exist")).toBeNull();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
test("an unknown template id yields nothing rather than throwing", () => {
|
|
373
|
+
expect(getTemplateGraphSpec("does-not-exist")).toBeNull();
|
|
374
|
+
expect(buildGraphForTemplate("does-not-exist", generateId)).toBeNull();
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test("the public template carries no graph, so the picker cannot depend on one", () => {
|
|
378
|
+
for (const template of templates) {
|
|
379
|
+
expect((template as unknown as JSONObject)["graph"]).toBeUndefined();
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
/*
|
|
384
|
+
* Every field on WorkflowTemplate has to survive the trip out of the module.
|
|
385
|
+
* The accessor used to hand-enumerate its output fields, which silently
|
|
386
|
+
* dropped anything newly added — the picker would render a card with no icon
|
|
387
|
+
* and the wizard would show no variables step.
|
|
388
|
+
*/
|
|
389
|
+
test("no declared field is dropped on the way out", () => {
|
|
390
|
+
for (const template of templates) {
|
|
391
|
+
expect(Object.keys(template).sort()).toEqual(
|
|
392
|
+
[
|
|
393
|
+
"category",
|
|
394
|
+
"description",
|
|
395
|
+
"icon",
|
|
396
|
+
"id",
|
|
397
|
+
"name",
|
|
398
|
+
"teaches",
|
|
399
|
+
"variables",
|
|
400
|
+
"workflowDescription",
|
|
401
|
+
"workflowName",
|
|
402
|
+
].sort(),
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
describe("workflow template variables", () => {
|
|
409
|
+
test("names are usable in a reference path", () => {
|
|
410
|
+
for (const template of templates) {
|
|
411
|
+
for (const variable of template.variables) {
|
|
412
|
+
expect(variable.name).toMatch(WORKFLOW_TEMPLATE_VARIABLE_NAME_REGEX);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
/*
|
|
418
|
+
* A dot is fatal specifically: VMUtil.deepFind splits the whole path on
|
|
419
|
+
* dots, so local.variables.slack.url looks for a variable called "slack".
|
|
420
|
+
*/
|
|
421
|
+
test("no name contains a dot or whitespace", () => {
|
|
422
|
+
for (const template of templates) {
|
|
423
|
+
for (const variable of template.variables) {
|
|
424
|
+
expect(variable.name).not.toContain(".");
|
|
425
|
+
expect(variable.name).not.toMatch(/\s/);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
test("names are unique within a template, because they become one row each", () => {
|
|
431
|
+
for (const template of templates) {
|
|
432
|
+
const names: Array<string> = template.variables.map(
|
|
433
|
+
(variable: WorkflowTemplateVariable) => {
|
|
434
|
+
return variable.name;
|
|
435
|
+
},
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
expect(new Set(names).size).toBe(names.length);
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test("each is described well enough to fill in", () => {
|
|
443
|
+
for (const template of templates) {
|
|
444
|
+
for (const variable of template.variables) {
|
|
445
|
+
expect(variable.title.length).toBeGreaterThan(0);
|
|
446
|
+
expect(variable.description.length).toBeGreaterThan(0);
|
|
447
|
+
expect(variable.placeholder.length).toBeGreaterThan(0);
|
|
448
|
+
expect(typeof variable.required).toBe("boolean");
|
|
449
|
+
expect(typeof variable.isSecret).toBe("boolean");
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
/*
|
|
455
|
+
* A variable name is reused across templates on purpose (slackWebhookUrl
|
|
456
|
+
* appears in many), and each template is free to label and explain it in its
|
|
457
|
+
* own words — "URL to call" reads better on an hourly poll than "URL to
|
|
458
|
+
* check" does. Variables are workflow-scoped, so two templates never share a
|
|
459
|
+
* row, and nothing forces the wording to agree.
|
|
460
|
+
*
|
|
461
|
+
* What must NOT drift is the behaviour attached to the name. `required`
|
|
462
|
+
* decides whether a row is written at all, and `isSecret` decides whether
|
|
463
|
+
* the value is redacted from run logs. The same field being secret in one
|
|
464
|
+
* template and not in another is a bug, not a wording choice.
|
|
465
|
+
*/
|
|
466
|
+
test("a name reused across templates behaves the same way", () => {
|
|
467
|
+
const byName: Map<string, { required: boolean; isSecret: boolean }> =
|
|
468
|
+
new Map();
|
|
469
|
+
|
|
470
|
+
for (const template of templates) {
|
|
471
|
+
for (const variable of template.variables) {
|
|
472
|
+
const behaviour: { required: boolean; isSecret: boolean } = {
|
|
473
|
+
required: variable.required,
|
|
474
|
+
isSecret: variable.isSecret,
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
const seen: { required: boolean; isSecret: boolean } | undefined =
|
|
478
|
+
byName.get(variable.name);
|
|
479
|
+
|
|
480
|
+
if (!seen) {
|
|
481
|
+
byName.set(variable.name, behaviour);
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
expect({ name: variable.name, ...behaviour }).toEqual({
|
|
486
|
+
name: variable.name,
|
|
487
|
+
...seen,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
test("secrets are the ones that should be secret", () => {
|
|
494
|
+
for (const template of templates) {
|
|
495
|
+
for (const variable of template.variables) {
|
|
496
|
+
if (!variable.isSecret) {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
expect(variable.title.toLowerCase()).toMatch(
|
|
501
|
+
/url|token|password|key|secret/,
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
describe("workflow template runtime contracts", () => {
|
|
509
|
+
test("JavaScript transform receives the webhook body as an object-shaped whole argument", () => {
|
|
510
|
+
const javascriptNode: TemplateNodeSpec = specOf(
|
|
511
|
+
"javascript-transform",
|
|
512
|
+
).nodes.find((node: TemplateNodeSpec) => {
|
|
513
|
+
return node.componentId === "javascript-1";
|
|
514
|
+
}) as TemplateNodeSpec;
|
|
515
|
+
|
|
516
|
+
expect(javascriptNode.args?.["arguments"]).toBe(
|
|
517
|
+
"{{local.components.webhook-1.returnValues.request-body}}",
|
|
518
|
+
);
|
|
519
|
+
expect(javascriptNode.args?.["code"] as string).toContain(
|
|
520
|
+
"const body = args || {};",
|
|
521
|
+
);
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
test("AI incident data stays in the protected context instead of the prompt", () => {
|
|
525
|
+
const aiNode: TemplateNodeSpec = specOf(
|
|
526
|
+
"incident-created-ai-summary",
|
|
527
|
+
).nodes.find((node: TemplateNodeSpec) => {
|
|
528
|
+
return node.componentId === "ai-1";
|
|
529
|
+
}) as TemplateNodeSpec;
|
|
530
|
+
|
|
531
|
+
expect(aiNode.args?.["prompt"] as string).not.toContain("{{");
|
|
532
|
+
expect(aiNode.args?.["context"]).toBe(
|
|
533
|
+
"{{local.components.incident-on-create-1.returnValues.model}}",
|
|
534
|
+
);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
test.each(["subscriber-added-slack", "subscriber-added-forward"])(
|
|
538
|
+
"%s waits for confirmation updates and normalizes the contact method",
|
|
539
|
+
(templateId: string) => {
|
|
540
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
541
|
+
const trigger: TemplateNodeSpec = spec.nodes.find(
|
|
542
|
+
(node: TemplateNodeSpec) => {
|
|
543
|
+
return node.componentType === ComponentType.Trigger;
|
|
544
|
+
},
|
|
545
|
+
) as TemplateNodeSpec;
|
|
546
|
+
|
|
547
|
+
expect(trigger.metadataId).toBe("status-page-subscriber-on-update");
|
|
548
|
+
expect(trigger.args?.["listen-on"]).toEqual({
|
|
549
|
+
isSubscriptionConfirmed: true,
|
|
550
|
+
});
|
|
551
|
+
expect(
|
|
552
|
+
spec.nodes.some((node: TemplateNodeSpec) => {
|
|
553
|
+
return node.componentId === "subscriber-normalize-1";
|
|
554
|
+
}),
|
|
555
|
+
).toBe(true);
|
|
556
|
+
},
|
|
557
|
+
);
|
|
558
|
+
|
|
559
|
+
test("on-call notification follows real execution updates, not the scheduled create event", () => {
|
|
560
|
+
const trigger: TemplateNodeSpec = specOf(
|
|
561
|
+
"oncall-executed-slack",
|
|
562
|
+
).nodes.find((node: TemplateNodeSpec) => {
|
|
563
|
+
return node.componentType === ComponentType.Trigger;
|
|
564
|
+
}) as TemplateNodeSpec;
|
|
565
|
+
|
|
566
|
+
expect(trigger.metadataId).toBe(
|
|
567
|
+
"on-call-duty-policy-execution-log-on-update",
|
|
568
|
+
);
|
|
569
|
+
expect(trigger.args?.["listen-on"]).toEqual({ status: true });
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
test("credential-bearing destination URLs are treated as secrets", () => {
|
|
573
|
+
for (const template of templates) {
|
|
574
|
+
for (const variable of template.variables) {
|
|
575
|
+
const normalizedVariableName: string = variable.name.toLowerCase();
|
|
576
|
+
|
|
577
|
+
if (
|
|
578
|
+
!["webhookurl", "forwardurl", "targeturl", "heartbeaturl"].some(
|
|
579
|
+
(secretUrlName: string): boolean => {
|
|
580
|
+
return normalizedVariableName.includes(secretUrlName);
|
|
581
|
+
},
|
|
582
|
+
)
|
|
583
|
+
) {
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
expect({
|
|
588
|
+
template: template.id,
|
|
589
|
+
variable: variable.name,
|
|
590
|
+
isSecret: variable.isSecret,
|
|
591
|
+
}).toEqual({
|
|
592
|
+
template: template.id,
|
|
593
|
+
variable: variable.name,
|
|
594
|
+
isSecret: true,
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
describe.each(
|
|
602
|
+
templates.map((template: WorkflowTemplate) => {
|
|
603
|
+
return [template.id, template] as [string, WorkflowTemplate];
|
|
604
|
+
}),
|
|
605
|
+
)("template %s", (templateId: string, template: WorkflowTemplate) => {
|
|
606
|
+
test("every component it uses exists in the registry", () => {
|
|
607
|
+
for (const node of specOf(templateId).nodes) {
|
|
608
|
+
expect({
|
|
609
|
+
metadataId: node.metadataId,
|
|
610
|
+
found: Boolean(findMetadata(node.metadataId)),
|
|
611
|
+
}).toEqual({ metadataId: node.metadataId, found: true });
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
/*
|
|
616
|
+
* The builder throws BadDataException on load for a node whose metadataId is
|
|
617
|
+
* not in the registry, which breaks the whole page rather than one node. So
|
|
618
|
+
* a typo here does not degrade a template, it bricks it.
|
|
619
|
+
*/
|
|
620
|
+
test("the node's declared componentType matches the registry's", () => {
|
|
621
|
+
for (const node of specOf(templateId).nodes) {
|
|
622
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
623
|
+
node.metadataId,
|
|
624
|
+
) as ComponentMetadata;
|
|
625
|
+
|
|
626
|
+
expect(node.componentType).toBe(metadata.componentType);
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
test("every argument it sets is a real argument on that component", () => {
|
|
631
|
+
for (const node of specOf(templateId).nodes) {
|
|
632
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
633
|
+
node.metadataId,
|
|
634
|
+
) as ComponentMetadata;
|
|
635
|
+
|
|
636
|
+
for (const argumentId of Object.keys(node.args || {})) {
|
|
637
|
+
const argument: Argument | undefined = metadata.arguments.find(
|
|
638
|
+
(candidate: Argument) => {
|
|
639
|
+
return candidate.id === argumentId;
|
|
640
|
+
},
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
expect({
|
|
644
|
+
node: node.componentId,
|
|
645
|
+
argumentId: argumentId,
|
|
646
|
+
found: Boolean(argument),
|
|
647
|
+
}).toEqual({
|
|
648
|
+
node: node.componentId,
|
|
649
|
+
argumentId: argumentId,
|
|
650
|
+
found: true,
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
test("every required argument is filled in", () => {
|
|
657
|
+
for (const node of specOf(templateId).nodes) {
|
|
658
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
659
|
+
node.metadataId,
|
|
660
|
+
) as ComponentMetadata;
|
|
661
|
+
|
|
662
|
+
for (const argument of metadata.arguments) {
|
|
663
|
+
if (!argument.required) {
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
expect(Object.keys(node.args || {})).toContain(argument.id);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
/*
|
|
673
|
+
* The runner looks up outPorts[sourceHandle] to decide what runs next. A
|
|
674
|
+
* port id that does not exist means the workflow silently stops after the
|
|
675
|
+
* first step.
|
|
676
|
+
*/
|
|
677
|
+
test("every edge leaves a port the component actually has", () => {
|
|
678
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
679
|
+
|
|
680
|
+
for (const edge of spec.edges) {
|
|
681
|
+
const node: TemplateNodeSpec = spec.nodes.find(
|
|
682
|
+
(candidate: TemplateNodeSpec) => {
|
|
683
|
+
return candidate.componentId === edge.fromComponentId;
|
|
684
|
+
},
|
|
685
|
+
) as TemplateNodeSpec;
|
|
686
|
+
|
|
687
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
688
|
+
node.metadataId,
|
|
689
|
+
) as ComponentMetadata;
|
|
690
|
+
|
|
691
|
+
const port: Port | undefined = metadata.outPorts.find(
|
|
692
|
+
(candidate: Port) => {
|
|
693
|
+
return candidate.id === edge.fromPort;
|
|
694
|
+
},
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
expect({
|
|
698
|
+
from: edge.fromComponentId,
|
|
699
|
+
port: edge.fromPort,
|
|
700
|
+
found: Boolean(port),
|
|
701
|
+
}).toEqual({
|
|
702
|
+
from: edge.fromComponentId,
|
|
703
|
+
port: edge.fromPort,
|
|
704
|
+
found: true,
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
test("every fallible component handles its Error port", () => {
|
|
710
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
711
|
+
|
|
712
|
+
for (const node of spec.nodes) {
|
|
713
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
714
|
+
node.metadataId,
|
|
715
|
+
) as ComponentMetadata;
|
|
716
|
+
const hasErrorPort: boolean = metadata.outPorts.some((port: Port) => {
|
|
717
|
+
return port.id === "error";
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
if (!hasErrorPort) {
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
expect({
|
|
725
|
+
componentId: node.componentId,
|
|
726
|
+
handlesError: spec.edges.some((edge: TemplateEdgeSpec) => {
|
|
727
|
+
return (
|
|
728
|
+
edge.fromComponentId === node.componentId &&
|
|
729
|
+
edge.fromPort === "error"
|
|
730
|
+
);
|
|
731
|
+
}),
|
|
732
|
+
}).toEqual({ componentId: node.componentId, handlesError: true });
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
test("Slack messages start with an emoji and a scannable heading", () => {
|
|
737
|
+
for (const node of specOf(templateId).nodes) {
|
|
738
|
+
if (node.metadataId !== ComponentID.SlackSendMessageToChannel) {
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
expect(node.args?.["text"]).toEqual(expect.any(String));
|
|
743
|
+
expect(node.args?.["text"] as string).toMatch(
|
|
744
|
+
/^:[a-z0-9_+-]+: \*[^\n]+\*/,
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
test("schedule expressions are valid cron", () => {
|
|
750
|
+
for (const node of specOf(templateId).nodes) {
|
|
751
|
+
if (node.metadataId !== ComponentID.Schedule) {
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
expect(CronTab.isValid(node.args?.["schedule"] as string)).toBe(true);
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
test("every edge connects component ids the template declares", () => {
|
|
760
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
761
|
+
|
|
762
|
+
const componentIds: Array<string> = spec.nodes.map(
|
|
763
|
+
(node: TemplateNodeSpec) => {
|
|
764
|
+
return node.componentId;
|
|
765
|
+
},
|
|
766
|
+
);
|
|
767
|
+
|
|
768
|
+
for (const edge of spec.edges) {
|
|
769
|
+
expect(componentIds).toContain(edge.fromComponentId);
|
|
770
|
+
expect(componentIds).toContain(edge.toComponentId);
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
test("component ids are unique and dot-free", () => {
|
|
775
|
+
const componentIds: Array<string> = specOf(templateId).nodes.map(
|
|
776
|
+
(node: TemplateNodeSpec) => {
|
|
777
|
+
return node.componentId;
|
|
778
|
+
},
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
expect(new Set(componentIds).size).toBe(componentIds.length);
|
|
782
|
+
|
|
783
|
+
for (const componentId of componentIds) {
|
|
784
|
+
expect(componentId).not.toContain(".");
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
test("has exactly one trigger, and it is a real trigger component", () => {
|
|
789
|
+
const triggers: Array<TemplateNodeSpec> = specOf(templateId).nodes.filter(
|
|
790
|
+
(node: TemplateNodeSpec) => {
|
|
791
|
+
return node.componentType === ComponentType.Trigger;
|
|
792
|
+
},
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
expect(triggers).toHaveLength(1);
|
|
796
|
+
|
|
797
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
798
|
+
triggers[0]?.metadataId as string,
|
|
799
|
+
) as ComponentMetadata;
|
|
800
|
+
|
|
801
|
+
expect(metadata.componentType).toBe(ComponentType.Trigger);
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
/*
|
|
805
|
+
* saveTriggerFromGraph takes the LAST trigger node in the graph while the
|
|
806
|
+
* runner takes the FIRST, so a second trigger would denormalize one id and
|
|
807
|
+
* run another.
|
|
808
|
+
*/
|
|
809
|
+
test("no node other than the trigger is a trigger", () => {
|
|
810
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
811
|
+
|
|
812
|
+
for (const node of spec.nodes) {
|
|
813
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
814
|
+
node.metadataId,
|
|
815
|
+
) as ComponentMetadata;
|
|
816
|
+
|
|
817
|
+
if (node.componentType === ComponentType.Trigger) {
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
expect(metadata.componentType).not.toBe(ComponentType.Trigger);
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
test("every reference is a root the runtime actually has", () => {
|
|
826
|
+
for (const reference of referencesOf(templateId)) {
|
|
827
|
+
expect({
|
|
828
|
+
reference: reference.raw,
|
|
829
|
+
rootType: reference.parsed.rootType,
|
|
830
|
+
}).not.toEqual({
|
|
831
|
+
reference: reference.raw,
|
|
832
|
+
rootType: ReferenceRootType.Unknown,
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
/*
|
|
838
|
+
* The runtime hands the raw capture to deepFind without trimming, so a space
|
|
839
|
+
* inside the braces resolves to nothing. The linter calls it an error too.
|
|
840
|
+
*/
|
|
841
|
+
test("no reference has whitespace inside its braces", () => {
|
|
842
|
+
for (const reference of referencesOf(templateId)) {
|
|
843
|
+
expect(reference.raw).toBe(`{{${reference.inner}}}`);
|
|
844
|
+
expect(reference.inner).not.toMatch(/\s/);
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
test("every component reference points at a component in this template", () => {
|
|
849
|
+
const componentIds: Array<string> = specOf(templateId).nodes.map(
|
|
850
|
+
(node: TemplateNodeSpec) => {
|
|
851
|
+
return node.componentId;
|
|
852
|
+
},
|
|
853
|
+
);
|
|
854
|
+
|
|
855
|
+
for (const reference of referencesOf(templateId)) {
|
|
856
|
+
if (
|
|
857
|
+
reference.parsed.rootType !== ReferenceRootType.ComponentReturnValue
|
|
858
|
+
) {
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
expect(componentIds).toContain(reference.parsed.componentId);
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
test("every component reference points at a return value that exists", () => {
|
|
867
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
868
|
+
|
|
869
|
+
for (const reference of referencesOf(templateId)) {
|
|
870
|
+
if (
|
|
871
|
+
reference.parsed.rootType !== ReferenceRootType.ComponentReturnValue
|
|
872
|
+
) {
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
const referenced: TemplateNodeSpec = spec.nodes.find(
|
|
877
|
+
(node: TemplateNodeSpec) => {
|
|
878
|
+
return node.componentId === reference.parsed.componentId;
|
|
879
|
+
},
|
|
880
|
+
) as TemplateNodeSpec;
|
|
881
|
+
|
|
882
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
883
|
+
referenced.metadataId,
|
|
884
|
+
) as ComponentMetadata;
|
|
885
|
+
|
|
886
|
+
const returnValue: ReturnValue | undefined = metadata.returnValues.find(
|
|
887
|
+
(candidate: ReturnValue) => {
|
|
888
|
+
return candidate.id === reference.parsed.returnValueId;
|
|
889
|
+
},
|
|
890
|
+
);
|
|
891
|
+
|
|
892
|
+
expect({
|
|
893
|
+
reference: reference.raw,
|
|
894
|
+
found: Boolean(returnValue),
|
|
895
|
+
}).toEqual({ reference: reference.raw, found: true });
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
/*
|
|
900
|
+
* The one that catches the subtlest template bug there is. A database
|
|
901
|
+
* trigger only hydrates the columns its `select` names, so reading
|
|
902
|
+
* .model.title without asking for `title` yields nothing — and yielding
|
|
903
|
+
* nothing is not an error anywhere in the stack. The run succeeds and posts
|
|
904
|
+
* "Incident: {{local.components.…}}" to Slack.
|
|
905
|
+
*/
|
|
906
|
+
test("every field read off a database record was asked for in select", () => {
|
|
907
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
908
|
+
|
|
909
|
+
for (const reference of referencesOf(templateId)) {
|
|
910
|
+
if (
|
|
911
|
+
reference.parsed.rootType !== ReferenceRootType.ComponentReturnValue
|
|
912
|
+
) {
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
if (reference.parsed.returnValueId !== "model") {
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
const referenced: TemplateNodeSpec = spec.nodes.find(
|
|
921
|
+
(node: TemplateNodeSpec) => {
|
|
922
|
+
return node.componentId === reference.parsed.componentId;
|
|
923
|
+
},
|
|
924
|
+
) as TemplateNodeSpec;
|
|
925
|
+
|
|
926
|
+
const select: JSONValue | undefined = (referenced.args || {})[
|
|
927
|
+
"select"
|
|
928
|
+
] as JSONValue | undefined;
|
|
929
|
+
|
|
930
|
+
const segments: Array<string> = reference.inner.split(".");
|
|
931
|
+
// local . components . <id> . returnValues . model . <field...>
|
|
932
|
+
const fieldPath: Array<string> = segments.slice(5);
|
|
933
|
+
|
|
934
|
+
if (fieldPath.length === 0) {
|
|
935
|
+
continue;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
expect({
|
|
939
|
+
reference: reference.raw,
|
|
940
|
+
covered: selectCovers(select, fieldPath),
|
|
941
|
+
}).toEqual({ reference: reference.raw, covered: true });
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
test("every variable it declares is actually used by the graph", () => {
|
|
946
|
+
const used: Set<string> = new Set(
|
|
947
|
+
referencesOf(templateId)
|
|
948
|
+
.filter((reference: TemplateReference) => {
|
|
949
|
+
return reference.parsed.rootType === ReferenceRootType.LocalVariable;
|
|
950
|
+
})
|
|
951
|
+
.map((reference: TemplateReference) => {
|
|
952
|
+
return reference.parsed.variableName as string;
|
|
953
|
+
}),
|
|
954
|
+
);
|
|
955
|
+
|
|
956
|
+
for (const variable of template.variables) {
|
|
957
|
+
expect({
|
|
958
|
+
variable: variable.name,
|
|
959
|
+
used: used.has(variable.name),
|
|
960
|
+
}).toEqual({ variable: variable.name, used: true });
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
/*
|
|
965
|
+
* The inverse, and the more dangerous direction: a reference to a variable
|
|
966
|
+
* the wizard never asks for means no row is ever written for it, and the
|
|
967
|
+
* literal braces ship.
|
|
968
|
+
*/
|
|
969
|
+
test("every variable the graph references is declared by the template", () => {
|
|
970
|
+
const declared: Array<string> = template.variables.map(
|
|
971
|
+
(variable: WorkflowTemplateVariable) => {
|
|
972
|
+
return variable.name;
|
|
973
|
+
},
|
|
974
|
+
);
|
|
975
|
+
|
|
976
|
+
for (const reference of referencesOf(templateId)) {
|
|
977
|
+
if (reference.parsed.rootType !== ReferenceRootType.LocalVariable) {
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
expect({
|
|
982
|
+
reference: reference.raw,
|
|
983
|
+
declared: declared.includes(reference.parsed.variableName as string),
|
|
984
|
+
}).toEqual({ reference: reference.raw, declared: true });
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
|
|
988
|
+
/*
|
|
989
|
+
* The wizard only ever writes workflow-scoped variables, so a template
|
|
990
|
+
* reaching for a project-global one would silently find nothing.
|
|
991
|
+
*/
|
|
992
|
+
test("it does not reach for project-global variables", () => {
|
|
993
|
+
for (const reference of referencesOf(templateId)) {
|
|
994
|
+
expect(reference.parsed.rootType).not.toBe(
|
|
995
|
+
ReferenceRootType.GlobalVariable,
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
/*
|
|
1001
|
+
* An optional variable's reference must be the ENTIRE argument value. That
|
|
1002
|
+
* is what lets the wizard drop the argument when the field is left blank; a
|
|
1003
|
+
* reference embedded in a longer string would survive the strip and leave
|
|
1004
|
+
* the braces behind in the saved workflow.
|
|
1005
|
+
*/
|
|
1006
|
+
test("an optional variable's reference is the whole argument, so it can be dropped", () => {
|
|
1007
|
+
for (const variable of template.variables) {
|
|
1008
|
+
if (variable.required) {
|
|
1009
|
+
continue;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
1013
|
+
const token: string = `{{local.variables.${variable.name}}}`;
|
|
1014
|
+
|
|
1015
|
+
for (const node of spec.nodes) {
|
|
1016
|
+
for (const value of Object.values(node.args || {})) {
|
|
1017
|
+
if (typeof value !== "string" || !value.includes(token)) {
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
expect(value.trim()).toBe(token);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
test("passes the builder's own graph checks with no errors", () => {
|
|
1028
|
+
const result: WorkflowLintResult = lintWorkflowGraph(hydrate(templateId));
|
|
1029
|
+
|
|
1030
|
+
const errors: Array<WorkflowLintIssue> = result.issues.filter(
|
|
1031
|
+
(issue: WorkflowLintIssue) => {
|
|
1032
|
+
return issue.severity === WorkflowLintSeverity.Error;
|
|
1033
|
+
},
|
|
1034
|
+
);
|
|
1035
|
+
|
|
1036
|
+
expect(
|
|
1037
|
+
errors.map((issue: WorkflowLintIssue) => {
|
|
1038
|
+
return issue.message;
|
|
1039
|
+
}),
|
|
1040
|
+
).toEqual([]);
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
/*
|
|
1044
|
+
* Warnings too. UnreachableComponent is only a warning, so without this a
|
|
1045
|
+
* template could ship with a stray node that never runs and no test would
|
|
1046
|
+
* notice.
|
|
1047
|
+
*/
|
|
1048
|
+
test("passes the builder's own graph checks with no warnings either", () => {
|
|
1049
|
+
const result: WorkflowLintResult = lintWorkflowGraph(hydrate(templateId));
|
|
1050
|
+
|
|
1051
|
+
expect(
|
|
1052
|
+
result.issues.map((issue: WorkflowLintIssue) => {
|
|
1053
|
+
return issue.message;
|
|
1054
|
+
}),
|
|
1055
|
+
).toEqual([]);
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
/*
|
|
1059
|
+
* Two workflows created from one template must not share react-flow ids, or
|
|
1060
|
+
* editing one would be liable to disturb the other on import/export.
|
|
1061
|
+
*/
|
|
1062
|
+
test("builds fresh node ids each time", () => {
|
|
1063
|
+
const first: JSONObject = buildGraphForTemplate(
|
|
1064
|
+
templateId,
|
|
1065
|
+
generateId,
|
|
1066
|
+
) as JSONObject;
|
|
1067
|
+
const second: JSONObject = buildGraphForTemplate(
|
|
1068
|
+
templateId,
|
|
1069
|
+
generateId,
|
|
1070
|
+
) as JSONObject;
|
|
1071
|
+
|
|
1072
|
+
const firstIds: Array<string> = (first["nodes"] as Array<JSONObject>).map(
|
|
1073
|
+
(node: JSONObject) => {
|
|
1074
|
+
return node["id"] as string;
|
|
1075
|
+
},
|
|
1076
|
+
);
|
|
1077
|
+
const secondIds: Array<string> = (second["nodes"] as Array<JSONObject>).map(
|
|
1078
|
+
(node: JSONObject) => {
|
|
1079
|
+
return node["id"] as string;
|
|
1080
|
+
},
|
|
1081
|
+
);
|
|
1082
|
+
|
|
1083
|
+
for (const id of firstIds) {
|
|
1084
|
+
expect(secondIds).not.toContain(id);
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
test("builds fresh edge ids each time too", () => {
|
|
1089
|
+
type EdgeIdsFunction = (graph: JSONObject) => Array<string>;
|
|
1090
|
+
|
|
1091
|
+
const edgeIds: EdgeIdsFunction = (graph: JSONObject): Array<string> => {
|
|
1092
|
+
return (graph["edges"] as Array<JSONObject>).map((edge: JSONObject) => {
|
|
1093
|
+
return edge["id"] as string;
|
|
1094
|
+
});
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
const first: Array<string> = edgeIds(
|
|
1098
|
+
buildGraphForTemplate(templateId, generateId) as JSONObject,
|
|
1099
|
+
);
|
|
1100
|
+
const second: Array<string> = edgeIds(
|
|
1101
|
+
buildGraphForTemplate(templateId, generateId) as JSONObject,
|
|
1102
|
+
);
|
|
1103
|
+
|
|
1104
|
+
for (const id of first) {
|
|
1105
|
+
expect(second).not.toContain(id);
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
test("keeps stable component ids, because references point at them", () => {
|
|
1110
|
+
type ComponentIdsFunction = (graph: JSONObject) => Array<string>;
|
|
1111
|
+
|
|
1112
|
+
const componentIds: ComponentIdsFunction = (
|
|
1113
|
+
graph: JSONObject,
|
|
1114
|
+
): Array<string> => {
|
|
1115
|
+
return (graph["nodes"] as Array<JSONObject>).map((node: JSONObject) => {
|
|
1116
|
+
return (node["data"] as JSONObject)["id"] as string;
|
|
1117
|
+
});
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
expect(
|
|
1121
|
+
componentIds(buildGraphForTemplate(templateId, generateId) as JSONObject),
|
|
1122
|
+
).toEqual(
|
|
1123
|
+
componentIds(buildGraphForTemplate(templateId, generateId) as JSONObject),
|
|
1124
|
+
);
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
/*
|
|
1128
|
+
* A built graph gets edited afterwards — by the wizard stripping arguments
|
|
1129
|
+
* for blank optional variables, and by the builder. Sharing the argument
|
|
1130
|
+
* object with the shipped definition would let that editing leak into every
|
|
1131
|
+
* later workflow built in the same process.
|
|
1132
|
+
*/
|
|
1133
|
+
test("built graphs do not share argument objects with the definition", () => {
|
|
1134
|
+
const first: JSONObject = buildGraphForTemplate(
|
|
1135
|
+
templateId,
|
|
1136
|
+
generateId,
|
|
1137
|
+
) as JSONObject;
|
|
1138
|
+
const second: JSONObject = buildGraphForTemplate(
|
|
1139
|
+
templateId,
|
|
1140
|
+
generateId,
|
|
1141
|
+
) as JSONObject;
|
|
1142
|
+
|
|
1143
|
+
const argumentsOf: (graph: JSONObject, index: number) => JSONObject = (
|
|
1144
|
+
graph: JSONObject,
|
|
1145
|
+
index: number,
|
|
1146
|
+
): JSONObject => {
|
|
1147
|
+
const node: JSONObject = (graph["nodes"] as Array<JSONObject>)[
|
|
1148
|
+
index
|
|
1149
|
+
] as JSONObject;
|
|
1150
|
+
|
|
1151
|
+
return (node["data"] as JSONObject)["arguments"] as JSONObject;
|
|
1152
|
+
};
|
|
1153
|
+
|
|
1154
|
+
const firstArguments: JSONObject = argumentsOf(first, 0);
|
|
1155
|
+
|
|
1156
|
+
(firstArguments as JSONObject)["__scribbled"] = "yes";
|
|
1157
|
+
|
|
1158
|
+
expect(argumentsOf(second, 0)["__scribbled"]).toBeUndefined();
|
|
1159
|
+
expect(
|
|
1160
|
+
(specOf(templateId).nodes[0]?.args || {})["__scribbled"],
|
|
1161
|
+
).toBeUndefined();
|
|
1162
|
+
});
|
|
1163
|
+
|
|
1164
|
+
test("edges connect nodes that are in the graph", () => {
|
|
1165
|
+
const graph: JSONObject = buildGraphForTemplate(
|
|
1166
|
+
templateId,
|
|
1167
|
+
generateId,
|
|
1168
|
+
) as JSONObject;
|
|
1169
|
+
|
|
1170
|
+
const nodeIds: Array<string> = (graph["nodes"] as Array<JSONObject>).map(
|
|
1171
|
+
(node: JSONObject) => {
|
|
1172
|
+
return node["id"] as string;
|
|
1173
|
+
},
|
|
1174
|
+
);
|
|
1175
|
+
|
|
1176
|
+
for (const edge of graph["edges"] as Array<JSONObject>) {
|
|
1177
|
+
expect(nodeIds).toContain(edge["source"] as string);
|
|
1178
|
+
expect(nodeIds).toContain(edge["target"] as string);
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
test("every edge targets the in port, which is what react-flow attaches to", () => {
|
|
1183
|
+
const graph: JSONObject = buildGraphForTemplate(
|
|
1184
|
+
templateId,
|
|
1185
|
+
generateId,
|
|
1186
|
+
) as JSONObject;
|
|
1187
|
+
|
|
1188
|
+
for (const edge of graph["edges"] as Array<JSONObject>) {
|
|
1189
|
+
expect(edge["targetHandle"]).toBe("in");
|
|
1190
|
+
}
|
|
1191
|
+
});
|
|
1192
|
+
|
|
1193
|
+
test("every non-trigger node has an in port for that edge to land on", () => {
|
|
1194
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
1195
|
+
|
|
1196
|
+
const targeted: Set<string> = new Set(
|
|
1197
|
+
spec.edges.map((edge: TemplateEdgeSpec) => {
|
|
1198
|
+
return edge.toComponentId;
|
|
1199
|
+
}),
|
|
1200
|
+
);
|
|
1201
|
+
|
|
1202
|
+
for (const node of spec.nodes) {
|
|
1203
|
+
if (!targeted.has(node.componentId)) {
|
|
1204
|
+
continue;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
const metadata: ComponentMetadata = findMetadata(
|
|
1208
|
+
node.metadataId,
|
|
1209
|
+
) as ComponentMetadata;
|
|
1210
|
+
|
|
1211
|
+
expect(
|
|
1212
|
+
metadata.inPorts.map((port: Port) => {
|
|
1213
|
+
return port.id;
|
|
1214
|
+
}),
|
|
1215
|
+
).toContain("in");
|
|
1216
|
+
}
|
|
1217
|
+
});
|
|
1218
|
+
});
|