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.
Files changed (395) hide show
  1. package/.dockerignore +58 -0
  2. package/.env.example +49 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.yml +79 -0
  6. package/.github/copilot-instructions.md +147 -0
  7. package/.github/workflows/build-image.yml +65 -0
  8. package/.github/workflows/ci-premerge-check.yml +24 -0
  9. package/.github/workflows/deploy-aws.yml +130 -0
  10. package/.github/workflows/lint-and-format.yml +33 -0
  11. package/.prettierignore +65 -0
  12. package/.prettierrc +9 -0
  13. package/CHANGELOG.md +3 -0
  14. package/CONTRIBUTING.md +126 -0
  15. package/Dockerfile +27 -0
  16. package/GITHUB_OAUTH_SETUP.md +49 -0
  17. package/GOOGLE_OAUTH_SETUP.md +148 -0
  18. package/LICENSE +201 -0
  19. package/README.md +134 -0
  20. package/assets/Dark.svg +23 -0
  21. package/assets/archDiagram.png +0 -0
  22. package/assets/banner.png +0 -0
  23. package/assets/mcpInstallv2.png +0 -0
  24. package/assets/sampleResponse.png +0 -0
  25. package/assets/signin.png +0 -0
  26. package/assets/userflow.png +0 -0
  27. package/backend/migrations/000_create-base-tables.sql +142 -0
  28. package/backend/migrations/001_create-helper-functions.sql +41 -0
  29. package/backend/migrations/002_rename-auth-tables.sql +30 -0
  30. package/backend/migrations/003_create-users-table.sql +56 -0
  31. package/backend/migrations/004_add-reload-postgrest-func.sql +24 -0
  32. package/backend/migrations/005_enable-project-admin-modify-users.sql +30 -0
  33. package/backend/migrations/006_modify-ai-usage-table.sql +25 -0
  34. package/backend/migrations/007_drop-metadata-table.sql +2 -0
  35. package/backend/migrations/008_add-system-tables.sql +77 -0
  36. package/backend/migrations/009_add-function-secrets.sql +24 -0
  37. package/backend/migrations/010_modify-ai-config-modalities.sql +93 -0
  38. package/backend/migrations/011_refactor-secrets-table.sql +15 -0
  39. package/backend/migrations/012_add-storage-uploaded-by.sql +8 -0
  40. package/backend/package.json +75 -0
  41. package/backend/src/api/middleware/auth.ts +240 -0
  42. package/backend/src/api/middleware/error.ts +231 -0
  43. package/backend/src/api/middleware/upload.ts +59 -0
  44. package/backend/src/api/routes/agent.ts +29 -0
  45. package/backend/src/api/routes/ai.ts +472 -0
  46. package/backend/src/api/routes/auth.oauth.ts +482 -0
  47. package/backend/src/api/routes/auth.ts +386 -0
  48. package/backend/src/api/routes/database.advance.ts +275 -0
  49. package/backend/src/api/routes/database.records.ts +246 -0
  50. package/backend/src/api/routes/database.tables.ts +161 -0
  51. package/backend/src/api/routes/docs.ts +66 -0
  52. package/backend/src/api/routes/functions.ts +183 -0
  53. package/backend/src/api/routes/logs.ts +150 -0
  54. package/backend/src/api/routes/metadata.ts +160 -0
  55. package/backend/src/api/routes/openapi.ts +82 -0
  56. package/backend/src/api/routes/secrets.ts +199 -0
  57. package/backend/src/api/routes/storage.ts +547 -0
  58. package/backend/src/api/routes/usage.ts +96 -0
  59. package/backend/src/core/ai/chat.ts +207 -0
  60. package/backend/src/core/ai/client.ts +242 -0
  61. package/backend/src/core/ai/config.ts +187 -0
  62. package/backend/src/core/ai/image.ts +156 -0
  63. package/backend/src/core/ai/model.ts +117 -0
  64. package/backend/src/core/ai/usage.ts +290 -0
  65. package/backend/src/core/auth/auth.ts +781 -0
  66. package/backend/src/core/auth/oauth.ts +398 -0
  67. package/backend/src/core/database/advance.ts +1074 -0
  68. package/backend/src/core/database/manager.ts +178 -0
  69. package/backend/src/core/database/table.ts +772 -0
  70. package/backend/src/core/documentation/agent.ts +689 -0
  71. package/backend/src/core/documentation/openapi.ts +856 -0
  72. package/backend/src/core/functions/functions.ts +310 -0
  73. package/backend/src/core/logs/analytics.ts +76 -0
  74. package/backend/src/core/logs/audit.ts +255 -0
  75. package/backend/src/core/logs/providers/base.provider.ts +83 -0
  76. package/backend/src/core/logs/providers/cloudwatch.provider.ts +510 -0
  77. package/backend/src/core/logs/providers/localdb.provider.ts +246 -0
  78. package/backend/src/core/secrets/encryption.ts +58 -0
  79. package/backend/src/core/secrets/secrets.ts +410 -0
  80. package/backend/src/core/socket/socket.ts +388 -0
  81. package/backend/src/core/socket/types.ts +79 -0
  82. package/backend/src/core/storage/storage.ts +923 -0
  83. package/backend/src/server.ts +288 -0
  84. package/backend/src/types/ai.ts +46 -0
  85. package/backend/src/types/auth.ts +90 -0
  86. package/backend/src/types/database.ts +136 -0
  87. package/backend/src/types/error-constants.ts +86 -0
  88. package/backend/src/types/logs.ts +47 -0
  89. package/backend/src/types/profile.ts +55 -0
  90. package/backend/src/types/storage.ts +23 -0
  91. package/backend/src/utils/cloud-token.ts +39 -0
  92. package/backend/src/utils/constants.ts +1 -0
  93. package/backend/src/utils/environment.ts +35 -0
  94. package/backend/src/utils/helpers.ts +49 -0
  95. package/backend/src/utils/logger.ts +13 -0
  96. package/backend/src/utils/response.ts +62 -0
  97. package/backend/src/utils/seed.ts +205 -0
  98. package/backend/src/utils/sql-parser.ts +63 -0
  99. package/backend/src/utils/uuid.ts +9 -0
  100. package/backend/src/utils/validations.ts +129 -0
  101. package/backend/tests/README.md +134 -0
  102. package/backend/tests/cleanup-all-test-data.sh +231 -0
  103. package/backend/tests/cloud/test-s3-multitenant.sh +132 -0
  104. package/backend/tests/local/comprehensive-curl-tests.sh +156 -0
  105. package/backend/tests/local/test-auth-router.sh +144 -0
  106. package/backend/tests/local/test-database-router.sh +222 -0
  107. package/backend/tests/local/test-e2e.sh +241 -0
  108. package/backend/tests/local/test-fk-errors.sh +97 -0
  109. package/backend/tests/local/test-id-field.sh +201 -0
  110. package/backend/tests/local/test-public-bucket.sh +265 -0
  111. package/backend/tests/local/test-secrets.sh +248 -0
  112. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -0
  113. package/backend/tests/local/test-traditional-rest.sh +209 -0
  114. package/backend/tests/manual/README.md +51 -0
  115. package/backend/tests/manual/create-large-table-simple.sql +11 -0
  116. package/backend/tests/manual/seed-large-table.sql +101 -0
  117. package/backend/tests/manual/setup-large-table-extras.sql +34 -0
  118. package/backend/tests/manual/test-better-auth.sh +303 -0
  119. package/backend/tests/manual/test-bulk-upsert.sh +410 -0
  120. package/backend/tests/manual/test-database-advance.sh +297 -0
  121. package/backend/tests/manual/test-postgrest-stability.sh +192 -0
  122. package/backend/tests/manual/test-rawsql-export-import.sh +412 -0
  123. package/backend/tests/manual/test-universal-storage.sh +264 -0
  124. package/backend/tests/manual/test-users.sql +18 -0
  125. package/backend/tests/run-all-tests.sh +140 -0
  126. package/backend/tests/setup.ts +22 -0
  127. package/backend/tests/test-config.sh +303 -0
  128. package/backend/tsconfig.json +23 -0
  129. package/backend/tsup.config.ts +18 -0
  130. package/backend/vitest.config.ts +22 -0
  131. package/docker-compose.prod.yml +145 -0
  132. package/docker-compose.yml +167 -0
  133. package/docker-init/db/db-init.sql +125 -0
  134. package/docker-init/db/jwt.sql +5 -0
  135. package/docker-init/db/logs.sql +9 -0
  136. package/docker-init/db/postgresql.conf +17 -0
  137. package/docs/deprecated/insforge-auth-api.md +215 -0
  138. package/docs/deprecated/insforge-auth-sdk.md +100 -0
  139. package/docs/deprecated/insforge-db-api.md +359 -0
  140. package/docs/deprecated/insforge-db-sdk.md +140 -0
  141. package/docs/deprecated/insforge-debug-sdk.md +157 -0
  142. package/docs/deprecated/insforge-debug.md +65 -0
  143. package/docs/deprecated/insforge-instructions.md +124 -0
  144. package/docs/deprecated/insforge-project.md +118 -0
  145. package/docs/deprecated/insforge-storage-api.md +279 -0
  146. package/docs/deprecated/insforge-storage-sdk.md +159 -0
  147. package/docs/insforge-instructions-sdk.md +407 -0
  148. package/eslint.config.js +317 -0
  149. package/examples/oauth/frontend-oauth-example.html +251 -0
  150. package/examples/response-examples.md +444 -0
  151. package/frontend/README.md +112 -0
  152. package/frontend/components.json +17 -0
  153. package/frontend/index.html +13 -0
  154. package/frontend/package.json +63 -0
  155. package/frontend/public/favicon.ico +0 -0
  156. package/frontend/src/App.tsx +106 -0
  157. package/frontend/src/assets/icons/checkbox_checked.svg +6 -0
  158. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -0
  159. package/frontend/src/assets/icons/checked.svg +3 -0
  160. package/frontend/src/assets/icons/error.svg +3 -0
  161. package/frontend/src/assets/icons/pencil.svg +4 -0
  162. package/frontend/src/assets/icons/refresh.svg +4 -0
  163. package/frontend/src/assets/icons/step_active.svg +3 -0
  164. package/frontend/src/assets/icons/step_inactive.svg +11 -0
  165. package/frontend/src/assets/icons/warning.svg +3 -0
  166. package/frontend/src/assets/logos/amazon.svg +1 -0
  167. package/frontend/src/assets/logos/claude_code.svg +3 -0
  168. package/frontend/src/assets/logos/cline.svg +6 -0
  169. package/frontend/src/assets/logos/cursor.svg +20 -0
  170. package/frontend/src/assets/logos/discord.svg +9 -0
  171. package/frontend/src/assets/logos/gemini.svg +19 -0
  172. package/frontend/src/assets/logos/github.svg +5 -0
  173. package/frontend/src/assets/logos/google.svg +13 -0
  174. package/frontend/src/assets/logos/grok.svg +10 -0
  175. package/frontend/src/assets/logos/insforge_dark.svg +15 -0
  176. package/frontend/src/assets/logos/insforge_light.svg +15 -0
  177. package/frontend/src/assets/logos/openai.svg +10 -0
  178. package/frontend/src/assets/logos/roo_code.svg +9 -0
  179. package/frontend/src/assets/logos/trae.svg +3 -0
  180. package/frontend/src/assets/logos/windsurf.svg +10 -0
  181. package/frontend/src/components/ButtonWithLoading.tsx +27 -0
  182. package/frontend/src/components/Checkbox.tsx +61 -0
  183. package/frontend/src/components/CodeBlock.tsx +32 -0
  184. package/frontend/src/components/ConfirmDialog.tsx +96 -0
  185. package/frontend/src/components/CopyButton.tsx +69 -0
  186. package/frontend/src/components/DeleteActionButton.tsx +42 -0
  187. package/frontend/src/components/EmptyState.tsx +41 -0
  188. package/frontend/src/components/ErrorState.tsx +35 -0
  189. package/frontend/src/components/FeatureSidebar.tsx +126 -0
  190. package/frontend/src/components/FeatureSidebarItem.tsx +101 -0
  191. package/frontend/src/components/JsonHighlight.tsx +61 -0
  192. package/frontend/src/components/LoadingState.tsx +16 -0
  193. package/frontend/src/components/PaginationControls.tsx +54 -0
  194. package/frontend/src/components/PromptDialog.tsx +68 -0
  195. package/frontend/src/components/SearchInput.tsx +90 -0
  196. package/frontend/src/components/SelectionClearButton.tsx +26 -0
  197. package/frontend/src/components/Stepper.tsx +139 -0
  198. package/frontend/src/components/ThemeToggle.tsx +58 -0
  199. package/frontend/src/components/TypeBadge.tsx +20 -0
  200. package/frontend/src/components/datagrid/DataGrid.tsx +264 -0
  201. package/frontend/src/components/datagrid/DefaultCellRenderer.tsx +114 -0
  202. package/frontend/src/components/datagrid/IdCell.tsx +44 -0
  203. package/frontend/src/components/datagrid/SortableHeader.tsx +74 -0
  204. package/frontend/src/components/datagrid/cell-editors/BooleanCellEditor.tsx +54 -0
  205. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +483 -0
  206. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +362 -0
  207. package/frontend/src/components/datagrid/cell-editors/TextCellEditor.tsx +38 -0
  208. package/frontend/src/components/datagrid/cell-editors/index.ts +14 -0
  209. package/frontend/src/components/datagrid/cell-editors/types.ts +43 -0
  210. package/frontend/src/components/datagrid/datagridTypes.tsx +72 -0
  211. package/frontend/src/components/datagrid/index.tsx +20 -0
  212. package/frontend/src/components/index.ts +39 -0
  213. package/frontend/src/components/layout/AppHeader.tsx +146 -0
  214. package/frontend/src/components/layout/AppSidebar.tsx +190 -0
  215. package/frontend/src/components/layout/CloudLayout.tsx +95 -0
  216. package/frontend/src/components/layout/Layout.tsx +43 -0
  217. package/frontend/src/components/radix/Alert.tsx +45 -0
  218. package/frontend/src/components/radix/AlertDialog.tsx +115 -0
  219. package/frontend/src/components/radix/Avatar.tsx +45 -0
  220. package/frontend/src/components/radix/Badge.tsx +33 -0
  221. package/frontend/src/components/radix/Button.tsx +50 -0
  222. package/frontend/src/components/radix/Card.tsx +58 -0
  223. package/frontend/src/components/radix/Dialog.tsx +98 -0
  224. package/frontend/src/components/radix/DropdownMenu.tsx +185 -0
  225. package/frontend/src/components/radix/Form.tsx +167 -0
  226. package/frontend/src/components/radix/Input.tsx +22 -0
  227. package/frontend/src/components/radix/Label.tsx +19 -0
  228. package/frontend/src/components/radix/Popover.tsx +29 -0
  229. package/frontend/src/components/radix/ScrollArea.tsx +44 -0
  230. package/frontend/src/components/radix/Select.tsx +151 -0
  231. package/frontend/src/components/radix/Separator.tsx +26 -0
  232. package/frontend/src/components/radix/Sheet.tsx +119 -0
  233. package/frontend/src/components/radix/Skeleton.tsx +7 -0
  234. package/frontend/src/components/radix/Switch.tsx +29 -0
  235. package/frontend/src/components/radix/Tabs.tsx +50 -0
  236. package/frontend/src/components/radix/Textarea.tsx +21 -0
  237. package/frontend/src/components/radix/Tooltip.tsx +28 -0
  238. package/frontend/src/features/ai/components/AIConfigCard.tsx +154 -0
  239. package/frontend/src/features/ai/components/AIConfigDialog.tsx +76 -0
  240. package/frontend/src/features/ai/components/AIConfigForm.tsx +222 -0
  241. package/frontend/src/features/ai/components/AIEmptyState.tsx +18 -0
  242. package/frontend/src/features/ai/components/fields/ModalityField.tsx +87 -0
  243. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +134 -0
  244. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +33 -0
  245. package/frontend/src/features/ai/helpers.ts +155 -0
  246. package/frontend/src/features/ai/hooks/useAIConfigs.ts +221 -0
  247. package/frontend/src/features/ai/hooks/useAIUsage.ts +77 -0
  248. package/frontend/src/features/ai/page/AIPage.tsx +178 -0
  249. package/frontend/src/features/ai/services/ai.service.ts +148 -0
  250. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +106 -0
  251. package/frontend/src/features/auth/components/AuthMethodTab.tsx +238 -0
  252. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +303 -0
  253. package/frontend/src/features/auth/components/OAuthEmptyState.tsx +15 -0
  254. package/frontend/src/features/auth/components/UserFormDialog.tsx +248 -0
  255. package/frontend/src/features/auth/components/UsersDataGrid.tsx +183 -0
  256. package/frontend/src/features/auth/components/UsersTab.tsx +114 -0
  257. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +129 -0
  258. package/frontend/src/features/auth/hooks/useUsers.ts +57 -0
  259. package/frontend/src/features/auth/index.ts +9 -0
  260. package/frontend/src/features/auth/page/AuthenticationPage.tsx +169 -0
  261. package/frontend/src/features/auth/services/auth.service.ts +112 -0
  262. package/frontend/src/features/auth/services/oauth.service.ts +49 -0
  263. package/frontend/src/features/dashboard/page/DashboardPage.tsx +194 -0
  264. package/frontend/src/features/database/components/ColumnTypeSelect.tsx +64 -0
  265. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +282 -0
  266. package/frontend/src/features/database/components/ForeignKeyCell.tsx +187 -0
  267. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +378 -0
  268. package/frontend/src/features/database/components/LinkRecordModal.tsx +288 -0
  269. package/frontend/src/features/database/components/RecordFormDialog.tsx +164 -0
  270. package/frontend/src/features/database/components/RecordFormField.tsx +568 -0
  271. package/frontend/src/features/database/components/TableEmptyState.tsx +21 -0
  272. package/frontend/src/features/database/components/TableForm.tsx +656 -0
  273. package/frontend/src/features/database/components/TableFormColumn.tsx +137 -0
  274. package/frontend/src/features/database/components/TableListSkeleton.tsx +9 -0
  275. package/frontend/src/features/database/components/TableSidebar.tsx +47 -0
  276. package/frontend/src/features/database/constants.ts +26 -0
  277. package/frontend/src/features/database/helpers.ts +125 -0
  278. package/frontend/src/features/database/hooks/UseLinkModal.tsx +78 -0
  279. package/frontend/src/features/database/index.ts +12 -0
  280. package/frontend/src/features/database/page/DatabasePage.tsx +626 -0
  281. package/frontend/src/features/database/schema.ts +25 -0
  282. package/frontend/src/features/database/services/database.service.ts +216 -0
  283. package/frontend/src/features/functions/components/FunctionEmptyState.tsx +15 -0
  284. package/frontend/src/features/functions/components/FunctionRow.tsx +71 -0
  285. package/frontend/src/features/functions/components/FunctionViewer.tsx +46 -0
  286. package/frontend/src/features/functions/components/FunctionsContent.tsx +88 -0
  287. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -0
  288. package/frontend/src/features/functions/components/SecretEmptyState.tsx +23 -0
  289. package/frontend/src/features/functions/components/SecretRow.tsx +68 -0
  290. package/frontend/src/features/functions/components/SecretsContent.tsx +120 -0
  291. package/frontend/src/features/functions/hooks/useFunctions.ts +106 -0
  292. package/frontend/src/features/functions/page/FunctionsPage.tsx +28 -0
  293. package/frontend/src/features/functions/services/functions.service.ts +48 -0
  294. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +87 -0
  295. package/frontend/src/features/login/components/PrivateRoute.tsx +24 -0
  296. package/frontend/src/features/login/page/CloudLoginPage.tsx +93 -0
  297. package/frontend/src/features/login/page/LoginPage.tsx +174 -0
  298. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +313 -0
  299. package/frontend/src/features/logs/components/LogsTable.tsx +199 -0
  300. package/frontend/src/features/logs/hooks/useAuditLogs.ts +39 -0
  301. package/frontend/src/features/logs/index.ts +5 -0
  302. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +530 -0
  303. package/frontend/src/features/logs/page/AuditsPage.tsx +192 -0
  304. package/frontend/src/features/logs/services/log.service.ts +171 -0
  305. package/frontend/src/features/metadata/hooks/useMetadata.ts +53 -0
  306. package/frontend/src/features/metadata/index.ts +0 -0
  307. package/frontend/src/features/metadata/page/MetadataPage.tsx +136 -0
  308. package/frontend/src/features/metadata/services/metadata.service.ts +17 -0
  309. package/frontend/src/features/onboard/components/CompletionCard.tsx +41 -0
  310. package/frontend/src/features/onboard/components/OnboardButton.tsx +84 -0
  311. package/frontend/src/features/onboard/components/StepContent.tsx +91 -0
  312. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +53 -0
  313. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +35 -0
  314. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +144 -0
  315. package/frontend/src/features/onboard/components/mcp/index.ts +4 -0
  316. package/frontend/src/features/onboard/components/mcp/mcp-helper.tsx +98 -0
  317. package/frontend/src/features/onboard/index.ts +3 -0
  318. package/frontend/src/features/onboard/page/OnBoardPage.tsx +104 -0
  319. package/frontend/src/features/onboard/types.ts +8 -0
  320. package/frontend/src/features/secrets/hooks/useSecrets.ts +139 -0
  321. package/frontend/src/features/secrets/services/secrets.service.ts +57 -0
  322. package/frontend/src/features/storage/components/BucketEmptyState.tsx +19 -0
  323. package/frontend/src/features/storage/components/BucketFormDialog.tsx +194 -0
  324. package/frontend/src/features/storage/components/BucketListSkeleton.tsx +17 -0
  325. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +287 -0
  326. package/frontend/src/features/storage/components/StorageDataGrid.tsx +239 -0
  327. package/frontend/src/features/storage/components/StorageManager.tsx +236 -0
  328. package/frontend/src/features/storage/components/StorageSidebar.tsx +44 -0
  329. package/frontend/src/features/storage/components/UploadToast.tsx +46 -0
  330. package/frontend/src/features/storage/index.ts +3 -0
  331. package/frontend/src/features/storage/page/StoragePage.tsx +553 -0
  332. package/frontend/src/features/storage/services/storage.service.ts +144 -0
  333. package/frontend/src/features/visualizer/components/AuthNode.tsx +107 -0
  334. package/frontend/src/features/visualizer/components/BucketNode.tsx +34 -0
  335. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +359 -0
  336. package/frontend/src/features/visualizer/components/TableNode.tsx +152 -0
  337. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +24 -0
  338. package/frontend/src/features/visualizer/components/index.ts +5 -0
  339. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +127 -0
  340. package/frontend/src/index.css +248 -0
  341. package/frontend/src/lib/api/client.ts +163 -0
  342. package/frontend/src/lib/contexts/AuthContext.tsx +157 -0
  343. package/frontend/src/lib/contexts/OnboardStepContext.tsx +68 -0
  344. package/frontend/src/lib/contexts/SocketContext.tsx +303 -0
  345. package/frontend/src/lib/contexts/ThemeContext.tsx +125 -0
  346. package/frontend/src/lib/hooks/useAuth.ts +4 -0
  347. package/frontend/src/lib/hooks/useConfirm.ts +55 -0
  348. package/frontend/src/lib/hooks/useInterval.ts +27 -0
  349. package/frontend/src/lib/hooks/useMediaQuery.ts +59 -0
  350. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +29 -0
  351. package/frontend/src/lib/hooks/usePagination.ts +27 -0
  352. package/frontend/src/lib/hooks/useTimeout.ts +27 -0
  353. package/frontend/src/lib/hooks/useToast.tsx +229 -0
  354. package/frontend/src/lib/utils/constants.ts +38 -0
  355. package/frontend/src/lib/utils/utils.ts +165 -0
  356. package/frontend/src/lib/utils/validation-schemas.ts +126 -0
  357. package/frontend/src/main.tsx +16 -0
  358. package/frontend/src/rdg.css +194 -0
  359. package/frontend/src/vite-env.d.ts +12 -0
  360. package/frontend/tailwind.config.js +97 -0
  361. package/frontend/tsconfig.json +26 -0
  362. package/frontend/tsconfig.node.json +10 -0
  363. package/frontend/vite.config.ts +37 -0
  364. package/frontend/vitest.config.ts +36 -0
  365. package/functions/deno.json +25 -0
  366. package/functions/server.ts +290 -0
  367. package/functions/worker-template.js +126 -0
  368. package/openapi/ai.yaml +689 -0
  369. package/openapi/auth.yaml +563 -0
  370. package/openapi/functions.yaml +476 -0
  371. package/openapi/health.yaml +30 -0
  372. package/openapi/logs.yaml +224 -0
  373. package/openapi/metadata.yaml +178 -0
  374. package/openapi/records.yaml +382 -0
  375. package/openapi/secrets.yaml +371 -0
  376. package/openapi/storage.yaml +876 -0
  377. package/openapi/tables.yaml +464 -0
  378. package/package.json +88 -0
  379. package/shared-schemas/package.json +31 -0
  380. package/shared-schemas/src/ai-api.schema.ts +167 -0
  381. package/shared-schemas/src/ai.schema.ts +54 -0
  382. package/shared-schemas/src/auth-api.schema.ts +193 -0
  383. package/shared-schemas/src/auth.schema.ts +94 -0
  384. package/shared-schemas/src/database-api.schema.ts +259 -0
  385. package/shared-schemas/src/database.schema.ts +69 -0
  386. package/shared-schemas/src/functions-api.schema.ts +25 -0
  387. package/shared-schemas/src/functions.schema.ts +16 -0
  388. package/shared-schemas/src/index.ts +13 -0
  389. package/shared-schemas/src/logs-api.schema.ts +49 -0
  390. package/shared-schemas/src/logs.schema.ts +14 -0
  391. package/shared-schemas/src/metadata.schema.ts +56 -0
  392. package/shared-schemas/src/storage-api.schema.ts +65 -0
  393. package/shared-schemas/src/storage.schema.ts +19 -0
  394. package/shared-schemas/tsconfig.json +21 -0
  395. package/tsconfig.json +8 -0
@@ -0,0 +1,97 @@
1
+ #!/bin/bash
2
+
3
+ # Simple FK error handling test - covers main scenarios we handle
4
+
5
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6
+ source "$SCRIPT_DIR/../test-config.sh"
7
+
8
+ print_blue "๐Ÿ”— Testing FK error handling..."
9
+
10
+ API_BASE="$TEST_API_BASE"
11
+
12
+ # Get admin token for table operations
13
+ ADMIN_TOKEN=$(get_admin_token)
14
+ if [ -z "$ADMIN_TOKEN" ]; then
15
+ print_fail "Could not get admin token"
16
+ exit 1
17
+ fi
18
+
19
+ # Dynamic table names
20
+ USERS_TABLE="users_$(date +%s)"
21
+ POSTS_TABLE="posts_$(date +%s)"
22
+
23
+ # Register for cleanup
24
+ register_test_table "$USERS_TABLE"
25
+ register_test_table "$POSTS_TABLE"
26
+
27
+ TOTAL_TESTS=0
28
+ PASSED_TESTS=0
29
+
30
+ test_fk() {
31
+ local method=$1 endpoint=$2 data=$3 desc=$4 expected=${5:-200}
32
+ TOTAL_TESTS=$((TOTAL_TESTS + 1))
33
+
34
+ print_info "Test $TOTAL_TESTS: $desc"
35
+
36
+ response=$(curl -s -w "\n%{http_code}" -X "$method" "$API_BASE$endpoint" \
37
+ -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" ${data:+-d "$data"})
38
+
39
+ status=$(echo "$response" | tail -n 1)
40
+
41
+ if [ "$status" = "$expected" ]; then
42
+ print_success "โœ… ($status)"
43
+ PASSED_TESTS=$((PASSED_TESTS + 1))
44
+ else
45
+ print_fail "โŒ Expected $expected, got $status"
46
+ fi
47
+ echo ""
48
+ }
49
+
50
+ main_test() {
51
+ print_info "Test tables: $USERS_TABLE, $POSTS_TABLE"
52
+
53
+ # Setup tables
54
+ test_fk "POST" "/database/tables" \
55
+ "{\"tableName\":\"$USERS_TABLE\",\"rlsEnabled\":false,\"columns\":[{\"columnName\":\"name\",\"type\":\"string\",\"isNullable\":false,\"isUnique\":false}]}" \
56
+ "Create users table" 201
57
+
58
+ test_fk "POST" "/database/tables" \
59
+ "{\"tableName\":\"$POSTS_TABLE\",\"rlsEnabled\":false,\"columns\":[{\"columnName\":\"author_id\",\"type\":\"uuid\",\"isNullable\":true,\"isUnique\":false}]}" \
60
+ "Create posts table" 201
61
+
62
+ # Test our error handling
63
+ test_fk "PATCH" "/database/tables/$POSTS_TABLE/schema" \
64
+ "{\"addForeignKeys\":[{\"columnName\":\"author_id\",\"foreignKey\":{\"referenceTable\":\"fake_table\",\"referenceColumn\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}}]}" \
65
+ "Non-existent table โ†’ 400" 400
66
+
67
+ test_fk "PATCH" "/database/tables/$POSTS_TABLE/schema" \
68
+ "{\"addForeignKeys\":[{\"columnName\":\"author_id\",\"foreignKey\":{\"referenceTable\":\"$USERS_TABLE\",\"referenceColumn\":\"name\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}}]}" \
69
+ "Type mismatch โ†’ 400" 400
70
+
71
+ test_fk "PATCH" "/database/tables/$POSTS_TABLE/schema" \
72
+ "{\"addColumns\":[{\"columnName\":\"cat_id\",\"type\":\"uuid\",\"isNullable\":true,\"isUnique\":false}],\"addForeignKeys\":[{\"columnName\":\"cat_id\",\"foreignKey\":{\"referenceTable\":\"fake_cats\",\"referenceColumn\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}}]}" \
73
+ "New column with non-existent table โ†’ 400" 400
74
+
75
+ # Valid FK should work
76
+ test_fk "PATCH" "/database/tables/$POSTS_TABLE/schema" \
77
+ "{\"addForeignKeys\":[{\"columnName\":\"author_id\",\"foreignKey\":{\"referenceTable\":\"$USERS_TABLE\",\"referenceColumn\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}}]}" \
78
+ "Valid FK constraint โ†’ 200" 200
79
+
80
+ # Summary
81
+ print_blue "Results: $PASSED_TESTS/$TOTAL_TESTS passed"
82
+ if [ $PASSED_TESTS -eq $TOTAL_TESTS ]; then
83
+ print_success "๐ŸŽ‰ FK error handling working correctly!"
84
+ return 0
85
+ else
86
+ print_fail "โŒ Some FK error tests failed"
87
+ return 1
88
+ fi
89
+ }
90
+
91
+ # Check requirements
92
+ if ! curl -s "$API_BASE/health" > /dev/null; then
93
+ print_fail "Server not running at $API_BASE"
94
+ exit 1
95
+ fi
96
+
97
+ main_test
@@ -0,0 +1,201 @@
1
+ #!/bin/bash
2
+
3
+ # Test script for ID field functionality
4
+
5
+ # Get the directory where this script is located
6
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
7
+
8
+ # Source the test configuration
9
+ source "$SCRIPT_DIR/../test-config.sh"
10
+
11
+ echo "=== Testing User Creation with ID Field ==="
12
+
13
+ # Use configuration from test-config.sh
14
+ API_URL="$TEST_API_BASE"
15
+
16
+ # Test users for cleanup tracking
17
+ USER1_EMAIL="${TEST_USER_EMAIL_PREFIX}id_test1_$(date +%s)@example.com"
18
+ USER2_EMAIL="${TEST_USER_EMAIL_PREFIX}id_test2_$(date +%s)@example.com"
19
+ USER3_EMAIL="${TEST_USER_EMAIL_PREFIX}id_test3_$(date +%s)@example.com"
20
+
21
+ # Register users for cleanup
22
+ register_test_user "$USER1_EMAIL"
23
+ register_test_user "$USER2_EMAIL"
24
+ register_test_user "$USER3_EMAIL"
25
+
26
+ # Test 1: Create user without ID (should auto-generate)
27
+ print_info "1. Creating user without ID (auto-generate):"
28
+ response1=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/auth/users" \
29
+ -H "Content-Type: application/json" \
30
+ -d "{
31
+ \"email\": \"$USER1_EMAIL\",
32
+ \"password\": \"password123\",
33
+ \"name\": \"Test User 1\"
34
+ }")
35
+
36
+ body1=$(echo "$response1" | sed '$d')
37
+ status1=$(echo "$response1" | tail -n 1)
38
+
39
+ if [ "$status1" -ge 200 ] && [ "$status1" -lt 300 ]; then
40
+ print_success "User created without ID ($status1)"
41
+ echo "Response: $body1" | head -c 200
42
+ echo ""
43
+ else
44
+ print_fail "User creation without ID failed ($status1)"
45
+ echo "Error: $body1"
46
+ fi
47
+
48
+ # Test 2: Create user with custom ID
49
+ print_info "2. Creating user with custom ID:"
50
+ # Generate a valid UUID v4
51
+ CUSTOM_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
52
+ response2=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/auth/users" \
53
+ -H "Content-Type: application/json" \
54
+ -d "{
55
+ \"id\": \"$CUSTOM_ID\",
56
+ \"email\": \"$USER2_EMAIL\",
57
+ \"password\": \"password123\",
58
+ \"name\": \"Test User 2\"
59
+ }")
60
+
61
+ body2=$(echo "$response2" | sed '$d')
62
+ status2=$(echo "$response2" | tail -n 1)
63
+
64
+ if [ "$status2" -ge 200 ] && [ "$status2" -lt 300 ]; then
65
+ print_success "User created with custom ID ($status2)"
66
+ echo "Response: $body2" | head -c 200
67
+ echo ""
68
+ else
69
+ print_fail "User creation with custom ID failed ($status2)"
70
+ echo "Error: $body2"
71
+ fi
72
+
73
+ # Test 3: Try to create user with duplicate ID (JWT auth doesn't support custom IDs)
74
+ print_info "3. Creating user with duplicate ID (JWT auth ignores custom ID):"
75
+ response3=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/auth/users" \
76
+ -H "Content-Type: application/json" \
77
+ -d "{
78
+ \"id\": \"$CUSTOM_ID\",
79
+ \"email\": \"$USER3_EMAIL\",
80
+ \"password\": \"password123\",
81
+ \"name\": \"Test User 3\"
82
+ }")
83
+
84
+ body3=$(echo "$response3" | sed '$d')
85
+ status3=$(echo "$response3" | tail -n 1)
86
+
87
+ # JWT auth doesn't support custom IDs, so it will always succeed with a new generated ID
88
+ if [ "$status3" -eq 200 ] || [ "$status3" -eq 201 ]; then
89
+ print_success "JWT auth created user with generated ID (expected behavior)"
90
+ print_info "Note: JWT auth doesn't support custom user IDs"
91
+ else
92
+ print_fail "Unexpected response ($status3)"
93
+ echo "Error: $body3"
94
+ fi
95
+
96
+ echo ""
97
+ echo "=== Testing Record Creation with ID Field ==="
98
+
99
+ # Get admin token for table creation
100
+ admin_token=$(get_admin_token)
101
+ if [ -z "$admin_token" ]; then
102
+ print_fail "Could not get admin token for table creation"
103
+ fi
104
+
105
+ # Create a test table
106
+ TEST_TABLE="test_items_$(date +%s)"
107
+ register_test_table "$TEST_TABLE"
108
+
109
+ print_info "4. Creating test table: $TEST_TABLE"
110
+ create_response=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/database/tables" \
111
+ -H "Authorization: Bearer $admin_token" \
112
+ -H "Content-Type: application/json" \
113
+ -d "{
114
+ \"tableName\": \"$TEST_TABLE\",
115
+ \"rlsEnabled\": false,
116
+ \"columns\": [
117
+ {\"columnName\": \"title\", \"type\": \"string\", \"isNullable\": false, \"isUnique\": false},
118
+ {\"columnName\": \"description\", \"type\": \"string\", \"isNullable\": true, \"isUnique\": false},
119
+ {\"columnName\": \"status\", \"type\": \"string\", \"isNullable\": false, \"isUnique\": false}
120
+ ]
121
+ }")
122
+
123
+ create_body=$(echo "$create_response" | sed '$d')
124
+ create_status=$(echo "$create_response" | tail -n 1)
125
+
126
+ if [ "$create_status" -ge 200 ] && [ "$create_status" -lt 300 ]; then
127
+ print_success "Test table created successfully ($create_status)"
128
+ # Wait for the table to be created and synced
129
+ sleep 1
130
+ else
131
+ print_fail "Test table creation failed ($create_status)"
132
+ echo "Error: $create_body"
133
+ fi
134
+
135
+ # Test 5: Create record without ID (should auto-generate)
136
+ print_info "5. Creating record without ID (auto-generate):"
137
+ record1_response=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/database/records/$TEST_TABLE" \
138
+ -H "Authorization: Bearer $admin_token" \
139
+ -H "Content-Type: application/json" \
140
+ -d '[{
141
+ "title": "Test Item 1",
142
+ "description": "This is a test item",
143
+ "status": "active"
144
+ }]')
145
+
146
+ record1_body=$(echo "$record1_response" | sed '$d')
147
+ record1_status=$(echo "$record1_response" | tail -n 1)
148
+
149
+ if [ "$record1_status" -ge 200 ] && [ "$record1_status" -lt 300 ]; then
150
+ print_success "Record created without ID ($record1_status)"
151
+ echo "Response: $record1_body" | head -c 200
152
+ echo ""
153
+ else
154
+ print_fail "Record creation without ID failed ($record1_status)"
155
+ echo "Error: $record1_body"
156
+ fi
157
+
158
+ # Test 6: Create record with custom ID
159
+ print_info "6. Creating record with custom ID:"
160
+ # Generate a valid UUID v4
161
+ CUSTOM_RECORD_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
162
+ record2_response=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/database/records/$TEST_TABLE" \
163
+ -H "Authorization: Bearer $admin_token" \
164
+ -H "Content-Type: application/json" \
165
+ -d "[{
166
+ \"id\": \"$CUSTOM_RECORD_ID\",
167
+ \"title\": \"Test Item 2\",
168
+ \"description\": \"This has a custom ID\",
169
+ \"status\": \"active\"
170
+ }]")
171
+
172
+ record2_body=$(echo "$record2_response" | sed '$d')
173
+ record2_status=$(echo "$record2_response" | tail -n 1)
174
+
175
+ if [ "$record2_status" -ge 200 ] && [ "$record2_status" -lt 300 ]; then
176
+ print_success "Record created with custom ID ($record2_status)"
177
+ echo "Response: $record2_body" | head -c 200
178
+ echo ""
179
+ else
180
+ print_fail "Record creation with custom ID failed ($record2_status)"
181
+ echo "Error: $record2_body"
182
+ fi
183
+
184
+ # Test 7: Query records to verify IDs
185
+ print_info "7. Querying all records to verify IDs:"
186
+ query_response=$(curl -s -w "\n%{http_code}" -X GET "$API_URL/database/records/$TEST_TABLE" \
187
+ -H "Authorization: Bearer $admin_token")
188
+
189
+ query_body=$(echo "$query_response" | sed '$d')
190
+ query_status=$(echo "$query_response" | tail -n 1)
191
+
192
+ if [ "$query_status" -ge 200 ] && [ "$query_status" -lt 300 ]; then
193
+ print_success "Records queried successfully ($query_status)"
194
+ echo "Records: $query_body" | head -c 500
195
+ echo ""
196
+ else
197
+ print_fail "Record query failed ($query_status)"
198
+ echo "Error: $query_body"
199
+ fi
200
+
201
+ print_success "๐ŸŽ‰ ID field tests completed!"
@@ -0,0 +1,265 @@
1
+ #!/bin/bash
2
+
3
+ # Get the directory where this script is located
4
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5
+
6
+ # Source the test configuration
7
+ source "$SCRIPT_DIR/../test-config.sh"
8
+
9
+ # Configuration
10
+ API_BASE_URL="$TEST_API_BASE"
11
+ PUBLIC_BUCKET="public-images-$(date +%s)"
12
+ PRIVATE_BUCKET="private-docs-$(date +%s)"
13
+ TEST_FILE="test.txt"
14
+
15
+ # Register buckets for cleanup
16
+ register_test_bucket "$PUBLIC_BUCKET"
17
+ register_test_bucket "$PRIVATE_BUCKET"
18
+
19
+ echo "๐Ÿงช Testing Public/Private Bucket Functionality"
20
+ echo "============================================="
21
+
22
+ # Get admin token for auth endpoints
23
+ admin_token=$(get_admin_token)
24
+ if [ -z "$admin_token" ]; then
25
+ print_fail "Could not get admin token"
26
+ else
27
+ print_success "Admin authentication successful"
28
+ fi
29
+
30
+ # Get API key for storage operations
31
+ api_key=$(get_admin_api_key)
32
+
33
+ # If that fails, try to get it via the API endpoint
34
+ if [ -z "$api_key" ] && [ -n "$admin_token" ]; then
35
+ api_key_response=$(curl -s "$TEST_API_BASE/metadata/api-key" \
36
+ -H "Authorization: Bearer $admin_token")
37
+ api_key=$(echo "$api_key_response" | grep -o '"apiKey":"[^"]*' | cut -d'"' -f4)
38
+ fi
39
+
40
+ # Export for cleanup
41
+ if [ -n "$api_key" ]; then
42
+ export ACCESS_API_KEY="$api_key"
43
+ print_success "API key obtained for storage operations"
44
+ else
45
+ print_fail "Could not get API key for storage operations"
46
+ fi
47
+
48
+ # Step 1: Create a public bucket
49
+ print_info "1๏ธโƒฃ Creating PUBLIC bucket: $PUBLIC_BUCKET"
50
+ response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets" \
51
+ -H "Authorization: Bearer ${api_key}" \
52
+ -H "Content-Type: application/json" \
53
+ -d "{\"bucketName\": \"${PUBLIC_BUCKET}\", \"isPublic\": true}")
54
+
55
+ body=$(echo "$response" | sed '$d')
56
+ status=$(echo "$response" | tail -n 1)
57
+
58
+ if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
59
+ print_success "Public bucket created ($status)"
60
+ # Pretty print JSON if available
61
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
62
+ echo "$body" | jq '.'
63
+ else
64
+ echo "Response: $body"
65
+ fi
66
+ else
67
+ print_fail "Public bucket creation failed ($status)"
68
+ echo "Error: $body"
69
+ fi
70
+
71
+ # Step 2: Create a private bucket
72
+ print_info "2๏ธโƒฃ Creating PRIVATE bucket: $PRIVATE_BUCKET"
73
+ response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets" \
74
+ -H "Authorization: Bearer ${api_key}" \
75
+ -H "Content-Type: application/json" \
76
+ -d "{\"bucketName\": \"${PRIVATE_BUCKET}\", \"isPublic\": false}")
77
+
78
+ body=$(echo "$response" | sed '$d')
79
+ status=$(echo "$response" | tail -n 1)
80
+
81
+ if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
82
+ print_success "Private bucket created ($status)"
83
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
84
+ echo "$body" | jq '.'
85
+ else
86
+ echo "Response: $body"
87
+ fi
88
+ else
89
+ print_fail "Private bucket creation failed ($status)"
90
+ echo "Error: $body"
91
+ fi
92
+
93
+ # Step 3: Upload a test file to public bucket
94
+ print_info "3๏ธโƒฃ Uploading file to PUBLIC bucket..."
95
+ # First delete if exists
96
+ curl -s -X DELETE "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}" \
97
+ -H "Authorization: Bearer ${api_key}" > /dev/null 2>&1
98
+
99
+ echo "This is a test file for public access" > /tmp/public-test.txt
100
+ response=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}" \
101
+ -H "Authorization: Bearer ${api_key}" \
102
+ -F "file=@/tmp/public-test.txt")
103
+
104
+ body=$(echo "$response" | sed '$d')
105
+ status=$(echo "$response" | tail -n 1)
106
+
107
+ if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
108
+ print_success "File uploaded to public bucket ($status)"
109
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
110
+ echo "$body" | jq '.'
111
+ else
112
+ echo "Response: $body"
113
+ fi
114
+ else
115
+ print_fail "File upload to public bucket failed ($status)"
116
+ echo "Error: $body"
117
+ fi
118
+
119
+ # Step 4: Upload a test file to private bucket
120
+ print_info "4๏ธโƒฃ Uploading file to PRIVATE bucket..."
121
+ # First delete if exists
122
+ curl -s -X DELETE "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}" \
123
+ -H "Authorization: Bearer ${api_key}" > /dev/null 2>&1
124
+
125
+ echo "This is a test file for private access" > /tmp/private-test.txt
126
+ response=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}" \
127
+ -H "Authorization: Bearer ${api_key}" \
128
+ -F "file=@/tmp/private-test.txt")
129
+
130
+ body=$(echo "$response" | sed '$d')
131
+ status=$(echo "$response" | tail -n 1)
132
+
133
+ if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
134
+ print_success "File uploaded to private bucket ($status)"
135
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
136
+ echo "$body" | jq '.'
137
+ else
138
+ echo "Response: $body"
139
+ fi
140
+ else
141
+ print_fail "File upload to private bucket failed ($status)"
142
+ echo "Error: $body"
143
+ fi
144
+
145
+ # Step 5: Test accessing PUBLIC file WITHOUT API key
146
+ print_info "5๏ธโƒฃ Testing PUBLIC file access WITHOUT API key..."
147
+ echo " Accessing: ${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}"
148
+ HTTP_CODE=$(curl -s -o /tmp/public-response.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}")
149
+ if [ "$HTTP_CODE" -eq 200 ]; then
150
+ print_success "Public file accessible without API key! (Status: ${HTTP_CODE})"
151
+ echo " ๐Ÿ“„ Content: $(cat /tmp/public-response.txt)"
152
+ else
153
+ print_fail "Public file NOT accessible without API key (Status: ${HTTP_CODE})"
154
+ fi
155
+
156
+ # Step 6: Test accessing PRIVATE file WITHOUT API key
157
+ print_info "6๏ธโƒฃ Testing PRIVATE file access WITHOUT API key..."
158
+ echo " Accessing: ${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}"
159
+ HTTP_CODE=$(curl -s -o /tmp/private-response.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}")
160
+ if [ "$HTTP_CODE" -eq 401 ]; then
161
+ print_success "Private file correctly blocked without API key! (Status: ${HTTP_CODE})"
162
+ else
163
+ print_fail "Private file should NOT be accessible without API key (Status: ${HTTP_CODE})"
164
+ fi
165
+
166
+ # Step 7: Test accessing PRIVATE file WITH API key
167
+ print_info "7๏ธโƒฃ Testing PRIVATE file access WITH API key..."
168
+ HTTP_CODE=$(curl -s -o /tmp/private-auth-response.txt -w "%{http_code}" \
169
+ -H "Authorization: Bearer ${api_key}" \
170
+ "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}")
171
+ if [ "$HTTP_CODE" -eq 200 ]; then
172
+ print_success "Private file accessible with API key! (Status: ${HTTP_CODE})"
173
+ echo " ๐Ÿ“„ Content: $(cat /tmp/private-auth-response.txt)"
174
+ else
175
+ print_fail "Private file should be accessible with API key (Status: ${HTTP_CODE})"
176
+ fi
177
+
178
+ # Step 8: List all buckets
179
+ print_info "8๏ธโƒฃ Listing all buckets..."
180
+ response=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer ${api_key}" "${API_BASE_URL}/storage/buckets")
181
+ body=$(echo "$response" | sed '$d')
182
+ status=$(echo "$response" | tail -n 1)
183
+
184
+ if [ "$status" -eq 200 ]; then
185
+ print_success "Buckets listed successfully"
186
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
187
+ echo "$body" | jq '.[] | "\(.name) - \(if .public then "๐ŸŒ PUBLIC" else "๐Ÿ”’ PRIVATE" end)"' -r 2>/dev/null || echo "Could not parse bucket list"
188
+ else
189
+ echo "Response: $body"
190
+ fi
191
+ else
192
+ print_fail "Failed to list buckets ($status)"
193
+ echo "Error: $body"
194
+ fi
195
+
196
+ # Step 9: Test POST upload with auto-generated key
197
+ print_info "9๏ธโƒฃ Testing POST upload with auto-generated key..."
198
+ echo "This is a test file for POST upload" > /tmp/post-test.txt
199
+ response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects" \
200
+ -H "Authorization: Bearer ${api_key}" \
201
+ -F "file=@/tmp/post-test.txt")
202
+
203
+ body=$(echo "$response" | sed '$d')
204
+ status=$(echo "$response" | tail -n 1)
205
+
206
+ if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
207
+ print_success "File uploaded via POST with auto-generated key ($status)"
208
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
209
+ echo "$body" | jq '.'
210
+ # Extract the generated key for verification
211
+ generated_key=$(echo "$body" | jq -r '.key')
212
+ echo " ๐Ÿ“ Generated key: $generated_key"
213
+ # Test downloading the file with generated key
214
+ HTTP_CODE=$(curl -s -o /tmp/post-download.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${generated_key}")
215
+ if [ "$HTTP_CODE" -eq 200 ]; then
216
+ print_success "Downloaded file with generated key!"
217
+ echo " ๐Ÿ“„ Content: $(cat /tmp/post-download.txt)"
218
+ else
219
+ print_fail "Could not download file with generated key (Status: ${HTTP_CODE})"
220
+ fi
221
+ else
222
+ echo "Response: $body"
223
+ fi
224
+ else
225
+ print_fail "POST upload failed ($status)"
226
+ echo "Error: $body"
227
+ fi
228
+
229
+ # Step 10: Update bucket visibility
230
+ print_info "๐Ÿ”Ÿ Testing bucket visibility update (making public bucket private)..."
231
+ response=$(curl -s -w "\n%{http_code}" -X PATCH "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}" \
232
+ -H "Authorization: Bearer ${api_key}" \
233
+ -H "Content-Type: application/json" \
234
+ -d '{"isPublic": false}')
235
+
236
+ body=$(echo "$response" | sed '$d')
237
+ status=$(echo "$response" | tail -n 1)
238
+
239
+ if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
240
+ print_success "Bucket visibility updated ($status)"
241
+ if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
242
+ echo "$body" | jq '.'
243
+ else
244
+ echo "Response: $body"
245
+ fi
246
+ else
247
+ print_fail "Bucket visibility update failed ($status)"
248
+ echo "Error: $body"
249
+ fi
250
+
251
+ # Test access again
252
+ echo " Testing access after update..."
253
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}")
254
+ if [ "$HTTP_CODE" -eq 401 ]; then
255
+ print_success "Previously public file now requires authentication!"
256
+ else
257
+ print_fail "File should now require authentication (Status: ${HTTP_CODE})"
258
+ fi
259
+
260
+ # Cleanup temp files only
261
+ print_info "๐Ÿงน Cleaning up temp files..."
262
+ rm -f /tmp/public-test.txt /tmp/private-test.txt /tmp/public-response.txt /tmp/private-response.txt /tmp/private-auth-response.txt /tmp/post-test.txt /tmp/post-download.txt
263
+
264
+ print_success "โœจ Public/Private bucket test completed!"
265
+ # Note: Buckets will be cleaned up automatically on exit via test-config.sh