@burdenoff/microfe-botmanor 2026.1108.1 → 2026.1109.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botlit/BotlitRoutes.d.ts +2 -0
- package/dist/botlit/BotlitRoutes.js +24 -25
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/BotmanorRoot.d.ts +3 -0
- package/dist/botlit/BotmanorRoot.js +1 -2
- package/dist/botlit/BotmanorRoot.js.map +1 -1
- package/dist/botlit/BotmanorRootInner.d.ts +3 -0
- package/dist/botlit/BotmanorRootInner.js +9 -10
- package/dist/botlit/BotmanorRootInner.js.map +1 -1
- package/dist/botlit/components/AgentApprovalPanel.d.ts +20 -0
- package/dist/botlit/components/AgentApprovalPanel.js +49 -50
- package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
- package/dist/botlit/components/AiOperationsPanel.d.ts +14 -0
- package/dist/botlit/components/AiOperationsPanel.js +54 -55
- package/dist/botlit/components/AiOperationsPanel.js.map +1 -1
- package/dist/botlit/components/AssistantChannelPanel.d.ts +3 -0
- package/dist/botlit/components/AssistantChannelPanel.js +12 -13
- package/dist/botlit/components/AssistantChannelPanel.js.map +1 -1
- package/dist/botlit/components/AssistantRuntimeSetupPanel.d.ts +4 -0
- package/dist/botlit/components/AssistantRuntimeSetupPanel.js +14 -14
- package/dist/botlit/components/AssistantRuntimeSetupPanel.js.map +1 -1
- package/dist/botlit/components/AssistantWebsitePanel.d.ts +5 -0
- package/dist/botlit/components/AssistantWebsitePanel.js +15 -16
- package/dist/botlit/components/AssistantWebsitePanel.js.map +1 -1
- package/dist/botlit/components/Badge.d.ts +9 -0
- package/dist/botlit/components/Badge.js +1 -2
- package/dist/botlit/components/Badge.js.map +1 -1
- package/dist/botlit/components/Button.d.ts +10 -0
- package/dist/botlit/components/Button.js +1 -2
- package/dist/botlit/components/Button.js.map +1 -1
- package/dist/botlit/components/Card.d.ts +16 -0
- package/dist/botlit/components/Card.js +1 -2
- package/dist/botlit/components/Card.js.map +1 -1
- package/dist/botlit/components/ChannelSelectorSheet.d.ts +23 -0
- package/dist/botlit/components/ChannelSelectorSheet.js +1 -2
- package/dist/botlit/components/ChannelSelectorSheet.js.map +1 -1
- package/dist/botlit/components/EmptyState.d.ts +12 -0
- package/dist/botlit/components/EmptyState.js +1 -2
- package/dist/botlit/components/EmptyState.js.map +1 -1
- package/dist/botlit/components/ErrorState.d.ts +10 -0
- package/dist/botlit/components/ErrorState.js +5 -6
- package/dist/botlit/components/ErrorState.js.map +1 -1
- package/dist/botlit/components/Input.d.ts +27 -0
- package/dist/botlit/components/Input.js +1 -2
- package/dist/botlit/components/Input.js.map +1 -1
- package/dist/botlit/components/KnowledgeSourceImportPanel.d.ts +3 -0
- package/dist/botlit/components/KnowledgeSourceImportPanel.js +12 -13
- package/dist/botlit/components/KnowledgeSourceImportPanel.js.map +1 -1
- package/dist/botlit/components/ModelRegistrationPanel.d.ts +5 -0
- package/dist/botlit/components/ModelRegistrationPanel.js +1 -2
- package/dist/botlit/components/ModelRegistrationPanel.js.map +1 -1
- package/dist/botlit/components/PageLayout.d.ts +12 -0
- package/dist/botlit/components/PageLayout.js +1 -2
- package/dist/botlit/components/PageLayout.js.map +1 -1
- package/dist/botlit/components/QuotaExhaustedDialog.d.ts +9 -0
- package/dist/botlit/components/QuotaExhaustedDialog.js +1 -2
- package/dist/botlit/components/QuotaExhaustedDialog.js.map +1 -1
- package/dist/botlit/components/RetentionStatusPanel.d.ts +2 -0
- package/dist/botlit/components/RetentionStatusPanel.js +18 -19
- package/dist/botlit/components/RetentionStatusPanel.js.map +1 -1
- package/dist/botlit/components/RouteLoader.d.ts +23 -0
- package/dist/botlit/components/RouteLoader.js +1 -2
- package/dist/botlit/components/RouteLoader.js.map +1 -1
- package/dist/botlit/components/VersionHistoryPanel.d.ts +12 -0
- package/dist/botlit/components/VersionHistoryPanel.js +23 -24
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
- package/dist/botlit/components/WorkspaceRequired.d.ts +18 -0
- package/dist/botlit/components/WorkspaceRequired.js +1 -2
- package/dist/botlit/components/WorkspaceRequired.js.map +1 -1
- package/dist/botlit/components/index.d.ts +14 -0
- package/dist/botlit/hooks/index.d.ts +36 -0
- package/dist/botlit/hooks/index.js +15 -14
- package/dist/botlit/hooks/internal/mutationInput.d.ts +56 -0
- package/dist/botlit/hooks/internal/mutationInput.js +1 -2
- package/dist/botlit/hooks/internal/mutationInput.js.map +1 -1
- package/dist/botlit/hooks/internal/workspaceGateway.d.ts +54 -0
- package/dist/botlit/hooks/internal/workspaceGateway.js +17 -19
- package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
- package/dist/botlit/hooks/useA2A.d.ts +104 -0
- package/dist/botlit/hooks/useA2A.js +45 -45
- package/dist/botlit/hooks/useA2A.js.map +1 -1
- package/dist/botlit/hooks/useAgentApprovals.d.ts +62 -0
- package/dist/botlit/hooks/useAgentApprovals.js +38 -39
- package/dist/botlit/hooks/useAgentApprovals.js.map +1 -1
- package/dist/botlit/hooks/useAgents.d.ts +105 -0
- package/dist/botlit/hooks/useAgents.js +53 -54
- package/dist/botlit/hooks/useAgents.js.map +1 -1
- package/dist/botlit/hooks/useAiOperations.d.ts +95 -0
- package/dist/botlit/hooks/useAiOperations.js +20 -19
- package/dist/botlit/hooks/useAiOperations.js.map +1 -1
- package/dist/botlit/hooks/useAssistantChannels.d.ts +16 -0
- package/dist/botlit/hooks/useAssistantChannels.js +1 -2
- package/dist/botlit/hooks/useAssistantChannels.js.map +1 -1
- package/dist/botlit/hooks/useAssistantRuntimeSetup.d.ts +17 -0
- package/dist/botlit/hooks/useAssistantRuntimeSetup.js +1 -2
- package/dist/botlit/hooks/useAssistantRuntimeSetup.js.map +1 -1
- package/dist/botlit/hooks/useAssistantWebsites.d.ts +18 -0
- package/dist/botlit/hooks/useAssistantWebsites.js +1 -2
- package/dist/botlit/hooks/useAssistantWebsites.js.map +1 -1
- package/dist/botlit/hooks/useBotWorkflow.d.ts +22 -0
- package/dist/botlit/hooks/useBotWorkflow.js +1 -2
- package/dist/botlit/hooks/useBotWorkflow.js.map +1 -1
- package/dist/botlit/hooks/useBots.d.ts +68 -0
- package/dist/botlit/hooks/useBots.js +32 -33
- package/dist/botlit/hooks/useBots.js.map +1 -1
- package/dist/botlit/hooks/useBuckets.d.ts +57 -0
- package/dist/botlit/hooks/useBuckets.js +38 -39
- package/dist/botlit/hooks/useBuckets.js.map +1 -1
- package/dist/botlit/hooks/useChannels.d.ts +87 -0
- package/dist/botlit/hooks/useChannels.js +73 -73
- package/dist/botlit/hooks/useChannels.js.map +1 -1
- package/dist/botlit/hooks/useConversations.d.ts +42 -0
- package/dist/botlit/hooks/useConversations.js +1 -2
- package/dist/botlit/hooks/useConversations.js.map +1 -1
- package/dist/botlit/hooks/useExecutions.d.ts +87 -0
- package/dist/botlit/hooks/useExecutions.js +37 -37
- package/dist/botlit/hooks/useExecutions.js.map +1 -1
- package/dist/botlit/hooks/useKnowledgeBases.d.ts +79 -0
- package/dist/botlit/hooks/useKnowledgeBases.js +40 -39
- package/dist/botlit/hooks/useKnowledgeBases.js.map +1 -1
- package/dist/botlit/hooks/useKnowledgeSourceImports.d.ts +21 -0
- package/dist/botlit/hooks/useKnowledgeSourceImports.js +1 -2
- package/dist/botlit/hooks/useKnowledgeSourceImports.js.map +1 -1
- package/dist/botlit/hooks/useLLMProviders.d.ts +66 -0
- package/dist/botlit/hooks/useLLMProviders.js +25 -26
- package/dist/botlit/hooks/useLLMProviders.js.map +1 -1
- package/dist/botlit/hooks/useMCPServers.d.ts +71 -0
- package/dist/botlit/hooks/useMCPServers.js +40 -38
- package/dist/botlit/hooks/useMCPServers.js.map +1 -1
- package/dist/botlit/hooks/usePolicies.d.ts +60 -0
- package/dist/botlit/hooks/usePolicies.js +49 -49
- package/dist/botlit/hooks/usePolicies.js.map +1 -1
- package/dist/botlit/hooks/usePromptTemplates.d.ts +88 -0
- package/dist/botlit/hooks/usePromptTemplates.js +57 -57
- package/dist/botlit/hooks/usePromptTemplates.js.map +1 -1
- package/dist/botlit/hooks/useRetention.d.ts +26 -0
- package/dist/botlit/hooks/useRetention.js +3 -3
- package/dist/botlit/hooks/useRetention.js.map +1 -1
- package/dist/botlit/hooks/useRetrievalProfiles.d.ts +75 -0
- package/dist/botlit/hooks/useRetrievalProfiles.js +47 -47
- package/dist/botlit/hooks/useRetrievalProfiles.js.map +1 -1
- package/dist/botlit/hooks/useSkills.d.ts +64 -0
- package/dist/botlit/hooks/useSkills.js +53 -53
- package/dist/botlit/hooks/useSkills.js.map +1 -1
- package/dist/botlit/hooks/useStore.d.ts +112 -0
- package/dist/botlit/hooks/useStore.js +55 -55
- package/dist/botlit/hooks/useStore.js.map +1 -1
- package/dist/botlit/hooks/useUserPlatformConnection.d.ts +80 -0
- package/dist/botlit/hooks/useUserPlatformConnection.js +19 -19
- package/dist/botlit/hooks/useUserPlatformConnection.js.map +1 -1
- package/dist/botlit/index.d.ts +16 -0
- package/dist/botlit/index.js +12 -11
- package/dist/botlit/pages/A2AAgentDetailPage.d.ts +6 -0
- package/dist/botlit/pages/A2AAgentDetailPage.js +171 -178
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/A2ARegistryPage.d.ts +2 -0
- package/dist/botlit/pages/A2ARegistryPage.js +25 -26
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
- package/dist/botlit/pages/AgentApprovalsPage.d.ts +2 -0
- package/dist/botlit/pages/AgentApprovalsPage.js +32 -33
- package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
- package/dist/botlit/pages/AgentBuilderPage.d.ts +2 -0
- package/dist/botlit/pages/AgentBuilderPage.js +59 -60
- package/dist/botlit/pages/AgentBuilderPage.js.map +1 -1
- package/dist/botlit/pages/AgentDetailPage.d.ts +2 -0
- package/dist/botlit/pages/AgentDetailPage.js +83 -84
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.d.ts +2 -0
- package/dist/botlit/pages/AgentsListPage.js +71 -72
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/AiOperationsPage.d.ts +2 -0
- package/dist/botlit/pages/AiOperationsPage.js +52 -53
- package/dist/botlit/pages/AiOperationsPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.d.ts +7 -0
- package/dist/botlit/pages/BotChannelsTab.js +120 -122
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotDetailPage.d.ts +7 -0
- package/dist/botlit/pages/BotDetailPage.js +353 -358
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.d.ts +11 -0
- package/dist/botlit/pages/BotWorkflowTab.js +20 -21
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.d.ts +2 -0
- package/dist/botlit/pages/BotsListPage.js +52 -53
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.d.ts +2 -0
- package/dist/botlit/pages/BucketsPage.js +260 -261
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.d.ts +6 -0
- package/dist/botlit/pages/ChannelDetailPage.js +97 -96
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChannelRoutesPage.d.ts +2 -0
- package/dist/botlit/pages/ChannelRoutesPage.js +23 -24
- package/dist/botlit/pages/ChannelRoutesPage.js.map +1 -1
- package/dist/botlit/pages/ChannelsPage.d.ts +2 -0
- package/dist/botlit/pages/ChannelsPage.js +44 -45
- package/dist/botlit/pages/ChannelsPage.js.map +1 -1
- package/dist/botlit/pages/ChatPage.d.ts +1 -0
- package/dist/botlit/pages/ChatPage.js +10 -11
- package/dist/botlit/pages/ChatPage.js.map +1 -1
- package/dist/botlit/pages/ConversationDetailPage.d.ts +2 -0
- package/dist/botlit/pages/ConversationsPage.d.ts +2 -0
- package/dist/botlit/pages/DashboardPage.d.ts +2 -0
- package/dist/botlit/pages/DashboardPage.js +37 -38
- package/dist/botlit/pages/DashboardPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionDetailPage.d.ts +2 -0
- package/dist/botlit/pages/ExecutionDetailPage.js +47 -48
- package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.d.ts +2 -0
- package/dist/botlit/pages/ExecutionsPage.js +72 -70
- package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
- package/dist/botlit/pages/InstalledPackagesPage.d.ts +2 -0
- package/dist/botlit/pages/InstalledPackagesPage.js +77 -78
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.d.ts +6 -0
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +171 -181
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBasesPage.d.ts +2 -0
- package/dist/botlit/pages/KnowledgeBasesPage.js +30 -31
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServerDetailPage.d.ts +6 -0
- package/dist/botlit/pages/MCPServerDetailPage.js +82 -83
- package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.d.ts +2 -0
- package/dist/botlit/pages/MCPServersPage.js +54 -55
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/PoliciesPage.d.ts +2 -0
- package/dist/botlit/pages/PoliciesPage.js +25 -26
- package/dist/botlit/pages/PoliciesPage.js.map +1 -1
- package/dist/botlit/pages/PolicyDetailPage.d.ts +6 -0
- package/dist/botlit/pages/PolicyDetailPage.js +257 -259
- package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptStudioPage.d.ts +2 -0
- package/dist/botlit/pages/PromptStudioPage.js +35 -35
- package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplateDetailPage.d.ts +6 -0
- package/dist/botlit/pages/PromptTemplateDetailPage.js +363 -362
- package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplatesPage.d.ts +2 -0
- package/dist/botlit/pages/PromptTemplatesPage.js +26 -27
- package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfileDetailPage.d.ts +6 -0
- package/dist/botlit/pages/RetrievalProfileDetailPage.js +150 -158
- package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfilesPage.d.ts +2 -0
- package/dist/botlit/pages/RetrievalProfilesPage.js +24 -25
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.d.ts +2 -0
- package/dist/botlit/pages/SettingsPage.js +124 -125
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillDetailPage.d.ts +6 -0
- package/dist/botlit/pages/SkillDetailPage.js +216 -217
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
- package/dist/botlit/pages/SkillsPage.d.ts +2 -0
- package/dist/botlit/pages/SkillsPage.js +24 -25
- package/dist/botlit/pages/SkillsPage.js.map +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.d.ts +2 -0
- package/dist/botlit/pages/StorePackageDetailPage.js +38 -39
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.d.ts +2 -0
- package/dist/botlit/pages/StorePage.js +135 -136
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/dist/botlit/pages/index.d.ts +39 -0
- package/dist/botlit/permissions/PermissionRequired.d.ts +20 -0
- package/dist/botlit/permissions/PermissionRequired.js +10 -11
- package/dist/botlit/permissions/PermissionRequired.js.map +1 -1
- package/dist/botlit/permissions/botmanorPermissions.d.ts +82 -0
- package/dist/botlit/permissions/botmanorPermissions.js +1 -2
- package/dist/botlit/permissions/botmanorPermissions.js.map +1 -1
- package/dist/botlit/permissions/index.d.ts +7 -0
- package/dist/botlit/permissions/index.js +4 -3
- package/dist/botlit/permissions/useBotmanorPermissions.d.ts +41 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js +1 -2
- package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -1
- package/dist/botlit/providers/BotlitProvider.d.ts +14 -0
- package/dist/botlit/providers/BotlitProvider.js +3 -3
- package/dist/botlit/providers/BotlitProvider.js.map +1 -1
- package/dist/botlit/store/botlitStore.d.ts +85 -0
- package/dist/botlit/store/botlitStore.js +1 -2
- package/dist/botlit/store/botlitStore.js.map +1 -1
- package/dist/botlit/store/renamedKeyStorage.d.ts +13 -0
- package/dist/botlit/store/renamedKeyStorage.js +1 -2
- package/dist/botlit/store/renamedKeyStorage.js.map +1 -1
- package/dist/botlit/types/index.d.ts +1008 -0
- package/dist/botlit/utils/cn.d.ts +2 -0
- package/dist/botlit/utils/cn.js +1 -2
- package/dist/botlit/utils/cn.js.map +1 -1
- package/dist/botlit/utils/embedding-models.d.ts +9 -0
- package/dist/botlit/utils/embedding-models.js +1 -2
- package/dist/botlit/utils/embedding-models.js.map +1 -1
- package/dist/botlit/utils/errors.d.ts +19 -0
- package/dist/botlit/utils/errors.js +1 -2
- package/dist/botlit/utils/errors.js.map +1 -1
- package/dist/botlit/utils/formatters.d.ts +38 -0
- package/dist/botlit/utils/formatters.js +0 -1
- package/dist/botlit/utils/formatters.js.map +1 -1
- package/dist/botlit/utils/navigation.d.ts +19 -0
- package/dist/botlit/utils/navigation.js +1 -2
- package/dist/botlit/utils/navigation.js.map +1 -1
- package/dist/botlit/utils/policyConfig.d.ts +68 -0
- package/dist/botlit/utils/policyConfig.js +2 -3
- package/dist/botlit/utils/policyConfig.js.map +1 -1
- package/dist/botlit/utils/unions.d.ts +25 -0
- package/dist/botlit/utils/unions.js +1 -2
- package/dist/botlit/utils/unions.js.map +1 -1
- package/dist/dev/App.d.ts +2 -0
- package/dist/dev/main.d.ts +0 -0
- package/dist/generated/global-operations.d.ts +197 -0
- package/dist/generated/global-operations.js +1 -2
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/generated/global-types.d.ts +27678 -0
- package/dist/generated/global-types.js +1 -2
- package/dist/generated/global-types.js.map +1 -1
- package/dist/generated/wspace-operations.d.ts +5489 -0
- package/dist/generated/wspace-operations.js +64 -60
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.d.ts +152017 -0
- package/dist/generated/wspace-types.js +1 -2
- package/dist/generated/wspace-types.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/shared/hooks/useTr.d.ts +16 -0
- package/dist/shared/hooks/useTr.js +1 -2
- package/dist/shared/hooks/useTr.js.map +1 -1
- package/dist/stories/Badge.stories.d.ts +11 -0
- package/dist/stories/Button.stories.d.ts +13 -0
- package/dist/stories/EmptyState.stories.d.ts +8 -0
- package/dist/stories/StatusBadge.stories.d.ts +9 -0
- package/dist/test/fixtures.d.ts +39 -0
- package/dist/test/happydom.d.ts +1 -0
- package/dist/test/renderPage.d.ts +18 -0
- package/dist/test/setup.d.ts +9 -0
- package/dist/utils/nativeBridge.d.ts +2 -0
- package/dist/utils/nativeBridge.js +1 -2
- package/package.json +87 -60
package/dist/botlit/utils/cn.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { clsx as e } from "clsx";
|
|
2
2
|
import { twMerge as t } from "tailwind-merge";
|
|
3
|
-
|
|
3
|
+
// src/botlit/utils/cn.ts
|
|
4
4
|
function n(...n) {
|
|
5
5
|
return t(e(n));
|
|
6
6
|
}
|
|
7
|
-
//#endregion
|
|
8
7
|
export { n as cn };
|
|
9
8
|
|
|
10
9
|
//# sourceMappingURL=cn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn.js","names":[],"sources":["../../../src/botlit/utils/cn.ts"],"sourcesContent":["/**\n * Class name utility\n * @module botlit/utils\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAQA,
|
|
1
|
+
{"version":3,"file":"cn.js","names":["cn","inputs","twMerge","clsx"],"sources":["../../../src/botlit/utils/cn.ts"],"sourcesContent":["/**\n * Class name utility\n * @module botlit/utils\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAQA,SAAgBA,EAAG,GAAGC,GAA8B;CAClD,OAAOC,EAAQC,EAAKF,CAAM,CAAC;AAC7B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LLMModelRecord, LLMProviderRecord } from '../hooks/useLLMProviders';
|
|
2
|
+
/** Embedding registrations must never be offered as answer-generation models. */
|
|
3
|
+
export declare function configuredAnswerModels(models: LLMModelRecord[], providers: LLMProviderRecord[]): LLMModelRecord[];
|
|
4
|
+
/** Use the registered model ID to pin its workspace provider during ingestion. */
|
|
5
|
+
export declare function configuredEmbeddingModels(models: LLMModelRecord[], providers: LLMProviderRecord[]): {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
dimensions: number;
|
|
9
|
+
}[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/botlit/utils/embedding-models.ts
|
|
2
2
|
var e = {
|
|
3
3
|
"amazon.titan-embed-text-v2:0": 1024,
|
|
4
4
|
"text-embedding-3-small": 1536,
|
|
@@ -30,7 +30,6 @@ function n(t, n) {
|
|
|
30
30
|
}];
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
//#endregion
|
|
34
33
|
export { t as configuredAnswerModels, n as configuredEmbeddingModels };
|
|
35
34
|
|
|
36
35
|
//# sourceMappingURL=embedding-models.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding-models.js","names":[],"sources":["../../../src/botlit/utils/embedding-models.ts"],"sourcesContent":["import type { LLMModelRecord, LLMProviderRecord } from '../hooks/useLLMProviders';\n\nconst DIMENSIONS: Record<string, number> = {\n 'amazon.titan-embed-text-v2:0': 1024,\n 'text-embedding-3-small': 1536,\n 'text-embedding-3-large': 3072,\n 'text-embedding-ada-002': 1536,\n};\n\n/** Embedding registrations must never be offered as answer-generation models. */\nexport function configuredAnswerModels(models: LLMModelRecord[], providers: LLMProviderRecord[]) {\n return models.filter(\n (model) =>\n model.isActive &&\n model.maxOutputTokens > 0 &&\n model.metadata?.purpose !== 'embedding' &&\n !DIMENSIONS[model.modelId] &&\n providers.some((provider) => provider.id === model.providerId && provider.isActive)\n );\n}\n\n/** Use the registered model ID to pin its workspace provider during ingestion. */\nexport function configuredEmbeddingModels(\n models: LLMModelRecord[],\n providers: LLMProviderRecord[]\n) {\n return models.flatMap((model) => {\n const provider = providers.find((entry) => entry.id === model.providerId && entry.isActive);\n const declared =\n model.metadata?.purpose === 'embedding' ? model.metadata.embeddingDimensions : undefined;\n const dimension = typeof declared === 'number' ? declared : DIMENSIONS[model.modelId];\n if (!model.isActive || !provider || !dimension) return [];\n if (\n model.metadata?.purpose === 'answer' ||\n !Number.isInteger(dimension) ||\n dimension < 1 ||\n dimension > 16000\n )\n return [];\n const titan = model.modelId === 'amazon.titan-embed-text-v2:0';\n if (\n titan\n ? provider.type !== 'AWS_BEDROCK'\n : !['OPENAI', 'AZURE_OPENAI', 'CUSTOM'].includes(provider.type)\n )\n return [];\n const dimensions = titan\n ? typeof provider.metadata?.embeddingDimensions === 'number'\n ? provider.metadata.embeddingDimensions\n : 1024\n : dimension;\n if (titan && ![256, 512, 1024].includes(dimensions)) return [];\n return [{ id: model.id, label: model.name, dimensions }];\n });\n}\n"],"mappings":";AAEA,
|
|
1
|
+
{"version":3,"file":"embedding-models.js","names":["DIMENSIONS","configuredAnswerModels","models","model","providers","provider","configuredEmbeddingModels","entry","declared","dimension","titan","dimensions"],"sources":["../../../src/botlit/utils/embedding-models.ts"],"sourcesContent":["import type { LLMModelRecord, LLMProviderRecord } from '../hooks/useLLMProviders';\n\nconst DIMENSIONS: Record<string, number> = {\n 'amazon.titan-embed-text-v2:0': 1024,\n 'text-embedding-3-small': 1536,\n 'text-embedding-3-large': 3072,\n 'text-embedding-ada-002': 1536,\n};\n\n/** Embedding registrations must never be offered as answer-generation models. */\nexport function configuredAnswerModels(models: LLMModelRecord[], providers: LLMProviderRecord[]) {\n return models.filter(\n (model) =>\n model.isActive &&\n model.maxOutputTokens > 0 &&\n model.metadata?.purpose !== 'embedding' &&\n !DIMENSIONS[model.modelId] &&\n providers.some((provider) => provider.id === model.providerId && provider.isActive)\n );\n}\n\n/** Use the registered model ID to pin its workspace provider during ingestion. */\nexport function configuredEmbeddingModels(\n models: LLMModelRecord[],\n providers: LLMProviderRecord[]\n) {\n return models.flatMap((model) => {\n const provider = providers.find((entry) => entry.id === model.providerId && entry.isActive);\n const declared =\n model.metadata?.purpose === 'embedding' ? model.metadata.embeddingDimensions : undefined;\n const dimension = typeof declared === 'number' ? declared : DIMENSIONS[model.modelId];\n if (!model.isActive || !provider || !dimension) return [];\n if (\n model.metadata?.purpose === 'answer' ||\n !Number.isInteger(dimension) ||\n dimension < 1 ||\n dimension > 16000\n )\n return [];\n const titan = model.modelId === 'amazon.titan-embed-text-v2:0';\n if (\n titan\n ? provider.type !== 'AWS_BEDROCK'\n : !['OPENAI', 'AZURE_OPENAI', 'CUSTOM'].includes(provider.type)\n )\n return [];\n const dimensions = titan\n ? typeof provider.metadata?.embeddingDimensions === 'number'\n ? provider.metadata.embeddingDimensions\n : 1024\n : dimension;\n if (titan && ![256, 512, 1024].includes(dimensions)) return [];\n return [{ id: model.id, label: model.name, dimensions }];\n });\n}\n"],"mappings":";AAEA,IAAMA,IAAqC;CACzC,gCAAgC;CAChC,0BAA0B;CAC1B,0BAA0B;CAC1B,0BAA0B;AAC5B;AAGA,SAAgBC,EAAuB,GAA0B,GAAgC;CAC/F,OAAOC,EAAO,QACX,MACCC,EAAM,YACNA,EAAM,kBAAkB,KACxBA,EAAM,UAAU,YAAY,eAC5B,CAACH,EAAWG,EAAM,YAClBC,EAAU,MAAM,MAAaC,EAAS,OAAOF,EAAM,cAAcE,EAAS,QAAQ,CACtF;AACF;AAGA,SAAgBC,EACd,GACA,GACA;CACA,OAAOJ,EAAO,SAAS,MAAU;EAC/B,IAAMG,IAAWD,EAAU,MAAM,MAAUG,EAAM,OAAOJ,EAAM,cAAcI,EAAM,QAAQ,GACpFC,IACJL,EAAM,UAAU,YAAY,cAAcA,EAAM,SAAS,sBAAsB,KAAA,GAC3EM,IAAY,OAAOD,KAAa,WAAWA,IAAWR,EAAWG,EAAM;EAE7E,IADI,CAACA,EAAM,YAAY,CAACE,KAAY,CAACI,KAEnCN,EAAM,UAAU,YAAY,YAC5B,CAAC,OAAO,UAAUM,CAAS,KAC3BA,IAAY,KACZA,IAAY,MAEZ,OAAO,CAAC;EACV,IAAMC,IAAQP,EAAM,YAAY;EAChC,IACEO,IACIL,EAAS,SAAS,gBAClB,CAAC;GAAC;GAAU;GAAgB;EAAQ,CAAC,CAAC,SAASA,EAAS,IAAI,GAEhE,OAAO,CAAC;EACV,IAAMM,IAAaD,IACf,OAAOL,EAAS,UAAU,uBAAwB,WAChDA,EAAS,SAAS,sBAClB,OACFI;EAEJ,OADIC,KAAS,CAAC;GAAC;GAAK;GAAK;EAAI,CAAC,CAAC,SAASC,CAAU,IAAU,CAAC,IACtD,CAAC;GAAE,IAAIR,EAAM;GAAI,OAAOA,EAAM;GAAM;EAAW,CAAC;CACzD,CAAC;AACH"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared unwrapping for the error shapes produced by the platform's GraphQL
|
|
3
|
+
* stack.
|
|
4
|
+
*
|
|
5
|
+
* Apollo Client v4 does not reject operations with a plain Error: failures
|
|
6
|
+
* arrive as `{ graphQLErrors }` / `{ networkError }` wrapper objects, and the
|
|
7
|
+
* shared batched fetch layer (fe-libs `enqueueGraphQLFetch`) attaches the
|
|
8
|
+
* structured GraphQL errors as `.errors` on the networkError, whose own
|
|
9
|
+
* message is the first GraphQL error's message. Prefers the first GraphQL
|
|
10
|
+
* error message, then the networkError message; `undefined` when nothing
|
|
11
|
+
* user-actionable is present.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractGraphqlFailureMessage(error: unknown): string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Extracts the user-actionable message from a failed GraphQL operation:
|
|
16
|
+
* the unwrapped GraphQL/network error message when present, otherwise the
|
|
17
|
+
* Error's own message, otherwise the caller's fallback.
|
|
18
|
+
*/
|
|
19
|
+
export declare function graphqlErrorMessage(error: unknown, fallback: string): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/botlit/utils/errors.ts
|
|
2
2
|
function e(e) {
|
|
3
3
|
let t = (e) => {
|
|
4
4
|
if (!Array.isArray(e)) return;
|
|
@@ -23,7 +23,6 @@ function e(e) {
|
|
|
23
23
|
function t(t, n) {
|
|
24
24
|
return e(t) || (t instanceof Error && t.message.trim() !== "" ? t.message : n);
|
|
25
25
|
}
|
|
26
|
-
//#endregion
|
|
27
26
|
export { e as extractGraphqlFailureMessage, t as graphqlErrorMessage };
|
|
28
27
|
|
|
29
28
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../../../src/botlit/utils/errors.ts"],"sourcesContent":["/**\n * Shared unwrapping for the error shapes produced by the platform's GraphQL\n * stack.\n *\n * Apollo Client v4 does not reject operations with a plain Error: failures\n * arrive as `{ graphQLErrors }` / `{ networkError }` wrapper objects, and the\n * shared batched fetch layer (fe-libs `enqueueGraphQLFetch`) attaches the\n * structured GraphQL errors as `.errors` on the networkError, whose own\n * message is the first GraphQL error's message. Prefers the first GraphQL\n * error message, then the networkError message; `undefined` when nothing\n * user-actionable is present.\n */\nexport function extractGraphqlFailureMessage(error: unknown): string | undefined {\n const firstMessage = (list: unknown): string | undefined => {\n if (!Array.isArray(list)) return undefined;\n const first: unknown = list[0];\n if (first !== null && typeof first === 'object' && 'message' in first) {\n const message = (first as { message?: unknown }).message;\n if (typeof message === 'string' && message.trim() !== '') return message;\n }\n return undefined;\n };\n\n if (error === null || typeof error !== 'object') return undefined;\n const candidate = error as {\n graphQLErrors?: unknown;\n errors?: unknown;\n networkError?: unknown;\n };\n const fromGraphQLErrors = firstMessage(candidate.graphQLErrors);\n if (fromGraphQLErrors) return fromGraphQLErrors;\n const fromErrors = firstMessage(candidate.errors);\n if (fromErrors) return fromErrors;\n const networkError = candidate.networkError;\n if (networkError !== null && typeof networkError === 'object') {\n const fromNetworkErrors = firstMessage((networkError as { errors?: unknown }).errors);\n if (fromNetworkErrors) return fromNetworkErrors;\n }\n if (networkError instanceof Error && networkError.message.trim() !== '') {\n return networkError.message;\n }\n return undefined;\n}\n\n/**\n * Extracts the user-actionable message from a failed GraphQL operation:\n * the unwrapped GraphQL/network error message when present, otherwise the\n * Error's own message, otherwise the caller's fallback.\n */\nexport function graphqlErrorMessage(error: unknown, fallback: string): string {\n const unwrapped = extractGraphqlFailureMessage(error);\n if (unwrapped) return unwrapped;\n if (error instanceof Error && error.message.trim() !== '') {\n return error.message;\n }\n return fallback;\n}\n"],"mappings":";AAYA,
|
|
1
|
+
{"version":3,"file":"errors.js","names":["extractGraphqlFailureMessage","firstMessage","list","first","message","error","candidate","fromGraphQLErrors","fromErrors","networkError","fromNetworkErrors","graphqlErrorMessage","fallback"],"sources":["../../../src/botlit/utils/errors.ts"],"sourcesContent":["/**\n * Shared unwrapping for the error shapes produced by the platform's GraphQL\n * stack.\n *\n * Apollo Client v4 does not reject operations with a plain Error: failures\n * arrive as `{ graphQLErrors }` / `{ networkError }` wrapper objects, and the\n * shared batched fetch layer (fe-libs `enqueueGraphQLFetch`) attaches the\n * structured GraphQL errors as `.errors` on the networkError, whose own\n * message is the first GraphQL error's message. Prefers the first GraphQL\n * error message, then the networkError message; `undefined` when nothing\n * user-actionable is present.\n */\nexport function extractGraphqlFailureMessage(error: unknown): string | undefined {\n const firstMessage = (list: unknown): string | undefined => {\n if (!Array.isArray(list)) return undefined;\n const first: unknown = list[0];\n if (first !== null && typeof first === 'object' && 'message' in first) {\n const message = (first as { message?: unknown }).message;\n if (typeof message === 'string' && message.trim() !== '') return message;\n }\n return undefined;\n };\n\n if (error === null || typeof error !== 'object') return undefined;\n const candidate = error as {\n graphQLErrors?: unknown;\n errors?: unknown;\n networkError?: unknown;\n };\n const fromGraphQLErrors = firstMessage(candidate.graphQLErrors);\n if (fromGraphQLErrors) return fromGraphQLErrors;\n const fromErrors = firstMessage(candidate.errors);\n if (fromErrors) return fromErrors;\n const networkError = candidate.networkError;\n if (networkError !== null && typeof networkError === 'object') {\n const fromNetworkErrors = firstMessage((networkError as { errors?: unknown }).errors);\n if (fromNetworkErrors) return fromNetworkErrors;\n }\n if (networkError instanceof Error && networkError.message.trim() !== '') {\n return networkError.message;\n }\n return undefined;\n}\n\n/**\n * Extracts the user-actionable message from a failed GraphQL operation:\n * the unwrapped GraphQL/network error message when present, otherwise the\n * Error's own message, otherwise the caller's fallback.\n */\nexport function graphqlErrorMessage(error: unknown, fallback: string): string {\n const unwrapped = extractGraphqlFailureMessage(error);\n if (unwrapped) return unwrapped;\n if (error instanceof Error && error.message.trim() !== '') {\n return error.message;\n }\n return fallback;\n}\n"],"mappings":";AAYA,SAAgBA,EAA6B,GAAoC;CAC/E,IAAMC,KAAgB,MAAsC;EAC1D,IAAI,CAAC,MAAM,QAAQC,CAAI,GAAG;EAC1B,IAAMC,IAAiBD,EAAK;EAC5B,IAAsB,OAAOC,KAAU,YAAnCA,KAA+C,aAAaA,GAAO;GACrE,IAAMC,IAAWD,EAAgC;GACjD,IAAI,OAAOC,KAAY,YAAYA,EAAQ,KAAK,MAAM,IAAI,OAAOA;EACnE;CAEF;CAEA,IAAsB,OAAOC,KAAU,aAAnCA,GAA6C;CACjD,IAAMC,IAAYD,GAKZE,IAAoBN,EAAaK,EAAU,aAAa;CAC9D,IAAIC,GAAmB,OAAOA;CAC9B,IAAMC,IAAaP,EAAaK,EAAU,MAAM;CAChD,IAAIE,GAAY,OAAOA;CACvB,IAAMC,IAAeH,EAAU;CAC/B,IAA6B,OAAOG,KAAiB,YAAjDA,GAA2D;EAC7D,IAAMC,IAAoBT,EAAcQ,EAAsC,MAAM;EACpF,IAAIC,GAAmB,OAAOA;CAChC;CACA,IAAID,aAAwB,SAASA,EAAa,QAAQ,KAAK,MAAM,IACnE,OAAOA,EAAa;AAGxB;AAOA,SAAgBE,EAAoB,GAAgB,GAA0B;CAM5E,OALkBX,EAA6BK,CAC3C,MACAA,aAAiB,SAASA,EAAM,QAAQ,KAAK,MAAM,KAC9CA,EAAM,UAERO;AACT"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formatting utilities
|
|
3
|
+
* @module botlit/utils
|
|
4
|
+
*/
|
|
5
|
+
/** Rendered in place of a value the service has not provided. */
|
|
6
|
+
export declare const MISSING_VALUE = "\u2014";
|
|
7
|
+
/**
|
|
8
|
+
* Format a date string to a localized date format
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatDate(dateString: string | null | undefined, options?: Intl.DateTimeFormatOptions): string;
|
|
11
|
+
/**
|
|
12
|
+
* Format a date string to a relative time (e.g., "2 hours ago")
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatRelativeTime(dateString: string | null | undefined): string;
|
|
15
|
+
/**
|
|
16
|
+
* Format a number with commas
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatNumber(num: number | null | undefined): string;
|
|
19
|
+
/**
|
|
20
|
+
* Format bytes to human-readable size
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatBytes(bytesValue: number | null | undefined): string;
|
|
23
|
+
/**
|
|
24
|
+
* Format duration in milliseconds to human-readable format
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatDuration(msValue: number | null | undefined): string;
|
|
27
|
+
/**
|
|
28
|
+
* Format tokens count
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatTokens(tokensValue: number | null | undefined): string;
|
|
31
|
+
/**
|
|
32
|
+
* Format cost in USD
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatCost(costValue: number | null | undefined): string;
|
|
35
|
+
/**
|
|
36
|
+
* Format currency (alias for formatCost with more flexibility)
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatCurrency(amountValue: number | null | undefined, currency?: string): string;
|
|
@@ -31,7 +31,6 @@ function i(e, t = "USD") {
|
|
|
31
31
|
maximumFractionDigits: n < 1 ? 4 : 2
|
|
32
32
|
}).format(n);
|
|
33
33
|
}
|
|
34
|
-
//#endregion
|
|
35
34
|
export { i as formatCurrency, e as formatDate, r as formatDuration, n as formatNumber, t as formatRelativeTime };
|
|
36
35
|
|
|
37
36
|
//# sourceMappingURL=formatters.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.js","names":[],"sources":["../../../src/botlit/utils/formatters.ts"],"sourcesContent":["/**\n * Formatting utilities\n * @module botlit/utils\n */\n\n/** Rendered in place of a value the service has not provided. */\nexport const MISSING_VALUE = '\\u2014';\n\n/**\n * Format a date string to a localized date format\n */\nexport function formatDate(\n dateString: string | null | undefined,\n options?: Intl.DateTimeFormatOptions\n): string {\n if (!dateString) return MISSING_VALUE;\n const date = new Date(dateString);\n if (Number.isNaN(date.getTime())) return MISSING_VALUE;\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n ...options,\n });\n}\n\n/**\n * Format a date string to a relative time (e.g., \"2 hours ago\")\n */\nexport function formatRelativeTime(dateString: string | null | undefined): string {\n if (!dateString) return MISSING_VALUE;\n const date = new Date(dateString);\n if (Number.isNaN(date.getTime())) return MISSING_VALUE;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffSec = Math.floor(diffMs / 1000);\n const diffMin = Math.floor(diffSec / 60);\n const diffHr = Math.floor(diffMin / 60);\n const diffDays = Math.floor(diffHr / 24);\n const diffWeeks = Math.floor(diffDays / 7);\n const diffMonths = Math.floor(diffDays / 30);\n\n if (diffSec < 60) {\n return 'just now';\n } else if (diffMin < 60) {\n return `${diffMin} minute${diffMin === 1 ? '' : 's'} ago`;\n } else if (diffHr < 24) {\n return `${diffHr} hour${diffHr === 1 ? '' : 's'} ago`;\n } else if (diffDays < 7) {\n return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;\n } else if (diffWeeks < 4) {\n return `${diffWeeks} week${diffWeeks === 1 ? '' : 's'} ago`;\n } else if (diffMonths < 12) {\n return `${diffMonths} month${diffMonths === 1 ? '' : 's'} ago`;\n } else {\n return formatDate(dateString);\n }\n}\n\n/**\n * Format a number with commas\n */\nexport function formatNumber(num: number | null | undefined): string {\n return (num ?? 0).toLocaleString('en-US');\n}\n\n/**\n * Format bytes to human-readable size\n */\nexport function formatBytes(bytesValue: number | null | undefined): string {\n const bytes = bytesValue ?? 0;\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Format duration in milliseconds to human-readable format\n */\nexport function formatDuration(msValue: number | null | undefined): string {\n const ms = msValue ?? 0;\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n const min = Math.floor(ms / 60000);\n const sec = Math.floor((ms % 60000) / 1000);\n return `${min}m ${sec}s`;\n }\n}\n\n/**\n * Format tokens count\n */\nexport function formatTokens(tokensValue: number | null | undefined): string {\n const tokens = tokensValue ?? 0;\n if (tokens < 1000) {\n return tokens.toString();\n } else if (tokens < 1000000) {\n return `${(tokens / 1000).toFixed(1)}K`;\n } else {\n return `${(tokens / 1000000).toFixed(2)}M`;\n }\n}\n\n/**\n * Format cost in USD\n */\nexport function formatCost(costValue: number | null | undefined): string {\n const cost = costValue ?? 0;\n if (cost < 0.01) {\n return `$${cost.toFixed(4)}`;\n } else if (cost < 1) {\n return `$${cost.toFixed(3)}`;\n } else {\n return `$${cost.toFixed(2)}`;\n }\n}\n\n/**\n * Format currency (alias for formatCost with more flexibility)\n */\nexport function formatCurrency(\n amountValue: number | null | undefined,\n currency: string = 'USD'\n): string {\n const amount = amountValue ?? 0;\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n minimumFractionDigits: 2,\n maximumFractionDigits: amount < 1 ? 4 : 2,\n }).format(amount);\n}\n"],"mappings":"AAWA,
|
|
1
|
+
{"version":3,"file":"formatters.js","names":["formatDate","dateString","date","options","formatRelativeTime","diffMs","diffSec","diffMin","diffHr","diffDays","diffWeeks","diffMonths","formatNumber","num","formatDuration","ms","msValue","formatCurrency","amount","amountValue"],"sources":["../../../src/botlit/utils/formatters.ts"],"sourcesContent":["/**\n * Formatting utilities\n * @module botlit/utils\n */\n\n/** Rendered in place of a value the service has not provided. */\nexport const MISSING_VALUE = '\\u2014';\n\n/**\n * Format a date string to a localized date format\n */\nexport function formatDate(\n dateString: string | null | undefined,\n options?: Intl.DateTimeFormatOptions\n): string {\n if (!dateString) return MISSING_VALUE;\n const date = new Date(dateString);\n if (Number.isNaN(date.getTime())) return MISSING_VALUE;\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n ...options,\n });\n}\n\n/**\n * Format a date string to a relative time (e.g., \"2 hours ago\")\n */\nexport function formatRelativeTime(dateString: string | null | undefined): string {\n if (!dateString) return MISSING_VALUE;\n const date = new Date(dateString);\n if (Number.isNaN(date.getTime())) return MISSING_VALUE;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffSec = Math.floor(diffMs / 1000);\n const diffMin = Math.floor(diffSec / 60);\n const diffHr = Math.floor(diffMin / 60);\n const diffDays = Math.floor(diffHr / 24);\n const diffWeeks = Math.floor(diffDays / 7);\n const diffMonths = Math.floor(diffDays / 30);\n\n if (diffSec < 60) {\n return 'just now';\n } else if (diffMin < 60) {\n return `${diffMin} minute${diffMin === 1 ? '' : 's'} ago`;\n } else if (diffHr < 24) {\n return `${diffHr} hour${diffHr === 1 ? '' : 's'} ago`;\n } else if (diffDays < 7) {\n return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;\n } else if (diffWeeks < 4) {\n return `${diffWeeks} week${diffWeeks === 1 ? '' : 's'} ago`;\n } else if (diffMonths < 12) {\n return `${diffMonths} month${diffMonths === 1 ? '' : 's'} ago`;\n } else {\n return formatDate(dateString);\n }\n}\n\n/**\n * Format a number with commas\n */\nexport function formatNumber(num: number | null | undefined): string {\n return (num ?? 0).toLocaleString('en-US');\n}\n\n/**\n * Format bytes to human-readable size\n */\nexport function formatBytes(bytesValue: number | null | undefined): string {\n const bytes = bytesValue ?? 0;\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Format duration in milliseconds to human-readable format\n */\nexport function formatDuration(msValue: number | null | undefined): string {\n const ms = msValue ?? 0;\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n const min = Math.floor(ms / 60000);\n const sec = Math.floor((ms % 60000) / 1000);\n return `${min}m ${sec}s`;\n }\n}\n\n/**\n * Format tokens count\n */\nexport function formatTokens(tokensValue: number | null | undefined): string {\n const tokens = tokensValue ?? 0;\n if (tokens < 1000) {\n return tokens.toString();\n } else if (tokens < 1000000) {\n return `${(tokens / 1000).toFixed(1)}K`;\n } else {\n return `${(tokens / 1000000).toFixed(2)}M`;\n }\n}\n\n/**\n * Format cost in USD\n */\nexport function formatCost(costValue: number | null | undefined): string {\n const cost = costValue ?? 0;\n if (cost < 0.01) {\n return `$${cost.toFixed(4)}`;\n } else if (cost < 1) {\n return `$${cost.toFixed(3)}`;\n } else {\n return `$${cost.toFixed(2)}`;\n }\n}\n\n/**\n * Format currency (alias for formatCost with more flexibility)\n */\nexport function formatCurrency(\n amountValue: number | null | undefined,\n currency: string = 'USD'\n): string {\n const amount = amountValue ?? 0;\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n minimumFractionDigits: 2,\n maximumFractionDigits: amount < 1 ? 4 : 2,\n }).format(amount);\n}\n"],"mappings":"AAWA,SAAgBA,EACd,GACA,GACQ;CACR,IAAI,CAACC,GAAY,OAAA;CACjB,IAAMC,IAAO,IAAI,KAAKD,CAAU;CAEhC,OADI,OAAO,MAAMC,EAAK,QAAQ,CAAC,IAAG,MAC3BA,EAAK,mBAAmB,SAAS;EACtC,MAAM;EACN,OAAO;EACP,KAAK;EACL,GAAGC;CACL,CAAC;AACH;AAKA,SAAgBC,EAAmB,GAA+C;CAChF,IAAI,CAACH,GAAY,OAAA;CACjB,IAAMC,IAAO,IAAI,KAAKD,CAAU;CAChC,IAAI,OAAO,MAAMC,EAAK,QAAQ,CAAC,GAAG,OAAA;CAElC,IAAMG,qBAAS,IADC,KACD,EAAA,CAAI,QAAQ,IAAIH,EAAK,QAAQ,GACtCI,IAAU,KAAK,MAAMD,IAAS,GAAI,GAClCE,IAAU,KAAK,MAAMD,IAAU,EAAE,GACjCE,IAAS,KAAK,MAAMD,IAAU,EAAE,GAChCE,IAAW,KAAK,MAAMD,IAAS,EAAE,GACjCE,IAAY,KAAK,MAAMD,IAAW,CAAC,GACnCE,IAAa,KAAK,MAAMF,IAAW,EAAE;CAezC,OAbEH,IAAU,KACL,aACEC,IAAU,KACZ,GAAGA,EAAQ,SAASA,MAAY,IAAI,KAAK,IAAI,QAC3CC,IAAS,KACX,GAAGA,EAAO,OAAOA,MAAW,IAAI,KAAK,IAAI,QACvCC,IAAW,IACb,GAAGA,EAAS,MAAMA,MAAa,IAAI,KAAK,IAAI,QAC1CC,IAAY,IACd,GAAGA,EAAU,OAAOA,MAAc,IAAI,KAAK,IAAI,QAC7CC,IAAa,KACf,GAAGA,EAAW,QAAQA,MAAe,IAAI,KAAK,IAAI,QAElDX,EAAWC,CAAU;AAEhC;AAKA,SAAgBW,EAAa,GAAwC;CACnE,QAAQC,KAAO,EAAA,CAAG,eAAe,OAAO;AAC1C;AAiBA,SAAgBC,EAAe,GAA4C;CACzE,IAAMC,IAAKC,KAAW;CAQpB,OAPED,IAAK,MACA,GAAGA,EAAG,MACJA,IAAK,MACP,IAAIA,IAAK,IAAA,CAAM,QAAQ,CAAC,EAAE,KAI1B,GAFK,KAAK,MAAMA,IAAK,GAElB,EAAI,IADF,KAAK,MAAOA,IAAK,MAAS,GACpB,EAAI;AAE1B;AAiCA,SAAgBE,EACd,GACA,IAAmB,OACX;CACR,IAAMC,IAASC,KAAe;CAC9B,OAAO,IAAI,KAAK,aAAa,SAAS;EACpC,OAAO;EACP;EACA,uBAAuB;EACvB,uBAAuBD,IAAS,IAAI,IAAI;CAC1C,CAAC,CAAC,CAAC,OAAOA,CAAM;AAClB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation utilities for the BotManor microfrontend
|
|
3
|
+
* @module botlit/utils
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Join basePath with a relative path, correctly handling slashes
|
|
7
|
+
*
|
|
8
|
+
* @param basePath - The base path (e.g., '/' or '/botlit')
|
|
9
|
+
* @param relativePath - The relative path (e.g., 'bots/new' or '/bots/new')
|
|
10
|
+
* @returns The joined path (e.g., '/botlit/bots/new')
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* joinPath('/', 'bots/new') // => '/bots/new'
|
|
14
|
+
* joinPath('/', '/bots/new') // => '/bots/new'
|
|
15
|
+
* joinPath('/botlit', 'bots') // => '/botlit/bots'
|
|
16
|
+
* joinPath('/botlit/', 'bots') // => '/botlit/bots'
|
|
17
|
+
* joinPath('/botlit', '') // => '/botlit'
|
|
18
|
+
*/
|
|
19
|
+
export declare function joinPath(basePath: string, relativePath: string): string;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
// src/botlit/utils/navigation.ts
|
|
2
2
|
function e(e, t) {
|
|
3
3
|
let n = e.endsWith("/") ? e.slice(0, -1) : e;
|
|
4
4
|
return !t || t === "" ? n || "/" : n + (t.startsWith("/") ? t : `/${t}`);
|
|
5
5
|
}
|
|
6
|
-
//#endregion
|
|
7
6
|
export { e as joinPath };
|
|
8
7
|
|
|
9
8
|
//# sourceMappingURL=navigation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","names":[],"sources":["../../../src/botlit/utils/navigation.ts"],"sourcesContent":["/**\n * Navigation utilities for the BotManor microfrontend\n * @module botlit/utils\n */\n\n/**\n * Join basePath with a relative path, correctly handling slashes\n *\n * @param basePath - The base path (e.g., '/' or '/botlit')\n * @param relativePath - The relative path (e.g., 'bots/new' or '/bots/new')\n * @returns The joined path (e.g., '/botlit/bots/new')\n *\n * @example\n * joinPath('/', 'bots/new') // => '/bots/new'\n * joinPath('/', '/bots/new') // => '/bots/new'\n * joinPath('/botlit', 'bots') // => '/botlit/bots'\n * joinPath('/botlit/', 'bots') // => '/botlit/bots'\n * joinPath('/botlit', '') // => '/botlit'\n */\nexport function joinPath(basePath: string, relativePath: string): string {\n // Remove trailing slash from base\n const cleanBase = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\n\n // Handle empty relative path (go to base)\n if (!relativePath || relativePath === '') {\n return cleanBase || '/';\n }\n\n // Ensure relative path starts with /\n const cleanPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`;\n\n // Join them\n return cleanBase + cleanPath;\n}\n"],"mappings":";AAmBA,
|
|
1
|
+
{"version":3,"file":"navigation.js","names":["joinPath","cleanBase","basePath","relativePath"],"sources":["../../../src/botlit/utils/navigation.ts"],"sourcesContent":["/**\n * Navigation utilities for the BotManor microfrontend\n * @module botlit/utils\n */\n\n/**\n * Join basePath with a relative path, correctly handling slashes\n *\n * @param basePath - The base path (e.g., '/' or '/botlit')\n * @param relativePath - The relative path (e.g., 'bots/new' or '/bots/new')\n * @returns The joined path (e.g., '/botlit/bots/new')\n *\n * @example\n * joinPath('/', 'bots/new') // => '/bots/new'\n * joinPath('/', '/bots/new') // => '/bots/new'\n * joinPath('/botlit', 'bots') // => '/botlit/bots'\n * joinPath('/botlit/', 'bots') // => '/botlit/bots'\n * joinPath('/botlit', '') // => '/botlit'\n */\nexport function joinPath(basePath: string, relativePath: string): string {\n // Remove trailing slash from base\n const cleanBase = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\n\n // Handle empty relative path (go to base)\n if (!relativePath || relativePath === '') {\n return cleanBase || '/';\n }\n\n // Ensure relative path starts with /\n const cleanPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`;\n\n // Join them\n return cleanBase + cleanPath;\n}\n"],"mappings":";AAmBA,SAAgBA,EAAS,GAAkB,GAA8B;CAEvE,IAAMC,IAAYC,EAAS,SAAS,GAAG,IAAIA,EAAS,MAAM,GAAG,EAAE,IAAIA;CAWnE,OARI,CAACC,KAAgBA,MAAiB,KAC7BF,KAAa,MAOfA,KAHWE,EAAa,WAAW,GAAG,IAAIA,IAAe,IAAIA;AAItE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { PolicyConfig, PolicyType } from '../types';
|
|
2
|
+
/** Policy types the editor can create, i.e. the types with a runtime evaluator. */
|
|
3
|
+
export declare const CREATABLE_POLICY_TYPES: readonly ["CONTENT", "TOOL", "RESPONSE", "BUDGET", "RATE_LIMIT", "RETENTION"];
|
|
4
|
+
export type CreatablePolicyType = (typeof CREATABLE_POLICY_TYPES)[number];
|
|
5
|
+
export declare function isCreatablePolicyType(type: PolicyType): type is CreatablePolicyType;
|
|
6
|
+
export declare const TOOL_RISK_LEVELS: readonly ["LOW", "MEDIUM", "HIGH"];
|
|
7
|
+
export declare const A2A_TRUST_LEVELS: readonly ["UNVERIFIED", "VERIFIED_PUBLISHER", "INTERNAL"];
|
|
8
|
+
/**
|
|
9
|
+
* Raw editor state. Numeric fields are strings so a field can be left empty,
|
|
10
|
+
* which means "not configured" rather than a default limit.
|
|
11
|
+
*/
|
|
12
|
+
export interface PolicyFormState {
|
|
13
|
+
content: {
|
|
14
|
+
piiDetection: boolean;
|
|
15
|
+
blockedKeywords: string;
|
|
16
|
+
blockedPatterns: string;
|
|
17
|
+
};
|
|
18
|
+
tool: {
|
|
19
|
+
allowedTools: string;
|
|
20
|
+
deniedTools: string;
|
|
21
|
+
maxToolRiskLevel: '' | (typeof TOOL_RISK_LEVELS)[number];
|
|
22
|
+
a2aMinTrustLevel: '' | (typeof A2A_TRUST_LEVELS)[number];
|
|
23
|
+
maxCallsPerExecution: string;
|
|
24
|
+
timeoutSeconds: string;
|
|
25
|
+
};
|
|
26
|
+
budget: {
|
|
27
|
+
maxTokensPerDay: string;
|
|
28
|
+
maxTokensPerExecution: string;
|
|
29
|
+
};
|
|
30
|
+
rateLimit: {
|
|
31
|
+
requestsPerMinute: string;
|
|
32
|
+
requestsPerHour: string;
|
|
33
|
+
tokensPerMinute: string;
|
|
34
|
+
};
|
|
35
|
+
response: {
|
|
36
|
+
allowedModels: string;
|
|
37
|
+
allowedProviders: string;
|
|
38
|
+
};
|
|
39
|
+
retention: {
|
|
40
|
+
executionDataRetentionDays: string;
|
|
41
|
+
conversationRetentionDays: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export declare const EMPTY_POLICY_FORM: PolicyFormState;
|
|
45
|
+
/** Longest retention period the runtime accepts (10 years). */
|
|
46
|
+
export declare const MAX_RETENTION_DAYS = 3650;
|
|
47
|
+
export type PolicyConfigResult = {
|
|
48
|
+
ok: true;
|
|
49
|
+
config: PolicyConfig;
|
|
50
|
+
} | {
|
|
51
|
+
ok: false;
|
|
52
|
+
error: string;
|
|
53
|
+
};
|
|
54
|
+
/** Split a comma-separated form value into trimmed, non-empty entries. */
|
|
55
|
+
export declare function splitList(value: string): string[];
|
|
56
|
+
/** Split a one-entry-per-line form value into trimmed, non-empty entries. */
|
|
57
|
+
export declare function splitLines(value: string): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Build the config for a new policy from the editor state, or explain what is
|
|
60
|
+
* wrong with the input. Only enforced keys are ever written.
|
|
61
|
+
*/
|
|
62
|
+
export declare function buildPolicyConfig(type: CreatablePolicyType, state: PolicyFormState): PolicyConfigResult;
|
|
63
|
+
/**
|
|
64
|
+
* Config keys on a stored policy that the runtime does not enforce, e.g.
|
|
65
|
+
* settings written by an earlier version of this editor. `null` when the
|
|
66
|
+
* policy type has no runtime evaluator at all.
|
|
67
|
+
*/
|
|
68
|
+
export declare function unenforcedConfigKeys(type: PolicyType, config: unknown): string[] | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/botlit/utils/policyConfig.ts
|
|
2
2
|
var e = [
|
|
3
3
|
"CONTENT",
|
|
4
4
|
"TOOL",
|
|
@@ -208,7 +208,6 @@ function S(e, t) {
|
|
|
208
208
|
}
|
|
209
209
|
return r;
|
|
210
210
|
}
|
|
211
|
-
|
|
212
|
-
export { r as A2A_TRUST_LEVELS, e as CREATABLE_POLICY_TYPES, i as EMPTY_POLICY_FORM, a as MAX_RETENTION_DAYS, n as TOOL_RISK_LEVELS, y as buildPolicyConfig, t as isCreatablePolicyType, S as unenforcedConfigKeys };
|
|
211
|
+
export { r as A2A_TRUST_LEVELS, e as CREATABLE_POLICY_TYPES, i as EMPTY_POLICY_FORM, a as MAX_RETENTION_DAYS, n as TOOL_RISK_LEVELS, y as buildPolicyConfig, t as isCreatablePolicyType, s as splitLines, o as splitList, S as unenforcedConfigKeys };
|
|
213
212
|
|
|
214
213
|
//# sourceMappingURL=policyConfig.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policyConfig.js","names":[],"sources":["../../../src/botlit/utils/policyConfig.ts"],"sourcesContent":["/**\n * Policy editor form state <-> the config shape the BotManor runtime enforces.\n *\n * Every key this module writes is read by the backend `PolicyEvaluatorService`\n * (or the tool runtime that applies a resolved TOOL policy). Settings the\n * runtime does not enforce are deliberately absent, so the editor never offers\n * a control that looks binding and is silently ignored (BOFF-9683).\n * @module botlit/utils\n */\n\nimport type { PolicyConfig, PolicyType } from '../types';\n\n/** Policy types the editor can create, i.e. the types with a runtime evaluator. */\nexport const CREATABLE_POLICY_TYPES = [\n 'CONTENT',\n 'TOOL',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n] as const;\nexport type CreatablePolicyType = (typeof CREATABLE_POLICY_TYPES)[number];\n\nexport function isCreatablePolicyType(type: PolicyType): type is CreatablePolicyType {\n return (CREATABLE_POLICY_TYPES as readonly string[]).includes(type);\n}\n\nexport const TOOL_RISK_LEVELS = ['LOW', 'MEDIUM', 'HIGH'] as const;\nexport const A2A_TRUST_LEVELS = ['UNVERIFIED', 'VERIFIED_PUBLISHER', 'INTERNAL'] as const;\n\n/**\n * Raw editor state. Numeric fields are strings so a field can be left empty,\n * which means \"not configured\" rather than a default limit.\n */\nexport interface PolicyFormState {\n content: { piiDetection: boolean; blockedKeywords: string; blockedPatterns: string };\n tool: {\n allowedTools: string;\n deniedTools: string;\n maxToolRiskLevel: '' | (typeof TOOL_RISK_LEVELS)[number];\n a2aMinTrustLevel: '' | (typeof A2A_TRUST_LEVELS)[number];\n maxCallsPerExecution: string;\n timeoutSeconds: string;\n };\n budget: { maxTokensPerDay: string; maxTokensPerExecution: string };\n rateLimit: { requestsPerMinute: string; requestsPerHour: string; tokensPerMinute: string };\n response: { allowedModels: string; allowedProviders: string };\n retention: { executionDataRetentionDays: string; conversationRetentionDays: string };\n}\n\nexport const EMPTY_POLICY_FORM: PolicyFormState = {\n content: { piiDetection: true, blockedKeywords: '', blockedPatterns: '' },\n tool: {\n allowedTools: '',\n deniedTools: '',\n maxToolRiskLevel: '',\n a2aMinTrustLevel: '',\n maxCallsPerExecution: '',\n timeoutSeconds: '',\n },\n budget: { maxTokensPerDay: '', maxTokensPerExecution: '' },\n rateLimit: { requestsPerMinute: '60', requestsPerHour: '1000', tokensPerMinute: '' },\n response: { allowedModels: '', allowedProviders: '' },\n retention: { executionDataRetentionDays: '90', conversationRetentionDays: '' },\n};\n\n/** Longest retention period the runtime accepts (10 years). */\nexport const MAX_RETENTION_DAYS = 3650;\n\nexport type PolicyConfigResult = { ok: true; config: PolicyConfig } | { ok: false; error: string };\n\n/** Split a comma-separated form value into trimmed, non-empty entries. */\nexport function splitList(value: string): string[] {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\n/** Split a one-entry-per-line form value into trimmed, non-empty entries. */\nexport function splitLines(value: string): string[] {\n return value\n .split('\\n')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\nclass PolicyFormError extends Error {}\n\n/** Parse an optional positive whole number; empty means \"not configured\". */\nfunction optionalPositiveInt(value: string, label: string): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const parsed = Number(trimmed);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new PolicyFormError(`${label} must be a whole number of at least 1, or left empty.`);\n }\n return parsed;\n}\n\n/** Parse an optional whole number of days in `[min, MAX_RETENTION_DAYS]`; empty means \"not set\". */\nfunction optionalDays(value: string, label: string, min: number): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const parsed = Number(trimmed);\n if (!Number.isInteger(parsed) || parsed < min || parsed > MAX_RETENTION_DAYS) {\n throw new PolicyFormError(\n `${label} must be a whole number of days from ${min} to ${MAX_RETENTION_DAYS}, or left empty.`\n );\n }\n return parsed;\n}\n\nfunction assertValidPatterns(patterns: string[]): void {\n for (const pattern of patterns) {\n try {\n // Compiled only to validate admin input; the runtime compiles the same source.\n new RegExp(pattern, 'i');\n } catch {\n throw new PolicyFormError(`\"${pattern}\" is not a valid regular expression.`);\n }\n }\n}\n\nfunction withDefined<T extends Record<string, unknown>>(entries: T): Partial<T> {\n return Object.fromEntries(\n Object.entries(entries).filter(([, value]) => value !== undefined && value !== '')\n ) as Partial<T>;\n}\n\nfunction buildContentConfig(state: PolicyFormState['content']): PolicyConfig {\n const blockedKeywords = splitList(state.blockedKeywords);\n const blockedPatterns = splitLines(state.blockedPatterns);\n assertValidPatterns(blockedPatterns);\n return {\n piiDetection: state.piiDetection,\n ...(blockedKeywords.length > 0 ? { blockedKeywords } : {}),\n ...(blockedPatterns.length > 0 ? { blockedPatterns } : {}),\n };\n}\n\nfunction buildToolConfig(state: PolicyFormState['tool']): PolicyConfig {\n const allowedTools = splitList(state.allowedTools);\n const deniedTools = splitList(state.deniedTools);\n const limits = withDefined({\n maxCallsPerExecution: optionalPositiveInt(\n state.maxCallsPerExecution,\n 'Max tool calls per execution'\n ),\n timeoutSeconds: optionalPositiveInt(state.timeoutSeconds, 'Tool call timeout'),\n });\n return {\n ...(allowedTools.length > 0 ? { allowedTools } : {}),\n ...(deniedTools.length > 0 ? { deniedTools } : {}),\n ...(state.maxToolRiskLevel ? { maxToolRiskLevel: state.maxToolRiskLevel } : {}),\n ...(state.a2aMinTrustLevel ? { a2aMinTrustLevel: state.a2aMinTrustLevel } : {}),\n ...(Object.keys(limits).length > 0 ? { limits } : {}),\n };\n}\n\nfunction buildBudgetConfig(state: PolicyFormState['budget']): PolicyConfig {\n return withDefined({\n maxTokensPerDay: optionalPositiveInt(state.maxTokensPerDay, 'Max tokens per day'),\n maxTokensPerExecution: optionalPositiveInt(\n state.maxTokensPerExecution,\n 'Max output tokens per model call'\n ),\n });\n}\n\nfunction buildRateLimitConfig(state: PolicyFormState['rateLimit']): PolicyConfig {\n const limits = withDefined({\n requestsPerMinute: optionalPositiveInt(state.requestsPerMinute, 'Requests per minute'),\n requestsPerHour: optionalPositiveInt(state.requestsPerHour, 'Requests per hour'),\n tokensPerMinute: optionalPositiveInt(state.tokensPerMinute, 'Tokens per minute'),\n });\n return Object.keys(limits).length > 0 ? { limits } : {};\n}\n\nfunction buildResponseConfig(state: PolicyFormState['response']): PolicyConfig {\n const allowedModels = splitList(state.allowedModels);\n const allowedProviders = splitList(state.allowedProviders).map((provider) =>\n provider.toUpperCase()\n );\n return {\n ...(allowedModels.length > 0 ? { allowedModels } : {}),\n ...(allowedProviders.length > 0 ? { allowedProviders } : {}),\n };\n}\n\nfunction buildRetentionConfig(state: PolicyFormState['retention']): PolicyConfig {\n const config = withDefined({\n executionDataRetentionDays: optionalDays(\n state.executionDataRetentionDays,\n 'Execution data retention',\n 0\n ),\n conversationRetentionDays: optionalDays(\n state.conversationRetentionDays,\n 'Conversation retention',\n 1\n ),\n });\n if (Object.keys(config).length === 0) {\n throw new PolicyFormError('Set at least one retention period.');\n }\n return config;\n}\n\n/**\n * Build the config for a new policy from the editor state, or explain what is\n * wrong with the input. Only enforced keys are ever written.\n */\nexport function buildPolicyConfig(\n type: CreatablePolicyType,\n state: PolicyFormState\n): PolicyConfigResult {\n try {\n switch (type) {\n case 'CONTENT':\n return { ok: true, config: buildContentConfig(state.content) };\n case 'TOOL':\n return { ok: true, config: buildToolConfig(state.tool) };\n case 'BUDGET':\n return { ok: true, config: buildBudgetConfig(state.budget) };\n case 'RATE_LIMIT':\n return { ok: true, config: buildRateLimitConfig(state.rateLimit) };\n case 'RESPONSE':\n return { ok: true, config: buildResponseConfig(state.response) };\n case 'RETENTION':\n return { ok: true, config: buildRetentionConfig(state.retention) };\n }\n } catch (error) {\n if (error instanceof PolicyFormError) return { ok: false, error: error.message };\n throw error;\n }\n}\n\n/** Config keys the runtime enforces, per policy type (top level). */\nconst ENFORCED_KEYS: Partial<Record<PolicyType, readonly string[]>> = {\n CONTENT: ['piiDetection', 'blockedKeywords', 'blockedPatterns', 'customPatterns'],\n TOOL: ['allowedTools', 'deniedTools', 'maxToolRiskLevel', 'a2aMinTrustLevel', 'limits'],\n RESPONSE: ['allowedModels', 'allowedProviders'],\n BUDGET: ['maxTokensPerDay', 'maxTokensPerExecution'],\n RATE_LIMIT: ['maxRequestsPerMinute', 'limits'],\n RETENTION: ['executionDataRetentionDays', 'conversationRetentionDays'],\n};\n\n/** Enforced keys inside `limits`, for the types that nest limits. */\nconst ENFORCED_LIMIT_KEYS: Partial<Record<PolicyType, readonly string[]>> = {\n TOOL: ['maxCallsPerExecution', 'timeoutSeconds'],\n RATE_LIMIT: ['requestsPerMinute', 'requestsPerHour', 'tokensPerMinute'],\n};\n\n/**\n * Config keys on a stored policy that the runtime does not enforce, e.g.\n * settings written by an earlier version of this editor. `null` when the\n * policy type has no runtime evaluator at all.\n */\nexport function unenforcedConfigKeys(type: PolicyType, config: unknown): string[] | null {\n const enforced = ENFORCED_KEYS[type];\n if (!enforced) return null;\n if (!config || typeof config !== 'object' || Array.isArray(config)) return [];\n\n const ignored: string[] = [];\n for (const [key, value] of Object.entries(config as Record<string, unknown>)) {\n if (!enforced.includes(key)) {\n ignored.push(key);\n continue;\n }\n const limitKeys = ENFORCED_LIMIT_KEYS[type];\n if (\n key === 'limits' &&\n limitKeys &&\n value &&\n typeof value === 'object' &&\n !Array.isArray(value)\n ) {\n for (const limitKey of Object.keys(value as Record<string, unknown>)) {\n if (!limitKeys.includes(limitKey)) ignored.push(`limits.${limitKey}`);\n }\n }\n }\n return ignored;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"policyConfig.js","names":["CREATABLE_POLICY_TYPES","isCreatablePolicyType","type","TOOL_RISK_LEVELS","A2A_TRUST_LEVELS","EMPTY_POLICY_FORM","MAX_RETENTION_DAYS","splitList","value","entry","splitLines","PolicyFormError","optionalPositiveInt","trimmed","parsed","label","optionalDays","min","assertValidPatterns","pattern","patterns","withDefined","entries","buildContentConfig","blockedKeywords","state","blockedPatterns","buildToolConfig","allowedTools","deniedTools","limits","buildBudgetConfig","buildRateLimitConfig","buildResponseConfig","allowedModels","allowedProviders","provider","buildRetentionConfig","config","buildPolicyConfig","error","ENFORCED_KEYS","ENFORCED_LIMIT_KEYS","unenforcedConfigKeys","enforced","ignored","key","limitKeys","limitKey"],"sources":["../../../src/botlit/utils/policyConfig.ts"],"sourcesContent":["/**\n * Policy editor form state <-> the config shape the BotManor runtime enforces.\n *\n * Every key this module writes is read by the backend `PolicyEvaluatorService`\n * (or the tool runtime that applies a resolved TOOL policy). Settings the\n * runtime does not enforce are deliberately absent, so the editor never offers\n * a control that looks binding and is silently ignored (BOFF-9683).\n * @module botlit/utils\n */\n\nimport type { PolicyConfig, PolicyType } from '../types';\n\n/** Policy types the editor can create, i.e. the types with a runtime evaluator. */\nexport const CREATABLE_POLICY_TYPES = [\n 'CONTENT',\n 'TOOL',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n] as const;\nexport type CreatablePolicyType = (typeof CREATABLE_POLICY_TYPES)[number];\n\nexport function isCreatablePolicyType(type: PolicyType): type is CreatablePolicyType {\n return (CREATABLE_POLICY_TYPES as readonly string[]).includes(type);\n}\n\nexport const TOOL_RISK_LEVELS = ['LOW', 'MEDIUM', 'HIGH'] as const;\nexport const A2A_TRUST_LEVELS = ['UNVERIFIED', 'VERIFIED_PUBLISHER', 'INTERNAL'] as const;\n\n/**\n * Raw editor state. Numeric fields are strings so a field can be left empty,\n * which means \"not configured\" rather than a default limit.\n */\nexport interface PolicyFormState {\n content: { piiDetection: boolean; blockedKeywords: string; blockedPatterns: string };\n tool: {\n allowedTools: string;\n deniedTools: string;\n maxToolRiskLevel: '' | (typeof TOOL_RISK_LEVELS)[number];\n a2aMinTrustLevel: '' | (typeof A2A_TRUST_LEVELS)[number];\n maxCallsPerExecution: string;\n timeoutSeconds: string;\n };\n budget: { maxTokensPerDay: string; maxTokensPerExecution: string };\n rateLimit: { requestsPerMinute: string; requestsPerHour: string; tokensPerMinute: string };\n response: { allowedModels: string; allowedProviders: string };\n retention: { executionDataRetentionDays: string; conversationRetentionDays: string };\n}\n\nexport const EMPTY_POLICY_FORM: PolicyFormState = {\n content: { piiDetection: true, blockedKeywords: '', blockedPatterns: '' },\n tool: {\n allowedTools: '',\n deniedTools: '',\n maxToolRiskLevel: '',\n a2aMinTrustLevel: '',\n maxCallsPerExecution: '',\n timeoutSeconds: '',\n },\n budget: { maxTokensPerDay: '', maxTokensPerExecution: '' },\n rateLimit: { requestsPerMinute: '60', requestsPerHour: '1000', tokensPerMinute: '' },\n response: { allowedModels: '', allowedProviders: '' },\n retention: { executionDataRetentionDays: '90', conversationRetentionDays: '' },\n};\n\n/** Longest retention period the runtime accepts (10 years). */\nexport const MAX_RETENTION_DAYS = 3650;\n\nexport type PolicyConfigResult = { ok: true; config: PolicyConfig } | { ok: false; error: string };\n\n/** Split a comma-separated form value into trimmed, non-empty entries. */\nexport function splitList(value: string): string[] {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\n/** Split a one-entry-per-line form value into trimmed, non-empty entries. */\nexport function splitLines(value: string): string[] {\n return value\n .split('\\n')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\nclass PolicyFormError extends Error {}\n\n/** Parse an optional positive whole number; empty means \"not configured\". */\nfunction optionalPositiveInt(value: string, label: string): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const parsed = Number(trimmed);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new PolicyFormError(`${label} must be a whole number of at least 1, or left empty.`);\n }\n return parsed;\n}\n\n/** Parse an optional whole number of days in `[min, MAX_RETENTION_DAYS]`; empty means \"not set\". */\nfunction optionalDays(value: string, label: string, min: number): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const parsed = Number(trimmed);\n if (!Number.isInteger(parsed) || parsed < min || parsed > MAX_RETENTION_DAYS) {\n throw new PolicyFormError(\n `${label} must be a whole number of days from ${min} to ${MAX_RETENTION_DAYS}, or left empty.`\n );\n }\n return parsed;\n}\n\nfunction assertValidPatterns(patterns: string[]): void {\n for (const pattern of patterns) {\n try {\n // Compiled only to validate admin input; the runtime compiles the same source.\n new RegExp(pattern, 'i');\n } catch {\n throw new PolicyFormError(`\"${pattern}\" is not a valid regular expression.`);\n }\n }\n}\n\nfunction withDefined<T extends Record<string, unknown>>(entries: T): Partial<T> {\n return Object.fromEntries(\n Object.entries(entries).filter(([, value]) => value !== undefined && value !== '')\n ) as Partial<T>;\n}\n\nfunction buildContentConfig(state: PolicyFormState['content']): PolicyConfig {\n const blockedKeywords = splitList(state.blockedKeywords);\n const blockedPatterns = splitLines(state.blockedPatterns);\n assertValidPatterns(blockedPatterns);\n return {\n piiDetection: state.piiDetection,\n ...(blockedKeywords.length > 0 ? { blockedKeywords } : {}),\n ...(blockedPatterns.length > 0 ? { blockedPatterns } : {}),\n };\n}\n\nfunction buildToolConfig(state: PolicyFormState['tool']): PolicyConfig {\n const allowedTools = splitList(state.allowedTools);\n const deniedTools = splitList(state.deniedTools);\n const limits = withDefined({\n maxCallsPerExecution: optionalPositiveInt(\n state.maxCallsPerExecution,\n 'Max tool calls per execution'\n ),\n timeoutSeconds: optionalPositiveInt(state.timeoutSeconds, 'Tool call timeout'),\n });\n return {\n ...(allowedTools.length > 0 ? { allowedTools } : {}),\n ...(deniedTools.length > 0 ? { deniedTools } : {}),\n ...(state.maxToolRiskLevel ? { maxToolRiskLevel: state.maxToolRiskLevel } : {}),\n ...(state.a2aMinTrustLevel ? { a2aMinTrustLevel: state.a2aMinTrustLevel } : {}),\n ...(Object.keys(limits).length > 0 ? { limits } : {}),\n };\n}\n\nfunction buildBudgetConfig(state: PolicyFormState['budget']): PolicyConfig {\n return withDefined({\n maxTokensPerDay: optionalPositiveInt(state.maxTokensPerDay, 'Max tokens per day'),\n maxTokensPerExecution: optionalPositiveInt(\n state.maxTokensPerExecution,\n 'Max output tokens per model call'\n ),\n });\n}\n\nfunction buildRateLimitConfig(state: PolicyFormState['rateLimit']): PolicyConfig {\n const limits = withDefined({\n requestsPerMinute: optionalPositiveInt(state.requestsPerMinute, 'Requests per minute'),\n requestsPerHour: optionalPositiveInt(state.requestsPerHour, 'Requests per hour'),\n tokensPerMinute: optionalPositiveInt(state.tokensPerMinute, 'Tokens per minute'),\n });\n return Object.keys(limits).length > 0 ? { limits } : {};\n}\n\nfunction buildResponseConfig(state: PolicyFormState['response']): PolicyConfig {\n const allowedModels = splitList(state.allowedModels);\n const allowedProviders = splitList(state.allowedProviders).map((provider) =>\n provider.toUpperCase()\n );\n return {\n ...(allowedModels.length > 0 ? { allowedModels } : {}),\n ...(allowedProviders.length > 0 ? { allowedProviders } : {}),\n };\n}\n\nfunction buildRetentionConfig(state: PolicyFormState['retention']): PolicyConfig {\n const config = withDefined({\n executionDataRetentionDays: optionalDays(\n state.executionDataRetentionDays,\n 'Execution data retention',\n 0\n ),\n conversationRetentionDays: optionalDays(\n state.conversationRetentionDays,\n 'Conversation retention',\n 1\n ),\n });\n if (Object.keys(config).length === 0) {\n throw new PolicyFormError('Set at least one retention period.');\n }\n return config;\n}\n\n/**\n * Build the config for a new policy from the editor state, or explain what is\n * wrong with the input. Only enforced keys are ever written.\n */\nexport function buildPolicyConfig(\n type: CreatablePolicyType,\n state: PolicyFormState\n): PolicyConfigResult {\n try {\n switch (type) {\n case 'CONTENT':\n return { ok: true, config: buildContentConfig(state.content) };\n case 'TOOL':\n return { ok: true, config: buildToolConfig(state.tool) };\n case 'BUDGET':\n return { ok: true, config: buildBudgetConfig(state.budget) };\n case 'RATE_LIMIT':\n return { ok: true, config: buildRateLimitConfig(state.rateLimit) };\n case 'RESPONSE':\n return { ok: true, config: buildResponseConfig(state.response) };\n case 'RETENTION':\n return { ok: true, config: buildRetentionConfig(state.retention) };\n }\n } catch (error) {\n if (error instanceof PolicyFormError) return { ok: false, error: error.message };\n throw error;\n }\n}\n\n/** Config keys the runtime enforces, per policy type (top level). */\nconst ENFORCED_KEYS: Partial<Record<PolicyType, readonly string[]>> = {\n CONTENT: ['piiDetection', 'blockedKeywords', 'blockedPatterns', 'customPatterns'],\n TOOL: ['allowedTools', 'deniedTools', 'maxToolRiskLevel', 'a2aMinTrustLevel', 'limits'],\n RESPONSE: ['allowedModels', 'allowedProviders'],\n BUDGET: ['maxTokensPerDay', 'maxTokensPerExecution'],\n RATE_LIMIT: ['maxRequestsPerMinute', 'limits'],\n RETENTION: ['executionDataRetentionDays', 'conversationRetentionDays'],\n};\n\n/** Enforced keys inside `limits`, for the types that nest limits. */\nconst ENFORCED_LIMIT_KEYS: Partial<Record<PolicyType, readonly string[]>> = {\n TOOL: ['maxCallsPerExecution', 'timeoutSeconds'],\n RATE_LIMIT: ['requestsPerMinute', 'requestsPerHour', 'tokensPerMinute'],\n};\n\n/**\n * Config keys on a stored policy that the runtime does not enforce, e.g.\n * settings written by an earlier version of this editor. `null` when the\n * policy type has no runtime evaluator at all.\n */\nexport function unenforcedConfigKeys(type: PolicyType, config: unknown): string[] | null {\n const enforced = ENFORCED_KEYS[type];\n if (!enforced) return null;\n if (!config || typeof config !== 'object' || Array.isArray(config)) return [];\n\n const ignored: string[] = [];\n for (const [key, value] of Object.entries(config as Record<string, unknown>)) {\n if (!enforced.includes(key)) {\n ignored.push(key);\n continue;\n }\n const limitKeys = ENFORCED_LIMIT_KEYS[type];\n if (\n key === 'limits' &&\n limitKeys &&\n value &&\n typeof value === 'object' &&\n !Array.isArray(value)\n ) {\n for (const limitKey of Object.keys(value as Record<string, unknown>)) {\n if (!limitKeys.includes(limitKey)) ignored.push(`limits.${limitKey}`);\n }\n }\n }\n return ignored;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Union narrowing helpers
|
|
3
|
+
* @module botlit/utils
|
|
4
|
+
*
|
|
5
|
+
* wspace-botlit-svc returns enum columns as plain `String` through the
|
|
6
|
+
* generated types, while the UI renders them against closed unions
|
|
7
|
+
* (`ChannelType`, `PolicyType`, `Visibility`…). Narrowing has to happen at the
|
|
8
|
+
* boundary — a value the service adds later must fall back to something
|
|
9
|
+
* renderable rather than reaching a lookup table that has no entry for it.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Narrows a free-form service string onto the union the UI renders.
|
|
13
|
+
*
|
|
14
|
+
* The match is by value, so the element returned from `allowed` is genuinely a
|
|
15
|
+
* `TUnion` — no cast is involved.
|
|
16
|
+
*/
|
|
17
|
+
export declare function toUnion<TUnion extends string>(value: string | null | undefined, allowed: readonly TUnion[], fallback: TUnion): TUnion;
|
|
18
|
+
/** Reads a string out of a free-form JSON object, or `undefined`. */
|
|
19
|
+
export declare function jsonString(source: Record<string, unknown> | null | undefined, key: string): string | undefined;
|
|
20
|
+
/** Reads a boolean out of a free-form JSON object (absent counts as `false`). */
|
|
21
|
+
export declare function jsonBoolean(source: Record<string, unknown> | null | undefined, key: string): boolean;
|
|
22
|
+
/** Reads a number out of a free-form JSON object, or `undefined`. */
|
|
23
|
+
export declare function jsonNumber(source: Record<string, unknown> | null | undefined, key: string): number | undefined;
|
|
24
|
+
/** Reads an array of records out of a free-form JSON value. */
|
|
25
|
+
export declare function jsonRecords(value: unknown): Record<string, unknown>[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/botlit/utils/unions.ts
|
|
2
2
|
function e(e, t, n) {
|
|
3
3
|
return t.find((t) => t === e) ?? n;
|
|
4
4
|
}
|
|
@@ -8,7 +8,6 @@ function t(e, t) {
|
|
|
8
8
|
function n(e) {
|
|
9
9
|
return Array.isArray(e) ? e.filter((e) => typeof e == "object" && !!e && !Array.isArray(e)) : [];
|
|
10
10
|
}
|
|
11
|
-
//#endregion
|
|
12
11
|
export { t as jsonBoolean, n as jsonRecords, e as toUnion };
|
|
13
12
|
|
|
14
13
|
//# sourceMappingURL=unions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unions.js","names":[],"sources":["../../../src/botlit/utils/unions.ts"],"sourcesContent":["/**\n * Union narrowing helpers\n * @module botlit/utils\n *\n * wspace-botlit-svc returns enum columns as plain `String` through the\n * generated types, while the UI renders them against closed unions\n * (`ChannelType`, `PolicyType`, `Visibility`…). Narrowing has to happen at the\n * boundary — a value the service adds later must fall back to something\n * renderable rather than reaching a lookup table that has no entry for it.\n */\n\n/**\n * Narrows a free-form service string onto the union the UI renders.\n *\n * The match is by value, so the element returned from `allowed` is genuinely a\n * `TUnion` — no cast is involved.\n */\nexport function toUnion<TUnion extends string>(\n value: string | null | undefined,\n allowed: readonly TUnion[],\n fallback: TUnion\n): TUnion {\n return allowed.find((candidate) => candidate === value) ?? fallback;\n}\n\n/** Reads a string out of a free-form JSON object, or `undefined`. */\nexport function jsonString(\n source: Record<string, unknown> | null | undefined,\n key: string\n): string | undefined {\n const value = source?.[key];\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\n/** Reads a boolean out of a free-form JSON object (absent counts as `false`). */\nexport function jsonBoolean(\n source: Record<string, unknown> | null | undefined,\n key: string\n): boolean {\n return source?.[key] === true;\n}\n\n/** Reads a number out of a free-form JSON object, or `undefined`. */\nexport function jsonNumber(\n source: Record<string, unknown> | null | undefined,\n key: string\n): number | undefined {\n const value = source?.[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n/** Reads an array of records out of a free-form JSON value. */\nexport function jsonRecords(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter(\n (entry): entry is Record<string, unknown> =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n );\n}\n"],"mappings":";AAiBA,
|
|
1
|
+
{"version":3,"file":"unions.js","names":["toUnion","allowed","candidate","value","fallback","jsonBoolean","source","key","jsonRecords","entry"],"sources":["../../../src/botlit/utils/unions.ts"],"sourcesContent":["/**\n * Union narrowing helpers\n * @module botlit/utils\n *\n * wspace-botlit-svc returns enum columns as plain `String` through the\n * generated types, while the UI renders them against closed unions\n * (`ChannelType`, `PolicyType`, `Visibility`…). Narrowing has to happen at the\n * boundary — a value the service adds later must fall back to something\n * renderable rather than reaching a lookup table that has no entry for it.\n */\n\n/**\n * Narrows a free-form service string onto the union the UI renders.\n *\n * The match is by value, so the element returned from `allowed` is genuinely a\n * `TUnion` — no cast is involved.\n */\nexport function toUnion<TUnion extends string>(\n value: string | null | undefined,\n allowed: readonly TUnion[],\n fallback: TUnion\n): TUnion {\n return allowed.find((candidate) => candidate === value) ?? fallback;\n}\n\n/** Reads a string out of a free-form JSON object, or `undefined`. */\nexport function jsonString(\n source: Record<string, unknown> | null | undefined,\n key: string\n): string | undefined {\n const value = source?.[key];\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\n/** Reads a boolean out of a free-form JSON object (absent counts as `false`). */\nexport function jsonBoolean(\n source: Record<string, unknown> | null | undefined,\n key: string\n): boolean {\n return source?.[key] === true;\n}\n\n/** Reads a number out of a free-form JSON object, or `undefined`. */\nexport function jsonNumber(\n source: Record<string, unknown> | null | undefined,\n key: string\n): number | undefined {\n const value = source?.[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n/** Reads an array of records out of a free-form JSON value. */\nexport function jsonRecords(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter(\n (entry): entry is Record<string, unknown> =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n );\n}\n"],"mappings":";AAiBA,SAAgBA,EACd,GACA,GACA,GACQ;CACR,OAAOC,EAAQ,MAAM,MAAcC,MAAcC,CAAK,KAAKC;AAC7D;AAYA,SAAgBC,EACd,GACA,GACS;CACT,OAAOC,IAASC,OAAS;AAC3B;AAYA,SAAgBC,EAAY,GAA2C;CAErE,OADK,MAAM,QAAQL,CAAK,IACjBA,EAAM,QACV,MACC,OAAOM,KAAU,cAAYA,KAAkB,CAAC,MAAM,QAAQA,CAAK,CACvE,IAJkC,CAAC;AAKrC"}
|
|
File without changes
|