@oneuptime/common 12.0.6 → 12.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AIInsight.ts +1 -1
- package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
- package/Models/DatabaseModels/DeletedProject.ts +595 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Monitor.ts +111 -0
- package/Models/DatabaseModels/Project.ts +3 -3
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
- package/Server/API/FileAPI.ts +15 -2
- package/Server/API/MicrosoftTeamsAPI.ts +6 -1
- package/Server/API/ProjectAPI.ts +214 -0
- package/Server/API/StatusPageAPI.ts +39 -6
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Services/AIAgentService.ts +20 -0
- package/Server/Services/DashboardDomainService.ts +73 -28
- package/Server/Services/DatabaseService.ts +1 -0
- package/Server/Services/DeletedProjectService.ts +138 -0
- package/Server/Services/FileService.ts +61 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
- package/Server/Services/IncidentPublicNoteService.ts +18 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +311 -0
- package/Server/Services/ProbeService.ts +20 -0
- package/Server/Services/ProjectService.ts +297 -1
- package/Server/Services/PushNotificationService.ts +71 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
- package/Server/Services/StatusPageAnnouncementService.ts +53 -0
- package/Server/Services/StatusPageDomainService.ts +73 -28
- package/Server/Services/TeamMemberService.ts +117 -12
- package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
- package/Server/Services/UserWebhookService.ts +34 -109
- package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
- package/Server/Types/Database/DeleteById.ts +2 -0
- package/Server/Types/Database/DeleteOneBy.ts +6 -0
- package/Server/Types/Domain.ts +41 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
- package/Server/Types/Workflow/Components/API/Get.ts +2 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
- package/Server/Types/Workflow/Components/API/Post.ts +2 -1
- package/Server/Types/Workflow/Components/API/Put.ts +2 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +41 -2
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
- package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
- package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
- package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
- package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
- package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
- package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
- package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
- package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
- package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
- package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
- package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
- package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
- package/Server/Utils/DataSource/EgressGuard.ts +176 -16
- package/Server/Utils/DataSource/HttpFetch.ts +6 -45
- package/Server/Utils/Execute.ts +8 -0
- package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
- package/Server/Utils/LLM/LLMService.ts +57 -12
- package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
- package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
- package/Server/Utils/Monitor/MonitorResource.ts +36 -0
- package/Server/Utils/Response.ts +142 -6
- package/Server/Utils/SSRFProtection.ts +273 -60
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/VM/VMRunner.ts +88 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
- package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
- package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
- package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
- package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
- package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
- package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
- package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
- package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
- package/Tests/Server/API/ProjectAPI.test.ts +299 -1
- package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
- package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
- package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
- package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
- package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
- package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
- package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
- package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
- package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
- package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
- package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
- package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
- package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
- package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
- package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
- package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
- package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
- package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
- package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
- package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
- package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
- package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
- package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
- package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
- package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
- package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
- package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
- package/Tests/Types/JSONFunctions.test.ts +252 -1
- package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
- package/Tests/UI/Components/404.test.tsx +1 -1
- package/Tests/UI/Components/Alert.test.tsx +1 -1
- package/Tests/UI/Components/Badge.test.tsx +1 -1
- package/Tests/UI/Components/BasicForm.test.tsx +39 -10
- package/Tests/UI/Components/Button.test.tsx +1 -1
- package/Tests/UI/Components/Card.test.tsx +1 -1
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
- package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
- package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
- package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
- package/Tests/UI/Components/Dropdown.test.tsx +1 -1
- package/Tests/UI/Components/FilePicker.test.tsx +1 -1
- package/Tests/UI/Components/HiddenText.test.tsx +1 -1
- package/Tests/UI/Components/Input.test.tsx +1 -1
- package/Tests/UI/Components/Loader.test.tsx +1 -1
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +1 -1
- package/Tests/UI/Components/MasterPage.test.tsx +1 -1
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +489 -0
- package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
- package/Tests/UI/Components/NavBar.test.tsx +1 -1
- package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
- package/Tests/UI/Components/Pagination.test.tsx +1 -1
- package/Tests/UI/Components/Pill.test.tsx +1 -1
- package/Tests/UI/Components/Probe.test.tsx +1 -1
- package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
- package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
- package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
- package/Tests/UI/Components/SideOver.test.tsx +500 -6
- package/Tests/UI/Components/Tabs.test.tsx +1 -1
- package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +1 -1
- package/Tests/UI/Components/TextArea.test.tsx +1 -1
- package/Tests/UI/Components/Toast.test.tsx +1 -1
- package/Tests/UI/Components/Toggle.test.tsx +1 -1
- package/Tests/UI/Components/TopSection.test.tsx +1 -1
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
- package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
- package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
- package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
- package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
- package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
- package/Tests/Utils/Realtime.test.ts +78 -0
- package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
- package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
- package/Types/AI/FixPullRequestCiStatus.ts +1 -1
- package/Types/AI/FixVerificationStatus.ts +2 -2
- package/Types/API/Hostname.ts +92 -4
- package/Types/API/URL.ts +43 -25
- package/Types/Billing/BalanceAdjustmentType.ts +14 -0
- package/Types/Billing/ProjectBalanceType.ts +13 -0
- package/Types/Domain.ts +26 -0
- package/Types/File/MimeType.ts +11 -0
- package/Types/JSONFunctions.ts +15 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
- package/Types/Workflow/Components/BaseModel.ts +92 -28
- package/Typings/Index.d.ts +12 -0
- package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
- package/UI/Components/Modal/ConfirmModal.tsx +10 -5
- package/UI/Components/Modal/Modal.tsx +27 -47
- package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
- package/UI/Components/SideOver/SideOver.tsx +195 -68
- package/UI/Utils/PageScrollLock.ts +66 -0
- package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
- package/Utils/Dashboard/VariableInterpolation.ts +19 -1
- package/Utils/LegacySerializedArray.ts +60 -0
- package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
- package/Utils/Telemetry/SavedViewFilters.ts +88 -0
- package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
- package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
- package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +3 -3
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/FileAPI.js +14 -2
- package/build/dist/Server/API/FileAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +157 -4
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +27 -3
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +17 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +55 -18
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +1 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DeletedProjectService.js +124 -0
- package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
- package/build/dist/Server/Services/FileService.js +52 -0
- package/build/dist/Server/Services/FileService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +232 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +17 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +228 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +56 -0
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
- package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
- package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +97 -6
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +31 -87
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Domain.js +37 -0
- package/build/dist/Server/Types/Domain.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +35 -2
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/Execute.js +2 -2
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +112 -5
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +219 -53
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
- package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
- package/build/dist/Types/API/Hostname.js +73 -4
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/API/URL.js +42 -24
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
- package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
- package/build/dist/Types/Domain.js +22 -0
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +11 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +14 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +83 -28
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +24 -34
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +52 -0
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
- package/build/dist/Utils/LegacySerializedArray.js +51 -0
- package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
- package/jest.config.json +3 -0
- package/package.json +1 -1
- package/tsconfig.json +3 -1
package/Types/API/Hostname.ts
CHANGED
|
@@ -5,6 +5,27 @@ import Port from "../Port";
|
|
|
5
5
|
import Typeof from "../Typeof";
|
|
6
6
|
import { FindOperator } from "typeorm";
|
|
7
7
|
|
|
8
|
+
/*
|
|
9
|
+
* A chain of DNS labels (which also covers IPv4 literals). Labels are
|
|
10
|
+
* alphanumeric plus "-" and "_", may not start or end with "-", and are
|
|
11
|
+
* capped at 63 characters; a single trailing dot (the fully-qualified form)
|
|
12
|
+
* is allowed. "_" is permitted because internal and service-discovery names
|
|
13
|
+
* use it and it is not a URL delimiter.
|
|
14
|
+
*/
|
|
15
|
+
const HOST_REGEX: RegExp =
|
|
16
|
+
/^[a-zA-Z0-9_](?:[a-zA-Z0-9_-]{0,61}[a-zA-Z0-9_])?(?:\.[a-zA-Z0-9_](?:[a-zA-Z0-9_-]{0,61}[a-zA-Z0-9_])?)*\.?$/;
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* Anything that is not a URL delimiter. The point is not to validate
|
|
20
|
+
* credentials, it is to make sure userinfo cannot smuggle a path, a query, a
|
|
21
|
+
* fragment or a second authority past the host check.
|
|
22
|
+
*/
|
|
23
|
+
const USER_INFO_REGEX: RegExp = /^[^@/?#\s[\]]*$/;
|
|
24
|
+
|
|
25
|
+
const IPV6_CHARS_REGEX: RegExp = /^[0-9a-fA-F:.]+$/;
|
|
26
|
+
|
|
27
|
+
const PORT_REGEX: RegExp = /^\d{1,5}$/;
|
|
28
|
+
|
|
8
29
|
export default class Hostname extends DatabaseProperty {
|
|
9
30
|
private _route: string = "";
|
|
10
31
|
public get hostname(): string {
|
|
@@ -31,13 +52,80 @@ export default class Hostname extends DatabaseProperty {
|
|
|
31
52
|
}
|
|
32
53
|
}
|
|
33
54
|
|
|
55
|
+
/*
|
|
56
|
+
* True when the value is a usable authority: an optional "userinfo@"
|
|
57
|
+
* prefix, a host (DNS name, IPv4, or IPv6 literal) and an optional ":port".
|
|
58
|
+
*
|
|
59
|
+
* The old check was a character allowlist that permitted "/", "?", "#" and
|
|
60
|
+
* "@" anywhere, which made "169.254.169.254/latest/meta-data/#" a valid
|
|
61
|
+
* Hostname. Anything that stores a Hostname and later interpolates it into
|
|
62
|
+
* a URL therefore inherited full control of the host, port and path of the
|
|
63
|
+
* resulting request. Structure, not a charset, is what rules that out.
|
|
64
|
+
*
|
|
65
|
+
* Userinfo is still accepted because "https://user:token@host/path" is a
|
|
66
|
+
* real thing customers put in webhook URLs, and those values are already in
|
|
67
|
+
* the database — rejecting them here would fail on read, not just on write.
|
|
68
|
+
* Callers that need the bare host must not split this string themselves;
|
|
69
|
+
* SSRFProtection.getBareHostname exists for that.
|
|
70
|
+
*/
|
|
34
71
|
public static isValid(value: string): boolean {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
72
|
+
const authorityWithUserInfo: string = value.trim();
|
|
73
|
+
|
|
74
|
+
/*
|
|
75
|
+
* 253 for a DNS name, plus room for ":65535" and a userinfo prefix.
|
|
76
|
+
* A bound here also keeps the label regex from being handed something
|
|
77
|
+
* pathological.
|
|
78
|
+
*/
|
|
79
|
+
if (!authorityWithUserInfo || authorityWithUserInfo.length > 512) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/*
|
|
84
|
+
* Split on the LAST "@": userinfo may itself contain "@" percent-encoded
|
|
85
|
+
* or not, and everything after the final one is the authority.
|
|
86
|
+
*/
|
|
87
|
+
const atIndex: number = authorityWithUserInfo.lastIndexOf("@");
|
|
88
|
+
|
|
89
|
+
if (atIndex !== -1) {
|
|
90
|
+
const userInfo: string = authorityWithUserInfo.substring(0, atIndex);
|
|
91
|
+
if (!USER_INFO_REGEX.test(userInfo)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const authority: string = authorityWithUserInfo.substring(atIndex + 1);
|
|
97
|
+
|
|
98
|
+
if (!authority) {
|
|
38
99
|
return false;
|
|
39
100
|
}
|
|
40
|
-
|
|
101
|
+
|
|
102
|
+
// Bracketed IPv6, with or without a port: "[::1]", "[::1]:8080".
|
|
103
|
+
const bracketedIpv6Match: RegExpMatchArray | null = authority.match(
|
|
104
|
+
/^\[([0-9a-fA-F:.]+)\](?::(\d{1,5}))?$/,
|
|
105
|
+
);
|
|
106
|
+
if (bracketedIpv6Match) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* Unbracketed IPv6 literal. Two or more colons cannot be a "host:port",
|
|
112
|
+
* so the colons must be part of the address itself.
|
|
113
|
+
*/
|
|
114
|
+
if ((authority.match(/:/g) || []).length > 1) {
|
|
115
|
+
return IPV6_CHARS_REGEX.test(authority);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const colonIndex: number = authority.indexOf(":");
|
|
119
|
+
const host: string =
|
|
120
|
+
colonIndex === -1 ? authority : authority.substring(0, colonIndex);
|
|
121
|
+
const port: string =
|
|
122
|
+
colonIndex === -1 ? "" : authority.substring(colonIndex + 1);
|
|
123
|
+
|
|
124
|
+
if (colonIndex !== -1 && !PORT_REGEX.test(port)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return HOST_REGEX.test(host);
|
|
41
129
|
}
|
|
42
130
|
|
|
43
131
|
public constructor(hostname: string, port?: Port | string | number) {
|
package/Types/API/URL.ts
CHANGED
|
@@ -131,37 +131,55 @@ export default class URL extends DatabaseProperty {
|
|
|
131
131
|
public static fromString(url: string): URL {
|
|
132
132
|
let protocol: Protocol = Protocol.HTTPS;
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
134
|
+
/*
|
|
135
|
+
* Schemes are case-insensitive (RFC 3986), so match on a lower-cased
|
|
136
|
+
* copy and strip by length. Matching the literal prefix left "HTTPS://"
|
|
137
|
+
* in place, which then read as an authority of "HTTPS:".
|
|
138
|
+
*
|
|
139
|
+
* Longest-first: "https://" has to be tested before "http://", and only
|
|
140
|
+
* the first match is stripped.
|
|
141
|
+
*/
|
|
142
|
+
const schemePrefixes: Array<[string, Protocol]> = [
|
|
143
|
+
["https://", Protocol.HTTPS],
|
|
144
|
+
["http://", Protocol.HTTP],
|
|
145
|
+
["wss://", Protocol.WSS],
|
|
146
|
+
["ws://", Protocol.WS],
|
|
147
|
+
["mongodb://", Protocol.MONGO_DB],
|
|
148
|
+
["mailto:", Protocol.MAIL],
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
const lowerCasedUrl: string = url.toLowerCase();
|
|
152
|
+
|
|
153
|
+
for (const [prefix, prefixProtocol] of schemePrefixes) {
|
|
154
|
+
if (lowerCasedUrl.startsWith(prefix)) {
|
|
155
|
+
protocol = prefixProtocol;
|
|
156
|
+
url = url.substring(prefix.length);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
147
159
|
}
|
|
148
160
|
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
161
|
+
if (protocol === Protocol.MAIL) {
|
|
162
|
+
/*
|
|
163
|
+
* Hand the bare address to the constructor so it is recognised as an
|
|
164
|
+
* Email. Routing it through Hostname instead would ask a host validator
|
|
165
|
+
* to accept an email address — and "?subject=..." along with it.
|
|
166
|
+
*/
|
|
167
|
+
const address: string = url.split("?")[0] || "";
|
|
168
|
+
const mailQueryString: string = url.split("?")[1] || "";
|
|
153
169
|
|
|
154
|
-
|
|
155
|
-
protocol = Protocol.MONGO_DB;
|
|
156
|
-
url = url.replace("mongodb://", "");
|
|
170
|
+
return new URL(protocol, address, undefined, mailQueryString);
|
|
157
171
|
}
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
/*
|
|
174
|
+
* The authority ends at the first "/", "?" or "#". Splitting on "/" alone
|
|
175
|
+
* left the query and fragment glued to the host for URLs with no path
|
|
176
|
+
* ("https://host?token=x" parsed to a host of "host?token=x"), which both
|
|
177
|
+
* round-tripped wrong and handed anything that later interpolated the
|
|
178
|
+
* host a way to smuggle a path.
|
|
179
|
+
*/
|
|
180
|
+
const authority: string = (url.split("/")[0] || "").split(/[?#]/)[0] || "";
|
|
163
181
|
|
|
164
|
-
const hostname: Hostname = new Hostname(
|
|
182
|
+
const hostname: Hostname = new Hostname(authority);
|
|
165
183
|
|
|
166
184
|
let route: Route | undefined;
|
|
167
185
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* How a manual balance adjustment is applied. Add and Deduct are relative and
|
|
3
|
+
* land as a single atomic SQL delta, so they cannot lose a usage charge that
|
|
4
|
+
* is being written at the same moment. Set is absolute - last writer wins -
|
|
5
|
+
* and is only there for the case where staff need the balance to read a
|
|
6
|
+
* specific number regardless of what it holds now.
|
|
7
|
+
*/
|
|
8
|
+
enum BalanceAdjustmentType {
|
|
9
|
+
Add = "Add",
|
|
10
|
+
Deduct = "Deduct",
|
|
11
|
+
Set = "Set",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default BalanceAdjustmentType;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The prepaid balances a project carries. Each one maps to its own column on
|
|
3
|
+
* the project and is drawn down by a different kind of usage, so they are
|
|
4
|
+
* topped up and corrected independently.
|
|
5
|
+
*/
|
|
6
|
+
enum ProjectBalanceType {
|
|
7
|
+
// Drawn down by SMS, voice calls, WhatsApp messages and incoming numbers.
|
|
8
|
+
SmsOrCall = "SmsOrCall",
|
|
9
|
+
// Drawn down by LLM spend - AI agents, investigations and code fixes.
|
|
10
|
+
AI = "AI",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default ProjectBalanceType;
|
package/Types/Domain.ts
CHANGED
|
@@ -67,6 +67,32 @@ export default class Domain extends DatabaseProperty {
|
|
|
67
67
|
return domainRegex.test(domain);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Validates a subdomain: one or more DNS labels, no scheme, no port, no
|
|
72
|
+
* path, no userinfo.
|
|
73
|
+
*
|
|
74
|
+
* This is a security control, not a nicety. A subdomain is concatenated
|
|
75
|
+
* with a verified base domain to build fullDomain, and fullDomain is
|
|
76
|
+
* interpolated into a URL that the certificate-provisioning cron fetches
|
|
77
|
+
* unattended. URL parsing takes everything before the first "/" as the
|
|
78
|
+
* host, so a subdomain of "169.254.169.254/latest/meta-data/#" yields a URL
|
|
79
|
+
* whose host, port and path are all attacker-chosen. Restricting the value
|
|
80
|
+
* to DNS labels removes the ability to smuggle any of those.
|
|
81
|
+
*
|
|
82
|
+
* The empty string is NOT valid here: callers use "" (or "@") to mean the
|
|
83
|
+
* apex and must check for that before calling.
|
|
84
|
+
*/
|
|
85
|
+
public static isValidSubdomain(subdomain: string): boolean {
|
|
86
|
+
if (!subdomain || subdomain.length > 253) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const subdomainRegex: RegExp =
|
|
91
|
+
/^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
92
|
+
|
|
93
|
+
return subdomainRegex.test(subdomain);
|
|
94
|
+
}
|
|
95
|
+
|
|
70
96
|
public constructor(domain: string) {
|
|
71
97
|
super();
|
|
72
98
|
this.domain = domain;
|
package/Types/File/MimeType.ts
CHANGED
|
@@ -8,6 +8,17 @@ enum MimeType {
|
|
|
8
8
|
svg = "image/svg+xml",
|
|
9
9
|
gif = "image/gif",
|
|
10
10
|
webp = "image/webp",
|
|
11
|
+
/*
|
|
12
|
+
* Raster formats a browser or an API client can legitimately report but the
|
|
13
|
+
* file picker never names. Listed so those uploads are not rejected outright
|
|
14
|
+
* now that FileService validates fileType against this enum, and so rows
|
|
15
|
+
* written before the picker normalised types are still servable.
|
|
16
|
+
*/
|
|
17
|
+
ico = "image/x-icon",
|
|
18
|
+
bmp = "image/bmp",
|
|
19
|
+
tiff = "image/tiff",
|
|
20
|
+
avif = "image/avif",
|
|
21
|
+
heic = "image/heic",
|
|
11
22
|
pdf = "application/pdf",
|
|
12
23
|
doc = "application/msword",
|
|
13
24
|
docx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
package/Types/JSONFunctions.ts
CHANGED
|
@@ -297,6 +297,21 @@ export default class JSONFunctions {
|
|
|
297
297
|
Object.keys(ObjectType).includes((val as JSONObject)["_type"] as string)
|
|
298
298
|
) {
|
|
299
299
|
return val;
|
|
300
|
+
} else if (Array.isArray(val)) {
|
|
301
|
+
/*
|
|
302
|
+
* This has to be checked before the plain-object branch below: arrays are
|
|
303
|
+
* typeof "object", so falling through to serialize() would walk them by
|
|
304
|
+
* key and hand back { "0": ..., "1": ... } instead of an array. That
|
|
305
|
+
* silently corrupts every nested array persisted into a JSON column —
|
|
306
|
+
* e.g. the [facetKey, value] filter tuples of a telemetry saved view.
|
|
307
|
+
*/
|
|
308
|
+
const arr: Array<JSONValue> = [];
|
|
309
|
+
|
|
310
|
+
for (const v of val) {
|
|
311
|
+
arr.push(this.serializeValue(v));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return arr;
|
|
300
315
|
} else if (typeof val === Typeof.Object) {
|
|
301
316
|
return this.serialize(val as JSONObject);
|
|
302
317
|
}
|
|
@@ -19,7 +19,15 @@ export interface TelemetrySavedViewTimeRange {
|
|
|
19
19
|
export default interface TelemetrySavedViewState {
|
|
20
20
|
// Submitted search string from the explorer search bar.
|
|
21
21
|
search?: string | undefined;
|
|
22
|
-
|
|
22
|
+
/*
|
|
23
|
+
* Active facet filters as [facetKey, value] tuples.
|
|
24
|
+
*
|
|
25
|
+
* Read these with readSavedViewFilters (Common/Utils/Telemetry/
|
|
26
|
+
* SavedViewFilters) rather than destructuring them. Rows written before
|
|
27
|
+
* JSONFunctions.serializeValue learned to preserve nested arrays hold
|
|
28
|
+
* { "0": facetKey, "1": value } instead, and destructuring one of those
|
|
29
|
+
* throws — which is what this type asserting otherwise once cost us.
|
|
30
|
+
*/
|
|
23
31
|
filters?: Array<[string, string]> | undefined;
|
|
24
32
|
// Selected time range.
|
|
25
33
|
timeRange?: TelemetrySavedViewTimeRange | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
2
|
+
import Route from "../../API/Route";
|
|
2
3
|
import IconProp from "../../Icon/IconProp";
|
|
3
4
|
import Text from "../../Text";
|
|
4
5
|
import ComponentMetadata, {
|
|
@@ -14,6 +15,29 @@ export default class BaseModelComponent {
|
|
|
14
15
|
return [];
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
/*
|
|
19
|
+
* Every one of these arguments is keyed on column names, and the single
|
|
20
|
+
* most common way to get one wrong is to write "id" - which is what an ID
|
|
21
|
+
* is called everywhere else in the product - when the column is "_id".
|
|
22
|
+
* Both spellings work now, but the hint has to say so where the builder is
|
|
23
|
+
* actually typing, because the Query argument is a bare JSON editor with
|
|
24
|
+
* no field picker behind it.
|
|
25
|
+
*/
|
|
26
|
+
const columnHint: string = `Keys are column names on ${model.singularName}. The ID column is "_id" (the "id" spelling is accepted too).`;
|
|
27
|
+
|
|
28
|
+
const queryDescription: string = `Query that selects which ${model.pluralName} this component acts on. ${columnHint}`;
|
|
29
|
+
|
|
30
|
+
const queryPlaceholder: string =
|
|
31
|
+
'Example: {"_id": "00000000-0000-0000-0000-000000000000"}';
|
|
32
|
+
|
|
33
|
+
const selectPlaceholder: string = 'Example: {"_id": true, "name": true}';
|
|
34
|
+
|
|
35
|
+
const dataDescription: string = `${model.singularName} fields to write, as a JSON object. ${columnHint}`;
|
|
36
|
+
|
|
37
|
+
const documentationLink: Route = Route.fromString(
|
|
38
|
+
"/workflow/docs/DatabaseComponents.md",
|
|
39
|
+
);
|
|
40
|
+
|
|
17
41
|
if (model.enableWorkflowOn.read) {
|
|
18
42
|
components.push({
|
|
19
43
|
id: `${Text.pascalCaseToDashes(model.tableName!)}-find-one`,
|
|
@@ -23,22 +47,23 @@ export default class BaseModelComponent {
|
|
|
23
47
|
iconProp: IconProp.ArrowCircleDown,
|
|
24
48
|
tableName: model.tableName!,
|
|
25
49
|
componentType: ComponentType.Component,
|
|
50
|
+
documentationLink: documentationLink,
|
|
26
51
|
arguments: [
|
|
27
52
|
{
|
|
28
53
|
type: ComponentInputType.Query,
|
|
29
54
|
name: "Query",
|
|
30
|
-
description:
|
|
55
|
+
description: queryDescription,
|
|
31
56
|
required: true,
|
|
32
57
|
id: "query",
|
|
33
|
-
placeholder:
|
|
58
|
+
placeholder: queryPlaceholder,
|
|
34
59
|
},
|
|
35
60
|
{
|
|
36
61
|
type: ComponentInputType.Select,
|
|
37
62
|
name: "Select Fields",
|
|
38
|
-
description: `
|
|
63
|
+
description: `Fields to read from ${model.singularName}. ${columnHint}`,
|
|
39
64
|
required: true,
|
|
40
65
|
id: "select",
|
|
41
|
-
placeholder:
|
|
66
|
+
placeholder: selectPlaceholder,
|
|
42
67
|
},
|
|
43
68
|
],
|
|
44
69
|
returnValues: [
|
|
@@ -82,22 +107,23 @@ export default class BaseModelComponent {
|
|
|
82
107
|
iconProp: IconProp.ArrowCircleDown,
|
|
83
108
|
tableName: model.tableName!,
|
|
84
109
|
componentType: ComponentType.Component,
|
|
110
|
+
documentationLink: documentationLink,
|
|
85
111
|
arguments: [
|
|
86
112
|
{
|
|
87
113
|
type: ComponentInputType.Query,
|
|
88
114
|
name: "Query",
|
|
89
|
-
description:
|
|
115
|
+
description: queryDescription,
|
|
90
116
|
required: true,
|
|
91
117
|
id: "query",
|
|
92
|
-
placeholder:
|
|
118
|
+
placeholder: queryPlaceholder,
|
|
93
119
|
},
|
|
94
120
|
{
|
|
95
121
|
type: ComponentInputType.Select,
|
|
96
122
|
name: "Select Fields",
|
|
97
|
-
description: `
|
|
123
|
+
description: `Fields to read from ${model.singularName}. ${columnHint}`,
|
|
98
124
|
required: true,
|
|
99
125
|
id: "select",
|
|
100
|
-
placeholder:
|
|
126
|
+
placeholder: selectPlaceholder,
|
|
101
127
|
},
|
|
102
128
|
{
|
|
103
129
|
type: ComponentInputType.Number,
|
|
@@ -196,17 +222,26 @@ export default class BaseModelComponent {
|
|
|
196
222
|
iconProp: IconProp.Trash,
|
|
197
223
|
tableName: model.tableName!,
|
|
198
224
|
componentType: ComponentType.Component,
|
|
225
|
+
documentationLink: documentationLink,
|
|
199
226
|
arguments: [
|
|
200
227
|
{
|
|
201
228
|
type: ComponentInputType.Query,
|
|
202
229
|
name: "Delete by",
|
|
203
|
-
description:
|
|
230
|
+
description: queryDescription,
|
|
204
231
|
required: true,
|
|
205
232
|
id: "query",
|
|
206
|
-
placeholder:
|
|
233
|
+
placeholder: queryPlaceholder,
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
returnValues: [
|
|
237
|
+
{
|
|
238
|
+
id: "items-deleted",
|
|
239
|
+
name: "Items Deleted",
|
|
240
|
+
description: `How many ${model.pluralName} the query matched and deleted. Zero is not an error - it means nothing matched.`,
|
|
241
|
+
type: ComponentInputType.Number,
|
|
242
|
+
required: false,
|
|
207
243
|
},
|
|
208
244
|
],
|
|
209
|
-
returnValues: [],
|
|
210
245
|
inPorts: [
|
|
211
246
|
{
|
|
212
247
|
title: "In",
|
|
@@ -239,14 +274,15 @@ export default class BaseModelComponent {
|
|
|
239
274
|
iconProp: IconProp.Trash,
|
|
240
275
|
tableName: model.tableName!,
|
|
241
276
|
componentType: ComponentType.Component,
|
|
277
|
+
documentationLink: documentationLink,
|
|
242
278
|
arguments: [
|
|
243
279
|
{
|
|
244
280
|
type: ComponentInputType.Query,
|
|
245
281
|
name: "Delete by",
|
|
246
|
-
description:
|
|
282
|
+
description: queryDescription,
|
|
247
283
|
required: true,
|
|
248
284
|
id: "query",
|
|
249
|
-
placeholder:
|
|
285
|
+
placeholder: queryPlaceholder,
|
|
250
286
|
},
|
|
251
287
|
{
|
|
252
288
|
type: ComponentInputType.Number,
|
|
@@ -263,7 +299,15 @@ export default class BaseModelComponent {
|
|
|
263
299
|
id: "limit",
|
|
264
300
|
},
|
|
265
301
|
],
|
|
266
|
-
returnValues: [
|
|
302
|
+
returnValues: [
|
|
303
|
+
{
|
|
304
|
+
id: "items-deleted",
|
|
305
|
+
name: "Items Deleted",
|
|
306
|
+
description: `How many ${model.pluralName} the query matched and deleted. Zero is not an error - it means nothing matched.`,
|
|
307
|
+
type: ComponentInputType.Number,
|
|
308
|
+
required: false,
|
|
309
|
+
},
|
|
310
|
+
],
|
|
267
311
|
inPorts: [
|
|
268
312
|
{
|
|
269
313
|
title: "In",
|
|
@@ -312,10 +356,10 @@ export default class BaseModelComponent {
|
|
|
312
356
|
{
|
|
313
357
|
type: ComponentInputType.Select,
|
|
314
358
|
name: "Select Fields",
|
|
315
|
-
description: `
|
|
359
|
+
description: `Fields to read from ${model.singularName}. ${columnHint}`,
|
|
316
360
|
required: true,
|
|
317
361
|
id: "select",
|
|
318
|
-
placeholder:
|
|
362
|
+
placeholder: selectPlaceholder,
|
|
319
363
|
},
|
|
320
364
|
],
|
|
321
365
|
returnValues: [
|
|
@@ -346,12 +390,13 @@ export default class BaseModelComponent {
|
|
|
346
390
|
iconProp: IconProp.Database,
|
|
347
391
|
tableName: model.tableName!,
|
|
348
392
|
componentType: ComponentType.Component,
|
|
393
|
+
documentationLink: documentationLink,
|
|
349
394
|
arguments: [
|
|
350
395
|
{
|
|
351
396
|
id: "json",
|
|
352
397
|
placeholder: 'Example: {"columnName": "value", ...}',
|
|
353
398
|
name: "JSON Object",
|
|
354
|
-
description: `${model.singularName} represented as JSON`,
|
|
399
|
+
description: `${model.singularName} represented as JSON. ${columnHint}`,
|
|
355
400
|
type: ComponentInputType.JSON,
|
|
356
401
|
required: true,
|
|
357
402
|
},
|
|
@@ -397,12 +442,13 @@ export default class BaseModelComponent {
|
|
|
397
442
|
iconProp: IconProp.Database,
|
|
398
443
|
tableName: model.tableName!,
|
|
399
444
|
componentType: ComponentType.Component,
|
|
445
|
+
documentationLink: documentationLink,
|
|
400
446
|
arguments: [
|
|
401
447
|
{
|
|
402
448
|
id: "json-array",
|
|
403
449
|
name: "JSON Array",
|
|
404
450
|
placeholder: 'Example: [{"columnName": "value", ...}, {...}]',
|
|
405
|
-
description:
|
|
451
|
+
description: `List of ${model.pluralName} represented as a JSON array. ${columnHint}`,
|
|
406
452
|
type: ComponentInputType.JSONArray,
|
|
407
453
|
required: true,
|
|
408
454
|
},
|
|
@@ -472,10 +518,10 @@ export default class BaseModelComponent {
|
|
|
472
518
|
{
|
|
473
519
|
type: ComponentInputType.Select,
|
|
474
520
|
name: "Select Fields",
|
|
475
|
-
description: `
|
|
521
|
+
description: `Fields to read from ${model.singularName}. ${columnHint}`,
|
|
476
522
|
required: true,
|
|
477
523
|
id: "select",
|
|
478
|
-
placeholder:
|
|
524
|
+
placeholder: selectPlaceholder,
|
|
479
525
|
},
|
|
480
526
|
],
|
|
481
527
|
returnValues: [
|
|
@@ -505,25 +551,34 @@ export default class BaseModelComponent {
|
|
|
505
551
|
iconProp: IconProp.ArrowCircleUp,
|
|
506
552
|
tableName: model.tableName!,
|
|
507
553
|
componentType: ComponentType.Component,
|
|
554
|
+
documentationLink: documentationLink,
|
|
508
555
|
arguments: [
|
|
509
556
|
{
|
|
510
557
|
type: ComponentInputType.Query,
|
|
511
558
|
name: "Query",
|
|
512
|
-
description:
|
|
559
|
+
description: queryDescription,
|
|
513
560
|
required: true,
|
|
514
561
|
id: "query",
|
|
515
|
-
placeholder:
|
|
562
|
+
placeholder: queryPlaceholder,
|
|
516
563
|
},
|
|
517
564
|
{
|
|
518
565
|
id: "data",
|
|
519
566
|
placeholder: 'Example: {"columnName": "value", ...}',
|
|
520
567
|
name: "Data (JSON Object)",
|
|
521
|
-
description:
|
|
568
|
+
description: dataDescription,
|
|
522
569
|
type: ComponentInputType.JSON,
|
|
523
570
|
required: true,
|
|
524
571
|
},
|
|
525
572
|
],
|
|
526
|
-
returnValues: [
|
|
573
|
+
returnValues: [
|
|
574
|
+
{
|
|
575
|
+
id: "items-updated",
|
|
576
|
+
name: "Items Updated",
|
|
577
|
+
description: `How many ${model.pluralName} the query matched and updated. Zero is not an error - it means nothing matched.`,
|
|
578
|
+
type: ComponentInputType.Number,
|
|
579
|
+
required: false,
|
|
580
|
+
},
|
|
581
|
+
],
|
|
527
582
|
inPorts: [
|
|
528
583
|
{
|
|
529
584
|
title: "In",
|
|
@@ -556,20 +611,21 @@ export default class BaseModelComponent {
|
|
|
556
611
|
iconProp: IconProp.ArrowCircleUp,
|
|
557
612
|
tableName: model.tableName!,
|
|
558
613
|
componentType: ComponentType.Component,
|
|
614
|
+
documentationLink: documentationLink,
|
|
559
615
|
arguments: [
|
|
560
616
|
{
|
|
561
617
|
type: ComponentInputType.Query,
|
|
562
618
|
name: "Query",
|
|
563
|
-
description:
|
|
619
|
+
description: queryDescription,
|
|
564
620
|
required: true,
|
|
565
621
|
id: "query",
|
|
566
|
-
placeholder:
|
|
622
|
+
placeholder: queryPlaceholder,
|
|
567
623
|
},
|
|
568
624
|
{
|
|
569
625
|
id: "data",
|
|
570
626
|
name: "Data (JSON Object)",
|
|
571
627
|
placeholder: 'Example: {"columnName": "value", ...}',
|
|
572
|
-
description:
|
|
628
|
+
description: dataDescription,
|
|
573
629
|
type: ComponentInputType.JSON,
|
|
574
630
|
required: true,
|
|
575
631
|
},
|
|
@@ -588,7 +644,15 @@ export default class BaseModelComponent {
|
|
|
588
644
|
id: "limit",
|
|
589
645
|
},
|
|
590
646
|
],
|
|
591
|
-
returnValues: [
|
|
647
|
+
returnValues: [
|
|
648
|
+
{
|
|
649
|
+
id: "items-updated",
|
|
650
|
+
name: "Items Updated",
|
|
651
|
+
description: `How many ${model.pluralName} the query matched and updated. Zero is not an error - it means nothing matched.`,
|
|
652
|
+
type: ComponentInputType.Number,
|
|
653
|
+
required: false,
|
|
654
|
+
},
|
|
655
|
+
],
|
|
592
656
|
inPorts: [
|
|
593
657
|
{
|
|
594
658
|
title: "In",
|
package/Typings/Index.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
declare module "*.png";
|
|
2
2
|
declare module "*.jpg";
|
|
3
3
|
declare module "*.gif";
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* i18next-browser-languagedetector is an App-only browser dependency that a
|
|
7
|
+
* few Common tests reach through imported App/FeatureSet sources (e.g. the
|
|
8
|
+
* StatusPage detail pages via their Utils/i18n). It is not installed in
|
|
9
|
+
* Common/node_modules — Common's jest moduleNameMapper mocks it at runtime —
|
|
10
|
+
* so the type checker has nothing to resolve when it compiles those App files
|
|
11
|
+
* from within the Common Test job (which installs Common alone). This ambient
|
|
12
|
+
* shim gives the type checker an `any` module so the suite compiles; the mock
|
|
13
|
+
* supplies the behaviour at runtime.
|
|
14
|
+
*/
|
|
15
|
+
declare module "i18next-browser-languagedetector";
|
|
@@ -36,9 +36,10 @@ const ChartContainer: FunctionComponent<ComponentProps> = (
|
|
|
36
36
|
/*
|
|
37
37
|
* `isolate` creates a new stacking context so the chart's internal
|
|
38
38
|
* z-indexes (e.g. a highlighted/matched bar uses z-30, see Bar/Index.tsx)
|
|
39
|
-
* stay trapped inside the chart. Without it those bars
|
|
40
|
-
* page-level overlays
|
|
41
|
-
* matched span "show above"
|
|
39
|
+
* stay trapped inside the chart. Without it those bars compete directly
|
|
40
|
+
* with page-level overlays such as the span-details SideOver (z-30, and
|
|
41
|
+
* portalled to the end of <body>), and a matched span would "show above"
|
|
42
|
+
* the sidebar.
|
|
42
43
|
*/
|
|
43
44
|
<div ref={divRef} className={"w-full"} style={{ isolation: "isolate" }}>
|
|
44
45
|
{props.children}
|
|
@@ -15,6 +15,8 @@ export interface ComponentProps {
|
|
|
15
15
|
isLoading?: boolean;
|
|
16
16
|
error?: string | undefined;
|
|
17
17
|
disableSubmitButton?: boolean | undefined;
|
|
18
|
+
// Rendered under the description - for confirmations that also ask something.
|
|
19
|
+
children?: ReactElement | undefined;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
const ConfirmModal: FunctionComponent<ComponentProps> = (
|
|
@@ -51,11 +53,14 @@ const ConfirmModal: FunctionComponent<ComponentProps> = (
|
|
|
51
53
|
* a long confirmation two nested scrollbars, and the inner one clipped
|
|
52
54
|
* the text well short of the space the modal had spare.
|
|
53
55
|
*/}
|
|
54
|
-
<div
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
<div>
|
|
57
|
+
<div
|
|
58
|
+
data-testid="confirm-modal-description"
|
|
59
|
+
className="whitespace-pre-wrap break-words text-sm leading-6 text-gray-600"
|
|
60
|
+
>
|
|
61
|
+
{translatedDescription}
|
|
62
|
+
</div>
|
|
63
|
+
{props.children ? <div className="mt-4">{props.children}</div> : <></>}
|
|
59
64
|
</div>
|
|
60
65
|
</Modal>
|
|
61
66
|
);
|