insforge 1.2.10 → 1.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/.claude-plugin/marketplace.json +20 -20
- package/.dockerignore +60 -60
- package/.env.example +83 -77
- package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
- package/.github/ISSUE_TEMPLATE/config.yml +11 -11
- package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
- package/.github/copilot-instructions.md +146 -146
- package/.github/workflows/build-image.yml +65 -65
- package/.github/workflows/ci-premerge-check.yml +23 -23
- package/.github/workflows/e2e.yml +63 -63
- package/.github/workflows/lint-and-format.yml +32 -32
- package/.prettierignore +64 -64
- package/CHANGELOG.md +44 -44
- package/CLAUDE_PLUGIN.md +104 -104
- package/CODE_OF_CONDUCT.md +128 -128
- package/CONTRIBUTING.md +125 -125
- package/Dockerfile +30 -30
- package/GITHUB_OAUTH_SETUP.md +49 -49
- package/GOOGLE_OAUTH_SETUP.md +148 -148
- package/LICENSE +201 -201
- package/README.md +182 -182
- package/assets/Dark.svg +23 -23
- package/auth/package.json +28 -28
- package/auth/src/lib/broadcastService.ts +117 -115
- package/auth/src/pages/SignInPage.tsx +60 -57
- package/auth/src/pages/SignUpPage.tsx +60 -57
- package/auth/tsconfig.json +32 -32
- package/auth/tsconfig.node.json +11 -11
- package/backend/package.json +78 -75
- package/backend/src/api/routes/ai/index.routes.ts +3 -3
- package/backend/src/api/routes/auth/index.routes.ts +667 -570
- package/backend/src/api/routes/auth/oauth.routes.ts +473 -448
- package/backend/src/api/routes/database/advance.routes.ts +37 -16
- package/backend/src/api/routes/database/index.routes.ts +78 -1
- package/backend/src/api/routes/database/records.routes.ts +10 -10
- package/backend/src/api/routes/database/tables.routes.ts +0 -14
- package/backend/src/api/routes/docs/index.routes.ts +75 -76
- package/backend/src/api/routes/email/index.routes.ts +35 -0
- package/backend/src/api/routes/functions/index.routes.ts +18 -12
- package/backend/src/api/routes/metadata/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
- package/backend/src/api/routes/realtime/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
- package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
- package/backend/src/api/routes/storage/index.routes.ts +18 -12
- package/backend/src/api/routes/usage/index.routes.ts +6 -4
- package/backend/src/infra/database/database.manager.ts +14 -1
- package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
- package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
- package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
- package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
- package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
- package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
- package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
- package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
- package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
- package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
- package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
- package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
- package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
- package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
- package/backend/src/infra/realtime/realtime.manager.ts +246 -0
- package/backend/src/infra/realtime/webhook-sender.ts +82 -0
- package/backend/src/infra/security/token.manager.ts +219 -125
- package/backend/src/infra/socket/socket.manager.ts +198 -64
- package/backend/src/providers/ai/openrouter.provider.ts +12 -9
- package/backend/src/providers/email/base.provider.ts +4 -7
- package/backend/src/providers/email/cloud.provider.ts +84 -0
- package/backend/src/providers/oauth/apple.provider.ts +266 -0
- package/backend/src/providers/oauth/index.ts +1 -0
- package/backend/src/server.ts +317 -284
- package/backend/src/services/ai/ai-model.service.ts +5 -5
- package/backend/src/services/ai/chat-completion.service.ts +4 -4
- package/backend/src/services/ai/image-generation.service.ts +3 -3
- package/backend/src/services/auth/auth.service.ts +14 -0
- package/backend/src/services/database/database-table.service.ts +0 -9
- package/backend/src/services/database/database.service.ts +127 -0
- package/backend/src/services/email/email.service.ts +5 -7
- package/backend/src/services/realtime/index.ts +3 -0
- package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
- package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
- package/backend/src/services/realtime/realtime-message.service.ts +260 -0
- package/backend/src/types/auth.ts +11 -0
- package/backend/src/types/realtime.ts +18 -0
- package/backend/src/types/socket.ts +7 -31
- package/backend/src/utils/cookies.ts +35 -0
- package/backend/src/utils/s3-config-loader.ts +64 -0
- package/backend/src/utils/seed.ts +301 -298
- package/backend/src/utils/sql-parser.ts +90 -0
- package/backend/tests/README.md +133 -133
- package/backend/tests/cleanup-all-test-data.sh +230 -230
- package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
- package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
- package/backend/tests/local/test-ai-config.sh +129 -129
- package/backend/tests/local/test-ai-usage.sh +80 -80
- package/backend/tests/local/test-auth-router.sh +143 -143
- package/backend/tests/local/test-database-router.sh +222 -222
- package/backend/tests/local/test-e2e.sh +240 -240
- package/backend/tests/local/test-fk-errors.sh +96 -96
- package/backend/tests/local/test-functions.sh +123 -123
- package/backend/tests/local/test-id-field.sh +200 -200
- package/backend/tests/local/test-logs.sh +132 -132
- package/backend/tests/local/test-public-bucket.sh +264 -264
- package/backend/tests/local/test-secrets.sh +249 -249
- package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
- package/backend/tests/local/test-traditional-rest.sh +208 -208
- package/backend/tests/manual/README.md +50 -50
- package/backend/tests/manual/create-large-table-simple.sql +10 -10
- package/backend/tests/manual/seed-large-table.sql +100 -100
- package/backend/tests/manual/setup-large-table-extras.sql +33 -33
- package/backend/tests/manual/test-bulk-upsert.sh +409 -409
- package/backend/tests/manual/test-database-advance.sh +296 -296
- package/backend/tests/manual/test-postgrest-stability.sh +191 -191
- package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
- package/backend/tests/manual/test-rawsql-modes.sh +244 -244
- package/backend/tests/manual/test-universal-storage.sh +263 -263
- package/backend/tests/manual/test-users.sql +17 -17
- package/backend/tests/run-all-tests.sh +139 -139
- package/backend/tests/setup.ts +0 -0
- package/backend/tests/test-config.sh +338 -338
- package/backend/tests/unit/analyze-query.test.ts +697 -0
- package/backend/tsconfig.json +22 -22
- package/claude-plugin/.claude-plugin/plugin.json +24 -24
- package/claude-plugin/README.md +133 -133
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -270
- package/docker-compose.prod.yml +204 -200
- package/docker-compose.yml +232 -228
- package/docker-init/db/db-init.sql +97 -97
- package/docker-init/db/jwt.sql +5 -5
- package/docker-init/db/postgresql.conf +16 -16
- package/docker-init/logs/vector.yml +236 -236
- package/docs/README.md +44 -44
- package/docs/agent-docs/real-time.md +269 -0
- package/docs/changelog.mdx +119 -67
- package/docs/core-concepts/ai/architecture.mdx +372 -372
- package/docs/core-concepts/ai/sdk.mdx +213 -213
- package/docs/core-concepts/authentication/architecture.mdx +278 -278
- package/docs/core-concepts/authentication/sdk.mdx +414 -414
- package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -529
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -221
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -184
- package/docs/core-concepts/authentication/ui-components/react.mdx +129 -129
- package/docs/core-concepts/database/architecture.mdx +255 -255
- package/docs/core-concepts/database/sdk.mdx +382 -382
- package/docs/core-concepts/email/architecture.mdx +101 -0
- package/docs/core-concepts/email/sdk.mdx +53 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -105
- package/docs/core-concepts/functions/sdk.mdx +184 -184
- package/docs/core-concepts/realtime/architecture.mdx +446 -0
- package/docs/core-concepts/realtime/sdk.mdx +409 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -243
- package/docs/core-concepts/storage/sdk.mdx +253 -253
- package/docs/deployment/README.md +94 -94
- package/docs/deployment/deploy-to-aws-ec2.md +564 -564
- package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
- package/docs/deployment/deploy-to-render.md +441 -441
- package/docs/deprecated/insforge-auth-api.md +214 -214
- package/docs/deprecated/insforge-auth-sdk.md +99 -99
- package/docs/deprecated/insforge-db-api.md +358 -358
- package/docs/deprecated/insforge-db-sdk.md +139 -139
- package/docs/deprecated/insforge-debug-sdk.md +156 -156
- package/docs/deprecated/insforge-debug.md +64 -64
- package/docs/deprecated/insforge-instructions.md +123 -123
- package/docs/deprecated/insforge-project.md +117 -117
- package/docs/deprecated/insforge-storage-api.md +278 -278
- package/docs/deprecated/insforge-storage-sdk.md +158 -158
- package/docs/docs.json +232 -210
- package/docs/examples/framework-guides/nextjs.mdx +131 -131
- package/docs/examples/framework-guides/nuxt.mdx +165 -165
- package/docs/examples/framework-guides/react.mdx +165 -165
- package/docs/examples/framework-guides/svelte.mdx +153 -153
- package/docs/examples/framework-guides/vue.mdx +159 -159
- package/docs/examples/overview.mdx +67 -67
- package/docs/favicon.svg +19 -19
- package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
- package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
- package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
- package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
- package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
- package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
- package/docs/images/icons/ai.svg +4 -4
- package/docs/images/logos/nextjs.svg +4 -4
- package/docs/images/logos/nuxt.svg +4 -4
- package/docs/images/logos/react.svg +5 -5
- package/docs/images/logos/svelte.svg +4 -4
- package/docs/images/logos/vue.svg +5 -5
- package/docs/insforge-instructions-sdk.md +89 -88
- package/docs/introduction.mdx +45 -45
- package/docs/logo/dark.svg +22 -22
- package/docs/logo/light.svg +20 -20
- package/docs/partnership.mdx +651 -646
- package/docs/quickstart.mdx +82 -82
- package/docs/showcase.mdx +52 -52
- package/docs/snippets/sdk-installation.mdx +21 -21
- package/docs/snippets/service-icons.mdx +27 -27
- package/examples/oauth/frontend-oauth-example.html +250 -250
- package/examples/response-examples.md +443 -443
- package/frontend/components.json +17 -17
- package/frontend/package.json +69 -69
- package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
- package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
- package/frontend/src/assets/icons/checked.svg +3 -3
- package/frontend/src/assets/icons/connected.svg +3 -3
- package/frontend/src/assets/icons/error.svg +3 -3
- package/frontend/src/assets/icons/loader.svg +9 -9
- package/frontend/src/assets/icons/pencil.svg +4 -4
- package/frontend/src/assets/icons/refresh.svg +4 -4
- package/frontend/src/assets/icons/step_active.svg +3 -3
- package/frontend/src/assets/icons/step_inactive.svg +11 -11
- package/frontend/src/assets/icons/warning.svg +3 -3
- package/frontend/src/assets/logos/apple.svg +3 -3
- package/frontend/src/assets/logos/claude_code.svg +3 -3
- package/frontend/src/assets/logos/cline.svg +6 -6
- package/frontend/src/assets/logos/cursor.svg +20 -20
- package/frontend/src/assets/logos/discord.svg +8 -8
- package/frontend/src/assets/logos/facebook.svg +3 -3
- package/frontend/src/assets/logos/gemini.svg +19 -19
- package/frontend/src/assets/logos/github.svg +5 -5
- package/frontend/src/assets/logos/google.svg +13 -13
- package/frontend/src/assets/logos/grok.svg +10 -10
- package/frontend/src/assets/logos/insforge_dark.svg +15 -15
- package/frontend/src/assets/logos/insforge_light.svg +15 -15
- package/frontend/src/assets/logos/instagram.svg +1 -1
- package/frontend/src/assets/logos/linkedin.svg +3 -3
- package/frontend/src/assets/logos/openai.svg +10 -10
- package/frontend/src/assets/logos/roo_code.svg +9 -9
- package/frontend/src/assets/logos/spotify.svg +16 -16
- package/frontend/src/assets/logos/tiktok.svg +5 -5
- package/frontend/src/assets/logos/trae.svg +3 -3
- package/frontend/src/assets/logos/windsurf.svg +10 -10
- package/frontend/src/assets/logos/x.svg +3 -3
- package/frontend/src/components/layout/AppHeader.tsx +9 -10
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +6 -0
- package/frontend/src/features/auth/helpers.tsx +8 -0
- package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
- package/frontend/src/features/database/components/SQLModal.tsx +75 -0
- package/frontend/src/features/database/components/TableForm.tsx +0 -4
- package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
- package/frontend/src/features/database/hooks/useTables.ts +32 -28
- package/frontend/src/features/database/index.ts +1 -0
- package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -37
- package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +35 -47
- package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +43 -54
- package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
- package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +35 -47
- package/frontend/src/features/database/services/advance.service.ts +0 -26
- package/frontend/src/features/database/services/database.service.ts +55 -0
- package/frontend/src/features/database/services/table.service.ts +0 -6
- package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
- package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +11 -9
- package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
- package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
- package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
- package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
- package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
- package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
- package/frontend/src/features/realtime/index.ts +11 -0
- package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
- package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
- package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
- package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
- package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +3 -3
- package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +1 -35
- package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
- package/frontend/src/lib/routing/AppRoutes.tsx +35 -20
- package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
- package/frontend/src/lib/utils/menuItems.ts +24 -0
- package/frontend/src/lib/utils/utils.ts +14 -1
- package/frontend/tsconfig.json +25 -25
- package/frontend/tsconfig.node.json +9 -9
- package/functions/deno.json +24 -24
- package/functions/server.ts +315 -315
- package/i18n/README.ar.md +130 -130
- package/i18n/README.de.md +130 -130
- package/i18n/README.es.md +154 -154
- package/i18n/README.fr.md +134 -134
- package/i18n/README.hi.md +129 -129
- package/i18n/README.ja.md +174 -174
- package/i18n/README.ko.md +136 -136
- package/i18n/README.pt-BR.md +131 -131
- package/i18n/README.ru.md +129 -129
- package/i18n/README.zh-CN.md +133 -133
- package/openapi/ai.yaml +715 -715
- package/openapi/auth.yaml +1244 -1244
- package/openapi/email.yaml +158 -0
- package/openapi/functions.yaml +475 -475
- package/openapi/health.yaml +29 -29
- package/openapi/logs.yaml +223 -223
- package/openapi/metadata.yaml +177 -177
- package/openapi/realtime.yaml +699 -0
- package/openapi/records.yaml +381 -381
- package/openapi/secrets.yaml +370 -370
- package/openapi/storage.yaml +875 -875
- package/openapi/tables.yaml +463 -463
- package/package.json +97 -97
- package/shared-schemas/package.json +31 -31
- package/shared-schemas/src/ai.schema.ts +63 -59
- package/shared-schemas/src/auth-api.schema.ts +352 -339
- package/shared-schemas/src/auth.schema.ts +1 -1
- package/shared-schemas/src/database-api.schema.ts +32 -1
- package/shared-schemas/src/database.schema.ts +39 -0
- package/shared-schemas/src/docs.schema.ts +26 -0
- package/shared-schemas/src/email-api.schema.ts +30 -0
- package/shared-schemas/src/index.ts +4 -0
- package/shared-schemas/src/metadata.schema.ts +9 -0
- package/shared-schemas/src/realtime-api.schema.ts +111 -0
- package/shared-schemas/src/realtime.schema.ts +143 -0
- package/shared-schemas/tsconfig.json +21 -21
- package/tsconfig.json +7 -7
- package/zeabur/README.md +13 -13
- package/zeabur/template.yml +1032 -1032
- package/.cursor/rules/cursor-rules.mdc +0 -94
- package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
- package/test-gemini.sh +0 -35
- package/test-usage-admin.sh +0 -57
- package/test-usage.sh +0 -50
- /package/frontend/src/features/ai/{page → pages}/AIPage.tsx +0 -0
- /package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +0 -0
- /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
- /package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
|
@@ -25,13 +25,6 @@ import {
|
|
|
25
25
|
TooltipProvider,
|
|
26
26
|
TooltipTrigger,
|
|
27
27
|
} from '@/components';
|
|
28
|
-
import {
|
|
29
|
-
DataUpdatePayload,
|
|
30
|
-
DataUpdateResourceType,
|
|
31
|
-
ServerEvents,
|
|
32
|
-
SocketMessage,
|
|
33
|
-
useSocket,
|
|
34
|
-
} from '@/lib/contexts/SocketContext';
|
|
35
28
|
|
|
36
29
|
interface BucketFormState {
|
|
37
30
|
mode: 'create' | 'edit';
|
|
@@ -53,15 +46,13 @@ export default function StoragePage() {
|
|
|
53
46
|
name: null,
|
|
54
47
|
isPublic: false,
|
|
55
48
|
});
|
|
49
|
+
const queryClient = useQueryClient();
|
|
56
50
|
const { confirm, confirmDialogProps } = useConfirm();
|
|
57
51
|
const { showToast } = useToast();
|
|
58
52
|
const { showUploadToast, updateUploadProgress, cancelUpload } = useUploadToast();
|
|
59
|
-
const queryClient = useQueryClient();
|
|
60
53
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
61
54
|
const uploadAbortControllerRef = useRef<AbortController | null>(null);
|
|
62
55
|
|
|
63
|
-
const { socket, isConnected } = useSocket();
|
|
64
|
-
|
|
65
56
|
const {
|
|
66
57
|
buckets,
|
|
67
58
|
isLoadingBuckets: isLoading,
|
|
@@ -80,25 +71,6 @@ export default function StoragePage() {
|
|
|
80
71
|
return bucketStats || {};
|
|
81
72
|
}, [bucketStats]);
|
|
82
73
|
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
if (!socket || !isConnected) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
|
|
89
|
-
if (message.payload?.resource === DataUpdateResourceType.BUCKETS) {
|
|
90
|
-
// Invalidate all buckets queries
|
|
91
|
-
void queryClient.invalidateQueries({ queryKey: ['storage'] });
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
96
|
-
|
|
97
|
-
return () => {
|
|
98
|
-
socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
99
|
-
};
|
|
100
|
-
}, [socket, isConnected, queryClient]);
|
|
101
|
-
|
|
102
74
|
// Auto-select first bucket
|
|
103
75
|
useEffect(() => {
|
|
104
76
|
if (buckets.length && !selectedBucket) {
|
|
@@ -15,7 +15,7 @@ import '@xyflow/react/dist/style.css';
|
|
|
15
15
|
import { TableNode } from './TableNode';
|
|
16
16
|
import { AuthNode } from './AuthNode';
|
|
17
17
|
import { BucketNode } from './BucketNode';
|
|
18
|
-
import {
|
|
18
|
+
import { useAllTableSchemas } from '@/features/database/hooks/useTables';
|
|
19
19
|
import { useTheme } from '@/lib/contexts/ThemeContext';
|
|
20
20
|
import {
|
|
21
21
|
AppMetadataSchema,
|
|
@@ -198,8 +198,8 @@ export function SchemaVisualizer({
|
|
|
198
198
|
}: SchemaVisualizerProps) {
|
|
199
199
|
const { resolvedTheme } = useTheme();
|
|
200
200
|
|
|
201
|
-
// Fetch all table schemas only
|
|
202
|
-
const { allSchemas, isLoadingSchemas } =
|
|
201
|
+
// Fetch all table schemas (only when external schemas are not provided)
|
|
202
|
+
const { allSchemas, isLoading: isLoadingSchemas } = useAllTableSchemas(!externalSchemas);
|
|
203
203
|
|
|
204
204
|
// Use external schemas if provided, otherwise use fetched schemas
|
|
205
205
|
const tables = externalSchemas || allSchemas;
|
|
@@ -1,22 +1,11 @@
|
|
|
1
|
-
import { useQueryClient } from '@tanstack/react-query';
|
|
2
1
|
import { RefreshCw } from 'lucide-react';
|
|
3
|
-
import { useCallback
|
|
2
|
+
import { useCallback } from 'react';
|
|
4
3
|
import { useMetadata } from '@/lib/hooks/useMetadata';
|
|
5
4
|
import { useUsers } from '@/features/auth/hooks/useUsers';
|
|
6
5
|
import { SchemaVisualizer, VisualizerSkeleton } from '../components';
|
|
7
6
|
import { Alert, AlertDescription, Button } from '@/components';
|
|
8
|
-
import {
|
|
9
|
-
useSocket,
|
|
10
|
-
ServerEvents,
|
|
11
|
-
DataUpdatePayload,
|
|
12
|
-
DataUpdateResourceType,
|
|
13
|
-
SocketMessage,
|
|
14
|
-
} from '@/lib/contexts/SocketContext';
|
|
15
7
|
|
|
16
8
|
const VisualizerPage = () => {
|
|
17
|
-
const { socket, isConnected } = useSocket();
|
|
18
|
-
const queryClient = useQueryClient();
|
|
19
|
-
|
|
20
9
|
const {
|
|
21
10
|
metadata,
|
|
22
11
|
isLoading: metadataLoading,
|
|
@@ -38,29 +27,6 @@ const VisualizerPage = () => {
|
|
|
38
27
|
void refetchUserStats();
|
|
39
28
|
}, [refetchMetadata, refetchUserStats]);
|
|
40
29
|
|
|
41
|
-
// Listen for schema change events
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
if (!socket || !isConnected) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
|
|
48
|
-
if (
|
|
49
|
-
message.payload?.resource === DataUpdateResourceType.DATABASE ||
|
|
50
|
-
message.payload?.resource === DataUpdateResourceType.BUCKETS
|
|
51
|
-
) {
|
|
52
|
-
// Invalidate all metadata-related queries
|
|
53
|
-
void queryClient.invalidateQueries({ queryKey: ['metadata'] });
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
58
|
-
|
|
59
|
-
return () => {
|
|
60
|
-
socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
61
|
-
};
|
|
62
|
-
}, [socket, isConnected, queryClient]);
|
|
63
|
-
|
|
64
30
|
if (isLoading) {
|
|
65
31
|
return <VisualizerSkeleton />;
|
|
66
32
|
}
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
createContext,
|
|
3
3
|
useContext,
|
|
4
4
|
useEffect,
|
|
5
|
+
useEffectEvent,
|
|
5
6
|
useRef,
|
|
6
7
|
useState,
|
|
7
8
|
useCallback,
|
|
@@ -9,8 +10,12 @@ import {
|
|
|
9
10
|
useMemo,
|
|
10
11
|
} from 'react';
|
|
11
12
|
import { io, Socket } from 'socket.io-client';
|
|
13
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
12
14
|
import { apiClient } from '@/lib/api/client';
|
|
13
15
|
import { useAuth } from '@/lib/contexts/AuthContext';
|
|
16
|
+
import { postMessageToParent } from '@/lib/utils/cloudMessaging';
|
|
17
|
+
import type { SocketMessage } from '@insforge/shared-schemas';
|
|
18
|
+
import { useMcpUsage } from '@/features/logs/hooks/useMcpUsage';
|
|
14
19
|
|
|
15
20
|
// ============================================================================
|
|
16
21
|
// Types & Enums
|
|
@@ -25,46 +30,21 @@ export enum ServerEvents {
|
|
|
25
30
|
MCP_CONNECTED = 'mcp:connected',
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
/**
|
|
29
|
-
* Client-to-server event types
|
|
30
|
-
*/
|
|
31
|
-
export enum ClientEvents {
|
|
32
|
-
SUBSCRIBE = 'subscribe',
|
|
33
|
-
UNSUBSCRIBE = 'unsubscribe',
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Base message structure for all socket communications
|
|
38
|
-
*/
|
|
39
|
-
export interface SocketMessage<T = unknown> {
|
|
40
|
-
type: string;
|
|
41
|
-
payload?: T;
|
|
42
|
-
timestamp: number;
|
|
43
|
-
id?: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
33
|
// ============================================================================
|
|
47
34
|
// Payload Types
|
|
48
35
|
// ============================================================================
|
|
49
36
|
|
|
50
|
-
export interface NotificationPayload {
|
|
51
|
-
level: 'info' | 'warning' | 'error' | 'success';
|
|
52
|
-
title: string;
|
|
53
|
-
message: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
37
|
export enum DataUpdateResourceType {
|
|
57
38
|
DATABASE = 'database',
|
|
58
39
|
USERS = 'users',
|
|
59
|
-
RECORDS = 'records',
|
|
60
40
|
BUCKETS = 'buckets',
|
|
61
41
|
FUNCTIONS = 'functions',
|
|
42
|
+
REALTIME = 'realtime',
|
|
62
43
|
}
|
|
63
44
|
|
|
64
|
-
export interface
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
data: unknown;
|
|
45
|
+
export interface DatabaseResourceUpdate {
|
|
46
|
+
type: 'tables' | 'table' | 'records' | 'index' | 'trigger' | 'policy' | 'function' | 'extension';
|
|
47
|
+
name?: string;
|
|
68
48
|
}
|
|
69
49
|
|
|
70
50
|
// ============================================================================
|
|
@@ -80,9 +60,6 @@ interface SocketState {
|
|
|
80
60
|
interface SocketActions {
|
|
81
61
|
connect: (token: string | null) => void;
|
|
82
62
|
disconnect: () => void;
|
|
83
|
-
subscribe: (channel: string, filters?: Record<string, unknown>) => void;
|
|
84
|
-
unsubscribe: (channel: string) => void;
|
|
85
|
-
emit: (event: ClientEvents, data?: unknown) => void;
|
|
86
63
|
}
|
|
87
64
|
|
|
88
65
|
interface SocketContextValue extends SocketState, SocketActions {
|
|
@@ -105,6 +82,9 @@ interface SocketProviderProps {
|
|
|
105
82
|
export function SocketProvider({ children }: SocketProviderProps) {
|
|
106
83
|
// Get authentication state
|
|
107
84
|
const { isAuthenticated } = useAuth();
|
|
85
|
+
const queryClient = useQueryClient();
|
|
86
|
+
const { recordsCount: mcpUsageCount } = useMcpUsage();
|
|
87
|
+
|
|
108
88
|
// State
|
|
109
89
|
const [state, setState] = useState<SocketState>({
|
|
110
90
|
isConnected: false,
|
|
@@ -114,7 +94,6 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|
|
114
94
|
|
|
115
95
|
// Refs
|
|
116
96
|
const socketRef = useRef<Socket | null>(null);
|
|
117
|
-
const subscriptionsRef = useRef<Set<string>>(new Set());
|
|
118
97
|
|
|
119
98
|
/**
|
|
120
99
|
* Update state helper
|
|
@@ -167,11 +146,6 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|
|
167
146
|
isConnected: true,
|
|
168
147
|
connectionError: null,
|
|
169
148
|
});
|
|
170
|
-
|
|
171
|
-
// Re-subscribe to channels after reconnection
|
|
172
|
-
subscriptionsRef.current.forEach((channel) => {
|
|
173
|
-
socket.emit(ClientEvents.SUBSCRIBE, { channel });
|
|
174
|
-
});
|
|
175
149
|
});
|
|
176
150
|
|
|
177
151
|
return socket;
|
|
@@ -219,41 +193,8 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|
|
219
193
|
connectionError: null,
|
|
220
194
|
socketId: null,
|
|
221
195
|
});
|
|
222
|
-
|
|
223
|
-
subscriptionsRef.current.clear();
|
|
224
196
|
}, [updateState]);
|
|
225
197
|
|
|
226
|
-
/**
|
|
227
|
-
* Subscribe to a channel
|
|
228
|
-
*/
|
|
229
|
-
const subscribe = useCallback((channel: string, filters?: Record<string, unknown>) => {
|
|
230
|
-
if (!socketRef.current?.connected) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
socketRef.current.emit(ClientEvents.SUBSCRIBE, { channel, filters });
|
|
235
|
-
subscriptionsRef.current.add(channel);
|
|
236
|
-
}, []);
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Unsubscribe from a channel
|
|
240
|
-
*/
|
|
241
|
-
const unsubscribe = useCallback((channel: string) => {
|
|
242
|
-
if (!socketRef.current?.connected) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
socketRef.current.emit(ClientEvents.UNSUBSCRIBE, { channel });
|
|
247
|
-
subscriptionsRef.current.delete(channel);
|
|
248
|
-
}, []);
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Emit event to server
|
|
252
|
-
*/
|
|
253
|
-
const emit = useCallback((event: ClientEvents, data?: unknown) => {
|
|
254
|
-
socketRef.current?.emit(event, data);
|
|
255
|
-
}, []);
|
|
256
|
-
|
|
257
198
|
// Monitor authentication state and token changes
|
|
258
199
|
useEffect(() => {
|
|
259
200
|
const token = apiClient.getToken();
|
|
@@ -274,6 +215,112 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|
|
274
215
|
};
|
|
275
216
|
}, [disconnect]);
|
|
276
217
|
|
|
218
|
+
// Send onboarding success only on first MCP connection
|
|
219
|
+
const onMcpConnectedSuccess = useEffectEvent(() => {
|
|
220
|
+
if (mcpUsageCount === 0) {
|
|
221
|
+
postMessageToParent({ type: 'ONBOARDING_SUCCESS' });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Register business event handlers when socket is connected
|
|
226
|
+
useEffect(() => {
|
|
227
|
+
const socket = socketRef.current;
|
|
228
|
+
if (!socket || !state.isConnected) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Handle DATA_UPDATE events - invalidate relevant queries
|
|
233
|
+
const handleDataUpdate = (message: SocketMessage) => {
|
|
234
|
+
const resource = message.resource as DataUpdateResourceType;
|
|
235
|
+
|
|
236
|
+
switch (resource) {
|
|
237
|
+
case DataUpdateResourceType.DATABASE: {
|
|
238
|
+
const { changes } = (message.data ?? {}) as { changes?: DatabaseResourceUpdate[] };
|
|
239
|
+
|
|
240
|
+
if (!changes || changes.length === 0) {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Invalidate specific queries based on resource types changed
|
|
245
|
+
for (const change of changes) {
|
|
246
|
+
switch (change.type) {
|
|
247
|
+
case 'tables':
|
|
248
|
+
// CREATE TABLE / DROP TABLE - affects table list
|
|
249
|
+
void queryClient.invalidateQueries({ queryKey: ['tables'] });
|
|
250
|
+
void queryClient.invalidateQueries({ queryKey: ['metadata', 'full'] });
|
|
251
|
+
break;
|
|
252
|
+
case 'table':
|
|
253
|
+
// ALTER TABLE / RENAME - affects specific table and list
|
|
254
|
+
void queryClient.invalidateQueries({ queryKey: ['tables'] });
|
|
255
|
+
if (change.name) {
|
|
256
|
+
void queryClient.invalidateQueries({ queryKey: ['table', change.name] });
|
|
257
|
+
}
|
|
258
|
+
break;
|
|
259
|
+
case 'records':
|
|
260
|
+
// INSERT / UPDATE / DELETE - affects records for specific table
|
|
261
|
+
if (change.name) {
|
|
262
|
+
void queryClient.invalidateQueries({ queryKey: ['records', change.name] });
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
case 'index':
|
|
266
|
+
void queryClient.invalidateQueries({ queryKey: ['database', 'indexes'] });
|
|
267
|
+
break;
|
|
268
|
+
case 'trigger':
|
|
269
|
+
void queryClient.invalidateQueries({ queryKey: ['database', 'triggers'] });
|
|
270
|
+
break;
|
|
271
|
+
case 'policy':
|
|
272
|
+
void queryClient.invalidateQueries({ queryKey: ['database', 'policies'] });
|
|
273
|
+
break;
|
|
274
|
+
case 'function':
|
|
275
|
+
void queryClient.invalidateQueries({ queryKey: ['database', 'functions'] });
|
|
276
|
+
break;
|
|
277
|
+
case 'extension':
|
|
278
|
+
// Extensions are not supported yet
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case DataUpdateResourceType.BUCKETS:
|
|
285
|
+
void queryClient.invalidateQueries({ queryKey: ['storage', 'buckets'] });
|
|
286
|
+
void queryClient.invalidateQueries({ queryKey: ['metadata', 'full'] });
|
|
287
|
+
break;
|
|
288
|
+
case DataUpdateResourceType.USERS:
|
|
289
|
+
void queryClient.invalidateQueries({ queryKey: ['users'] });
|
|
290
|
+
break;
|
|
291
|
+
case DataUpdateResourceType.FUNCTIONS:
|
|
292
|
+
void queryClient.invalidateQueries({ queryKey: ['functions'] });
|
|
293
|
+
break;
|
|
294
|
+
case DataUpdateResourceType.REALTIME:
|
|
295
|
+
void queryClient.invalidateQueries({ queryKey: ['realtime'] });
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// Handle MCP_CONNECTED events
|
|
301
|
+
const handleMcpConnected = (message: SocketMessage) => {
|
|
302
|
+
void queryClient.invalidateQueries({ queryKey: ['mcp-usage'] });
|
|
303
|
+
|
|
304
|
+
// Notify parent window (for cloud onboarding)
|
|
305
|
+
postMessageToParent({
|
|
306
|
+
type: 'MCP_CONNECTION_STATUS',
|
|
307
|
+
connected: true,
|
|
308
|
+
tool_name: message.tool_name as string,
|
|
309
|
+
timestamp: message.created_at as string,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
onMcpConnectedSuccess();
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
316
|
+
socket.on(ServerEvents.MCP_CONNECTED, handleMcpConnected);
|
|
317
|
+
|
|
318
|
+
return () => {
|
|
319
|
+
socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
320
|
+
socket.off(ServerEvents.MCP_CONNECTED, handleMcpConnected);
|
|
321
|
+
};
|
|
322
|
+
}, [state.isConnected, queryClient]);
|
|
323
|
+
|
|
277
324
|
// Context value
|
|
278
325
|
const contextValue = useMemo<SocketContextValue>(
|
|
279
326
|
() => ({
|
|
@@ -283,11 +330,8 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|
|
283
330
|
// Actions
|
|
284
331
|
connect,
|
|
285
332
|
disconnect,
|
|
286
|
-
subscribe,
|
|
287
|
-
unsubscribe,
|
|
288
|
-
emit,
|
|
289
333
|
}),
|
|
290
|
-
[state, connect, disconnect
|
|
334
|
+
[state, connect, disconnect]
|
|
291
335
|
);
|
|
292
336
|
|
|
293
337
|
return <SocketContext.Provider value={contextValue}>{children}</SocketContext.Provider>;
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import { Routes, Route, Navigate } from 'react-router-dom';
|
|
2
2
|
import { RequireAuth } from '@/lib/routing/RequireAuth';
|
|
3
3
|
import Layout from '@/components/layout/Layout';
|
|
4
|
-
import LoginPage from '@/features/login/
|
|
5
|
-
import CloudLoginPage from '@/features/login/
|
|
6
|
-
import DashboardPage from '@/features/dashboard/
|
|
7
|
-
import TablesPage from '@/features/database/
|
|
8
|
-
import UsersPage from '@/features/auth/
|
|
9
|
-
import AuthMethodsPage from '@/features/auth/
|
|
10
|
-
import ConfigurationPage from '@/features/auth/
|
|
11
|
-
import LogsPage from '@/features/logs/
|
|
12
|
-
import MCPLogsPage from '@/features/logs/
|
|
13
|
-
import StoragePage from '@/features/storage/
|
|
14
|
-
import VisualizerPage from '@/features/visualizer/
|
|
15
|
-
import FunctionsPage from '@/features/functions/
|
|
16
|
-
import SecretsPage from '@/features/functions/
|
|
17
|
-
import AIPage from '@/features/ai/
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
4
|
+
import LoginPage from '@/features/login/pages/LoginPage';
|
|
5
|
+
import CloudLoginPage from '@/features/login/pages/CloudLoginPage';
|
|
6
|
+
import DashboardPage from '@/features/dashboard/pages/DashboardPage';
|
|
7
|
+
import TablesPage from '@/features/database/pages/TablesPage';
|
|
8
|
+
import UsersPage from '@/features/auth/pages/UsersPage';
|
|
9
|
+
import AuthMethodsPage from '@/features/auth/pages/AuthMethodsPage';
|
|
10
|
+
import ConfigurationPage from '@/features/auth/pages/ConfigurationPage';
|
|
11
|
+
import LogsPage from '@/features/logs/pages/LogsPage';
|
|
12
|
+
import MCPLogsPage from '@/features/logs/pages/MCPLogsPage';
|
|
13
|
+
import StoragePage from '@/features/storage/pages/StoragePage';
|
|
14
|
+
import VisualizerPage from '@/features/visualizer/pages/VisualizerPage';
|
|
15
|
+
import FunctionsPage from '@/features/functions/pages/FunctionsPage';
|
|
16
|
+
import SecretsPage from '@/features/functions/pages/SecretsPage';
|
|
17
|
+
import AIPage from '@/features/ai/pages/AIPage';
|
|
18
|
+
import RealtimeChannelsPage from '@/features/realtime/pages/RealtimeChannelsPage';
|
|
19
|
+
import RealtimeMessagesPage from '@/features/realtime/pages/RealtimeMessagesPage';
|
|
20
|
+
import RealtimePermissionsPage from '@/features/realtime/pages/RealtimePermissionsPage';
|
|
21
|
+
import SQLEditorPage from '@/features/database/pages/SQLEditorPage';
|
|
22
|
+
import IndexesPage from '@/features/database/pages/IndexesPage';
|
|
23
|
+
import DatabaseFunctionsPage from '@/features/database/pages/FunctionsPage';
|
|
24
|
+
import TriggersPage from '@/features/database/pages/TriggersPage';
|
|
25
|
+
import PoliciesPage from '@/features/database/pages/PoliciesPage';
|
|
26
|
+
import TemplatesPage from '@/features/database/pages/TemplatesPage';
|
|
27
|
+
import AuditsPage from '@/features/logs/pages/AuditsPage';
|
|
24
28
|
|
|
25
29
|
export function AppRoutes() {
|
|
26
30
|
return (
|
|
@@ -64,6 +68,7 @@ export function AppRoutes() {
|
|
|
64
68
|
element={<Navigate to="/dashboard/logs/MCP" replace />}
|
|
65
69
|
/>
|
|
66
70
|
<Route path="/dashboard/logs/MCP" element={<MCPLogsPage />} />
|
|
71
|
+
<Route path="/dashboard/logs/audits" element={<AuditsPage />} />
|
|
67
72
|
<Route path="/dashboard/logs/:source" element={<LogsPage />} />
|
|
68
73
|
<Route
|
|
69
74
|
path="/dashboard/functions"
|
|
@@ -73,6 +78,16 @@ export function AppRoutes() {
|
|
|
73
78
|
<Route path="/dashboard/functions/secrets" element={<SecretsPage />} />
|
|
74
79
|
<Route path="/dashboard/visualizer" element={<VisualizerPage />} />
|
|
75
80
|
<Route path="/dashboard/ai" element={<AIPage />} />
|
|
81
|
+
<Route
|
|
82
|
+
path="/dashboard/realtime"
|
|
83
|
+
element={<Navigate to="/dashboard/realtime/channels" replace />}
|
|
84
|
+
/>
|
|
85
|
+
<Route path="/dashboard/realtime/channels" element={<RealtimeChannelsPage />} />
|
|
86
|
+
<Route path="/dashboard/realtime/messages" element={<RealtimeMessagesPage />} />
|
|
87
|
+
<Route
|
|
88
|
+
path="/dashboard/realtime/permissions"
|
|
89
|
+
element={<RealtimePermissionsPage />}
|
|
90
|
+
/>
|
|
76
91
|
<Route path="*" element={<Navigate to="/dashboard" replace />} />
|
|
77
92
|
</Routes>
|
|
78
93
|
</Layout>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cloudEventSchema, CloudEvent } from '@insforge/shared-schemas';
|
|
2
2
|
|
|
3
|
-
export function postMessageToParent(evt:
|
|
3
|
+
export function postMessageToParent(evt: Record<string, unknown>, targetOrigin: string = '*') {
|
|
4
4
|
if (typeof window === 'undefined') {
|
|
5
5
|
return;
|
|
6
6
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Lock,
|
|
6
6
|
HardDrive,
|
|
7
7
|
Code2,
|
|
8
|
+
Radio,
|
|
8
9
|
Sparkles,
|
|
9
10
|
ChartLine,
|
|
10
11
|
BookOpen,
|
|
@@ -139,6 +140,29 @@ export const staticMenuItems: PrimaryMenuItem[] = [
|
|
|
139
140
|
},
|
|
140
141
|
],
|
|
141
142
|
},
|
|
143
|
+
{
|
|
144
|
+
id: 'realtime',
|
|
145
|
+
label: 'Realtime',
|
|
146
|
+
href: '/dashboard/realtime',
|
|
147
|
+
icon: Radio,
|
|
148
|
+
secondaryMenu: [
|
|
149
|
+
{
|
|
150
|
+
id: 'channels',
|
|
151
|
+
label: 'Channels',
|
|
152
|
+
href: '/dashboard/realtime/channels',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'messages',
|
|
156
|
+
label: 'Messages',
|
|
157
|
+
href: '/dashboard/realtime/messages',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: 'permissions',
|
|
161
|
+
label: 'Permissions',
|
|
162
|
+
href: '/dashboard/realtime/permissions',
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
},
|
|
142
166
|
{
|
|
143
167
|
id: 'ai',
|
|
144
168
|
label: 'AI',
|
|
@@ -169,7 +169,7 @@ export const isIframe = () => {
|
|
|
169
169
|
};
|
|
170
170
|
|
|
171
171
|
/**
|
|
172
|
-
* Formats a timestamp string to a human-readable format
|
|
172
|
+
* Formats a timestamp string to a human-readable format with time
|
|
173
173
|
* Used consistently across the application for displaying timestamps
|
|
174
174
|
* @param timestamp - ISO timestamp string
|
|
175
175
|
* @returns Formatted date string (e.g., "Jan 15, 2025, 03:30 PM")
|
|
@@ -181,3 +181,16 @@ export function formatTime(timestamp: string): string {
|
|
|
181
181
|
}
|
|
182
182
|
return format(date, 'MMM dd, yyyy, hh:mm a');
|
|
183
183
|
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Formats a timestamp string to a date-only format
|
|
187
|
+
* @param timestamp - ISO timestamp string
|
|
188
|
+
* @returns Formatted date string (e.g., "Jan 15, 2025")
|
|
189
|
+
*/
|
|
190
|
+
export function formatDate(timestamp: string): string {
|
|
191
|
+
const date = parseISO(timestamp);
|
|
192
|
+
if (!isValid(date)) {
|
|
193
|
+
return timestamp; // Return original if invalid
|
|
194
|
+
}
|
|
195
|
+
return format(date, 'MMM dd, yyyy');
|
|
196
|
+
}
|
package/frontend/tsconfig.json
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"moduleResolution": "bundler",
|
|
9
|
-
"allowImportingTsExtensions": true,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"jsx": "react-jsx",
|
|
14
|
-
"strict": true,
|
|
15
|
-
"noUnusedLocals": true,
|
|
16
|
-
"noUnusedParameters": true,
|
|
17
|
-
"noFallthroughCasesInSwitch": true,
|
|
18
|
-
"baseUrl": ".",
|
|
19
|
-
"paths": {
|
|
20
|
-
"@/*": ["./src/*"],
|
|
21
|
-
"@insforge/shared-schemas": ["../shared-schemas/src/index.ts"],
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"include": ["src", "src/vite-env.d.ts", "../shared-schemas"],
|
|
25
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"noUnusedParameters": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"baseUrl": ".",
|
|
19
|
+
"paths": {
|
|
20
|
+
"@/*": ["./src/*"],
|
|
21
|
+
"@insforge/shared-schemas": ["../shared-schemas/src/index.ts"],
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"include": ["src", "src/vite-env.d.ts", "../shared-schemas"],
|
|
25
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
26
26
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
|
-
"skipLibCheck": true,
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"moduleResolution": "bundler",
|
|
7
|
-
"allowSyntheticDefaultImports": true
|
|
8
|
-
},
|
|
9
|
-
"include": ["vite.config.ts"]
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"composite": true,
|
|
4
|
+
"skipLibCheck": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"allowSyntheticDefaultImports": true
|
|
8
|
+
},
|
|
9
|
+
"include": ["vite.config.ts"]
|
|
10
10
|
}
|