@robosystems/core 0.3.0
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/LICENSE +21 -0
- package/README.md +252 -0
- package/actions/entity-actions.d.ts +8 -0
- package/actions/entity-actions.js +16 -0
- package/actions/graph-actions.d.ts +3 -0
- package/actions/graph-actions.js +13 -0
- package/auth-components/AppSwitcher.d.ts +6 -0
- package/auth-components/AppSwitcher.js +28 -0
- package/auth-components/AuthGuard.d.ts +7 -0
- package/auth-components/AuthGuard.js +31 -0
- package/auth-components/AuthProvider.d.ts +9 -0
- package/auth-components/AuthProvider.js +565 -0
- package/auth-components/SessionWarningDialog.d.ts +1 -0
- package/auth-components/SessionWarningDialog.js +51 -0
- package/auth-components/SignInForm.d.ts +20 -0
- package/auth-components/SignInForm.js +139 -0
- package/auth-components/SignUpForm.d.ts +15 -0
- package/auth-components/SignUpForm.js +167 -0
- package/auth-components/TurnstileWidget.d.ts +99 -0
- package/auth-components/TurnstileWidget.js +224 -0
- package/auth-components/index.d.ts +6 -0
- package/auth-components/index.js +6 -0
- package/auth-core/cleanup.d.ts +44 -0
- package/auth-core/cleanup.js +157 -0
- package/auth-core/client.d.ts +121 -0
- package/auth-core/client.js +767 -0
- package/auth-core/config.d.ts +19 -0
- package/auth-core/config.js +56 -0
- package/auth-core/hooks.d.ts +19 -0
- package/auth-core/hooks.js +63 -0
- package/auth-core/index.d.ts +6 -0
- package/auth-core/index.js +6 -0
- package/auth-core/sso.d.ts +42 -0
- package/auth-core/sso.js +281 -0
- package/auth-core/token-storage.d.ts +58 -0
- package/auth-core/token-storage.js +177 -0
- package/auth-core/types.d.ts +145 -0
- package/auth-core/types.js +1 -0
- package/components/EntitySelector.d.ts +44 -0
- package/components/EntitySelector.js +64 -0
- package/components/EntitySelectorCore.d.ts +45 -0
- package/components/EntitySelectorCore.js +67 -0
- package/components/GraphSelectorCore.d.ts +21 -0
- package/components/GraphSelectorCore.js +39 -0
- package/components/PageLayout.d.ts +8 -0
- package/components/PageLayout.js +5 -0
- package/components/RepositoryGuard.d.ts +68 -0
- package/components/RepositoryGuard.js +91 -0
- package/components/console/ConsoleContent.d.ts +4 -0
- package/components/console/ConsoleContent.js +612 -0
- package/components/console/ConsoleMarkdown.d.ts +11 -0
- package/components/console/ConsoleMarkdown.js +49 -0
- package/components/console/ProgressiveText.d.ts +6 -0
- package/components/console/ProgressiveText.js +21 -0
- package/components/console/graphAwareConfig.d.ts +70 -0
- package/components/console/graphAwareConfig.js +411 -0
- package/components/console/index.d.ts +6 -0
- package/components/console/index.js +4 -0
- package/components/console/types.d.ts +84 -0
- package/components/console/types.js +1 -0
- package/components/graph-filters.d.ts +75 -0
- package/components/graph-filters.js +111 -0
- package/components/index.d.ts +10 -0
- package/components/index.js +9 -0
- package/components/repositories/ActiveSubscriptions.d.ts +26 -0
- package/components/repositories/ActiveSubscriptions.js +103 -0
- package/components/repositories/BrowseRepositories.d.ts +11 -0
- package/components/repositories/BrowseRepositories.js +184 -0
- package/components/repositories/index.d.ts +2 -0
- package/components/repositories/index.js +2 -0
- package/components/search/SearchContent.d.ts +4 -0
- package/components/search/SearchContent.js +168 -0
- package/components/search/index.d.ts +2 -0
- package/components/search/index.js +1 -0
- package/components/search/types.d.ts +15 -0
- package/components/search/types.js +1 -0
- package/contexts/entity-context.d.ts +28 -0
- package/contexts/entity-context.js +89 -0
- package/contexts/graph-context.d.ts +27 -0
- package/contexts/graph-context.js +128 -0
- package/contexts/index.d.ts +5 -0
- package/contexts/index.js +5 -0
- package/contexts/org-context.d.ts +25 -0
- package/contexts/org-context.js +64 -0
- package/contexts/service-offerings-context.d.ts +45 -0
- package/contexts/service-offerings-context.js +98 -0
- package/contexts/sidebar-context.d.ts +18 -0
- package/contexts/sidebar-context.js +44 -0
- package/hooks/index.d.ts +6 -0
- package/hooks/index.js +6 -0
- package/hooks/use-api-error.d.ts +3 -0
- package/hooks/use-api-error.js +24 -0
- package/hooks/use-media-query.d.ts +1 -0
- package/hooks/use-media-query.js +21 -0
- package/hooks/use-streaming-query.d.ts +22 -0
- package/hooks/use-streaming-query.js +142 -0
- package/hooks/use-toast.d.ts +37 -0
- package/hooks/use-toast.js +117 -0
- package/hooks/use-user-limits.d.ts +12 -0
- package/hooks/use-user-limits.js +73 -0
- package/hooks/use-user.d.ts +11 -0
- package/hooks/use-user.js +39 -0
- package/index.d.ts +29 -0
- package/index.js +77 -0
- package/lib/entity-cookie.d.ts +10 -0
- package/lib/entity-cookie.js +38 -0
- package/lib/graph-cookie.d.ts +11 -0
- package/lib/graph-cookie.js +62 -0
- package/lib/graph-tiers.d.ts +41 -0
- package/lib/graph-tiers.js +107 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/sidebar-cookie.d.ts +11 -0
- package/lib/sidebar-cookie.js +42 -0
- package/library/colors.d.ts +4 -0
- package/library/colors.js +41 -0
- package/library/components/ClassificationPicker.d.ts +8 -0
- package/library/components/ClassificationPicker.js +55 -0
- package/library/components/ElementBrowser.d.ts +11 -0
- package/library/components/ElementBrowser.js +106 -0
- package/library/components/ElementDetail.d.ts +7 -0
- package/library/components/ElementDetail.js +97 -0
- package/library/components/LibraryHierarchy.d.ts +13 -0
- package/library/components/LibraryHierarchy.js +380 -0
- package/library/components/TaxonomySidebar.d.ts +6 -0
- package/library/components/TaxonomySidebar.js +45 -0
- package/library/index.d.ts +8 -0
- package/library/index.js +7 -0
- package/package.json +37 -0
- package/research/CoverageCard.d.ts +12 -0
- package/research/CoverageCard.js +15 -0
- package/research/CoverageGrid.d.ts +6 -0
- package/research/CoverageGrid.js +9 -0
- package/research/CoverageHistory.d.ts +5 -0
- package/research/CoverageHistory.js +7 -0
- package/research/ResearchArticle.d.ts +15 -0
- package/research/ResearchArticle.js +26 -0
- package/research/catalog.d.ts +14 -0
- package/research/catalog.js +42 -0
- package/research/index.d.ts +6 -0
- package/research/index.js +9 -0
- package/research/types.d.ts +38 -0
- package/research/types.js +4 -0
- package/task-monitoring/hooks.d.ts +26 -0
- package/task-monitoring/hooks.js +126 -0
- package/task-monitoring/index.d.ts +5 -0
- package/task-monitoring/index.js +7 -0
- package/task-monitoring/operationErrors.d.ts +82 -0
- package/task-monitoring/operationErrors.js +251 -0
- package/task-monitoring/operationHooks.d.ts +117 -0
- package/task-monitoring/operationHooks.js +536 -0
- package/task-monitoring/operationMonitor.d.ts +78 -0
- package/task-monitoring/operationMonitor.js +200 -0
- package/task-monitoring/operationTypes.d.ts +236 -0
- package/task-monitoring/operationTypes.js +60 -0
- package/task-monitoring/taskMonitor.d.ts +14 -0
- package/task-monitoring/taskMonitor.js +132 -0
- package/task-monitoring/types.d.ts +31 -0
- package/task-monitoring/types.js +1 -0
- package/theme/flowbite-theme.d.ts +758 -0
- package/theme/flowbite-theme.js +765 -0
- package/theme/index.d.ts +1 -0
- package/theme/index.js +1 -0
- package/types/entity.d.ts +19 -0
- package/types/index.d.ts +2 -0
- package/types/index.js +1 -0
- package/types/user.d.ts +6 -0
- package/ui-components/ConfirmModal.d.ts +41 -0
- package/ui-components/ConfirmModal.js +19 -0
- package/ui-components/EmptyState.d.ts +22 -0
- package/ui-components/EmptyState.js +10 -0
- package/ui-components/LoadingState.d.ts +27 -0
- package/ui-components/LoadingState.js +12 -0
- package/ui-components/Logo.d.ts +28 -0
- package/ui-components/Logo.js +95 -0
- package/ui-components/Spinner.d.ts +37 -0
- package/ui-components/Spinner.js +48 -0
- package/ui-components/StatCard.d.ts +21 -0
- package/ui-components/StatCard.js +10 -0
- package/ui-components/api-keys/ApiKeyDisplay.d.ts +13 -0
- package/ui-components/api-keys/ApiKeyDisplay.js +7 -0
- package/ui-components/api-keys/ApiKeyTable.d.ts +9 -0
- package/ui-components/api-keys/ApiKeyTable.js +17 -0
- package/ui-components/api-keys/ApiKeysCard.d.ts +6 -0
- package/ui-components/api-keys/ApiKeysCard.js +97 -0
- package/ui-components/api-keys/CreateApiKeyModal.d.ts +11 -0
- package/ui-components/api-keys/CreateApiKeyModal.js +47 -0
- package/ui-components/api-keys/SecureApiKeyField.d.ts +13 -0
- package/ui-components/api-keys/SecureApiKeyField.js +64 -0
- package/ui-components/api-keys/index.d.ts +5 -0
- package/ui-components/api-keys/index.js +5 -0
- package/ui-components/chat/ChatHeader.d.ts +12 -0
- package/ui-components/chat/ChatHeader.js +5 -0
- package/ui-components/chat/ChatInputArea.d.ts +16 -0
- package/ui-components/chat/ChatInputArea.js +9 -0
- package/ui-components/chat/ChatMessage.d.ts +7 -0
- package/ui-components/chat/ChatMessage.js +24 -0
- package/ui-components/chat/DeepResearchToggle.d.ts +8 -0
- package/ui-components/chat/DeepResearchToggle.js +13 -0
- package/ui-components/chat/index.d.ts +9 -0
- package/ui-components/chat/index.js +8 -0
- package/ui-components/chat/types.d.ts +23 -0
- package/ui-components/chat/types.js +51 -0
- package/ui-components/forms/PasswordRequirements.d.ts +10 -0
- package/ui-components/forms/PasswordRequirements.js +15 -0
- package/ui-components/forms/SettingsCard.d.ts +11 -0
- package/ui-components/forms/SettingsCard.js +5 -0
- package/ui-components/forms/SettingsFormField.d.ts +18 -0
- package/ui-components/forms/SettingsFormField.js +17 -0
- package/ui-components/forms/StatusAlert.d.ts +8 -0
- package/ui-components/forms/StatusAlert.js +7 -0
- package/ui-components/forms/index.d.ts +4 -0
- package/ui-components/forms/index.js +4 -0
- package/ui-components/index.d.ts +13 -0
- package/ui-components/index.js +18 -0
- package/ui-components/layout/CoreNavbar.d.ts +14 -0
- package/ui-components/layout/CoreNavbar.js +53 -0
- package/ui-components/layout/CoreSidebar.d.ts +28 -0
- package/ui-components/layout/CoreSidebar.js +62 -0
- package/ui-components/layout/LandingFooter.d.ts +28 -0
- package/ui-components/layout/LandingFooter.js +34 -0
- package/ui-components/layout/PageContainer.d.ts +8 -0
- package/ui-components/layout/PageContainer.js +17 -0
- package/ui-components/layout/PageHeader.d.ts +23 -0
- package/ui-components/layout/PageHeader.js +12 -0
- package/ui-components/layout/SettingsContainer.d.ts +10 -0
- package/ui-components/layout/SettingsContainer.js +9 -0
- package/ui-components/layout/ThemeToggle.d.ts +4 -0
- package/ui-components/layout/ThemeToggle.js +6 -0
- package/ui-components/layout/index.d.ts +7 -0
- package/ui-components/layout/index.js +7 -0
- package/ui-components/settings/GeneralInformationCard.d.ts +12 -0
- package/ui-components/settings/GeneralInformationCard.js +72 -0
- package/ui-components/settings/PasswordInformationCard.d.ts +10 -0
- package/ui-components/settings/PasswordInformationCard.js +167 -0
- package/ui-components/settings/SettingsPageHeader.d.ts +7 -0
- package/ui-components/settings/SettingsPageHeader.js +6 -0
- package/ui-components/settings/index.d.ts +3 -0
- package/ui-components/settings/index.js +3 -0
- package/ui-components/support/SupportModal.d.ts +15 -0
- package/ui-components/support/SupportModal.js +74 -0
- package/ui-components/support/index.d.ts +2 -0
- package/ui-components/support/index.js +1 -0
- package/ui-components/types/index.d.ts +39 -0
- package/ui-components/types/index.js +1 -0
- package/utils/index.d.ts +31 -0
- package/utils/index.js +38 -0
- package/utils/turnstile-config.d.ts +11 -0
- package/utils/turnstile-config.js +19 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RFS LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# @robosystems/core
|
|
2
|
+
|
|
3
|
+
Shared React components, hooks, contexts, and utilities for the RoboSystems ecosystem apps, published as an npm package.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@robosystems/core)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This library contains the platform-coupled frontend core shared between:
|
|
10
|
+
|
|
11
|
+
- **robosystems-app** — Graph database management interface
|
|
12
|
+
- **roboledger-app** — Accounting and bookkeeping interface
|
|
13
|
+
- **roboinvestor-app** — Investment management interface
|
|
14
|
+
|
|
15
|
+
It is Next.js-specific by design (App Router client/server components, Server Actions, `next/headers` cookie helpers) and is intended to be consumed by Next.js applications only. The compiled output targets bundler resolution — it is not loadable by Node's native ESM resolver.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @robosystems/core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer dependencies
|
|
24
|
+
|
|
25
|
+
The consuming app provides:
|
|
26
|
+
|
|
27
|
+
| Peer | Range |
|
|
28
|
+
| --------------------- | ---------- |
|
|
29
|
+
| `react` / `react-dom` | >=18 <20 |
|
|
30
|
+
| `next` | >=15 <17 |
|
|
31
|
+
| `flowbite-react` | ^0.12.5 |
|
|
32
|
+
| `react-icons` | >=4 <6 |
|
|
33
|
+
| `@robosystems/client` | >=0.3.2 <1 |
|
|
34
|
+
|
|
35
|
+
### App wiring
|
|
36
|
+
|
|
37
|
+
Two integration points beyond the install:
|
|
38
|
+
|
|
39
|
+
1. **Tailwind content scan** — the package ships Tailwind utility classes in its compiled JS; add it to the app's `tailwind.config.ts`:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
content: [
|
|
43
|
+
// ...existing globs
|
|
44
|
+
'node_modules/@robosystems/core/**/*.js',
|
|
45
|
+
]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. **Vitest** (if the app tests components that render core) — the package is compiled ESM with directory imports and must be processed by vite, in `vitest.config.ts`:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
test: {
|
|
52
|
+
server: { deps: { inline: [/@robosystems\/core/] } },
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
Everything is importable from the root barrel, or from subpaths mirroring the folder structure:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import {
|
|
62
|
+
AuthProvider,
|
|
63
|
+
useAuth,
|
|
64
|
+
useGraphContext,
|
|
65
|
+
customTheme,
|
|
66
|
+
} from '@robosystems/core'
|
|
67
|
+
import { PageHeader, Spinner } from '@robosystems/core/ui-components'
|
|
68
|
+
import { useToast } from '@robosystems/core/hooks/use-toast'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
> The root barrel has an import-time side effect: it configures the `@robosystems/client` SDK singleton (base URL from `NEXT_PUBLIC_ROBOSYSTEMS_API_URL`, Bearer-token request interceptor).
|
|
72
|
+
|
|
73
|
+
## Structure
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
├── actions/ # Next.js Server Actions
|
|
77
|
+
│ ├── entity-actions.ts # Entity creation and management
|
|
78
|
+
│ └── graph-actions.ts # Graph creation and lifecycle
|
|
79
|
+
├── auth-components/ # Authentication UI components
|
|
80
|
+
│ ├── AppSwitcher.tsx # Cross-app navigation switcher
|
|
81
|
+
│ ├── AuthGuard.tsx # Route protection wrapper
|
|
82
|
+
│ ├── AuthProvider.tsx # Authentication context provider
|
|
83
|
+
│ ├── SessionWarningDialog.tsx # Session expiry warning
|
|
84
|
+
│ ├── SignInForm.tsx # Login form
|
|
85
|
+
│ ├── SignUpForm.tsx # Registration form
|
|
86
|
+
│ └── TurnstileWidget.tsx # Cloudflare Turnstile CAPTCHA
|
|
87
|
+
├── auth-core/ # Authentication logic and types
|
|
88
|
+
│ ├── cleanup.ts # Session cleanup utilities
|
|
89
|
+
│ ├── client.ts # Authentication client
|
|
90
|
+
│ ├── config.ts # Auth configuration
|
|
91
|
+
│ ├── hooks.ts # useAuth and related hooks
|
|
92
|
+
│ ├── sso.ts # SSO/OAuth support
|
|
93
|
+
│ ├── token-storage.ts # JWT storage utilities
|
|
94
|
+
│ └── types.ts # Auth TypeScript types
|
|
95
|
+
├── components/ # Shared UI components
|
|
96
|
+
│ ├── console/ # Terminal-style output display
|
|
97
|
+
│ ├── repositories/ # Repository browsing and subscriptions
|
|
98
|
+
│ ├── search/ # Search UI
|
|
99
|
+
│ ├── EntitySelector.tsx # Entity picker component
|
|
100
|
+
│ ├── GraphSelectorCore.tsx # Graph picker component
|
|
101
|
+
│ ├── PageLayout.tsx # Standard page layout
|
|
102
|
+
│ └── RepositoryGuard.tsx # Repository access protection
|
|
103
|
+
├── contexts/ # React contexts
|
|
104
|
+
│ ├── entity-context.tsx # Active entity state
|
|
105
|
+
│ ├── graph-context.tsx # Active graph state
|
|
106
|
+
│ ├── org-context.tsx # Organization state
|
|
107
|
+
│ ├── service-offerings-context.tsx # Available plans and tiers
|
|
108
|
+
│ └── sidebar-context.tsx # Sidebar collapsed/expanded state
|
|
109
|
+
├── hooks/ # Custom React hooks
|
|
110
|
+
│ ├── use-api-error.ts # API error normalization
|
|
111
|
+
│ ├── use-media-query.ts # Responsive breakpoint detection
|
|
112
|
+
│ ├── use-streaming-query.ts # SSE streaming data hook
|
|
113
|
+
│ ├── use-toast.tsx # Toast notification hook
|
|
114
|
+
│ ├── use-user-limits.ts # User quota and limit checks
|
|
115
|
+
│ └── use-user.ts # Current user data hook
|
|
116
|
+
├── lib/ # Utility libraries
|
|
117
|
+
│ ├── entity-cookie.ts # Entity selection persistence
|
|
118
|
+
│ ├── graph-cookie.ts # Graph selection persistence
|
|
119
|
+
│ ├── graph-tiers.ts # Tier display helpers
|
|
120
|
+
│ └── sidebar-cookie.ts # Sidebar state persistence
|
|
121
|
+
├── library/ # XBRL taxonomy browser
|
|
122
|
+
├── research/ # Research coverage components
|
|
123
|
+
├── task-monitoring/ # Background job and operation tracking
|
|
124
|
+
│ ├── hooks.ts # useTaskMonitoring, useEntityCreationTask
|
|
125
|
+
│ ├── operationErrors.ts # Operation error types
|
|
126
|
+
│ ├── operationHooks.ts # useOperationMonitoring, useGraphCreation
|
|
127
|
+
│ ├── operationMonitor.ts # SSE-based operation monitor
|
|
128
|
+
│ ├── operationTypes.ts # Shared operation types
|
|
129
|
+
│ ├── taskMonitor.ts # Polling-based task monitor (fallback)
|
|
130
|
+
│ └── types.ts # Task and operation TypeScript types
|
|
131
|
+
├── theme/ # UI theming
|
|
132
|
+
│ └── flowbite-theme.ts # Flowbite React custom theme
|
|
133
|
+
├── types/ # Shared TypeScript definitions
|
|
134
|
+
│ ├── entity.d.ts # Entity type definitions
|
|
135
|
+
│ └── user.d.ts # User type definitions
|
|
136
|
+
├── ui-components/ # Reusable UI components
|
|
137
|
+
│ ├── api-keys/ # API key management
|
|
138
|
+
│ ├── chat/ # Chat UI (header, input, messages, deep research toggle)
|
|
139
|
+
│ ├── forms/ # Form components and validation
|
|
140
|
+
│ ├── layout/ # Navbar, sidebar, page containers
|
|
141
|
+
│ ├── settings/ # Settings page components
|
|
142
|
+
│ ├── support/ # Support modal
|
|
143
|
+
│ ├── Logo.tsx # RoboSystems logo component
|
|
144
|
+
│ └── Spinner.tsx # Loading spinner
|
|
145
|
+
└── utils/ # Utility functions
|
|
146
|
+
└── turnstile-config.ts # Cloudflare Turnstile configuration
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Technology Stack
|
|
150
|
+
|
|
151
|
+
- **React 18/19** with modern hooks and patterns
|
|
152
|
+
- **TypeScript** for type safety
|
|
153
|
+
- **Flowbite React** for UI components
|
|
154
|
+
- **Tailwind CSS** for styling (classes compiled by the consuming app)
|
|
155
|
+
- **Next.js 15/16** App Router
|
|
156
|
+
- **Auto-generated SDK** (`@robosystems/client`) from OpenAPI specifications
|
|
157
|
+
|
|
158
|
+
## Key Patterns
|
|
159
|
+
|
|
160
|
+
### Task Monitoring
|
|
161
|
+
|
|
162
|
+
Two monitors handle async operations:
|
|
163
|
+
|
|
164
|
+
- **`operationMonitor`** — SSE-based, used for graph lifecycle ops (create, materialize, etc.) that return `OperationEnvelope` with an `operationId`
|
|
165
|
+
- **`taskMonitor`** — Polling-based fallback for older task-style operations
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import { useOperationMonitoring, useGraphCreation } from '@robosystems/core/task-monitoring'
|
|
169
|
+
|
|
170
|
+
// Monitor a graph operation via SSE
|
|
171
|
+
const { startMonitoring, progress, result } = useOperationMonitoring()
|
|
172
|
+
await startMonitoring(operationId)
|
|
173
|
+
|
|
174
|
+
// Full graph creation with monitoring
|
|
175
|
+
const { createGraph, isCreating } = useGraphCreation()
|
|
176
|
+
await createGraph({ graph_type: 'entity', graph_name: 'Acme Corp', ... })
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Contexts
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { useGraphContext, useOrgContext } from '@robosystems/core/contexts'
|
|
183
|
+
|
|
184
|
+
function MyComponent() {
|
|
185
|
+
const { currentGraphId, setCurrentGraphId } = useGraphContext()
|
|
186
|
+
const { org } = useOrgContext()
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Authentication
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { useAuth, AuthProvider, AuthGuard } from '@robosystems/core/auth-core'
|
|
194
|
+
import { SignInForm, SignUpForm } from '@robosystems/core/auth-components'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Development
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npm install # Also wires .githooks via the prepare script
|
|
201
|
+
npm run test # Vitest suite (jsdom, app-equivalent mocks in test/__mocks__)
|
|
202
|
+
npm run test:all # format:check + lint + typecheck + test + build
|
|
203
|
+
npm run build # tsc → dist/ + prepare-package.mjs (publishable package root)
|
|
204
|
+
npm run pack:local # Build + npm pack ./dist → tarball for local app testing
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
To test changes in an app before releasing:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npm run pack:local
|
|
211
|
+
cd ../roboledger-app && npm install ../robosystems-core/robosystems-core-<version>.tgz
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Packaging notes
|
|
215
|
+
|
|
216
|
+
- The package is published **from `dist/`** so compiled files sit at the package root — the apps' directory-barrel and direct-file deep imports both resolve without an `exports` map.
|
|
217
|
+
- The build is **per-file tsc** (not a bundler) so `'use client'` / `'use server'` directives survive at the top of each emitted file.
|
|
218
|
+
- **No CommonJS**: the output is ESM — `require()` is not available at runtime. Use static or dynamic `import`.
|
|
219
|
+
|
|
220
|
+
### Adding New Components
|
|
221
|
+
|
|
222
|
+
1. Create component in the appropriate directory
|
|
223
|
+
2. Add TypeScript types in `types/` if needed
|
|
224
|
+
3. Export from the directory's `index.ts` (and the root `index.ts` if broadly useful)
|
|
225
|
+
4. Add tests in the adjacent `__tests__/` directory
|
|
226
|
+
5. Validate in an app with a `pack:local` tarball before releasing
|
|
227
|
+
|
|
228
|
+
### Naming Conventions
|
|
229
|
+
|
|
230
|
+
- **Components**: PascalCase (`SidebarProvider`)
|
|
231
|
+
- **Hooks**: camelCase with `use` prefix (`useMediaQuery`)
|
|
232
|
+
- **Types**: PascalCase (`SidebarCookie`)
|
|
233
|
+
- **Utilities**: camelCase (`sidebarCookie`)
|
|
234
|
+
|
|
235
|
+
## Releasing
|
|
236
|
+
|
|
237
|
+
Releases run through GitHub Actions (same pipeline as `@robosystems/report-components`):
|
|
238
|
+
|
|
239
|
+
1. Run the **Create Release & Publish** workflow (`gh workflow run create-release.yml --field version_type=patch|minor|major`, or `npm run release:create`)
|
|
240
|
+
2. It bumps the version on `main`, cuts a `release/<version>` branch, tags `v<version>`, and creates a GitHub Release with an AI-generated changelog
|
|
241
|
+
3. The `release/**` push triggers `publish.yml`, which builds and runs `npm publish ./dist --provenance` via npm OIDC Trusted Publishing
|
|
242
|
+
|
|
243
|
+
## Security
|
|
244
|
+
|
|
245
|
+
- Never commit secrets or API keys
|
|
246
|
+
- Use environment variables for configuration
|
|
247
|
+
- Follow authentication best practices
|
|
248
|
+
- Validate all inputs and API responses
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
MIT
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Entity } from '../types';
|
|
2
|
+
export declare function persistEntitySelection(entity: Entity, graphId: string): Promise<void>;
|
|
3
|
+
export declare function clearEntitySelection(): Promise<void>;
|
|
4
|
+
export declare function getEntitySelection(): Promise<{
|
|
5
|
+
identifier: string;
|
|
6
|
+
name: string;
|
|
7
|
+
graphId: string;
|
|
8
|
+
} | null>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { entityCookie } from '../lib/entity-cookie';
|
|
3
|
+
export async function persistEntitySelection(entity, graphId) {
|
|
4
|
+
await entityCookie.set({
|
|
5
|
+
identifier: entity.identifier,
|
|
6
|
+
name: entity.name,
|
|
7
|
+
graphId,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function clearEntitySelection() {
|
|
11
|
+
await entityCookie.delete();
|
|
12
|
+
}
|
|
13
|
+
export async function getEntitySelection() {
|
|
14
|
+
const cookie = await entityCookie.get();
|
|
15
|
+
return cookie !== null && cookie !== void 0 ? cookie : null;
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { graphCookie } from '../lib/graph-cookie';
|
|
3
|
+
export async function persistGraphSelection(graphId) {
|
|
4
|
+
await graphCookie.set({ graphId });
|
|
5
|
+
}
|
|
6
|
+
export async function clearGraphSelection() {
|
|
7
|
+
await graphCookie.delete();
|
|
8
|
+
}
|
|
9
|
+
export async function getGraphSelection() {
|
|
10
|
+
var _a;
|
|
11
|
+
const cookie = await graphCookie.get();
|
|
12
|
+
return (_a = cookie === null || cookie === void 0 ? void 0 : cookie.graphId) !== null && _a !== void 0 ? _a : null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Dropdown, DropdownItem } from 'flowbite-react';
|
|
4
|
+
import { HiViewGrid } from 'react-icons/hi';
|
|
5
|
+
import { useSSO } from '../auth-core/sso';
|
|
6
|
+
import { useToast } from '../hooks/use-toast';
|
|
7
|
+
import { customTheme } from '../theme';
|
|
8
|
+
import { LogoBadge } from '../ui-components/Logo';
|
|
9
|
+
export function AppSwitcher({ apiUrl, currentApp, className = '', }) {
|
|
10
|
+
const { navigateToApp, getAvailableApps } = useSSO(apiUrl);
|
|
11
|
+
const { showError, ToastContainer } = useToast();
|
|
12
|
+
const availableApps = getAvailableApps().filter((app) => app.name !== currentApp);
|
|
13
|
+
const handleAppClick = async (app) => {
|
|
14
|
+
try {
|
|
15
|
+
await navigateToApp(app.name);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (process.env.NODE_ENV === 'development') {
|
|
19
|
+
console.error(`[SSO] Navigation to ${app.name} failed:`, error);
|
|
20
|
+
}
|
|
21
|
+
showError(`Failed to navigate to ${app.displayName}. Please try again.`);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
if (availableApps.length === 0) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return (_jsxs(_Fragment, { children: [_jsx(ToastContainer, {}), _jsx("div", { className: className, children: _jsx(Dropdown, { theme: Object.assign(Object.assign({}, customTheme.dropdown), { floating: Object.assign(Object.assign({}, customTheme.dropdown.floating), { base: `${customTheme.dropdown.floating.base} z-50!` }) }), className: "w-64", arrowIcon: false, inline: true, label: _jsx("span", { className: "inline-flex h-10 w-10 items-center justify-center rounded-lg text-sm text-gray-500 hover:bg-zinc-100 focus:ring-2 focus:ring-gray-200 focus:outline-hidden dark:text-gray-400 dark:hover:bg-zinc-700 dark:focus:ring-gray-600", children: _jsx(HiViewGrid, { className: "h-5 w-5" }) }), children: availableApps.map((app) => (_jsxs(DropdownItem, { theme: customTheme.dropdown.floating.item, onClick: () => handleAppClick(app), className: "flex w-full items-center space-x-3 p-3", children: [_jsx(LogoBadge, { app: app.name, animate: "once", className: "h-8 w-8" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-left text-sm font-medium text-gray-900 dark:text-white", children: app.displayName }), _jsx("p", { className: "truncate text-left text-xs text-gray-500 dark:text-gray-400", children: app.description })] })] }, app.name))) }) })] }));
|
|
28
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PropsWithChildren } from 'react';
|
|
2
|
+
interface AuthGuardProps extends PropsWithChildren {
|
|
3
|
+
redirectTo?: string;
|
|
4
|
+
loadingComponent?: React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare function AuthGuard({ children, redirectTo, loadingComponent, }: AuthGuardProps): string | number | bigint | true | import("react").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode>>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useRouter } from 'next/navigation';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
import { BrandSpinner } from '../ui-components';
|
|
6
|
+
import { useAuth } from './AuthProvider';
|
|
7
|
+
export function AuthGuard({ children, redirectTo = '/login', loadingComponent, }) {
|
|
8
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
9
|
+
const router = useRouter();
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!isLoading && !isAuthenticated) {
|
|
12
|
+
try {
|
|
13
|
+
router.push(redirectTo);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (process.env.NODE_ENV === 'development') {
|
|
17
|
+
// Fallback to window.location if router.push fails
|
|
18
|
+
console.error('Router push failed, using window.location fallback:', error);
|
|
19
|
+
}
|
|
20
|
+
window.location.href = redirectTo;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, [isAuthenticated, isLoading, router, redirectTo]);
|
|
24
|
+
if (isLoading) {
|
|
25
|
+
return loadingComponent || _jsx(BrandSpinner, { size: "xl", fullScreen: true });
|
|
26
|
+
}
|
|
27
|
+
if (!isAuthenticated) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return _jsx(_Fragment, { children: children });
|
|
31
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { AuthContextType } from '../auth-core/types';
|
|
3
|
+
interface AuthProviderProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function AuthProvider({ children, apiUrl, }: AuthProviderProps): import("react").JSX.Element;
|
|
8
|
+
export declare function useAuth(): AuthContextType;
|
|
9
|
+
export {};
|