insforge 0.3.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/.dockerignore +58 -0
- package/.env.example +49 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
- package/.github/ISSUE_TEMPLATE/config.yml +11 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +79 -0
- package/.github/copilot-instructions.md +147 -0
- package/.github/workflows/build-image.yml +65 -0
- package/.github/workflows/ci-premerge-check.yml +24 -0
- package/.github/workflows/deploy-aws.yml +130 -0
- package/.github/workflows/lint-and-format.yml +33 -0
- package/.prettierignore +65 -0
- package/.prettierrc +9 -0
- package/CHANGELOG.md +3 -0
- package/CONTRIBUTING.md +126 -0
- package/Dockerfile +27 -0
- package/GITHUB_OAUTH_SETUP.md +49 -0
- package/GOOGLE_OAUTH_SETUP.md +148 -0
- package/LICENSE +201 -0
- package/README.md +134 -0
- package/assets/Dark.svg +23 -0
- package/assets/archDiagram.png +0 -0
- package/assets/banner.png +0 -0
- package/assets/mcpInstallv2.png +0 -0
- package/assets/sampleResponse.png +0 -0
- package/assets/signin.png +0 -0
- package/assets/userflow.png +0 -0
- package/backend/migrations/000_create-base-tables.sql +142 -0
- package/backend/migrations/001_create-helper-functions.sql +41 -0
- package/backend/migrations/002_rename-auth-tables.sql +30 -0
- package/backend/migrations/003_create-users-table.sql +56 -0
- package/backend/migrations/004_add-reload-postgrest-func.sql +24 -0
- package/backend/migrations/005_enable-project-admin-modify-users.sql +30 -0
- package/backend/migrations/006_modify-ai-usage-table.sql +25 -0
- package/backend/migrations/007_drop-metadata-table.sql +2 -0
- package/backend/migrations/008_add-system-tables.sql +77 -0
- package/backend/migrations/009_add-function-secrets.sql +24 -0
- package/backend/migrations/010_modify-ai-config-modalities.sql +93 -0
- package/backend/migrations/011_refactor-secrets-table.sql +15 -0
- package/backend/migrations/012_add-storage-uploaded-by.sql +8 -0
- package/backend/package.json +75 -0
- package/backend/src/api/middleware/auth.ts +240 -0
- package/backend/src/api/middleware/error.ts +231 -0
- package/backend/src/api/middleware/upload.ts +59 -0
- package/backend/src/api/routes/agent.ts +29 -0
- package/backend/src/api/routes/ai.ts +472 -0
- package/backend/src/api/routes/auth.oauth.ts +482 -0
- package/backend/src/api/routes/auth.ts +386 -0
- package/backend/src/api/routes/database.advance.ts +275 -0
- package/backend/src/api/routes/database.records.ts +246 -0
- package/backend/src/api/routes/database.tables.ts +161 -0
- package/backend/src/api/routes/docs.ts +66 -0
- package/backend/src/api/routes/functions.ts +183 -0
- package/backend/src/api/routes/logs.ts +150 -0
- package/backend/src/api/routes/metadata.ts +160 -0
- package/backend/src/api/routes/openapi.ts +82 -0
- package/backend/src/api/routes/secrets.ts +199 -0
- package/backend/src/api/routes/storage.ts +547 -0
- package/backend/src/api/routes/usage.ts +96 -0
- package/backend/src/core/ai/chat.ts +207 -0
- package/backend/src/core/ai/client.ts +242 -0
- package/backend/src/core/ai/config.ts +187 -0
- package/backend/src/core/ai/image.ts +156 -0
- package/backend/src/core/ai/model.ts +117 -0
- package/backend/src/core/ai/usage.ts +290 -0
- package/backend/src/core/auth/auth.ts +781 -0
- package/backend/src/core/auth/oauth.ts +398 -0
- package/backend/src/core/database/advance.ts +1074 -0
- package/backend/src/core/database/manager.ts +178 -0
- package/backend/src/core/database/table.ts +772 -0
- package/backend/src/core/documentation/agent.ts +689 -0
- package/backend/src/core/documentation/openapi.ts +856 -0
- package/backend/src/core/functions/functions.ts +310 -0
- package/backend/src/core/logs/analytics.ts +76 -0
- package/backend/src/core/logs/audit.ts +255 -0
- package/backend/src/core/logs/providers/base.provider.ts +83 -0
- package/backend/src/core/logs/providers/cloudwatch.provider.ts +510 -0
- package/backend/src/core/logs/providers/localdb.provider.ts +246 -0
- package/backend/src/core/secrets/encryption.ts +58 -0
- package/backend/src/core/secrets/secrets.ts +410 -0
- package/backend/src/core/socket/socket.ts +388 -0
- package/backend/src/core/socket/types.ts +79 -0
- package/backend/src/core/storage/storage.ts +923 -0
- package/backend/src/server.ts +288 -0
- package/backend/src/types/ai.ts +46 -0
- package/backend/src/types/auth.ts +90 -0
- package/backend/src/types/database.ts +136 -0
- package/backend/src/types/error-constants.ts +86 -0
- package/backend/src/types/logs.ts +47 -0
- package/backend/src/types/profile.ts +55 -0
- package/backend/src/types/storage.ts +23 -0
- package/backend/src/utils/cloud-token.ts +39 -0
- package/backend/src/utils/constants.ts +1 -0
- package/backend/src/utils/environment.ts +35 -0
- package/backend/src/utils/helpers.ts +49 -0
- package/backend/src/utils/logger.ts +13 -0
- package/backend/src/utils/response.ts +62 -0
- package/backend/src/utils/seed.ts +205 -0
- package/backend/src/utils/sql-parser.ts +63 -0
- package/backend/src/utils/uuid.ts +9 -0
- package/backend/src/utils/validations.ts +129 -0
- package/backend/tests/README.md +134 -0
- package/backend/tests/cleanup-all-test-data.sh +231 -0
- package/backend/tests/cloud/test-s3-multitenant.sh +132 -0
- package/backend/tests/local/comprehensive-curl-tests.sh +156 -0
- package/backend/tests/local/test-auth-router.sh +144 -0
- package/backend/tests/local/test-database-router.sh +222 -0
- package/backend/tests/local/test-e2e.sh +241 -0
- package/backend/tests/local/test-fk-errors.sh +97 -0
- package/backend/tests/local/test-id-field.sh +201 -0
- package/backend/tests/local/test-public-bucket.sh +265 -0
- package/backend/tests/local/test-secrets.sh +248 -0
- package/backend/tests/local/test-serverless-functions.sh.disabled +325 -0
- package/backend/tests/local/test-traditional-rest.sh +209 -0
- package/backend/tests/manual/README.md +51 -0
- package/backend/tests/manual/create-large-table-simple.sql +11 -0
- package/backend/tests/manual/seed-large-table.sql +101 -0
- package/backend/tests/manual/setup-large-table-extras.sql +34 -0
- package/backend/tests/manual/test-better-auth.sh +303 -0
- package/backend/tests/manual/test-bulk-upsert.sh +410 -0
- package/backend/tests/manual/test-database-advance.sh +297 -0
- package/backend/tests/manual/test-postgrest-stability.sh +192 -0
- package/backend/tests/manual/test-rawsql-export-import.sh +412 -0
- package/backend/tests/manual/test-universal-storage.sh +264 -0
- package/backend/tests/manual/test-users.sql +18 -0
- package/backend/tests/run-all-tests.sh +140 -0
- package/backend/tests/setup.ts +22 -0
- package/backend/tests/test-config.sh +303 -0
- package/backend/tsconfig.json +23 -0
- package/backend/tsup.config.ts +18 -0
- package/backend/vitest.config.ts +22 -0
- package/docker-compose.prod.yml +145 -0
- package/docker-compose.yml +167 -0
- package/docker-init/db/db-init.sql +125 -0
- package/docker-init/db/jwt.sql +5 -0
- package/docker-init/db/logs.sql +9 -0
- package/docker-init/db/postgresql.conf +17 -0
- package/docs/deprecated/insforge-auth-api.md +215 -0
- package/docs/deprecated/insforge-auth-sdk.md +100 -0
- package/docs/deprecated/insforge-db-api.md +359 -0
- package/docs/deprecated/insforge-db-sdk.md +140 -0
- package/docs/deprecated/insforge-debug-sdk.md +157 -0
- package/docs/deprecated/insforge-debug.md +65 -0
- package/docs/deprecated/insforge-instructions.md +124 -0
- package/docs/deprecated/insforge-project.md +118 -0
- package/docs/deprecated/insforge-storage-api.md +279 -0
- package/docs/deprecated/insforge-storage-sdk.md +159 -0
- package/docs/insforge-instructions-sdk.md +407 -0
- package/eslint.config.js +317 -0
- package/examples/oauth/frontend-oauth-example.html +251 -0
- package/examples/response-examples.md +444 -0
- package/frontend/README.md +112 -0
- package/frontend/components.json +17 -0
- package/frontend/index.html +13 -0
- package/frontend/package.json +63 -0
- package/frontend/public/favicon.ico +0 -0
- package/frontend/src/App.tsx +106 -0
- package/frontend/src/assets/icons/checkbox_checked.svg +6 -0
- package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -0
- package/frontend/src/assets/icons/checked.svg +3 -0
- package/frontend/src/assets/icons/error.svg +3 -0
- package/frontend/src/assets/icons/pencil.svg +4 -0
- package/frontend/src/assets/icons/refresh.svg +4 -0
- package/frontend/src/assets/icons/step_active.svg +3 -0
- package/frontend/src/assets/icons/step_inactive.svg +11 -0
- package/frontend/src/assets/icons/warning.svg +3 -0
- package/frontend/src/assets/logos/amazon.svg +1 -0
- package/frontend/src/assets/logos/claude_code.svg +3 -0
- package/frontend/src/assets/logos/cline.svg +6 -0
- package/frontend/src/assets/logos/cursor.svg +20 -0
- package/frontend/src/assets/logos/discord.svg +9 -0
- package/frontend/src/assets/logos/gemini.svg +19 -0
- package/frontend/src/assets/logos/github.svg +5 -0
- package/frontend/src/assets/logos/google.svg +13 -0
- package/frontend/src/assets/logos/grok.svg +10 -0
- package/frontend/src/assets/logos/insforge_dark.svg +15 -0
- package/frontend/src/assets/logos/insforge_light.svg +15 -0
- package/frontend/src/assets/logos/openai.svg +10 -0
- package/frontend/src/assets/logos/roo_code.svg +9 -0
- package/frontend/src/assets/logos/trae.svg +3 -0
- package/frontend/src/assets/logos/windsurf.svg +10 -0
- package/frontend/src/components/ButtonWithLoading.tsx +27 -0
- package/frontend/src/components/Checkbox.tsx +61 -0
- package/frontend/src/components/CodeBlock.tsx +32 -0
- package/frontend/src/components/ConfirmDialog.tsx +96 -0
- package/frontend/src/components/CopyButton.tsx +69 -0
- package/frontend/src/components/DeleteActionButton.tsx +42 -0
- package/frontend/src/components/EmptyState.tsx +41 -0
- package/frontend/src/components/ErrorState.tsx +35 -0
- package/frontend/src/components/FeatureSidebar.tsx +126 -0
- package/frontend/src/components/FeatureSidebarItem.tsx +101 -0
- package/frontend/src/components/JsonHighlight.tsx +61 -0
- package/frontend/src/components/LoadingState.tsx +16 -0
- package/frontend/src/components/PaginationControls.tsx +54 -0
- package/frontend/src/components/PromptDialog.tsx +68 -0
- package/frontend/src/components/SearchInput.tsx +90 -0
- package/frontend/src/components/SelectionClearButton.tsx +26 -0
- package/frontend/src/components/Stepper.tsx +139 -0
- package/frontend/src/components/ThemeToggle.tsx +58 -0
- package/frontend/src/components/TypeBadge.tsx +20 -0
- package/frontend/src/components/datagrid/DataGrid.tsx +264 -0
- package/frontend/src/components/datagrid/DefaultCellRenderer.tsx +114 -0
- package/frontend/src/components/datagrid/IdCell.tsx +44 -0
- package/frontend/src/components/datagrid/SortableHeader.tsx +74 -0
- package/frontend/src/components/datagrid/cell-editors/BooleanCellEditor.tsx +54 -0
- package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +483 -0
- package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +362 -0
- package/frontend/src/components/datagrid/cell-editors/TextCellEditor.tsx +38 -0
- package/frontend/src/components/datagrid/cell-editors/index.ts +14 -0
- package/frontend/src/components/datagrid/cell-editors/types.ts +43 -0
- package/frontend/src/components/datagrid/datagridTypes.tsx +72 -0
- package/frontend/src/components/datagrid/index.tsx +20 -0
- package/frontend/src/components/index.ts +39 -0
- package/frontend/src/components/layout/AppHeader.tsx +146 -0
- package/frontend/src/components/layout/AppSidebar.tsx +190 -0
- package/frontend/src/components/layout/CloudLayout.tsx +95 -0
- package/frontend/src/components/layout/Layout.tsx +43 -0
- package/frontend/src/components/radix/Alert.tsx +45 -0
- package/frontend/src/components/radix/AlertDialog.tsx +115 -0
- package/frontend/src/components/radix/Avatar.tsx +45 -0
- package/frontend/src/components/radix/Badge.tsx +33 -0
- package/frontend/src/components/radix/Button.tsx +50 -0
- package/frontend/src/components/radix/Card.tsx +58 -0
- package/frontend/src/components/radix/Dialog.tsx +98 -0
- package/frontend/src/components/radix/DropdownMenu.tsx +185 -0
- package/frontend/src/components/radix/Form.tsx +167 -0
- package/frontend/src/components/radix/Input.tsx +22 -0
- package/frontend/src/components/radix/Label.tsx +19 -0
- package/frontend/src/components/radix/Popover.tsx +29 -0
- package/frontend/src/components/radix/ScrollArea.tsx +44 -0
- package/frontend/src/components/radix/Select.tsx +151 -0
- package/frontend/src/components/radix/Separator.tsx +26 -0
- package/frontend/src/components/radix/Sheet.tsx +119 -0
- package/frontend/src/components/radix/Skeleton.tsx +7 -0
- package/frontend/src/components/radix/Switch.tsx +29 -0
- package/frontend/src/components/radix/Tabs.tsx +50 -0
- package/frontend/src/components/radix/Textarea.tsx +21 -0
- package/frontend/src/components/radix/Tooltip.tsx +28 -0
- package/frontend/src/features/ai/components/AIConfigCard.tsx +154 -0
- package/frontend/src/features/ai/components/AIConfigDialog.tsx +76 -0
- package/frontend/src/features/ai/components/AIConfigForm.tsx +222 -0
- package/frontend/src/features/ai/components/AIEmptyState.tsx +18 -0
- package/frontend/src/features/ai/components/fields/ModalityField.tsx +87 -0
- package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +134 -0
- package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +33 -0
- package/frontend/src/features/ai/helpers.ts +155 -0
- package/frontend/src/features/ai/hooks/useAIConfigs.ts +221 -0
- package/frontend/src/features/ai/hooks/useAIUsage.ts +77 -0
- package/frontend/src/features/ai/page/AIPage.tsx +178 -0
- package/frontend/src/features/ai/services/ai.service.ts +148 -0
- package/frontend/src/features/auth/components/AddOAuthDialog.tsx +106 -0
- package/frontend/src/features/auth/components/AuthMethodTab.tsx +238 -0
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +303 -0
- package/frontend/src/features/auth/components/OAuthEmptyState.tsx +15 -0
- package/frontend/src/features/auth/components/UserFormDialog.tsx +248 -0
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +183 -0
- package/frontend/src/features/auth/components/UsersTab.tsx +114 -0
- package/frontend/src/features/auth/hooks/useOAuthConfig.ts +129 -0
- package/frontend/src/features/auth/hooks/useUsers.ts +57 -0
- package/frontend/src/features/auth/index.ts +9 -0
- package/frontend/src/features/auth/page/AuthenticationPage.tsx +169 -0
- package/frontend/src/features/auth/services/auth.service.ts +112 -0
- package/frontend/src/features/auth/services/oauth.service.ts +49 -0
- package/frontend/src/features/dashboard/page/DashboardPage.tsx +194 -0
- package/frontend/src/features/database/components/ColumnTypeSelect.tsx +64 -0
- package/frontend/src/features/database/components/DatabaseDataGrid.tsx +282 -0
- package/frontend/src/features/database/components/ForeignKeyCell.tsx +187 -0
- package/frontend/src/features/database/components/ForeignKeyPopover.tsx +378 -0
- package/frontend/src/features/database/components/LinkRecordModal.tsx +288 -0
- package/frontend/src/features/database/components/RecordFormDialog.tsx +164 -0
- package/frontend/src/features/database/components/RecordFormField.tsx +568 -0
- package/frontend/src/features/database/components/TableEmptyState.tsx +21 -0
- package/frontend/src/features/database/components/TableForm.tsx +656 -0
- package/frontend/src/features/database/components/TableFormColumn.tsx +137 -0
- package/frontend/src/features/database/components/TableListSkeleton.tsx +9 -0
- package/frontend/src/features/database/components/TableSidebar.tsx +47 -0
- package/frontend/src/features/database/constants.ts +26 -0
- package/frontend/src/features/database/helpers.ts +125 -0
- package/frontend/src/features/database/hooks/UseLinkModal.tsx +78 -0
- package/frontend/src/features/database/index.ts +12 -0
- package/frontend/src/features/database/page/DatabasePage.tsx +626 -0
- package/frontend/src/features/database/schema.ts +25 -0
- package/frontend/src/features/database/services/database.service.ts +216 -0
- package/frontend/src/features/functions/components/FunctionEmptyState.tsx +15 -0
- package/frontend/src/features/functions/components/FunctionRow.tsx +71 -0
- package/frontend/src/features/functions/components/FunctionViewer.tsx +46 -0
- package/frontend/src/features/functions/components/FunctionsContent.tsx +88 -0
- package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -0
- package/frontend/src/features/functions/components/SecretEmptyState.tsx +23 -0
- package/frontend/src/features/functions/components/SecretRow.tsx +68 -0
- package/frontend/src/features/functions/components/SecretsContent.tsx +120 -0
- package/frontend/src/features/functions/hooks/useFunctions.ts +106 -0
- package/frontend/src/features/functions/page/FunctionsPage.tsx +28 -0
- package/frontend/src/features/functions/services/functions.service.ts +48 -0
- package/frontend/src/features/login/components/AuthErrorBoundary.tsx +87 -0
- package/frontend/src/features/login/components/PrivateRoute.tsx +24 -0
- package/frontend/src/features/login/page/CloudLoginPage.tsx +93 -0
- package/frontend/src/features/login/page/LoginPage.tsx +174 -0
- package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +313 -0
- package/frontend/src/features/logs/components/LogsTable.tsx +199 -0
- package/frontend/src/features/logs/hooks/useAuditLogs.ts +39 -0
- package/frontend/src/features/logs/index.ts +5 -0
- package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +530 -0
- package/frontend/src/features/logs/page/AuditsPage.tsx +192 -0
- package/frontend/src/features/logs/services/log.service.ts +171 -0
- package/frontend/src/features/metadata/hooks/useMetadata.ts +53 -0
- package/frontend/src/features/metadata/index.ts +0 -0
- package/frontend/src/features/metadata/page/MetadataPage.tsx +136 -0
- package/frontend/src/features/metadata/services/metadata.service.ts +17 -0
- package/frontend/src/features/onboard/components/CompletionCard.tsx +41 -0
- package/frontend/src/features/onboard/components/OnboardButton.tsx +84 -0
- package/frontend/src/features/onboard/components/StepContent.tsx +91 -0
- package/frontend/src/features/onboard/components/TestConnectionStep.tsx +53 -0
- package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +35 -0
- package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +144 -0
- package/frontend/src/features/onboard/components/mcp/index.ts +4 -0
- package/frontend/src/features/onboard/components/mcp/mcp-helper.tsx +98 -0
- package/frontend/src/features/onboard/index.ts +3 -0
- package/frontend/src/features/onboard/page/OnBoardPage.tsx +104 -0
- package/frontend/src/features/onboard/types.ts +8 -0
- package/frontend/src/features/secrets/hooks/useSecrets.ts +139 -0
- package/frontend/src/features/secrets/services/secrets.service.ts +57 -0
- package/frontend/src/features/storage/components/BucketEmptyState.tsx +19 -0
- package/frontend/src/features/storage/components/BucketFormDialog.tsx +194 -0
- package/frontend/src/features/storage/components/BucketListSkeleton.tsx +17 -0
- package/frontend/src/features/storage/components/FilePreviewDialog.tsx +287 -0
- package/frontend/src/features/storage/components/StorageDataGrid.tsx +239 -0
- package/frontend/src/features/storage/components/StorageManager.tsx +236 -0
- package/frontend/src/features/storage/components/StorageSidebar.tsx +44 -0
- package/frontend/src/features/storage/components/UploadToast.tsx +46 -0
- package/frontend/src/features/storage/index.ts +3 -0
- package/frontend/src/features/storage/page/StoragePage.tsx +553 -0
- package/frontend/src/features/storage/services/storage.service.ts +144 -0
- package/frontend/src/features/visualizer/components/AuthNode.tsx +107 -0
- package/frontend/src/features/visualizer/components/BucketNode.tsx +34 -0
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +359 -0
- package/frontend/src/features/visualizer/components/TableNode.tsx +152 -0
- package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +24 -0
- package/frontend/src/features/visualizer/components/index.ts +5 -0
- package/frontend/src/features/visualizer/page/VisualizerPage.tsx +127 -0
- package/frontend/src/index.css +248 -0
- package/frontend/src/lib/api/client.ts +163 -0
- package/frontend/src/lib/contexts/AuthContext.tsx +157 -0
- package/frontend/src/lib/contexts/OnboardStepContext.tsx +68 -0
- package/frontend/src/lib/contexts/SocketContext.tsx +303 -0
- package/frontend/src/lib/contexts/ThemeContext.tsx +125 -0
- package/frontend/src/lib/hooks/useAuth.ts +4 -0
- package/frontend/src/lib/hooks/useConfirm.ts +55 -0
- package/frontend/src/lib/hooks/useInterval.ts +27 -0
- package/frontend/src/lib/hooks/useMediaQuery.ts +59 -0
- package/frontend/src/lib/hooks/useOnboardingCompletion.ts +29 -0
- package/frontend/src/lib/hooks/usePagination.ts +27 -0
- package/frontend/src/lib/hooks/useTimeout.ts +27 -0
- package/frontend/src/lib/hooks/useToast.tsx +229 -0
- package/frontend/src/lib/utils/constants.ts +38 -0
- package/frontend/src/lib/utils/utils.ts +165 -0
- package/frontend/src/lib/utils/validation-schemas.ts +126 -0
- package/frontend/src/main.tsx +16 -0
- package/frontend/src/rdg.css +194 -0
- package/frontend/src/vite-env.d.ts +12 -0
- package/frontend/tailwind.config.js +97 -0
- package/frontend/tsconfig.json +26 -0
- package/frontend/tsconfig.node.json +10 -0
- package/frontend/vite.config.ts +37 -0
- package/frontend/vitest.config.ts +36 -0
- package/functions/deno.json +25 -0
- package/functions/server.ts +290 -0
- package/functions/worker-template.js +126 -0
- package/openapi/ai.yaml +689 -0
- package/openapi/auth.yaml +563 -0
- package/openapi/functions.yaml +476 -0
- package/openapi/health.yaml +30 -0
- package/openapi/logs.yaml +224 -0
- package/openapi/metadata.yaml +178 -0
- package/openapi/records.yaml +382 -0
- package/openapi/secrets.yaml +371 -0
- package/openapi/storage.yaml +876 -0
- package/openapi/tables.yaml +464 -0
- package/package.json +88 -0
- package/shared-schemas/package.json +31 -0
- package/shared-schemas/src/ai-api.schema.ts +167 -0
- package/shared-schemas/src/ai.schema.ts +54 -0
- package/shared-schemas/src/auth-api.schema.ts +193 -0
- package/shared-schemas/src/auth.schema.ts +94 -0
- package/shared-schemas/src/database-api.schema.ts +259 -0
- package/shared-schemas/src/database.schema.ts +69 -0
- package/shared-schemas/src/functions-api.schema.ts +25 -0
- package/shared-schemas/src/functions.schema.ts +16 -0
- package/shared-schemas/src/index.ts +13 -0
- package/shared-schemas/src/logs-api.schema.ts +49 -0
- package/shared-schemas/src/logs.schema.ts +14 -0
- package/shared-schemas/src/metadata.schema.ts +56 -0
- package/shared-schemas/src/storage-api.schema.ts +65 -0
- package/shared-schemas/src/storage.schema.ts +19 -0
- package/shared-schemas/tsconfig.json +21 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import express, { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import rateLimit from 'express-rate-limit';
|
|
4
|
+
import dotenv from 'dotenv';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import authRouter from '@/api/routes/auth.js';
|
|
9
|
+
import { databaseTablesRouter } from '@/api/routes/database.tables.js';
|
|
10
|
+
import { databaseRecordsRouter } from '@/api/routes/database.records.js';
|
|
11
|
+
import databaseAdvanceRouter from '@/api/routes/database.advance.js';
|
|
12
|
+
import { storageRouter } from '@/api/routes/storage.js';
|
|
13
|
+
import { metadataRouter } from '@/api/routes/metadata.js';
|
|
14
|
+
import { logsRouter } from '@/api/routes/logs.js';
|
|
15
|
+
import { docsRouter } from '@/api/routes/docs.js';
|
|
16
|
+
import functionsRouter from '@/api/routes/functions.js';
|
|
17
|
+
import secretsRouter from '@/api/routes/secrets.js';
|
|
18
|
+
import { usageRouter } from '@/api/routes/usage.js';
|
|
19
|
+
import { openAPIRouter } from '@/api/routes/openapi.js';
|
|
20
|
+
import { agentDocsRouter } from '@/api/routes/agent.js';
|
|
21
|
+
import { aiRouter } from '@/api/routes/ai.js';
|
|
22
|
+
import { errorMiddleware } from '@/api/middleware/error.js';
|
|
23
|
+
import fetch, { HeadersInit } from 'node-fetch';
|
|
24
|
+
import { DatabaseManager } from '@/core/database/manager.js';
|
|
25
|
+
import { AnalyticsManager } from '@/core/logs/analytics.js';
|
|
26
|
+
import { StorageService } from '@/core/storage/storage.js';
|
|
27
|
+
import { SocketService } from '@/core/socket/socket.js';
|
|
28
|
+
import { seedBackend } from '@/utils/seed.js';
|
|
29
|
+
import logger from '@/utils/logger.js';
|
|
30
|
+
import { isProduction } from './utils/environment';
|
|
31
|
+
import packageJson from '../../package.json';
|
|
32
|
+
|
|
33
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
const __dirname = path.dirname(__filename);
|
|
35
|
+
|
|
36
|
+
// Load .env file from the root directory (parent of backend)
|
|
37
|
+
const envPath = path.resolve(__dirname, '../../.env');
|
|
38
|
+
if (fs.existsSync(envPath)) {
|
|
39
|
+
dotenv.config({ path: envPath });
|
|
40
|
+
} else {
|
|
41
|
+
// Fallback to default behavior (looks in current working directory)
|
|
42
|
+
dotenv.config();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function createApp() {
|
|
46
|
+
// Initialize database first
|
|
47
|
+
const dbManager = DatabaseManager.getInstance();
|
|
48
|
+
await dbManager.initialize(); // create data/app.db
|
|
49
|
+
|
|
50
|
+
// Initialize storage service
|
|
51
|
+
const storageService = StorageService.getInstance();
|
|
52
|
+
await storageService.initialize(); // create data/storage
|
|
53
|
+
|
|
54
|
+
// Metadata is now handled by individual modules on-demand
|
|
55
|
+
|
|
56
|
+
// Initialize analytics service
|
|
57
|
+
const analyticsManager = AnalyticsManager.getInstance();
|
|
58
|
+
await analyticsManager.initialize(); // connect to _insforge database
|
|
59
|
+
|
|
60
|
+
const app = express();
|
|
61
|
+
|
|
62
|
+
// Enable trust proxy setting for rate limiting behind proxies/load balancers
|
|
63
|
+
app.set('trust proxy', true);
|
|
64
|
+
|
|
65
|
+
const limiter = rateLimit({
|
|
66
|
+
windowMs: 15 * 60 * 1000,
|
|
67
|
+
max: 1000,
|
|
68
|
+
message: 'Too many requests from this IP',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Basic middleware
|
|
72
|
+
app.use(
|
|
73
|
+
cors({
|
|
74
|
+
origin: true, // Allow all origins (matches Better Auth's trustedOrigins: ['*'])
|
|
75
|
+
credentials: true, // Allow cookies/credentials
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
if (isProduction()) {
|
|
79
|
+
app.use(limiter);
|
|
80
|
+
}
|
|
81
|
+
app.use((req: Request, res: Response, next: NextFunction) => {
|
|
82
|
+
const startTime = Date.now();
|
|
83
|
+
const originalSend = res.send;
|
|
84
|
+
const originalJson = res.json;
|
|
85
|
+
|
|
86
|
+
// Track response size
|
|
87
|
+
let responseSize = 0;
|
|
88
|
+
|
|
89
|
+
// Override send method
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
91
|
+
res.send = function (data: any) {
|
|
92
|
+
if (data) {
|
|
93
|
+
responseSize = Buffer.byteLength(typeof data === 'string' ? data : JSON.stringify(data));
|
|
94
|
+
}
|
|
95
|
+
return originalSend.call(this, data);
|
|
96
|
+
};
|
|
97
|
+
// Override json method
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
99
|
+
res.json = function (data: any) {
|
|
100
|
+
if (data) {
|
|
101
|
+
responseSize = Buffer.byteLength(JSON.stringify(data));
|
|
102
|
+
}
|
|
103
|
+
return originalJson.call(this, data);
|
|
104
|
+
};
|
|
105
|
+
// Log after response is finished
|
|
106
|
+
res.on('finish', () => {
|
|
107
|
+
// Skip logging for analytics endpoints to avoid infinite loops
|
|
108
|
+
if (req.path.includes('/analytics/')) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const duration = Date.now() - startTime;
|
|
113
|
+
logger.info('HTTP Request', {
|
|
114
|
+
method: req.method,
|
|
115
|
+
path: req.path,
|
|
116
|
+
status: res.statusCode,
|
|
117
|
+
size: responseSize,
|
|
118
|
+
duration: `${duration}ms`,
|
|
119
|
+
ip: req.ip || req.socket.remoteAddress,
|
|
120
|
+
userAgent: req.headers['user-agent'],
|
|
121
|
+
timestamp: new Date().toISOString(),
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
next();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Apply JSON middleware
|
|
128
|
+
app.use(express.json({ limit: '100mb' }));
|
|
129
|
+
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
|
130
|
+
|
|
131
|
+
// Create API router and mount all API routes under /api
|
|
132
|
+
const apiRouter = express.Router();
|
|
133
|
+
|
|
134
|
+
apiRouter.get('/health', (_req: Request, res: Response) => {
|
|
135
|
+
// Traditional REST: return data directly
|
|
136
|
+
const version = packageJson.version;
|
|
137
|
+
res.json({
|
|
138
|
+
status: 'ok',
|
|
139
|
+
version,
|
|
140
|
+
service: 'Insforge OSS Backend',
|
|
141
|
+
timestamp: new Date().toISOString(),
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Mount auth routes
|
|
146
|
+
apiRouter.use('/auth', authRouter);
|
|
147
|
+
apiRouter.use('/database/tables', databaseTablesRouter);
|
|
148
|
+
apiRouter.use('/database/records', databaseRecordsRouter);
|
|
149
|
+
apiRouter.use('/database/advance', databaseAdvanceRouter);
|
|
150
|
+
apiRouter.use('/storage', storageRouter);
|
|
151
|
+
apiRouter.use('/metadata', metadataRouter);
|
|
152
|
+
apiRouter.use('/logs', logsRouter);
|
|
153
|
+
apiRouter.use('/docs', docsRouter);
|
|
154
|
+
apiRouter.use('/functions', functionsRouter);
|
|
155
|
+
apiRouter.use('/secrets', secretsRouter);
|
|
156
|
+
apiRouter.use('/usage', usageRouter);
|
|
157
|
+
apiRouter.use('/openapi', openAPIRouter);
|
|
158
|
+
apiRouter.use('/agent-docs', agentDocsRouter);
|
|
159
|
+
apiRouter.use('/ai', aiRouter);
|
|
160
|
+
|
|
161
|
+
// Mount all API routes under /api prefix
|
|
162
|
+
app.use('/api', apiRouter);
|
|
163
|
+
|
|
164
|
+
// Add direct OpenAPI route at /openapi
|
|
165
|
+
app.get('/openapi', async (_req: Request, res: Response) => {
|
|
166
|
+
try {
|
|
167
|
+
const { OpenAPIService } = await import('@/core/documentation/openapi.js');
|
|
168
|
+
const openAPIService = OpenAPIService.getInstance();
|
|
169
|
+
const openAPIDocument = await openAPIService.generateOpenAPIDocument();
|
|
170
|
+
res.json(openAPIDocument);
|
|
171
|
+
} catch {
|
|
172
|
+
res.status(500).json({ error: 'Failed to generate OpenAPI document' });
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Add direct AI agent documentation route at /agent-docs
|
|
177
|
+
app.get('/agent-docs', async (_req: Request, res: Response) => {
|
|
178
|
+
try {
|
|
179
|
+
const { AgentAPIDocService } = await import('@/core/documentation/agent.js');
|
|
180
|
+
const agentAPIDocService = AgentAPIDocService.getInstance();
|
|
181
|
+
const agentDocs = await agentAPIDocService.generateAgentDocumentation();
|
|
182
|
+
res.json(agentDocs);
|
|
183
|
+
} catch {
|
|
184
|
+
res.status(500).json({ error: 'Failed to generate agent API documentation' });
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Proxy function execution to Deno runtime
|
|
189
|
+
app.all('/functions/:slug', async (req: Request, res: Response) => {
|
|
190
|
+
try {
|
|
191
|
+
const { slug } = req.params;
|
|
192
|
+
const denoUrl = process.env.DENO_RUNTIME_URL || 'http://localhost:7133';
|
|
193
|
+
|
|
194
|
+
// Simple direct proxy - just pass everything through
|
|
195
|
+
const response = await fetch(
|
|
196
|
+
`${denoUrl}/${slug}${req.url.includes('?') ? req.url.substring(req.url.indexOf('?')) : ''}`,
|
|
197
|
+
{
|
|
198
|
+
method: req.method,
|
|
199
|
+
headers: req.headers as HeadersInit,
|
|
200
|
+
body: ['GET', 'HEAD'].includes(req.method) ? undefined : JSON.stringify(req.body),
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// Get response text
|
|
205
|
+
const responseText = await response.text();
|
|
206
|
+
|
|
207
|
+
res
|
|
208
|
+
.status(response.status)
|
|
209
|
+
.set('Content-Type', response.headers.get('content-type') || 'application/json')
|
|
210
|
+
.set('Access-Control-Allow-Origin', '*')
|
|
211
|
+
.send(responseText);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
logger.error('Failed to proxy to Deno runtime', {
|
|
214
|
+
error: error instanceof Error ? error.message : String(error),
|
|
215
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
216
|
+
slug: req.params.slug,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Return the actual error from Deno or connection error
|
|
220
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
221
|
+
res.status(502).json({
|
|
222
|
+
error: errorMessage,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Always try to serve frontend if it exists
|
|
228
|
+
const frontendPath = path.join(__dirname, 'frontend');
|
|
229
|
+
|
|
230
|
+
// Check if frontend build exists
|
|
231
|
+
if (fs.existsSync(frontendPath)) {
|
|
232
|
+
// Catch all handler for SPA routes
|
|
233
|
+
app.get('/cloud*', (_req: Request, res: Response) => {
|
|
234
|
+
res.sendFile(path.join(frontendPath, 'index.html'));
|
|
235
|
+
});
|
|
236
|
+
app.get('/dashboard*', (_req: Request, res: Response) => {
|
|
237
|
+
res.sendFile(path.join(frontendPath, 'index.html'));
|
|
238
|
+
});
|
|
239
|
+
app.use(express.static(frontendPath));
|
|
240
|
+
} else {
|
|
241
|
+
// Catch-all for 404 errors - Traditional REST format
|
|
242
|
+
app.use('*', (req: Request, res: Response) => {
|
|
243
|
+
res.status(404).json({
|
|
244
|
+
error: 'NOT_FOUND',
|
|
245
|
+
message: `Endpoint ${req.originalUrl} not found`,
|
|
246
|
+
statusCode: 404,
|
|
247
|
+
nextActions: 'Please check the API documentation for available endpoints',
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
app.use(errorMiddleware);
|
|
253
|
+
await seedBackend();
|
|
254
|
+
|
|
255
|
+
return app;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Use PORT from environment variable, fallback to 7130
|
|
259
|
+
const PORT = parseInt(process.env.PORT || '7130');
|
|
260
|
+
|
|
261
|
+
async function initializeServer() {
|
|
262
|
+
try {
|
|
263
|
+
const app = await createApp();
|
|
264
|
+
const server = app.listen(PORT, () => {
|
|
265
|
+
logger.info(`Backend API service listening on port ${PORT}`);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Initialize Socket.IO service
|
|
269
|
+
const socketService = SocketService.getInstance();
|
|
270
|
+
socketService.initialize(server);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
logger.error('Failed to initialize server', {
|
|
273
|
+
error: error instanceof Error ? error.message : String(error),
|
|
274
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
275
|
+
});
|
|
276
|
+
process.exit(1);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
void initializeServer();
|
|
281
|
+
|
|
282
|
+
function cleanup() {
|
|
283
|
+
logger.info('Shutting down gracefully...');
|
|
284
|
+
process.exit(0);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
process.on('SIGINT', cleanup);
|
|
288
|
+
process.on('SIGTERM', cleanup);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Additional types that are backend-specific or internal
|
|
2
|
+
|
|
3
|
+
import { ChatCompletionRequest } from '@insforge/shared-schemas';
|
|
4
|
+
|
|
5
|
+
export type ChatCompletionOptions = Omit<ChatCompletionRequest, 'stream' | 'messages'>;
|
|
6
|
+
|
|
7
|
+
export interface OpenRouterImageMessage {
|
|
8
|
+
type: 'image_url';
|
|
9
|
+
image_url: {
|
|
10
|
+
url: string; // Can be a direct URL or data:image base64 URL
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ============= OpenRouter API Types =============
|
|
15
|
+
|
|
16
|
+
export interface RawOpenRouterModel {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
created: number;
|
|
20
|
+
description?: string;
|
|
21
|
+
architecture?: {
|
|
22
|
+
input_modalities: string[];
|
|
23
|
+
output_modalities: string[];
|
|
24
|
+
tokenizer: string;
|
|
25
|
+
instruct_type: string;
|
|
26
|
+
};
|
|
27
|
+
topProvider?: {
|
|
28
|
+
is_moderated: boolean;
|
|
29
|
+
context_length: number;
|
|
30
|
+
max_completion_tokens: number;
|
|
31
|
+
};
|
|
32
|
+
pricing: {
|
|
33
|
+
prompt: string;
|
|
34
|
+
completion: string;
|
|
35
|
+
image?: string;
|
|
36
|
+
request?: string;
|
|
37
|
+
web_search?: string;
|
|
38
|
+
internal_reasoning?: string;
|
|
39
|
+
input_cache_read?: string;
|
|
40
|
+
input_cache_write?: string;
|
|
41
|
+
};
|
|
42
|
+
context_length: number;
|
|
43
|
+
max_completion_tokens?: number;
|
|
44
|
+
per_request_limits?: Record<string, unknown>;
|
|
45
|
+
supported_parameters?: string[];
|
|
46
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Type definitions for database user records
|
|
2
|
+
export interface UserRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
email: string;
|
|
5
|
+
name: string;
|
|
6
|
+
email_verified: boolean;
|
|
7
|
+
created_at: string;
|
|
8
|
+
updated_at: string;
|
|
9
|
+
password: string | null;
|
|
10
|
+
providers: string | null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// OAuth provider data from external providers
|
|
14
|
+
export interface OAuthIdentityData {
|
|
15
|
+
sub?: string; // Subject identifier from provider
|
|
16
|
+
email?: string;
|
|
17
|
+
email_verified?: boolean;
|
|
18
|
+
name?: string;
|
|
19
|
+
given_name?: string;
|
|
20
|
+
family_name?: string;
|
|
21
|
+
picture?: string;
|
|
22
|
+
locale?: string;
|
|
23
|
+
[key: string]: string | boolean | number | undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Auth database record
|
|
27
|
+
export interface AuthRecord {
|
|
28
|
+
id: string;
|
|
29
|
+
email: string;
|
|
30
|
+
password_hash: string;
|
|
31
|
+
created_at: string;
|
|
32
|
+
updated_at: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Identity record for OAuth providers
|
|
36
|
+
export interface IdentifiesRecord {
|
|
37
|
+
auth_id: string;
|
|
38
|
+
provider?: string;
|
|
39
|
+
provider_id?: string;
|
|
40
|
+
identity_data?: OAuthIdentityData;
|
|
41
|
+
email?: string;
|
|
42
|
+
last_login_at?: string;
|
|
43
|
+
created_at: string;
|
|
44
|
+
updated_at: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Superuser auth record
|
|
48
|
+
export interface SuperUserAuthRecord {
|
|
49
|
+
id: string;
|
|
50
|
+
email: string;
|
|
51
|
+
password_hash: string;
|
|
52
|
+
created_at: string;
|
|
53
|
+
updated_at: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Superuser profile record
|
|
57
|
+
export interface SuperUserProfileRecord {
|
|
58
|
+
id: string;
|
|
59
|
+
auth_id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
created_at: string;
|
|
62
|
+
updated_at: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Type definitions for OAuth providers
|
|
66
|
+
export interface GoogleUserInfo {
|
|
67
|
+
sub: string;
|
|
68
|
+
email: string;
|
|
69
|
+
email_verified?: boolean;
|
|
70
|
+
name?: string;
|
|
71
|
+
picture?: string;
|
|
72
|
+
given_name?: string;
|
|
73
|
+
family_name?: string;
|
|
74
|
+
locale?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface GitHubUserInfo {
|
|
78
|
+
id: number;
|
|
79
|
+
login: string;
|
|
80
|
+
name?: string;
|
|
81
|
+
email?: string;
|
|
82
|
+
avatar_url?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface GitHubEmailInfo {
|
|
86
|
+
email: string;
|
|
87
|
+
primary: boolean;
|
|
88
|
+
verified: boolean;
|
|
89
|
+
visibility?: string;
|
|
90
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Type definitions for database schema management
|
|
2
|
+
import { ColumnType, ColumnSchema, ForeignKeySchema } from '@insforge/shared-schemas';
|
|
3
|
+
|
|
4
|
+
// Database metadata format returned by getDatabaseMetadata
|
|
5
|
+
export interface DatabaseMetadata {
|
|
6
|
+
tables: Record<
|
|
7
|
+
string,
|
|
8
|
+
{
|
|
9
|
+
columns: ColumnSchema[];
|
|
10
|
+
record_count: number;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ColumnTypeInfo {
|
|
16
|
+
type: ColumnType;
|
|
17
|
+
sqlType: string;
|
|
18
|
+
defaultValue: string | null;
|
|
19
|
+
description: string;
|
|
20
|
+
icon?: string;
|
|
21
|
+
validation?: {
|
|
22
|
+
min?: number;
|
|
23
|
+
max?: number;
|
|
24
|
+
pattern?: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Map frontend types to PostgreSQL types with metadata
|
|
29
|
+
export const COLUMN_TYPES: Record<ColumnType, ColumnTypeInfo> = {
|
|
30
|
+
[ColumnType.STRING]: {
|
|
31
|
+
type: ColumnType.STRING,
|
|
32
|
+
sqlType: 'TEXT',
|
|
33
|
+
defaultValue: null,
|
|
34
|
+
description: 'Text up to 255 characters',
|
|
35
|
+
icon: 'text',
|
|
36
|
+
},
|
|
37
|
+
[ColumnType.DATE]: {
|
|
38
|
+
type: ColumnType.DATE,
|
|
39
|
+
sqlType: 'DATE',
|
|
40
|
+
defaultValue: 'now()',
|
|
41
|
+
description: 'Date',
|
|
42
|
+
icon: 'calendar',
|
|
43
|
+
},
|
|
44
|
+
[ColumnType.DATETIME]: {
|
|
45
|
+
type: ColumnType.DATETIME,
|
|
46
|
+
sqlType: 'TIMESTAMPTZ',
|
|
47
|
+
defaultValue: 'now()',
|
|
48
|
+
description: 'Date and time with timezone',
|
|
49
|
+
icon: 'calendar',
|
|
50
|
+
},
|
|
51
|
+
[ColumnType.INTEGER]: {
|
|
52
|
+
type: ColumnType.INTEGER,
|
|
53
|
+
sqlType: 'INTEGER',
|
|
54
|
+
defaultValue: null,
|
|
55
|
+
description: 'Whole numbers',
|
|
56
|
+
icon: 'hash',
|
|
57
|
+
},
|
|
58
|
+
[ColumnType.FLOAT]: {
|
|
59
|
+
type: ColumnType.FLOAT,
|
|
60
|
+
sqlType: 'DOUBLE PRECISION',
|
|
61
|
+
defaultValue: null,
|
|
62
|
+
description: 'Decimal numbers with double precision',
|
|
63
|
+
icon: 'percent',
|
|
64
|
+
},
|
|
65
|
+
[ColumnType.BOOLEAN]: {
|
|
66
|
+
type: ColumnType.BOOLEAN,
|
|
67
|
+
sqlType: 'BOOLEAN',
|
|
68
|
+
defaultValue: 'false',
|
|
69
|
+
description: 'True/false values',
|
|
70
|
+
icon: 'toggle',
|
|
71
|
+
},
|
|
72
|
+
[ColumnType.UUID]: {
|
|
73
|
+
type: ColumnType.UUID,
|
|
74
|
+
sqlType: 'UUID',
|
|
75
|
+
defaultValue: 'gen_random_uuid()',
|
|
76
|
+
description: 'Unique identifier (auto-generated)',
|
|
77
|
+
icon: 'fingerprint',
|
|
78
|
+
},
|
|
79
|
+
[ColumnType.JSON]: {
|
|
80
|
+
type: ColumnType.JSON,
|
|
81
|
+
sqlType: 'JSONB',
|
|
82
|
+
defaultValue: null,
|
|
83
|
+
description: 'Structured JSON data with indexing support',
|
|
84
|
+
icon: 'code',
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export interface ForeignKeyDefinition {
|
|
89
|
+
column: string;
|
|
90
|
+
references_table: string;
|
|
91
|
+
references_column: string;
|
|
92
|
+
on_delete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
|
|
93
|
+
on_update?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Type definition for foreign key information
|
|
97
|
+
export type ForeignKeyInfo = ForeignKeySchema & {
|
|
98
|
+
constraint_name: string;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Type definition for foreign key row from database
|
|
102
|
+
export interface ForeignKeyRow {
|
|
103
|
+
constraint_name: string;
|
|
104
|
+
from_column: string;
|
|
105
|
+
foreign_table: string;
|
|
106
|
+
foreign_column: string;
|
|
107
|
+
on_delete: string;
|
|
108
|
+
on_update: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Type definition for column information from database
|
|
112
|
+
export interface ColumnInfo {
|
|
113
|
+
column_name: string;
|
|
114
|
+
data_type: string;
|
|
115
|
+
is_nullable: string;
|
|
116
|
+
column_default: string | null;
|
|
117
|
+
character_maximum_length: number | null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Type definition for primary key information
|
|
121
|
+
export interface PrimaryKeyInfo {
|
|
122
|
+
column_name: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Valid types for database column values
|
|
126
|
+
export type DatabaseValue =
|
|
127
|
+
| string
|
|
128
|
+
| number
|
|
129
|
+
| boolean
|
|
130
|
+
| null
|
|
131
|
+
| Date
|
|
132
|
+
| DatabaseValue[]
|
|
133
|
+
| { [key: string]: DatabaseValue }; // jsonB type
|
|
134
|
+
|
|
135
|
+
// Generic database record type - used when we don't know the exact table structure
|
|
136
|
+
export type DatabaseRecord = Record<string, DatabaseValue>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Common types and constants used across the application
|
|
2
|
+
|
|
3
|
+
// Error codes - what went wrong
|
|
4
|
+
export enum ERROR_CODES {
|
|
5
|
+
// AUTH module
|
|
6
|
+
AUTH_INVALID_EMAIL = 'AUTH_INVALID_EMAIL',
|
|
7
|
+
AUTH_WEAK_PASSWORD = 'AUTH_WEAK_PASSWORD',
|
|
8
|
+
AUTH_INVALID_CREDENTIALS = 'AUTH_INVALID_CREDENTIALS',
|
|
9
|
+
AUTH_INVALID_API_KEY = 'AUTH_INVALID_API_KEY',
|
|
10
|
+
AUTH_EMAIL_EXISTS = 'AUTH_EMAIL_EXISTS',
|
|
11
|
+
AUTH_OAUTH_CONFIG_ERROR = 'AUTH_OAUTH_CONFIG_ERROR',
|
|
12
|
+
AUTH_UNSUPPORTED_PROVIDER = 'AUTH_UNSUPPORTED_PROVIDER',
|
|
13
|
+
AUTH_TOKEN_EXPIRED = 'AUTH_TOKEN_EXPIRED',
|
|
14
|
+
AUTH_UNAUTHORIZED = 'AUTH_UNAUTHORIZED',
|
|
15
|
+
AUTH_NEED_VERIFICATION = 'AUTH_NEED_VERIFICATION',
|
|
16
|
+
|
|
17
|
+
// DATABASE module
|
|
18
|
+
DATABASE_INVALID_PARAMETER = 'DATABASE_INVALID_PARAMETER',
|
|
19
|
+
DATABASE_VALIDATION_ERROR = 'DATABASE_VALIDATION_ERROR',
|
|
20
|
+
DATABASE_CONSTRAINT_VIOLATION = 'DATABASE_CONSTRAINT_VIOLATION',
|
|
21
|
+
DATABASE_NOT_FOUND = 'DATABASE_NOT_FOUND',
|
|
22
|
+
DATABASE_DUPLICATE = 'DATABASE_DUPLICATE',
|
|
23
|
+
DATABASE_PERMISSION_DENIED = 'DATABASE_PERMISSION_DENIED',
|
|
24
|
+
DATABASE_INTERNAL_ERROR = 'DATABASE_INTERNAL_ERROR',
|
|
25
|
+
DATABASE_FORBIDDEN = 'DATABASE_FORBIDDEN',
|
|
26
|
+
|
|
27
|
+
// STORAGE module
|
|
28
|
+
STORAGE_INVALID_PARAMETER = 'STORAGE_INVALID_PARAMETER',
|
|
29
|
+
STORAGE_INVALID_FILE_TYPE = 'STORAGE_INVALID_FILE_TYPE',
|
|
30
|
+
STORAGE_INSUFFICIENT_QUOTA = 'STORAGE_INSUFFICIENT_QUOTA',
|
|
31
|
+
STORAGE_NOT_FOUND = 'STORAGE_NOT_FOUND',
|
|
32
|
+
STORAGE_PERMISSION_DENIED = 'STORAGE_PERMISSION_DENIED',
|
|
33
|
+
|
|
34
|
+
// REALTIME module
|
|
35
|
+
REALTIME_CONNECTION_FAILED = 'REALTIME_CONNECTION_FAILED',
|
|
36
|
+
REALTIME_UNAUTHORIZED = 'REALTIME_UNAUTHORIZED',
|
|
37
|
+
REALTIME_INVALID_EVENT = 'REALTIME_INVALID_EVENT',
|
|
38
|
+
|
|
39
|
+
// AI module
|
|
40
|
+
AI_INVALID_API_KEY = 'AI_INVALID_API_KEY',
|
|
41
|
+
|
|
42
|
+
// Billing module
|
|
43
|
+
BILLING_INSUFFICIENT_BALANCE = 'BILLING_INSUFFICIENT_BALANCE',
|
|
44
|
+
|
|
45
|
+
// General
|
|
46
|
+
MISSING_FIELD = 'MISSING_FIELD',
|
|
47
|
+
ALREADY_EXISTS = 'ALREADY_EXISTS',
|
|
48
|
+
INVALID_INPUT = 'INVALID_INPUT',
|
|
49
|
+
NOT_FOUND = 'NOT_FOUND',
|
|
50
|
+
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
|
51
|
+
INTERNAL_ERROR = 'INTERNAL_ERROR',
|
|
52
|
+
TOO_MANY_REQUESTS = 'TOO_MANY_REQUESTS',
|
|
53
|
+
FORBIDDEN = 'FORBIDDEN',
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Next actions - what the user should do
|
|
57
|
+
export const NEXT_ACTION = {
|
|
58
|
+
// Authentication next actions
|
|
59
|
+
CHECK_TOKEN: 'Check the token is valid or login to get a new token.',
|
|
60
|
+
CHECK_ADMIN_TOKEN: 'Check the admin token is valid or login as admin to get a new token.',
|
|
61
|
+
CHECK_API_KEY: 'Check the API key is valid or generate a new API key.',
|
|
62
|
+
|
|
63
|
+
// Database next actions
|
|
64
|
+
CHECK_UNIQUE_FIELD: (field: string) =>
|
|
65
|
+
`A record with this field(${field}) already exists. You can query the existing record by using the query tool and then try again.`,
|
|
66
|
+
CHECK_TABLE_EXISTS:
|
|
67
|
+
'The resource you are trying to access does not exist. Please check the table with get metadata tool and try again.',
|
|
68
|
+
FILL_REQUIRED_FIELD: (field: string) =>
|
|
69
|
+
`The ${field} field is required and cannot be empty. Please fill in a value and try again.`,
|
|
70
|
+
CHECK_REFERENCE_EXISTS:
|
|
71
|
+
'The referenced record does not exist. Please check the reference with get metadata tool and try again.',
|
|
72
|
+
|
|
73
|
+
// Schema validation next actions
|
|
74
|
+
CHECK_COLUMN_EXISTS:
|
|
75
|
+
'Check the column name spelling and verify it exists in the table using GET /api/database/tables/{table}/schema',
|
|
76
|
+
CHECK_UNIQUE_CONSTRAINT:
|
|
77
|
+
'Ensure the referenced column has a unique constraint or is a primary key',
|
|
78
|
+
CHECK_DATATYPE_MATCH:
|
|
79
|
+
'Ensure the foreign key column and the referenced column have the same data type.',
|
|
80
|
+
REMOVE_DUPLICATE_COLUMN: (column: string) =>
|
|
81
|
+
`Remove the duplicate "${column}" column definition. Each column name must be unique within a table.`,
|
|
82
|
+
|
|
83
|
+
// Add more next actions as needed
|
|
84
|
+
} as const;
|
|
85
|
+
|
|
86
|
+
export type NextActionKey = keyof typeof NEXT_ACTION;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Audit log types
|
|
2
|
+
export interface AuditLogEntry {
|
|
3
|
+
actor: string;
|
|
4
|
+
action: string;
|
|
5
|
+
module: string;
|
|
6
|
+
details?: Record<string, unknown>;
|
|
7
|
+
ip_address?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface AuditLogQuery {
|
|
11
|
+
actor?: string;
|
|
12
|
+
action?: string;
|
|
13
|
+
module?: string;
|
|
14
|
+
start_date?: Date;
|
|
15
|
+
end_date?: Date;
|
|
16
|
+
limit?: number;
|
|
17
|
+
offset?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Types for Logflare analytics logs
|
|
21
|
+
export interface LogSource {
|
|
22
|
+
id: number;
|
|
23
|
+
name: string;
|
|
24
|
+
token: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AnalyticsLogRecord {
|
|
28
|
+
id: string;
|
|
29
|
+
event_message: string;
|
|
30
|
+
timestamp: string;
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
body: Record<string, any>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface AnalyticsLogResponse {
|
|
36
|
+
source: string;
|
|
37
|
+
logs: AnalyticsLogRecord[];
|
|
38
|
+
total: number;
|
|
39
|
+
page: number;
|
|
40
|
+
pageSize: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface LogSourceStats {
|
|
44
|
+
source: string;
|
|
45
|
+
count: number;
|
|
46
|
+
lastActivity: string;
|
|
47
|
+
}
|