@oneuptime/common 12.0.8 → 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} +139 -9
- package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
- package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +8 -8
- 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/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/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/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 +20 -0
- package/Server/Infrastructure/Queue.ts +78 -13
- 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} +4 -4
- package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +89 -20
- 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/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/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 +25 -25
- package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
- 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/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/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/{TelemetryEntityManualCreate.test.ts → InventoryItemManualCreate.test.ts} +27 -27
- 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/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/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 +15 -15
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
- 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/Telemetry/EntityTypeGroups.test.ts +6 -6
- 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/TemplateSyntax.test.ts +112 -0
- package/Tests/Types/Workflow/Templates.test.ts +916 -101
- package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
- package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
- package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
- package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -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/Workflow/GraphLint.test.ts +72 -0
- package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +242 -7
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +15 -7
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +242 -28
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +59 -1
- 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/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/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/NetworkTopologyUtil.test.ts +487 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -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 +49 -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/Telemetry/EntityRelationshipType.ts +1 -1
- package/Types/Telemetry/EntitySource.ts +1 -1
- package/Types/Telemetry/EntityType.ts +1 -1
- package/Types/Telemetry/EntityTypeGroups.ts +1 -1
- package/Types/Workflow/Components/BaseModel.ts +75 -29
- 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/TemplateSyntax.ts +44 -0
- package/Types/Workflow/Templates.ts +2097 -45
- 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/Dictionary/Dictionary.tsx +48 -9
- package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
- package/UI/Components/Input/Input.tsx +1 -0
- 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/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/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/Workflow/ArgumentsForm.tsx +155 -9
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +10 -1
- 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 +42 -5
- package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +154 -22
- package/UI/Components/Workflow/ModelSchema.ts +115 -33
- package/UI/Components/Workflow/RunStatusWatcher.ts +1 -1
- package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
- package/UI/Components/Workflow/UseRunWatch.ts +212 -0
- package/UI/Components/Workflow/VariableModal.tsx +6 -2
- package/UI/Components/Workflow/Workflow.tsx +49 -3
- 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/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/NetworkTopologyUtil.ts +888 -164
- package/Utils/Telemetry/CrossSignalScope.ts +502 -0
- package/Utils/Telemetry/EntityKey.ts +5 -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} +167 -31
- 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} +27 -27
- 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/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/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/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 +20 -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/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} +6 -6
- package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +68 -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/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/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 +11 -11
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- 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/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/Telemetry/EntityRelationshipType.js +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +66 -28
- 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/TemplateSyntax.js +12 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -1
- package/build/dist/Types/Workflow/Templates.js +1931 -38
- package/build/dist/Types/Workflow/Templates.js.map +1 -1
- 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/Dictionary/Dictionary.js +25 -11
- 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/Header/HeaderIconDropdownButton.js +27 -4
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +1 -0
- 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/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/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/Workflow/ArgumentsForm.js +130 -12
- package/build/dist/UI/Components/Workflow/ArgumentsForm.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 +4 -4
- 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 +33 -4
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -1
- 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 +116 -21
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ModelSchema.js +72 -34
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
- 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/VariableModal.js +3 -2
- package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +41 -1
- 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/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/NetworkTopologyUtil.js +642 -136
- 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 +5 -5
- 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
|
@@ -10,15 +10,35 @@
|
|
|
10
10
|
* argument is "value" (not "log-message"), the Schedule trigger's is
|
|
11
11
|
* "schedule" (not "schedule-at"), the Manual trigger leaves by "success" and
|
|
12
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.
|
|
13
28
|
*/
|
|
14
29
|
|
|
15
30
|
import {
|
|
31
|
+
WORKFLOW_TEMPLATE_VARIABLE_NAME_REGEX,
|
|
16
32
|
WorkflowTemplate,
|
|
33
|
+
WorkflowTemplateCategories,
|
|
34
|
+
WorkflowTemplateCategory,
|
|
35
|
+
WorkflowTemplateVariable,
|
|
17
36
|
buildGraphForTemplate,
|
|
18
37
|
getTemplateGraphSpec,
|
|
38
|
+
getWorkflowTemplate,
|
|
19
39
|
getWorkflowTemplates,
|
|
40
|
+
getWorkflowTemplatesByCategory,
|
|
20
41
|
} from "../../../Types/Workflow/Templates";
|
|
21
|
-
import Components from "../../../Types/Workflow/Components";
|
|
22
42
|
import ComponentMetadata, {
|
|
23
43
|
Argument,
|
|
24
44
|
ComponentType,
|
|
@@ -26,7 +46,8 @@ import ComponentMetadata, {
|
|
|
26
46
|
Port,
|
|
27
47
|
ReturnValue,
|
|
28
48
|
} from "../../../Types/Workflow/Component";
|
|
29
|
-
import { JSONObject } from "../../../Types/JSON";
|
|
49
|
+
import { JSONObject, JSONValue } from "../../../Types/JSON";
|
|
50
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
30
51
|
import {
|
|
31
52
|
LintGraphEdge,
|
|
32
53
|
LintGraphNode,
|
|
@@ -35,10 +56,28 @@ import {
|
|
|
35
56
|
WorkflowLintSeverity,
|
|
36
57
|
lintWorkflowGraph,
|
|
37
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";
|
|
38
68
|
import { describe, expect, test } from "@jest/globals";
|
|
69
|
+
import ComponentID from "../../../Types/Workflow/ComponentID";
|
|
70
|
+
import CronTab from "../../../Utils/CronTab";
|
|
39
71
|
|
|
40
72
|
const templates: Array<WorkflowTemplate> = getWorkflowTemplates();
|
|
41
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
|
+
|
|
42
81
|
type FindMetadataFunction = (
|
|
43
82
|
metadataId: string,
|
|
44
83
|
) => ComponentMetadata | undefined;
|
|
@@ -46,7 +85,7 @@ type FindMetadataFunction = (
|
|
|
46
85
|
const findMetadata: FindMetadataFunction = (
|
|
47
86
|
metadataId: string,
|
|
48
87
|
): ComponentMetadata | undefined => {
|
|
49
|
-
return
|
|
88
|
+
return registry.find((component: ComponentMetadata) => {
|
|
50
89
|
return component.id === metadataId;
|
|
51
90
|
});
|
|
52
91
|
};
|
|
@@ -60,6 +99,30 @@ const generateId: GenerateIdFunction = (): string => {
|
|
|
60
99
|
return `generated-${idCounter}`;
|
|
61
100
|
};
|
|
62
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
|
+
|
|
63
126
|
/**
|
|
64
127
|
* Build a template's graph and hydrate each node with its real metadata, the
|
|
65
128
|
* way the builder does on load. Without the metadata the linter cannot check
|
|
@@ -110,9 +173,128 @@ const hydrate: HydrateFunction = (
|
|
|
110
173
|
return { nodes: nodes, edges: edges };
|
|
111
174
|
};
|
|
112
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
|
+
|
|
113
295
|
describe("workflow templates", () => {
|
|
114
|
-
test("there
|
|
115
|
-
expect(templates.length).toBeGreaterThan(
|
|
296
|
+
test("there are plenty to choose from", () => {
|
|
297
|
+
expect(templates.length).toBeGreaterThan(10);
|
|
116
298
|
});
|
|
117
299
|
|
|
118
300
|
test("each has a unique id", () => {
|
|
@@ -123,6 +305,20 @@ describe("workflow templates", () => {
|
|
|
123
305
|
expect(new Set(ids).size).toBe(ids.length);
|
|
124
306
|
});
|
|
125
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
|
+
|
|
126
322
|
test("each is described well enough to choose between them", () => {
|
|
127
323
|
for (const template of templates) {
|
|
128
324
|
expect(template.name.length).toBeGreaterThan(0);
|
|
@@ -133,35 +329,306 @@ describe("workflow templates", () => {
|
|
|
133
329
|
}
|
|
134
330
|
});
|
|
135
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
|
+
|
|
136
372
|
test("an unknown template id yields nothing rather than throwing", () => {
|
|
137
373
|
expect(getTemplateGraphSpec("does-not-exist")).toBeNull();
|
|
138
374
|
expect(buildGraphForTemplate("does-not-exist", generateId)).toBeNull();
|
|
139
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
|
+
});
|
|
140
599
|
});
|
|
141
600
|
|
|
142
601
|
describe.each(
|
|
143
602
|
templates.map((template: WorkflowTemplate) => {
|
|
144
603
|
return [template.id, template] as [string, WorkflowTemplate];
|
|
145
604
|
}),
|
|
146
|
-
)("template %s", (templateId: string) => {
|
|
605
|
+
)("template %s", (templateId: string, template: WorkflowTemplate) => {
|
|
147
606
|
test("every component it uses exists in the registry", () => {
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
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
|
+
});
|
|
151
614
|
|
|
152
|
-
|
|
153
|
-
|
|
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);
|
|
154
627
|
}
|
|
155
628
|
});
|
|
156
629
|
|
|
157
630
|
test("every argument it sets is a real argument on that component", () => {
|
|
158
|
-
const
|
|
159
|
-
nodes: Array<{ metadataId: string; args?: JSONObject | undefined }>;
|
|
160
|
-
} = getTemplateGraphSpec(templateId) as {
|
|
161
|
-
nodes: Array<{ metadataId: string; args?: JSONObject | undefined }>;
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
for (const node of spec.nodes) {
|
|
631
|
+
for (const node of specOf(templateId).nodes) {
|
|
165
632
|
const metadata: ComponentMetadata = findMetadata(
|
|
166
633
|
node.metadataId,
|
|
167
634
|
) as ComponentMetadata;
|
|
@@ -173,7 +640,31 @@ describe.each(
|
|
|
173
640
|
},
|
|
174
641
|
);
|
|
175
642
|
|
|
176
|
-
expect(
|
|
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);
|
|
177
668
|
}
|
|
178
669
|
}
|
|
179
670
|
});
|
|
@@ -184,20 +675,14 @@ describe.each(
|
|
|
184
675
|
* first step.
|
|
185
676
|
*/
|
|
186
677
|
test("every edge leaves a port the component actually has", () => {
|
|
187
|
-
const spec:
|
|
188
|
-
nodes: Array<{ componentId: string; metadataId: string }>;
|
|
189
|
-
edges: Array<{ fromComponentId: string; fromPort: string }>;
|
|
190
|
-
} = getTemplateGraphSpec(templateId) as {
|
|
191
|
-
nodes: Array<{ componentId: string; metadataId: string }>;
|
|
192
|
-
edges: Array<{ fromComponentId: string; fromPort: string }>;
|
|
193
|
-
};
|
|
678
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
194
679
|
|
|
195
680
|
for (const edge of spec.edges) {
|
|
196
|
-
const node:
|
|
197
|
-
(candidate:
|
|
681
|
+
const node: TemplateNodeSpec = spec.nodes.find(
|
|
682
|
+
(candidate: TemplateNodeSpec) => {
|
|
198
683
|
return candidate.componentId === edge.fromComponentId;
|
|
199
684
|
},
|
|
200
|
-
) as
|
|
685
|
+
) as TemplateNodeSpec;
|
|
201
686
|
|
|
202
687
|
const metadata: ComponentMetadata = findMetadata(
|
|
203
688
|
node.metadataId,
|
|
@@ -209,89 +694,336 @@ describe.each(
|
|
|
209
694
|
},
|
|
210
695
|
);
|
|
211
696
|
|
|
212
|
-
expect(
|
|
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
|
+
});
|
|
213
706
|
}
|
|
214
707
|
});
|
|
215
708
|
|
|
216
|
-
test("every
|
|
217
|
-
const spec:
|
|
218
|
-
nodes: Array<{ metadataId: string; args?: JSONObject | undefined }>;
|
|
219
|
-
} = getTemplateGraphSpec(templateId) as {
|
|
220
|
-
nodes: Array<{ metadataId: string; args?: JSONObject | undefined }>;
|
|
221
|
-
};
|
|
709
|
+
test("every fallible component handles its Error port", () => {
|
|
710
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
222
711
|
|
|
223
712
|
for (const node of spec.nodes) {
|
|
224
713
|
const metadata: ComponentMetadata = findMetadata(
|
|
225
714
|
node.metadataId,
|
|
226
715
|
) as ComponentMetadata;
|
|
716
|
+
const hasErrorPort: boolean = metadata.outPorts.some((port: Port) => {
|
|
717
|
+
return port.id === "error";
|
|
718
|
+
});
|
|
227
719
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
720
|
+
if (!hasErrorPort) {
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
232
723
|
|
|
233
|
-
|
|
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;
|
|
234
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
|
+
);
|
|
235
746
|
}
|
|
236
747
|
});
|
|
237
748
|
|
|
238
|
-
test("
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
};
|
|
749
|
+
test("schedule expressions are valid cron", () => {
|
|
750
|
+
for (const node of specOf(templateId).nodes) {
|
|
751
|
+
if (node.metadataId !== ComponentID.Schedule) {
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
244
754
|
|
|
245
|
-
|
|
246
|
-
|
|
755
|
+
expect(CronTab.isValid(node.args?.["schedule"] as string)).toBe(true);
|
|
756
|
+
}
|
|
757
|
+
});
|
|
247
758
|
|
|
248
|
-
|
|
759
|
+
test("every edge connects component ids the template declares", () => {
|
|
760
|
+
const spec: TemplateSpec = specOf(templateId);
|
|
249
761
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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;
|
|
255
816
|
|
|
256
|
-
|
|
257
|
-
|
|
817
|
+
if (node.componentType === ComponentType.Trigger) {
|
|
818
|
+
continue;
|
|
258
819
|
}
|
|
820
|
+
|
|
821
|
+
expect(metadata.componentType).not.toBe(ComponentType.Trigger);
|
|
259
822
|
}
|
|
823
|
+
});
|
|
260
824
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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
|
+
});
|
|
264
836
|
|
|
265
|
-
|
|
266
|
-
|
|
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
|
+
});
|
|
267
847
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
+
);
|
|
273
854
|
|
|
274
|
-
|
|
275
|
-
|
|
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;
|
|
276
881
|
|
|
277
882
|
const metadata: ComponentMetadata = findMetadata(
|
|
278
|
-
|
|
883
|
+
referenced.metadataId,
|
|
279
884
|
) as ComponentMetadata;
|
|
280
885
|
|
|
281
886
|
const returnValue: ReturnValue | undefined = metadata.returnValues.find(
|
|
282
887
|
(candidate: ReturnValue) => {
|
|
283
|
-
return candidate.id ===
|
|
888
|
+
return candidate.id === reference.parsed.returnValueId;
|
|
284
889
|
},
|
|
285
890
|
);
|
|
286
891
|
|
|
287
|
-
expect(
|
|
892
|
+
expect({
|
|
893
|
+
reference: reference.raw,
|
|
894
|
+
found: Boolean(returnValue),
|
|
895
|
+
}).toEqual({ reference: reference.raw, found: true });
|
|
288
896
|
}
|
|
289
897
|
});
|
|
290
898
|
|
|
291
899
|
/*
|
|
292
|
-
* The
|
|
293
|
-
*
|
|
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.
|
|
294
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
|
+
|
|
295
1027
|
test("passes the builder's own graph checks with no errors", () => {
|
|
296
1028
|
const result: WorkflowLintResult = lintWorkflowGraph(hydrate(templateId));
|
|
297
1029
|
|
|
@@ -308,26 +1040,19 @@ describe.each(
|
|
|
308
1040
|
).toEqual([]);
|
|
309
1041
|
});
|
|
310
1042
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const triggers: Array<{ metadataId: string }> = spec.nodes.filter(
|
|
319
|
-
(node: { componentType: ComponentType }) => {
|
|
320
|
-
return node.componentType === ComponentType.Trigger;
|
|
321
|
-
},
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
expect(triggers).toHaveLength(1);
|
|
325
|
-
|
|
326
|
-
const metadata: ComponentMetadata = findMetadata(
|
|
327
|
-
triggers[0]?.metadataId as string,
|
|
328
|
-
) as ComponentMetadata;
|
|
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));
|
|
329
1050
|
|
|
330
|
-
expect(
|
|
1051
|
+
expect(
|
|
1052
|
+
result.issues.map((issue: WorkflowLintIssue) => {
|
|
1053
|
+
return issue.message;
|
|
1054
|
+
}),
|
|
1055
|
+
).toEqual([]);
|
|
331
1056
|
});
|
|
332
1057
|
|
|
333
1058
|
/*
|
|
@@ -360,7 +1085,52 @@ describe.each(
|
|
|
360
1085
|
}
|
|
361
1086
|
});
|
|
362
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
|
+
|
|
363
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", () => {
|
|
364
1134
|
const first: JSONObject = buildGraphForTemplate(
|
|
365
1135
|
templateId,
|
|
366
1136
|
generateId,
|
|
@@ -370,17 +1140,25 @@ describe.each(
|
|
|
370
1140
|
generateId,
|
|
371
1141
|
) as JSONObject;
|
|
372
1142
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const componentIds: ComponentIdsFunction = (
|
|
1143
|
+
const argumentsOf: (graph: JSONObject, index: number) => JSONObject = (
|
|
376
1144
|
graph: JSONObject,
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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;
|
|
381
1152
|
};
|
|
382
1153
|
|
|
383
|
-
|
|
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();
|
|
384
1162
|
});
|
|
385
1163
|
|
|
386
1164
|
test("edges connect nodes that are in the graph", () => {
|
|
@@ -400,4 +1178,41 @@ describe.each(
|
|
|
400
1178
|
expect(nodeIds).toContain(edge["target"] as string);
|
|
401
1179
|
}
|
|
402
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
|
+
});
|
|
403
1218
|
});
|