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,159 @@
|
|
|
1
|
+
# InsForge Storage SDK
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
```javascript
|
|
5
|
+
import { createClient } from '@insforge/sdk';
|
|
6
|
+
const client = createClient({ baseUrl: 'http://localhost:7130' });
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Bucket Operations
|
|
10
|
+
|
|
11
|
+
### from(bucketName)
|
|
12
|
+
```javascript
|
|
13
|
+
const bucket = client.storage.from('avatars') // Returns StorageBucket instance
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## File Operations
|
|
17
|
+
|
|
18
|
+
### upload
|
|
19
|
+
```javascript
|
|
20
|
+
// Upload with specific key
|
|
21
|
+
const { data, error } = await client.storage
|
|
22
|
+
.from('avatars')
|
|
23
|
+
.upload('user-123.jpg', file);
|
|
24
|
+
|
|
25
|
+
// data: StorageFileSchema { bucket, key, size, mimeType, uploadedAt, url }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### uploadAuto
|
|
29
|
+
```javascript
|
|
30
|
+
// Upload with auto-generated key
|
|
31
|
+
const { data, error } = await client.storage
|
|
32
|
+
.from('avatars')
|
|
33
|
+
.uploadAuto(file);
|
|
34
|
+
|
|
35
|
+
// Generated key format: filename-timestamp-random.ext
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### download
|
|
39
|
+
```javascript
|
|
40
|
+
const { data: blob, error } = await client.storage
|
|
41
|
+
.from('avatars')
|
|
42
|
+
.download('user-123.jpg');
|
|
43
|
+
|
|
44
|
+
// data: Blob (can convert to URL with URL.createObjectURL(blob))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### remove
|
|
48
|
+
```javascript
|
|
49
|
+
const { data, error } = await client.storage
|
|
50
|
+
.from('avatars')
|
|
51
|
+
.remove('user-123.jpg');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### list
|
|
55
|
+
```javascript
|
|
56
|
+
const { data, error } = await client.storage
|
|
57
|
+
.from('avatars')
|
|
58
|
+
.list({
|
|
59
|
+
prefix: 'users/', // Filter by prefix
|
|
60
|
+
search: 'profile', // Search in filenames
|
|
61
|
+
limit: 10, // Max results (default: 100)
|
|
62
|
+
offset: 0 // Skip results
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// data: ListObjectsResponseSchema { bucketName, objects[], pagination }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### getPublicUrl
|
|
69
|
+
```javascript
|
|
70
|
+
// Get public URL (no API call)
|
|
71
|
+
const url = client.storage
|
|
72
|
+
.from('avatars')
|
|
73
|
+
.getPublicUrl('user-123.jpg');
|
|
74
|
+
|
|
75
|
+
// Returns: http://localhost:7130/api/storage/buckets/avatars/objects/user-123.jpg
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## File Upload Examples
|
|
79
|
+
|
|
80
|
+
### Upload File from Input
|
|
81
|
+
```javascript
|
|
82
|
+
// HTML: <input type="file" id="fileInput">
|
|
83
|
+
const fileInput = document.getElementById('fileInput');
|
|
84
|
+
const file = fileInput.files[0];
|
|
85
|
+
|
|
86
|
+
const { data, error } = await client.storage
|
|
87
|
+
.from('uploads')
|
|
88
|
+
.upload(`photos/${file.name}`, file);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Upload Blob
|
|
92
|
+
```javascript
|
|
93
|
+
const blob = new Blob(['Hello World'], { type: 'text/plain' });
|
|
94
|
+
|
|
95
|
+
const { data, error } = await client.storage
|
|
96
|
+
.from('documents')
|
|
97
|
+
.upload('hello.txt', blob);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Upload with Custom Name
|
|
101
|
+
```javascript
|
|
102
|
+
// Simple file upload - SDK handles FormData creation
|
|
103
|
+
const file = fileInput.files[0];
|
|
104
|
+
|
|
105
|
+
const { data, error } = await client.storage
|
|
106
|
+
.from('uploads')
|
|
107
|
+
.upload('custom-name.jpg', file);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Download & Display
|
|
111
|
+
|
|
112
|
+
### Download and Display Image
|
|
113
|
+
```javascript
|
|
114
|
+
const { data: blob, error } = await client.storage
|
|
115
|
+
.from('avatars')
|
|
116
|
+
.download('user-123.jpg');
|
|
117
|
+
|
|
118
|
+
if (blob) {
|
|
119
|
+
const url = URL.createObjectURL(blob);
|
|
120
|
+
document.getElementById('avatar').src = url;
|
|
121
|
+
|
|
122
|
+
// Clean up
|
|
123
|
+
URL.revokeObjectURL(url);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Direct URL for Public Buckets
|
|
128
|
+
```javascript
|
|
129
|
+
// For public buckets, use direct URL
|
|
130
|
+
const url = client.storage
|
|
131
|
+
.from('public-avatars')
|
|
132
|
+
.getPublicUrl('user-123.jpg');
|
|
133
|
+
|
|
134
|
+
document.getElementById('avatar').src = url;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Error Handling
|
|
138
|
+
```javascript
|
|
139
|
+
const { data, error } = await client.storage
|
|
140
|
+
.from('avatars')
|
|
141
|
+
.upload('user-123.jpg', file);
|
|
142
|
+
|
|
143
|
+
if (error) {
|
|
144
|
+
if (error.statusCode === 409) {
|
|
145
|
+
console.error('File already exists');
|
|
146
|
+
} else if (error.statusCode === 404) {
|
|
147
|
+
console.error('Bucket not found');
|
|
148
|
+
} else {
|
|
149
|
+
console.error(error.message);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Notes
|
|
155
|
+
- Bucket creation/deletion handled via MCP tools, not SDK
|
|
156
|
+
- Public buckets allow unauthenticated downloads
|
|
157
|
+
- Private buckets require authentication for all operations
|
|
158
|
+
- File keys can include paths (e.g., 'folder/subfolder/file.jpg')
|
|
159
|
+
- Use `uploadAuto()` to prevent filename conflicts
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# InsForge SDK Documentation
|
|
2
|
+
|
|
3
|
+
## What Insforge OSS Does
|
|
4
|
+
|
|
5
|
+
Backend-as-a-service with database, authentication, file storage, out of box AI abilities
|
|
6
|
+
|
|
7
|
+
**Key Concept**: InsForge replaces your traditional backend - implement business logic by calling database operations directly. Instead of building API endpoints, use our database API as your application's backend.
|
|
8
|
+
|
|
9
|
+
## Critical Rule: Check Metadata First
|
|
10
|
+
|
|
11
|
+
Before ANY operation, call `get-backend-metadata` to get the current backend state.
|
|
12
|
+
|
|
13
|
+
## When to Use SDK vs MCP Tools
|
|
14
|
+
|
|
15
|
+
### Use SDK for:
|
|
16
|
+
- Authentication (register, login, logout)
|
|
17
|
+
- Database CRUD operations (select, insert, update, delete)
|
|
18
|
+
- User profile management
|
|
19
|
+
- AI operations (chat completions, image generation)
|
|
20
|
+
- Storage operations (upload, download, list files)
|
|
21
|
+
- Application logic
|
|
22
|
+
|
|
23
|
+
### Use MCP Tools for:
|
|
24
|
+
- Getting started & documentation (`get-instructions`)
|
|
25
|
+
- Database operations (`run-raw-sql` for CREATE/ALTER/DROP tables, `get-table-schema` for inspection)
|
|
26
|
+
- Backend metadata (`get-backend-metadata`)
|
|
27
|
+
- Storage bucket creation (`create-bucket`, `list-buckets`, `delete-bucket`)
|
|
28
|
+
- Edge Functions Creation and Upload (`create-function`, `get-function`, `update-function`, `delete-function`)
|
|
29
|
+
- **Important**: Edge functions should only be used for backend API services
|
|
30
|
+
- **CRITICAL**: Edge functions do NOT support subpaths - single endpoint only per function
|
|
31
|
+
- ❌ **Will NOT work**: `/functions/my-api/users`, `/functions/my-api/posts/123`, `/functions/my-api/admin/stats`
|
|
32
|
+
- ✅ **Will work**: `/functions/my-api` with `{ "action": "getUsers" }`, `/functions/my-api` with `{ "action": "getPost", "id": 123 }`
|
|
33
|
+
- Use request method + body to route: `GET /functions/task-api?action=list`, `POST /functions/task-api {"action": "create", "title": "New"}`
|
|
34
|
+
|
|
35
|
+
### Edge Functions Pattern
|
|
36
|
+
|
|
37
|
+
**Create secure edge functions using Insforge SDK:**
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// No import needed - createClient is injected by the worker template
|
|
41
|
+
module.exports = async function(request) {
|
|
42
|
+
// CORS headers
|
|
43
|
+
const corsHeaders = {
|
|
44
|
+
'Access-Control-Allow-Origin': '*',
|
|
45
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
46
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Handle OPTIONS
|
|
50
|
+
if (request.method === 'OPTIONS') {
|
|
51
|
+
return new Response(null, { status: 204, headers: corsHeaders });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Extract token from request headers
|
|
55
|
+
const authHeader = request.headers.get('Authorization');
|
|
56
|
+
const userToken = authHeader ? authHeader.replace('Bearer ', '') : null;
|
|
57
|
+
|
|
58
|
+
// Create client with the edge function token
|
|
59
|
+
// Use BACKEND_INTERNAL_URL environment variable for internal Docker communication
|
|
60
|
+
const client = createClient({
|
|
61
|
+
baseUrl: Deno.env.get('BACKEND_INTERNAL_URL') || 'http://insforge:7130',
|
|
62
|
+
edgeFunctionToken: userToken
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Example: Get authenticated user for database operations
|
|
66
|
+
const { data: userData } = await client.auth.getCurrentUser();
|
|
67
|
+
if (userData?.user?.id) {
|
|
68
|
+
// Use userData.user.id for foreign key constraints
|
|
69
|
+
await client.database.from('table').insert([{ user_id: userData.user.id }]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Setup
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm install @insforge/sdk
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
import { createClient } from '@insforge/sdk';
|
|
82
|
+
const client = createClient({ baseUrl: 'http://localhost:7130' });
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Authentication
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
// Sign Up
|
|
89
|
+
const { data, error } = await client.auth.signUp({
|
|
90
|
+
email: 'user@example.com',
|
|
91
|
+
password: 'password123'
|
|
92
|
+
});
|
|
93
|
+
// Returns: { user: {...}, accessToken: 'jwt...' }
|
|
94
|
+
// Backend auto-creates user profile in 'users' table
|
|
95
|
+
|
|
96
|
+
// Sign In
|
|
97
|
+
const { data, error } = await client.auth.signInWithPassword({
|
|
98
|
+
email: 'user@example.com',
|
|
99
|
+
password: 'password123'
|
|
100
|
+
});
|
|
101
|
+
// Token stored automatically for all requests
|
|
102
|
+
|
|
103
|
+
// Sign In with OAuth
|
|
104
|
+
const { data, error } = await client.auth.signInWithOAuth({
|
|
105
|
+
provider: 'google'|'github',
|
|
106
|
+
redirectTo: window.location.origin,
|
|
107
|
+
skipBrowserRedirect: true
|
|
108
|
+
})
|
|
109
|
+
// Returns: { data: { url, provider }, error }
|
|
110
|
+
|
|
111
|
+
// Manual redirect required
|
|
112
|
+
if (data?.url) {
|
|
113
|
+
window.location.href = data.url
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ⚠️ IMPORTANT: No callback handling needed!
|
|
117
|
+
// After OAuth, user returns to redirectTo URL already authenticated
|
|
118
|
+
// The SDK automatically:
|
|
119
|
+
// - Handles the OAuth callback
|
|
120
|
+
// - Stores the JWT token
|
|
121
|
+
// - Makes user available via getCurrentUser()
|
|
122
|
+
|
|
123
|
+
// ❌ DON'T DO THIS (not needed):
|
|
124
|
+
// const accessToken = urlParams.get('access_token')
|
|
125
|
+
// const userId = urlParams.get('user_id')
|
|
126
|
+
|
|
127
|
+
// ✅ DO THIS INSTEAD (after redirect back):
|
|
128
|
+
const { data, error } = await client.auth.getCurrentUser()
|
|
129
|
+
|
|
130
|
+
// Get Current User (with profile)
|
|
131
|
+
const { data, error } = await client.auth.getCurrentUser();
|
|
132
|
+
// Returns: {
|
|
133
|
+
// user: {id, email, role}, // Auth data
|
|
134
|
+
// profile: {id, nickname, ...} // Users table data (object, not array!)
|
|
135
|
+
// }
|
|
136
|
+
|
|
137
|
+
// Update Profile
|
|
138
|
+
const { data, error } = await client.auth.setProfile({
|
|
139
|
+
nickname: 'John',
|
|
140
|
+
bio: 'Developer',
|
|
141
|
+
avatar_url: 'https://...'
|
|
142
|
+
});
|
|
143
|
+
// Returns: {id, nickname, bio, ...} // Single object, not array!
|
|
144
|
+
|
|
145
|
+
// Get Any User's Profile
|
|
146
|
+
const { data, error } = await client.auth.getProfile(userId);
|
|
147
|
+
// Returns: {id, nickname, bio, ...} // Single object, not array!
|
|
148
|
+
|
|
149
|
+
// Get Session (local storage only, no API call)
|
|
150
|
+
const { data } = await client.auth.getCurrentSession();
|
|
151
|
+
// Returns: { session: { accessToken: 'jwt...', user: {...} } }
|
|
152
|
+
|
|
153
|
+
// Sign Out
|
|
154
|
+
await client.auth.signOut();
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Database Operations
|
|
158
|
+
|
|
159
|
+
Before ANY operation, call `get-backend-metadata` to get the current backend state.
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
// Select with filters
|
|
163
|
+
const { data, error } = await client.database
|
|
164
|
+
.from('posts')
|
|
165
|
+
.select('*, users!inner(*)')
|
|
166
|
+
.eq('user_id', userId)
|
|
167
|
+
.order('created_at', { ascending: false })
|
|
168
|
+
.limit(10);
|
|
169
|
+
|
|
170
|
+
// Insert (array required, but use .single() for one record)
|
|
171
|
+
const { data, error } = await client.database
|
|
172
|
+
.from('posts')
|
|
173
|
+
.insert([{
|
|
174
|
+
title: 'My Post',
|
|
175
|
+
user_id: userId,
|
|
176
|
+
image_url: 'https://...'
|
|
177
|
+
}])
|
|
178
|
+
.select()
|
|
179
|
+
.single(); // Returns single object!
|
|
180
|
+
|
|
181
|
+
// Update (returns single object with .single())
|
|
182
|
+
const { data, error } = await client.database
|
|
183
|
+
.from('users')
|
|
184
|
+
.update({ nickname: 'John', bio: 'Developer' })
|
|
185
|
+
.eq('id', userId)
|
|
186
|
+
.select()
|
|
187
|
+
.single(); // Returns single object!
|
|
188
|
+
|
|
189
|
+
// Delete
|
|
190
|
+
const { data, error } = await client.database
|
|
191
|
+
.from('posts')
|
|
192
|
+
.delete()
|
|
193
|
+
.eq('id', postId);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Edge Functions Invocation
|
|
197
|
+
|
|
198
|
+
Invoke deployed edge functions from the SDK (similar to Supabase):
|
|
199
|
+
|
|
200
|
+
```javascript
|
|
201
|
+
// Basic invocation with JSON body (POST by default)
|
|
202
|
+
const { data, error } = await client.functions.invoke('hello-world', {
|
|
203
|
+
body: { name: 'World' }
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// GET request (no body)
|
|
207
|
+
const { data, error } = await client.functions.invoke('my-function', {
|
|
208
|
+
method: 'GET'
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// With custom headers
|
|
212
|
+
const { data, error } = await client.functions.invoke('my-function', {
|
|
213
|
+
body: { action: 'create', item: 'task' },
|
|
214
|
+
headers: { 'x-custom-header': 'value' }
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Different HTTP methods
|
|
218
|
+
const { data, error } = await client.functions.invoke('api-endpoint', {
|
|
219
|
+
method: 'PUT',
|
|
220
|
+
body: { id: '123', status: 'active' }
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Error handling
|
|
224
|
+
if (error) {
|
|
225
|
+
console.error('Function error:', error.message);
|
|
226
|
+
} else {
|
|
227
|
+
console.log('Success:', data);
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Storage Operations
|
|
232
|
+
|
|
233
|
+
Before ANY operation, call `get-backend-metadata` to get the current backend state.
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
// Upload file with auto-generated key
|
|
237
|
+
const { data, error } = await client.storage
|
|
238
|
+
.from('images')
|
|
239
|
+
.uploadAuto(fileObject);
|
|
240
|
+
|
|
241
|
+
// data.url = "http://localhost:7130/api/storage/buckets/images/objects/file-timestamp-random.jpg"
|
|
242
|
+
|
|
243
|
+
// Or upload with specific key
|
|
244
|
+
const { data, error } = await client.storage
|
|
245
|
+
.from('images')
|
|
246
|
+
.upload('custom-name.jpg', fileObject);
|
|
247
|
+
|
|
248
|
+
// Download file
|
|
249
|
+
const { data: blob, error } = await client.storage
|
|
250
|
+
.from('images')
|
|
251
|
+
.download('file.jpg');
|
|
252
|
+
|
|
253
|
+
// Get public URL (no API call)
|
|
254
|
+
const url = client.storage
|
|
255
|
+
.from('images')
|
|
256
|
+
.getPublicUrl('file.jpg');
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## AI Operations
|
|
260
|
+
|
|
261
|
+
Before ANY operation, call `get-backend-metadata` to get the current backend state.
|
|
262
|
+
|
|
263
|
+
### Chat Completions (OpenAI-compatible response)
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
// Non-streaming chat completion (OpenAI-compatible response)
|
|
267
|
+
const completion = await client.ai.chat.completions.create({
|
|
268
|
+
model: 'openai/gpt-4o',
|
|
269
|
+
messages: [
|
|
270
|
+
{
|
|
271
|
+
role: 'system',
|
|
272
|
+
content: 'You are a helpful assistant'
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
role: 'user',
|
|
276
|
+
content: 'What is the capital of France?',
|
|
277
|
+
images: [ // Optional: attach images for vision models
|
|
278
|
+
{ url: 'https://example.com/image.jpg' },
|
|
279
|
+
{ url: 'data:image/jpeg;base64,...' } // Base64 also supported
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
temperature: 0.7, // Optional: 0-2
|
|
284
|
+
maxTokens: 1000, // Optional: max completion tokens
|
|
285
|
+
topP: 0.9, // Optional: 0-1
|
|
286
|
+
stream: false // Optional: enable streaming
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// Access response - OpenAI format
|
|
290
|
+
console.log(completion.choices[0].message.content); // "The capital of France is Paris"
|
|
291
|
+
console.log(completion.usage.total_tokens); // Token usage
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Image + Chat Completions Generation
|
|
295
|
+
|
|
296
|
+
```javascript
|
|
297
|
+
// Image + chat completion generation request
|
|
298
|
+
// This model can generate images AND provide text responses
|
|
299
|
+
const response = await client.ai.images.generate({
|
|
300
|
+
model: 'google/gemini-2.5-flash-image-preview',
|
|
301
|
+
prompt: 'A serene landscape with mountains at sunset',
|
|
302
|
+
images: [ // Optional: input images for image-to-image models
|
|
303
|
+
{ url: 'https://example.com/reference.jpg' }
|
|
304
|
+
]
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Access response - OpenAI format
|
|
308
|
+
console.log(response.data[0].b64_json); // Base64 encoded image string (OpenAI format)
|
|
309
|
+
console.log(response.data[0].content); // AI's text response about the image or prompt
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Complete Example
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
import { createClient } from '@insforge/sdk';
|
|
316
|
+
|
|
317
|
+
const client = new createClient({ baseUrl: 'http://localhost:7130' });
|
|
318
|
+
|
|
319
|
+
// 1. Sign up new user
|
|
320
|
+
const { data: auth, error } = await client.auth.signUp({
|
|
321
|
+
email: 'user@example.com',
|
|
322
|
+
password: 'password123'
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// 2. Update profile (returns object, not array!)
|
|
326
|
+
const { data: profile } = await client.auth.setProfile({
|
|
327
|
+
nickname: 'JohnDoe',
|
|
328
|
+
bio: 'Full-stack developer'
|
|
329
|
+
});
|
|
330
|
+
console.log(profile.nickname); // 'JohnDoe' - direct access!
|
|
331
|
+
|
|
332
|
+
// 3. Get current user with profile
|
|
333
|
+
const { data: userData } = await client.auth.getCurrentUser();
|
|
334
|
+
console.log(userData.user.email); // 'user@example.com'
|
|
335
|
+
console.log(userData.profile.nickname); // 'JohnDoe'
|
|
336
|
+
|
|
337
|
+
// 4. Create a post
|
|
338
|
+
const { data: post } = await client.database
|
|
339
|
+
.from('posts')
|
|
340
|
+
.insert([{
|
|
341
|
+
user_id: userData.user.id,
|
|
342
|
+
caption: 'Hello World',
|
|
343
|
+
image_url: 'https://example.com/image.jpg'
|
|
344
|
+
}])
|
|
345
|
+
.select()
|
|
346
|
+
.single(); // Returns single object!
|
|
347
|
+
|
|
348
|
+
// 5. Get another user's profile (returns object!)
|
|
349
|
+
const { data: otherUser } = await client.auth.getProfile('other-user-id');
|
|
350
|
+
console.log(otherUser.nickname); // Direct access to properties
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Key Points
|
|
354
|
+
|
|
355
|
+
### Edge Functions
|
|
356
|
+
- **SDK Availability**: `createClient` is globally available - no import needed
|
|
357
|
+
- **Token Handling**: Extract from `Authorization` header, use as `anonKey` parameter
|
|
358
|
+
- **Flexible Auth**: Can use user token or anon token (from `ACCESS_API_KEY` env var)
|
|
359
|
+
- **Backend Validation**: Tokens are validated by backend on each SDK request
|
|
360
|
+
- **Internal Networking**: Use `BACKEND_INTERNAL_URL` environment variable (defaults to `http://insforge:7130` for Docker container communication)
|
|
361
|
+
|
|
362
|
+
### Edge Functions Invocation (SDK)
|
|
363
|
+
- **Simple API**: `client.functions.invoke(slug, options)
|
|
364
|
+
- **Auto-authentication**: SDK automatically includes auth token from logged-in user
|
|
365
|
+
- **Flexible body**: Accepts any JSON-serializable data
|
|
366
|
+
- **HTTP methods**: Supports GET, POST, PUT, PATCH, DELETE (default: POST)
|
|
367
|
+
- **Returns**: `{ data, error }` structure consistent with other SDK methods
|
|
368
|
+
|
|
369
|
+
### AI Operations - OpenAI Compatibility
|
|
370
|
+
- **Request Format**: Consistent structure across chat and image generation
|
|
371
|
+
- `model`: Model identifier (provider/model-name format)
|
|
372
|
+
- `messages` for chat, `prompt` for images
|
|
373
|
+
- Optional `images` array for multimodal inputs
|
|
374
|
+
- **Response Format**: AI module returns OpenAI-compatible response structures for Chat Completion
|
|
375
|
+
- **Multimodal Support**: Both endpoints accept image inputs via `images` array
|
|
376
|
+
- **Streaming**: Chat completions support streaming with `stream: true`
|
|
377
|
+
|
|
378
|
+
### Profile Management
|
|
379
|
+
- **Auto-creation**: When users sign up/sign in, backend automatically creates a record in `users` table
|
|
380
|
+
- **Profile methods return objects**: `setProfile()` and `getProfile()` return single objects, not arrays!
|
|
381
|
+
- **Two data sources**:
|
|
382
|
+
- `user` = auth data (id, email, role)
|
|
383
|
+
- `profile` = users table data (id, nickname, avatar_url, bio, etc.)
|
|
384
|
+
|
|
385
|
+
### SDK Behavior
|
|
386
|
+
- Tokens stored and managed automatically after login
|
|
387
|
+
- All operations return `{data, error}` structure
|
|
388
|
+
- Database insert requires array format: `[{...}]` even for single records
|
|
389
|
+
- Use `.single()` to get object instead of array from queries
|
|
390
|
+
- Raw SQL is NOT available in SDK
|
|
391
|
+
|
|
392
|
+
### When to Use What
|
|
393
|
+
- **SDK**: Authentication, database CRUD, profile management, AI operations, storage
|
|
394
|
+
- **MCP Tools**: Table creation/modification, schema management
|
|
395
|
+
|
|
396
|
+
### Storage Best Practices
|
|
397
|
+
- **ALWAYS use Storage for**:
|
|
398
|
+
- Images (URLs, base64, binary data)
|
|
399
|
+
- Files and documents
|
|
400
|
+
- Large text content (>1KB)
|
|
401
|
+
- AI-generated images
|
|
402
|
+
- Chat message attachments
|
|
403
|
+
- **Store in Database**:
|
|
404
|
+
- Storage URLs only (not the actual data)
|
|
405
|
+
- Small text fields (<1KB)
|
|
406
|
+
- Metadata and references
|
|
407
|
+
- **Example**: For chat with images, store image in storage bucket, save only the URL in database
|