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,192 @@
1
+ #!/bin/bash
2
+
3
+ # Configuration
4
+ BASE_URL="http://localhost:7130/api/database/records/posts"
5
+ DURATION=600 # 5 minutes in seconds
6
+ CONCURRENT_REQUESTS=10 # Number of concurrent requests
7
+ REQUEST_INTERVAL=0.1 # Seconds between requests per thread
8
+
9
+ # Function to generate random 8-character string (macOS compatible)
10
+ generate_random_string() {
11
+ # Use LC_ALL=C to avoid locale issues with tr on macOS
12
+ LC_ALL=C cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | head -c 8
13
+ }
14
+
15
+ # Colors for output
16
+ RED='\033[0;31m'
17
+ GREEN='\033[0;32m'
18
+ YELLOW='\033[1;33m'
19
+ NC='\033[0m' # No Color
20
+
21
+ # Statistics
22
+ TOTAL_REQUESTS=0
23
+ SUCCESS_COUNT=0
24
+ ERROR_COUNT=0
25
+ NOT_MODIFIED_COUNT=0
26
+ ERROR_MESSAGES=""
27
+ START_TIME=$(date +%s)
28
+ END_TIME=$((START_TIME + DURATION))
29
+
30
+ # Create temp directory for logs
31
+ LOG_DIR="/tmp/postgrest-test-$(date +%Y%m%d-%H%M%S)"
32
+ mkdir -p "$LOG_DIR"
33
+
34
+ # Create lock file for thread safety (macOS compatible)
35
+ LOCK_FILE="$LOG_DIR/lock"
36
+ touch "$LOCK_FILE"
37
+
38
+ echo "========================================="
39
+ echo "PostgREST Stability Test"
40
+ echo "========================================="
41
+ echo "Base URL: $BASE_URL"
42
+ echo "Duration: $DURATION seconds (5 minutes)"
43
+ echo "Concurrent requests: $CONCURRENT_REQUESTS"
44
+ echo "Request interval: $REQUEST_INTERVAL seconds"
45
+ echo "Log directory: $LOG_DIR"
46
+ echo "========================================="
47
+ echo ""
48
+
49
+ # Function to make requests
50
+ make_requests() {
51
+ local thread_id=$1
52
+ local log_file="$LOG_DIR/thread-$thread_id.log"
53
+
54
+ while [ $(date +%s) -lt $END_TIME ]; do
55
+ # Generate random 8-character string for query parameter
56
+ RANDOM_STR=$(generate_random_string)
57
+ URL="${BASE_URL}?title=eq.${RANDOM_STR}"
58
+
59
+ # Make request and capture response (macOS compatible)
60
+ RESPONSE=$(curl -s -w "\n:HTTP_CODE:%{http_code}\n:TIME:%{time_total}" "$URL" 2>&1)
61
+ HTTP_CODE=$(echo "$RESPONSE" | grep ":HTTP_CODE:" | cut -d: -f3)
62
+ RESPONSE_TIME=$(echo "$RESPONSE" | grep ":TIME:" | cut -d: -f3)
63
+ RESPONSE_BODY=$(echo "$RESPONSE" | sed '/^:HTTP_CODE:/d' | sed '/^:TIME:/d')
64
+
65
+ # Update global counters (using simple file-based locking for macOS)
66
+ while ! mkdir "$LOCK_FILE.lock" 2>/dev/null; do
67
+ sleep 0.01
68
+ done
69
+
70
+ # Read current values
71
+ [ -f "$LOG_DIR/total.cnt" ] && TOTAL_REQUESTS=$(cat "$LOG_DIR/total.cnt") || TOTAL_REQUESTS=0
72
+ [ -f "$LOG_DIR/success.cnt" ] && SUCCESS_COUNT=$(cat "$LOG_DIR/success.cnt") || SUCCESS_COUNT=0
73
+ [ -f "$LOG_DIR/error.cnt" ] && ERROR_COUNT=$(cat "$LOG_DIR/error.cnt") || ERROR_COUNT=0
74
+ [ -f "$LOG_DIR/not_modified.cnt" ] && NOT_MODIFIED_COUNT=$(cat "$LOG_DIR/not_modified.cnt") || NOT_MODIFIED_COUNT=0
75
+
76
+ TOTAL_REQUESTS=$((TOTAL_REQUESTS + 1))
77
+
78
+ if [ "$HTTP_CODE" = "200" ]; then
79
+ SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
80
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] Thread $thread_id: SUCCESS (${RESPONSE_TIME}s)" >> "$log_file"
81
+ elif [ "$HTTP_CODE" = "304" ]; then
82
+ NOT_MODIFIED_COUNT=$((NOT_MODIFIED_COUNT + 1))
83
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] Thread $thread_id: NOT MODIFIED (${RESPONSE_TIME}s)" >> "$log_file"
84
+ else
85
+ ERROR_COUNT=$((ERROR_COUNT + 1))
86
+ ERROR_MSG="[$(date '+%Y-%m-%d %H:%M:%S')] Thread $thread_id: ERROR - HTTP $HTTP_CODE (${RESPONSE_TIME}s)"
87
+ echo "$ERROR_MSG" >> "$log_file"
88
+ echo "Response: $RESPONSE_BODY" >> "$log_file"
89
+ echo -e "${RED}$ERROR_MSG${NC}"
90
+
91
+ # Log error details to main error file
92
+ echo "$ERROR_MSG" >> "$LOG_DIR/errors.log"
93
+ echo "Response: $RESPONSE_BODY" >> "$LOG_DIR/errors.log"
94
+ echo "---" >> "$LOG_DIR/errors.log"
95
+ fi
96
+
97
+ # Update counter files
98
+ echo $TOTAL_REQUESTS > "$LOG_DIR/total.cnt"
99
+ echo $SUCCESS_COUNT > "$LOG_DIR/success.cnt"
100
+ echo $ERROR_COUNT > "$LOG_DIR/error.cnt"
101
+ echo $NOT_MODIFIED_COUNT > "$LOG_DIR/not_modified.cnt"
102
+
103
+ # Release lock
104
+ rmdir "$LOCK_FILE.lock" 2>/dev/null
105
+
106
+ sleep $REQUEST_INTERVAL
107
+ done
108
+ }
109
+
110
+ # Function to display statistics
111
+ display_stats() {
112
+ while [ $(date +%s) -lt $END_TIME ]; do
113
+ # Read current values
114
+ [ -f "$LOG_DIR/total.cnt" ] && TOTAL_REQUESTS=$(cat "$LOG_DIR/total.cnt")
115
+ [ -f "$LOG_DIR/success.cnt" ] && SUCCESS_COUNT=$(cat "$LOG_DIR/success.cnt")
116
+ [ -f "$LOG_DIR/error.cnt" ] && ERROR_COUNT=$(cat "$LOG_DIR/error.cnt")
117
+ [ -f "$LOG_DIR/not_modified.cnt" ] && NOT_MODIFIED_COUNT=$(cat "$LOG_DIR/not_modified.cnt")
118
+
119
+ ELAPSED=$(($(date +%s) - START_TIME))
120
+ REMAINING=$((END_TIME - $(date +%s)))
121
+
122
+ if [ $TOTAL_REQUESTS -gt 0 ]; then
123
+ SUCCESS_RATE=$(echo "scale=2; $SUCCESS_COUNT * 100 / $TOTAL_REQUESTS" | bc)
124
+ REQ_PER_SEC=$(echo "scale=2; $TOTAL_REQUESTS / $ELAPSED" | bc)
125
+ else
126
+ SUCCESS_RATE=0
127
+ REQ_PER_SEC=0
128
+ fi
129
+
130
+ # Clear line and print stats
131
+ printf "\r${GREEN}[%ds/%ds]${NC} Requests: %d | Success: %d (%.1f%%) | 304s: %d | Errors: %d | Rate: %.1f req/s | Remaining: %ds" \
132
+ "$ELAPSED" "$DURATION" "$TOTAL_REQUESTS" "$SUCCESS_COUNT" "$SUCCESS_RATE" "$NOT_MODIFIED_COUNT" "$ERROR_COUNT" "$REQ_PER_SEC" "$REMAINING"
133
+
134
+ sleep 1
135
+ done
136
+ }
137
+
138
+ # Start concurrent request threads
139
+ echo "Starting $CONCURRENT_REQUESTS concurrent request threads..."
140
+ for i in $(seq 1 $CONCURRENT_REQUESTS); do
141
+ make_requests $i &
142
+ PIDS[$i]=$!
143
+ done
144
+
145
+ # Start statistics display
146
+ display_stats &
147
+ STATS_PID=$!
148
+
149
+ # Wait for all threads to complete
150
+ for pid in ${PIDS[@]}; do
151
+ wait $pid
152
+ done
153
+
154
+ # Kill stats display
155
+ kill $STATS_PID 2>/dev/null
156
+
157
+ # Final statistics
158
+ echo ""
159
+ echo ""
160
+ echo "========================================="
161
+ echo "Test Complete - Final Statistics"
162
+ echo "========================================="
163
+ echo "Total Requests: $TOTAL_REQUESTS"
164
+ echo -e "Successful: ${GREEN}$SUCCESS_COUNT${NC}"
165
+ echo -e "Not Modified (304): ${YELLOW}$NOT_MODIFIED_COUNT${NC}"
166
+ echo -e "Failed: ${RED}$ERROR_COUNT${NC}"
167
+
168
+ if [ $TOTAL_REQUESTS -gt 0 ]; then
169
+ SUCCESS_RATE=$(echo "scale=2; $SUCCESS_COUNT * 100 / $TOTAL_REQUESTS" | bc)
170
+ echo "Success Rate: $SUCCESS_RATE%"
171
+ AVG_REQ_PER_SEC=$(echo "scale=2; $TOTAL_REQUESTS / $DURATION" | bc)
172
+ echo "Average Rate: $AVG_REQ_PER_SEC requests/second"
173
+ fi
174
+
175
+ echo "========================================="
176
+
177
+ # Check for errors
178
+ if [ $ERROR_COUNT -gt 0 ]; then
179
+ echo ""
180
+ echo -e "${YELLOW}⚠️ Errors detected! Check the following files for details:${NC}"
181
+ echo " - Error log: $LOG_DIR/errors.log"
182
+ echo " - Thread logs: $LOG_DIR/thread-*.log"
183
+ echo ""
184
+ echo "First 10 errors:"
185
+ head -n 20 "$LOG_DIR/errors.log" 2>/dev/null || echo "No error details available"
186
+ else
187
+ echo ""
188
+ echo -e "${GREEN}✓ No errors detected during the test!${NC}"
189
+ fi
190
+
191
+ echo ""
192
+ echo "Full logs available at: $LOG_DIR"
@@ -0,0 +1,412 @@
1
+ #!/bin/bash
2
+
3
+ # Test RawSQL, Export, and Import endpoints
4
+ # This script tests the database advanced operations
5
+
6
+ # Get the directory where this script is located
7
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
8
+
9
+ # Source the test configuration
10
+ source "$SCRIPT_DIR/../test-config.sh"
11
+
12
+ # Check requirements
13
+ check_requirements
14
+
15
+ print_blue "🧪 Testing RawSQL, Export, and Import Endpoints..."
16
+
17
+ # Test tracking
18
+ TEST_FAILED=0
19
+
20
+ # Function to track test failures
21
+ track_test_failure() {
22
+ TEST_FAILED=$((TEST_FAILED + 1))
23
+ }
24
+
25
+ # Function to cleanup and exit
26
+ cleanup_and_exit() {
27
+ local exit_code=$1
28
+
29
+ print_info "🧹 Cleaning up test data..."
30
+
31
+ # Drop the test table if it exists
32
+ if [ -n "$AUTH_TOKEN" ]; then
33
+ print_info "Dropping large_table..."
34
+ local drop_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
35
+ -H "Content-Type: application/json" \
36
+ -H "Authorization: Bearer $AUTH_TOKEN" \
37
+ -d '{
38
+ "query": "DROP TABLE IF EXISTS large_table CASCADE;"
39
+ }')
40
+
41
+ if echo "$drop_response" | grep -q '"success"'; then
42
+ print_success "Table large_table dropped successfully"
43
+ else
44
+ print_info "Table cleanup response: $drop_response"
45
+ fi
46
+ fi
47
+
48
+ exit $exit_code
49
+ }
50
+
51
+ # Function to exit with proper status
52
+ exit_with_status() {
53
+ if [ $TEST_FAILED -eq 0 ]; then
54
+ print_success "All tests passed!"
55
+ cleanup_and_exit 0
56
+ else
57
+ print_fail "Failed $TEST_FAILED test(s)"
58
+ cleanup_and_exit 1
59
+ fi
60
+ }
61
+
62
+ # API Configuration
63
+ API_BASE="$TEST_API_BASE"
64
+ AUTH_TOKEN=""
65
+
66
+ # Read .env file to get admin credentials
67
+ if [ -f "$SCRIPT_DIR/../../.env" ]; then
68
+ export $(grep -v '^#' "$SCRIPT_DIR/../../.env" | xargs)
69
+ print_info "Loaded environment variables from .env"
70
+ fi
71
+
72
+ # Use admin credentials from environment
73
+ ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}"
74
+ ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin123}"
75
+
76
+ print_info "Using admin credentials: $ADMIN_EMAIL"
77
+
78
+ # ========================================
79
+ # 1. Login as admin
80
+ # ========================================
81
+ print_blue "1. Logging in as admin..."
82
+
83
+ auth_response=$(curl -s -X POST "$API_BASE/auth/admin/sessions" \
84
+ -H "Content-Type: application/json" \
85
+ -d "{
86
+ \"email\": \"$ADMIN_EMAIL\",
87
+ \"password\": \"$ADMIN_PASSWORD\"
88
+ }")
89
+
90
+ # Check if login was successful
91
+ if echo "$auth_response" | grep -q '"accessToken"'; then
92
+ AUTH_TOKEN=$(echo "$auth_response" | grep -o '"accessToken":"[^"]*' | cut -d'"' -f4)
93
+ print_success "Admin login successful"
94
+ else
95
+ print_fail "Failed to login as admin"
96
+ echo "Response: $auth_response"
97
+ exit 1
98
+ fi
99
+
100
+ # ========================================
101
+ # 2. Create large_table using RawSQL
102
+ # ========================================
103
+ print_blue "2. Creating large_table using RawSQL endpoint..."
104
+
105
+ # Step 1: Create the basic table
106
+ print_info "Creating basic table structure..."
107
+ CREATE_TABLE_SQL=$(cat "$SCRIPT_DIR/create-large-table-simple.sql")
108
+
109
+ if command -v jq &> /dev/null; then
110
+ json_payload=$(jq -n --arg query "$CREATE_TABLE_SQL" '{"query": $query}')
111
+ create_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
112
+ -H "Content-Type: application/json" \
113
+ -H "Authorization: Bearer $AUTH_TOKEN" \
114
+ -d "$json_payload")
115
+ else
116
+ CREATE_TABLE_SQL_ESCAPED=$(echo "$CREATE_TABLE_SQL" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
117
+ create_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
118
+ -H "Content-Type: application/json" \
119
+ -H "Authorization: Bearer $AUTH_TOKEN" \
120
+ -d "{\"query\": \"$CREATE_TABLE_SQL_ESCAPED\"}")
121
+ fi
122
+
123
+ if echo "$create_response" | grep -q '"error"'; then
124
+ print_fail "Failed to create table"
125
+ echo "Response: $create_response"
126
+ track_test_failure
127
+ else
128
+ print_success "Basic table created successfully"
129
+
130
+ # Step 2: Add indexes, triggers and RLS
131
+ print_info "Setting up indexes, triggers and RLS..."
132
+ SETUP_SQL=$(cat "$SCRIPT_DIR/setup-large-table-extras.sql")
133
+
134
+ if command -v jq &> /dev/null; then
135
+ json_payload=$(jq -n --arg query "$SETUP_SQL" '{"query": $query}')
136
+ setup_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
137
+ -H "Content-Type: application/json" \
138
+ -H "Authorization: Bearer $AUTH_TOKEN" \
139
+ -d "$json_payload")
140
+ else
141
+ SETUP_SQL_ESCAPED=$(echo "$SETUP_SQL" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
142
+ setup_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
143
+ -H "Content-Type: application/json" \
144
+ -H "Authorization: Bearer $AUTH_TOKEN" \
145
+ -d "{\"query\": \"$SETUP_SQL_ESCAPED\"}")
146
+ fi
147
+
148
+ if echo "$setup_response" | grep -q '"error"'; then
149
+ print_fail "Failed to setup table extras"
150
+ echo "Response: $setup_response"
151
+ track_test_failure
152
+ else
153
+ print_success "Table fully configured with indexes, triggers and RLS"
154
+ fi
155
+ fi
156
+
157
+ # ========================================
158
+ # 3. Verify table schema
159
+ # ========================================
160
+ print_blue "3. Verifying table schema..."
161
+
162
+ # Get table schema
163
+ schema_response=$(curl -s "$API_BASE/metadata/large_table" \
164
+ -H "Authorization: Bearer $AUTH_TOKEN")
165
+
166
+ if echo "$schema_response" | grep -q '"large_table"'; then
167
+ print_success "Table schema retrieved successfully"
168
+
169
+ # Verify required columns exist
170
+ if echo "$schema_response" | grep -q '"columnName":"user_id"' && \
171
+ echo "$schema_response" | grep -q '"columnName":"created_at"' && \
172
+ echo "$schema_response" | grep -q '"columnName":"updated_at"'; then
173
+ print_success "Required columns (user_id, created_at, updated_at) exist"
174
+ else
175
+ print_fail "Missing required columns"
176
+ echo "Schema response: $schema_response"
177
+ track_test_failure
178
+ fi
179
+
180
+ # Verify RLS is enabled
181
+ if echo "$schema_response" | grep -q '"rlsEnabled":true'; then
182
+ print_success "RLS is enabled on the table"
183
+ else
184
+ print_fail "RLS is not enabled"
185
+ track_test_failure
186
+ fi
187
+ else
188
+ print_fail "Failed to get table schema"
189
+ echo "Response: $schema_response"
190
+ track_test_failure
191
+ fi
192
+
193
+ # ========================================
194
+ # 4. Import test data
195
+ # ========================================
196
+ print_blue "4. Importing test data using Import endpoint..."
197
+
198
+ # Use multipart form-data to upload the SQL file
199
+ import_response=$(curl -s -X POST "$API_BASE/database/advance/import" \
200
+ -H "Authorization: Bearer $AUTH_TOKEN" \
201
+ -F "file=@$SCRIPT_DIR/seed-large-table.sql" \
202
+ -F "truncate=false")
203
+
204
+ if echo "$import_response" | grep -q '"error"'; then
205
+ print_fail "Failed to import data"
206
+ echo "Response: $import_response"
207
+ track_test_failure
208
+ else
209
+ print_success "Data imported successfully"
210
+
211
+ # Check if response contains success information
212
+ if echo "$import_response" | grep -q '"rowsAffected"'; then
213
+ rows_affected=$(echo "$import_response" | grep -o '"rowsAffected":[0-9]*' | cut -d':' -f2)
214
+ print_success "Rows affected: $rows_affected"
215
+
216
+ if [ "$rows_affected" -ge 1000 ]; then
217
+ print_success "Successfully imported 1000+ rows"
218
+ else
219
+ print_fail "Less than 1000 rows imported"
220
+ track_test_failure
221
+ fi
222
+ fi
223
+ fi
224
+
225
+ # ========================================
226
+ # 5. Verify imported data
227
+ # ========================================
228
+ print_blue "5. Verifying imported data..."
229
+
230
+ # Count records using RawSQL
231
+ count_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
232
+ -H "Content-Type: application/json" \
233
+ -H "Authorization: Bearer $AUTH_TOKEN" \
234
+ -d '{
235
+ "query": "SELECT COUNT(*) as total FROM large_table;"
236
+ }')
237
+
238
+ if echo "$count_response" | grep -q '"rows"'; then
239
+ # Extract the count from the rows array
240
+ if command -v jq &> /dev/null; then
241
+ total_count=$(echo "$count_response" | jq -r '.rows[0].total // 0')
242
+ else
243
+ # Fallback without jq
244
+ total_count=$(echo "$count_response" | grep -o '"total":[0-9]*' | cut -d':' -f2 | head -1)
245
+ if [ -z "$total_count" ]; then
246
+ # Try another pattern
247
+ total_count=$(echo "$count_response" | sed -n 's/.*"total":\([0-9]*\).*/\1/p' | head -1)
248
+ fi
249
+ fi
250
+
251
+ if [ -n "$total_count" ] && [ "$total_count" -ge 0 ]; then
252
+ print_info "Total records in large_table: $total_count"
253
+
254
+ if [ "$total_count" -ge 1000 ]; then
255
+ print_success "Table contains 1000+ records as expected"
256
+ else
257
+ print_fail "Table has less than 1000 records ($total_count found)"
258
+ track_test_failure
259
+ fi
260
+ else
261
+ print_fail "Could not parse record count"
262
+ echo "Response: $count_response"
263
+ track_test_failure
264
+ fi
265
+ else
266
+ print_fail "Failed to count records"
267
+ echo "Response: $count_response"
268
+ track_test_failure
269
+ fi
270
+
271
+ # ========================================
272
+ # 6. Test Export endpoint
273
+ # ========================================
274
+ print_blue "6. Testing Export endpoint..."
275
+
276
+ # Export all data including schema
277
+ export_response=$(curl -s -X POST "$API_BASE/database/advance/export" \
278
+ -H "Content-Type: application/json" \
279
+ -H "Authorization: Bearer $AUTH_TOKEN" \
280
+ -d '{
281
+ "tables": ["large_table"],
282
+ "format": "sql",
283
+ "includeData": true,
284
+ "includeFunctions": true,
285
+ "includeSequences": true,
286
+ "includeViews": false
287
+ }')
288
+
289
+ if echo "$export_response" | grep -q '"error"'; then
290
+ print_fail "Failed to export database"
291
+ echo "Response preview: $(echo "$export_response" | head -c 500)..."
292
+ track_test_failure
293
+ else
294
+ print_success "Database exported successfully"
295
+
296
+ # Verify export contains expected elements
297
+ if echo "$export_response" | grep -q '"data"'; then
298
+ export_content=$(echo "$export_response" | jq -r '.data // empty')
299
+
300
+ if [ -n "$export_content" ]; then
301
+ # Check for table creation (use case statement to avoid broken pipe)
302
+ case "$export_content" in
303
+ *"CREATE TABLE"*"large_table"*)
304
+ print_success "Export contains table creation statement"
305
+ ;;
306
+ *)
307
+ print_fail "Export missing table creation statement"
308
+ track_test_failure
309
+ ;;
310
+ esac
311
+
312
+ # Check for data
313
+ case "$export_content" in
314
+ *"INSERT INTO"*"large_table"*)
315
+ print_success "Export contains data insertion statements"
316
+ ;;
317
+ *)
318
+ print_fail "Export missing data insertion statements"
319
+ track_test_failure
320
+ ;;
321
+ esac
322
+
323
+ # Check for RLS policies
324
+ case "$export_content" in
325
+ *"CREATE POLICY"*)
326
+ print_success "Export contains RLS policies"
327
+ ;;
328
+ *)
329
+ print_fail "Export missing RLS policies"
330
+ track_test_failure
331
+ ;;
332
+ esac
333
+
334
+ # Check for trigger
335
+ case "$export_content" in
336
+ *"CREATE TRIGGER"*"update_large_table_updated_at"*)
337
+ print_success "Export contains update trigger"
338
+ ;;
339
+ *)
340
+ print_fail "Export missing update trigger"
341
+ track_test_failure
342
+ ;;
343
+ esac
344
+
345
+ # Count INSERT statements to verify all data exported (using awk for efficiency)
346
+ insert_count=$(echo "$export_content" | awk '/INSERT INTO/ {count++} END {print count+0}')
347
+ print_info "Number of INSERT statements in export: $insert_count"
348
+ else
349
+ print_fail "Export content is empty"
350
+ track_test_failure
351
+ fi
352
+ else
353
+ print_fail "Export response missing data field"
354
+ echo "Response structure: $(echo "$export_response" | jq -r 'keys' 2>/dev/null || echo "$export_response" | head -c 200)"
355
+ track_test_failure
356
+ fi
357
+ fi
358
+
359
+ # ========================================
360
+ # 7. Test Export with row limit
361
+ # ========================================
362
+ print_blue "7. Testing Export with row limit..."
363
+
364
+ limited_export_response=$(curl -s -X POST "$API_BASE/database/advance/export" \
365
+ -H "Content-Type: application/json" \
366
+ -H "Authorization: Bearer $AUTH_TOKEN" \
367
+ -d '{
368
+ "tables": ["large_table"],
369
+ "format": "sql",
370
+ "includeData": true,
371
+ "rowLimit": 10
372
+ }')
373
+
374
+ if echo "$limited_export_response" | grep -q '"error"'; then
375
+ print_fail "Failed to export with row limit"
376
+ echo "Response preview: $(echo "$limited_export_response" | head -c 500)..."
377
+ track_test_failure
378
+ else
379
+ print_success "Export with row limit successful"
380
+
381
+ if echo "$limited_export_response" | grep -q '"data"'; then
382
+ limited_content=$(echo "$limited_export_response" | jq -r '.data // empty')
383
+
384
+ # Count data rows in limited export (should be much less than full export)
385
+ if [ -n "$limited_content" ]; then
386
+ limited_insert_count=$(echo "$limited_content" | awk '/INSERT INTO/ {count++} END {print count+0}')
387
+ print_info "INSERT statements in limited export: $limited_insert_count"
388
+
389
+ # Only compare if insert_count is set and valid
390
+ if [ -n "$insert_count" ] && [ "$insert_count" -gt 0 ] 2>/dev/null; then
391
+ if [ "$limited_insert_count" -lt "$insert_count" ] 2>/dev/null; then
392
+ print_success "Row limit is working (limited export has fewer rows)"
393
+ else
394
+ print_info "Unable to verify row limit effectiveness"
395
+ fi
396
+ else
397
+ print_info "Skipping row limit comparison (no full export count available)"
398
+ fi
399
+ fi
400
+ fi
401
+ fi
402
+
403
+ # ========================================
404
+ # Summary
405
+ # ========================================
406
+ echo ""
407
+ print_blue "=========================================="
408
+ print_blue "RawSQL/Export/Import Test Complete"
409
+ print_blue "=========================================="
410
+
411
+ # Exit with proper status
412
+ exit_with_status