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,264 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Test script for universal storage API with presigned URL support
|
|
4
|
+
# Tests both the "backend decides" approach for S3 and local storage
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
API_URL="http://localhost:7130"
|
|
9
|
+
BUCKET_NAME="test-universal-bucket"
|
|
10
|
+
TEST_FILE="test-upload.txt"
|
|
11
|
+
|
|
12
|
+
# Colors for output
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
NC='\033[0m' # No Color
|
|
17
|
+
|
|
18
|
+
echo "=== Universal Storage API Test ==="
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
# Create test file
|
|
22
|
+
echo "This is a test file for universal storage upload" > $TEST_FILE
|
|
23
|
+
FILE_SIZE=$(stat -f%z "$TEST_FILE" 2>/dev/null || stat -c%s "$TEST_FILE" 2>/dev/null)
|
|
24
|
+
|
|
25
|
+
# Step 1: Login to get auth token
|
|
26
|
+
echo "1. Logging in..."
|
|
27
|
+
LOGIN_RESPONSE=$(curl -s -X POST $API_URL/api/auth/admin/sessions \
|
|
28
|
+
-H 'Content-Type: application/json' \
|
|
29
|
+
-d '{
|
|
30
|
+
"email": "admin@example.com",
|
|
31
|
+
"password": "change-this-password"
|
|
32
|
+
}')
|
|
33
|
+
|
|
34
|
+
TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.accessToken')
|
|
35
|
+
if [ "$TOKEN" == "null" ] || [ -z "$TOKEN" ]; then
|
|
36
|
+
echo -e "${RED}✗ Failed to login${NC}"
|
|
37
|
+
echo $LOGIN_RESPONSE | jq .
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
echo -e "${GREEN}✓ Logged in successfully${NC}"
|
|
41
|
+
|
|
42
|
+
# Step 2: Create bucket
|
|
43
|
+
echo ""
|
|
44
|
+
echo "2. Creating bucket '$BUCKET_NAME'..."
|
|
45
|
+
CREATE_RESPONSE=$(curl -s -X POST $API_URL/api/storage/buckets \
|
|
46
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
47
|
+
-H 'Content-Type: application/json' \
|
|
48
|
+
-d "{
|
|
49
|
+
\"bucketName\": \"$BUCKET_NAME\",
|
|
50
|
+
\"isPublic\": true
|
|
51
|
+
}")
|
|
52
|
+
|
|
53
|
+
echo $CREATE_RESPONSE | jq .
|
|
54
|
+
|
|
55
|
+
# Step 3: Request upload strategy
|
|
56
|
+
echo ""
|
|
57
|
+
echo "3. Requesting upload strategy (backend decides)..."
|
|
58
|
+
UPLOAD_STRATEGY=$(curl -s -X POST $API_URL/api/storage/buckets/$BUCKET_NAME/upload-strategy \
|
|
59
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
60
|
+
-H 'Content-Type: application/json' \
|
|
61
|
+
-d "{
|
|
62
|
+
\"filename\": \"$TEST_FILE\",
|
|
63
|
+
\"contentType\": \"text/plain\",
|
|
64
|
+
\"size\": $FILE_SIZE
|
|
65
|
+
}")
|
|
66
|
+
|
|
67
|
+
echo -e "${YELLOW}Upload Strategy Response:${NC}"
|
|
68
|
+
echo $UPLOAD_STRATEGY | jq .
|
|
69
|
+
|
|
70
|
+
# Extract strategy details
|
|
71
|
+
METHOD=$(echo $UPLOAD_STRATEGY | jq -r '.method')
|
|
72
|
+
UPLOAD_URL=$(echo $UPLOAD_STRATEGY | jq -r '.uploadUrl')
|
|
73
|
+
KEY=$(echo $UPLOAD_STRATEGY | jq -r '.key')
|
|
74
|
+
CONFIRM_REQUIRED=$(echo $UPLOAD_STRATEGY | jq -r '.confirmRequired')
|
|
75
|
+
|
|
76
|
+
if [ "$METHOD" == "null" ] || [ -z "$METHOD" ]; then
|
|
77
|
+
echo -e "${RED}✗ Failed to get upload strategy${NC}"
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
echo ""
|
|
82
|
+
echo -e "${GREEN}✓ Got upload strategy:${NC}"
|
|
83
|
+
echo " - Method: $METHOD"
|
|
84
|
+
echo " - Upload URL: $UPLOAD_URL"
|
|
85
|
+
echo " - Key: $KEY"
|
|
86
|
+
echo " - Confirm Required: $CONFIRM_REQUIRED"
|
|
87
|
+
|
|
88
|
+
# Step 4: Upload based on strategy
|
|
89
|
+
echo ""
|
|
90
|
+
echo "4. Uploading file using $METHOD method..."
|
|
91
|
+
|
|
92
|
+
if [ "$METHOD" == "presigned" ]; then
|
|
93
|
+
echo "Using presigned URL upload (S3)..."
|
|
94
|
+
|
|
95
|
+
# Build multipart form data with fields from strategy
|
|
96
|
+
FIELDS=$(echo $UPLOAD_STRATEGY | jq -r '.fields')
|
|
97
|
+
FORM_FIELDS=""
|
|
98
|
+
|
|
99
|
+
if [ "$FIELDS" != "null" ] && [ "$FIELDS" != "{}" ]; then
|
|
100
|
+
for field in $(echo $FIELDS | jq -r 'to_entries[] | @base64'); do
|
|
101
|
+
_jq() {
|
|
102
|
+
echo ${field} | base64 --decode | jq -r ${1}
|
|
103
|
+
}
|
|
104
|
+
FIELD_NAME=$(_jq '.key')
|
|
105
|
+
FIELD_VALUE=$(_jq '.value')
|
|
106
|
+
FORM_FIELDS="$FORM_FIELDS -F $FIELD_NAME=$FIELD_VALUE"
|
|
107
|
+
done
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# Upload to S3
|
|
111
|
+
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST $UPLOAD_URL \
|
|
112
|
+
$FORM_FIELDS \
|
|
113
|
+
-F "file=@$TEST_FILE")
|
|
114
|
+
|
|
115
|
+
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -n1)
|
|
116
|
+
|
|
117
|
+
if [ "$HTTP_CODE" -ge "200" ] && [ "$HTTP_CODE" -lt "300" ]; then
|
|
118
|
+
echo -e "${GREEN}✓ File uploaded to S3 (HTTP $HTTP_CODE)${NC}"
|
|
119
|
+
else
|
|
120
|
+
echo -e "${RED}✗ S3 upload failed (HTTP $HTTP_CODE)${NC}"
|
|
121
|
+
echo "Response: $(echo "$UPLOAD_RESPONSE" | head -n-1)"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
elif [ "$METHOD" == "direct" ]; then
|
|
125
|
+
echo "Using direct upload (Local Storage)..."
|
|
126
|
+
|
|
127
|
+
# For local storage, upload directly to backend
|
|
128
|
+
if [[ "$UPLOAD_URL" == /* ]]; then
|
|
129
|
+
# Relative URL, prepend API_URL
|
|
130
|
+
FULL_URL="${API_URL}${UPLOAD_URL}"
|
|
131
|
+
else
|
|
132
|
+
FULL_URL="$UPLOAD_URL"
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT "$FULL_URL" \
|
|
136
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
137
|
+
-F "file=@$TEST_FILE")
|
|
138
|
+
|
|
139
|
+
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -n1)
|
|
140
|
+
|
|
141
|
+
if [ "$HTTP_CODE" -ge "200" ] && [ "$HTTP_CODE" -lt "300" ]; then
|
|
142
|
+
echo -e "${GREEN}✓ File uploaded directly to backend (HTTP $HTTP_CODE)${NC}"
|
|
143
|
+
else
|
|
144
|
+
echo -e "${RED}✗ Direct upload failed (HTTP $HTTP_CODE)${NC}"
|
|
145
|
+
echo "Response: $(echo "$UPLOAD_RESPONSE" | head -n-1)"
|
|
146
|
+
fi
|
|
147
|
+
else
|
|
148
|
+
echo -e "${RED}✗ Unknown upload method: $METHOD${NC}"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# Step 5: Confirm upload if required
|
|
153
|
+
if [ "$CONFIRM_REQUIRED" == "true" ]; then
|
|
154
|
+
echo ""
|
|
155
|
+
echo "5. Confirming upload..."
|
|
156
|
+
|
|
157
|
+
CONFIRM_RESPONSE=$(curl -s -X POST $API_URL/api/storage/buckets/$BUCKET_NAME/objects/$KEY/confirm-upload \
|
|
158
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
159
|
+
-H 'Content-Type: application/json' \
|
|
160
|
+
-d "{
|
|
161
|
+
\"size\": $FILE_SIZE,
|
|
162
|
+
\"contentType\": \"text/plain\"
|
|
163
|
+
}")
|
|
164
|
+
|
|
165
|
+
echo -e "${YELLOW}Confirmation Response:${NC}"
|
|
166
|
+
echo $CONFIRM_RESPONSE | jq .
|
|
167
|
+
|
|
168
|
+
CONFIRM_KEY=$(echo $CONFIRM_RESPONSE | jq -r '.key')
|
|
169
|
+
if [ "$CONFIRM_KEY" == "$KEY" ]; then
|
|
170
|
+
echo -e "${GREEN}✓ Upload confirmed successfully${NC}"
|
|
171
|
+
else
|
|
172
|
+
echo -e "${RED}✗ Upload confirmation failed${NC}"
|
|
173
|
+
fi
|
|
174
|
+
else
|
|
175
|
+
echo ""
|
|
176
|
+
echo "5. No confirmation required for $METHOD upload"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Step 6: Get download URL
|
|
180
|
+
echo ""
|
|
181
|
+
echo "6. Getting download URL..."
|
|
182
|
+
DOWNLOAD_STRATEGY=$(curl -s -X POST $API_URL/api/storage/buckets/$BUCKET_NAME/objects/$KEY/download-strategy \
|
|
183
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
184
|
+
-H 'Content-Type: application/json' \
|
|
185
|
+
-d '{
|
|
186
|
+
"expiresIn": 3600
|
|
187
|
+
}')
|
|
188
|
+
|
|
189
|
+
echo -e "${YELLOW}Download Strategy Response:${NC}"
|
|
190
|
+
echo $DOWNLOAD_STRATEGY | jq .
|
|
191
|
+
|
|
192
|
+
DOWNLOAD_METHOD=$(echo $DOWNLOAD_STRATEGY | jq -r '.method')
|
|
193
|
+
DOWNLOAD_URL=$(echo $DOWNLOAD_STRATEGY | jq -r '.url')
|
|
194
|
+
EXPIRES_AT=$(echo $DOWNLOAD_STRATEGY | jq -r '.expiresAt')
|
|
195
|
+
|
|
196
|
+
echo ""
|
|
197
|
+
echo -e "${GREEN}✓ Got download strategy:${NC}"
|
|
198
|
+
echo " - Method: $DOWNLOAD_METHOD"
|
|
199
|
+
echo " - URL: $DOWNLOAD_URL"
|
|
200
|
+
if [ "$EXPIRES_AT" != "null" ]; then
|
|
201
|
+
echo " - Expires: $EXPIRES_AT"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# Step 7: Test download
|
|
205
|
+
echo ""
|
|
206
|
+
echo "7. Testing download..."
|
|
207
|
+
|
|
208
|
+
if [ "$DOWNLOAD_METHOD" == "presigned" ]; then
|
|
209
|
+
# Direct download from S3 with presigned URL
|
|
210
|
+
curl -s -o downloaded-$TEST_FILE "$DOWNLOAD_URL"
|
|
211
|
+
elif [ "$DOWNLOAD_METHOD" == "direct" ]; then
|
|
212
|
+
# Download from backend
|
|
213
|
+
if [[ "$DOWNLOAD_URL" == /* ]]; then
|
|
214
|
+
FULL_DOWNLOAD_URL="${API_URL}${DOWNLOAD_URL}"
|
|
215
|
+
else
|
|
216
|
+
FULL_DOWNLOAD_URL="$DOWNLOAD_URL"
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
curl -s -o downloaded-$TEST_FILE "$FULL_DOWNLOAD_URL" \
|
|
220
|
+
-H "Authorization: Bearer $TOKEN"
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
if cmp -s "$TEST_FILE" "downloaded-$TEST_FILE"; then
|
|
224
|
+
echo -e "${GREEN}✓ Downloaded file matches original${NC}"
|
|
225
|
+
else
|
|
226
|
+
echo -e "${RED}✗ Downloaded file doesn't match${NC}"
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
# Step 8: List objects
|
|
230
|
+
echo ""
|
|
231
|
+
echo "8. Listing objects in bucket..."
|
|
232
|
+
LIST_RESPONSE=$(curl -s $API_URL/api/storage/buckets/$BUCKET_NAME/objects \
|
|
233
|
+
-H "Authorization: Bearer $TOKEN")
|
|
234
|
+
|
|
235
|
+
OBJECT_COUNT=$(echo $LIST_RESPONSE | jq '.objects | length')
|
|
236
|
+
echo -e "${GREEN}✓ Found $OBJECT_COUNT object(s) in bucket${NC}"
|
|
237
|
+
|
|
238
|
+
# Cleanup
|
|
239
|
+
echo ""
|
|
240
|
+
echo "9. Cleaning up..."
|
|
241
|
+
|
|
242
|
+
# Delete the uploaded object
|
|
243
|
+
DELETE_RESPONSE=$(curl -s -X DELETE $API_URL/api/storage/buckets/$BUCKET_NAME/objects/$KEY \
|
|
244
|
+
-H "Authorization: Bearer $TOKEN")
|
|
245
|
+
echo " - Deleted object: $KEY"
|
|
246
|
+
|
|
247
|
+
# Delete the bucket
|
|
248
|
+
DELETE_BUCKET_RESPONSE=$(curl -s -X DELETE $API_URL/api/storage/buckets/$BUCKET_NAME \
|
|
249
|
+
-H "Authorization: Bearer $TOKEN")
|
|
250
|
+
echo " - Deleted bucket: $BUCKET_NAME"
|
|
251
|
+
|
|
252
|
+
# Remove test files
|
|
253
|
+
rm -f $TEST_FILE downloaded-$TEST_FILE
|
|
254
|
+
|
|
255
|
+
echo ""
|
|
256
|
+
echo "=== Test Complete ==="
|
|
257
|
+
echo ""
|
|
258
|
+
echo -e "${YELLOW}Summary:${NC}"
|
|
259
|
+
echo "- The backend successfully returned upload/download strategies"
|
|
260
|
+
echo "- Upload method was: $METHOD"
|
|
261
|
+
echo "- Download method was: $DOWNLOAD_METHOD"
|
|
262
|
+
echo "- For S3: Uses presigned URLs (direct to S3)"
|
|
263
|
+
echo "- For Local: Uses direct upload to backend"
|
|
264
|
+
echo "- The SDK can use the same code for both backends!"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- Table: test_users2
|
|
2
|
+
CREATE TABLE IF NOT EXISTS test_users (
|
|
3
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
4
|
+
nickname text,
|
|
5
|
+
avatar_url text,
|
|
6
|
+
birthday date,
|
|
7
|
+
extra jsonb,
|
|
8
|
+
created_at timestamp with time zone DEFAULT now(),
|
|
9
|
+
updated_at timestamp with time zone DEFAULT now()
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CREATE POLICY "Enable read access for all users" ON test_users FOR SELECT TO public USING (true);
|
|
13
|
+
CREATE POLICY "Enable update for users based on user_id" ON test_users FOR UPDATE TO authenticated USING ((uid() = id));
|
|
14
|
+
|
|
15
|
+
-- Sample data for test_users
|
|
16
|
+
INSERT INTO test_users (nickname, avatar_url, birthday) VALUES
|
|
17
|
+
('John Doe', 'https://example.com/avatar1.jpg', '1990-01-01'),
|
|
18
|
+
('Jane Smith', 'https://example.com/avatar2.jpg', '1985-05-15');
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Universal test runner for Insforge backend tests
|
|
4
|
+
# This script runs all test files in the tests directory
|
|
5
|
+
|
|
6
|
+
# Don't exit on error - we want to run all tests even if some fail
|
|
7
|
+
# set -e # Exit on error
|
|
8
|
+
|
|
9
|
+
# Colors for output
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
YELLOW='\033[1;33m'
|
|
13
|
+
NC='\033[0m' # No Color
|
|
14
|
+
|
|
15
|
+
# Get the directory where this script is located
|
|
16
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
17
|
+
# PROJECT_ROOT is the repository root, not just the backend directory
|
|
18
|
+
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
19
|
+
BACKEND_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
20
|
+
|
|
21
|
+
# Load environment from .env file if it exists
|
|
22
|
+
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
23
|
+
echo "Loading environment from .env file..."
|
|
24
|
+
set -a # automatically export all variables
|
|
25
|
+
source "$PROJECT_ROOT/.env"
|
|
26
|
+
set +a # turn off automatic export
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
echo "=========================================="
|
|
30
|
+
echo "Running all Insforge backend tests"
|
|
31
|
+
echo "=========================================="
|
|
32
|
+
echo ""
|
|
33
|
+
|
|
34
|
+
# Export API configuration for all tests
|
|
35
|
+
export TEST_API_BASE="${TEST_API_BASE:-http://localhost:7130/api}"
|
|
36
|
+
|
|
37
|
+
# Check if admin credentials are set
|
|
38
|
+
if [ -z "$ADMIN_EMAIL" ] || [ -z "$ADMIN_PASSWORD" ]; then
|
|
39
|
+
echo -e "${YELLOW}Warning: Admin credentials not set. Using defaults.${NC}"
|
|
40
|
+
echo "Set with: export ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=your_password"
|
|
41
|
+
export ADMIN_EMAIL="admin@example.com"
|
|
42
|
+
export ADMIN_PASSWORD="change-this-password"
|
|
43
|
+
echo ""
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Check if API key is set
|
|
47
|
+
if [ -z "$ACCESS_API_KEY" ]; then
|
|
48
|
+
echo -e "${YELLOW}Warning: ACCESS_API_KEY not set. Some tests may fail.${NC}"
|
|
49
|
+
echo "Set with: export ACCESS_API_KEY=your_api_key"
|
|
50
|
+
echo ""
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Check if running cloud tests
|
|
54
|
+
if [ -z "$AWS_S3_BUCKET" ]; then
|
|
55
|
+
echo -e "${YELLOW}Note: AWS_S3_BUCKET not set. Cloud/S3 tests will be skipped.${NC}"
|
|
56
|
+
echo ""
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Export admin credentials for tests
|
|
60
|
+
export TEST_ADMIN_EMAIL="$ADMIN_EMAIL"
|
|
61
|
+
export TEST_ADMIN_PASSWORD="$ADMIN_PASSWORD"
|
|
62
|
+
|
|
63
|
+
# Keep track of test results
|
|
64
|
+
TOTAL_TESTS=0
|
|
65
|
+
PASSED_TESTS=0
|
|
66
|
+
FAILED_TESTS=0
|
|
67
|
+
FAILED_TEST_NAMES=()
|
|
68
|
+
|
|
69
|
+
# Function to run a test and handle cleanup
|
|
70
|
+
run_test() {
|
|
71
|
+
local test_script=$1
|
|
72
|
+
local test_name=$(basename "$test_script" .sh)
|
|
73
|
+
|
|
74
|
+
echo -e "${YELLOW}Running $test_name...${NC}"
|
|
75
|
+
echo "----------------------------------------"
|
|
76
|
+
|
|
77
|
+
# Run the test in a subshell to isolate cleanup
|
|
78
|
+
(
|
|
79
|
+
# Run the test script
|
|
80
|
+
"$test_script"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
local exit_code=$?
|
|
84
|
+
|
|
85
|
+
if [ $exit_code -eq 0 ]; then
|
|
86
|
+
echo -e "${GREEN}✓ $test_name passed${NC}"
|
|
87
|
+
PASSED_TESTS=$((PASSED_TESTS + 1))
|
|
88
|
+
else
|
|
89
|
+
echo -e "${RED}✗ $test_name failed${NC}"
|
|
90
|
+
FAILED_TESTS=$((FAILED_TESTS + 1))
|
|
91
|
+
FAILED_TEST_NAMES+=("$test_name")
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
echo ""
|
|
95
|
+
# Don't return the exit code - we want to continue running other tests
|
|
96
|
+
return 0
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Run local tests
|
|
100
|
+
echo -e "${YELLOW}=== Running Local Tests ===${NC}"
|
|
101
|
+
for test_script in "$SCRIPT_DIR"/local/test-*.sh; do
|
|
102
|
+
if [ -f "$test_script" ] && [ -x "$test_script" ]; then
|
|
103
|
+
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
|
104
|
+
run_test "$test_script"
|
|
105
|
+
fi
|
|
106
|
+
done
|
|
107
|
+
|
|
108
|
+
# Run cloud tests if AWS is configured
|
|
109
|
+
if [ -n "$AWS_S3_BUCKET" ] && [ -n "$APP_KEY" ]; then
|
|
110
|
+
echo -e "${YELLOW}=== Running Cloud Tests ===${NC}"
|
|
111
|
+
for test_script in "$SCRIPT_DIR"/cloud/test-*.sh; do
|
|
112
|
+
if [ -f "$test_script" ] && [ -x "$test_script" ]; then
|
|
113
|
+
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
|
114
|
+
run_test "$test_script"
|
|
115
|
+
fi
|
|
116
|
+
done
|
|
117
|
+
else
|
|
118
|
+
echo -e "${YELLOW}Skipping cloud tests (AWS_S3_BUCKET or APP_KEY not configured)${NC}"
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# Summary
|
|
122
|
+
echo "=========================================="
|
|
123
|
+
echo "Test Summary"
|
|
124
|
+
echo "=========================================="
|
|
125
|
+
echo "Total tests: $TOTAL_TESTS"
|
|
126
|
+
echo -e "Passed: ${GREEN}$PASSED_TESTS${NC}"
|
|
127
|
+
echo -e "Failed: ${RED}$FAILED_TESTS${NC}"
|
|
128
|
+
|
|
129
|
+
if [ $FAILED_TESTS -gt 0 ]; then
|
|
130
|
+
echo ""
|
|
131
|
+
echo -e "${RED}Failed tests:${NC}"
|
|
132
|
+
for failed_test in "${FAILED_TEST_NAMES[@]}"; do
|
|
133
|
+
echo " - $failed_test"
|
|
134
|
+
done
|
|
135
|
+
exit 1
|
|
136
|
+
else
|
|
137
|
+
echo ""
|
|
138
|
+
echo -e "${GREEN}All tests passed!${NC}"
|
|
139
|
+
exit 0
|
|
140
|
+
fi
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
|
|
4
|
+
// Clean up test database before each test
|
|
5
|
+
beforeEach(async () => {
|
|
6
|
+
const testDataDir = './test-data';
|
|
7
|
+
try {
|
|
8
|
+
await fs.rm(testDataDir, { recursive: true, force: true });
|
|
9
|
+
} catch {
|
|
10
|
+
// Directory might not exist, that's ok
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Clean up after all tests
|
|
15
|
+
afterEach(async () => {
|
|
16
|
+
const testDataDir = './test-data';
|
|
17
|
+
try {
|
|
18
|
+
await fs.rm(testDataDir, { recursive: true, force: true });
|
|
19
|
+
} catch {
|
|
20
|
+
// Directory might not exist, that's ok
|
|
21
|
+
}
|
|
22
|
+
});
|