insforge 1.2.10 → 1.3.0

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 (335) hide show
  1. package/.claude-plugin/marketplace.json +20 -20
  2. package/.dockerignore +60 -60
  3. package/.env.example +83 -77
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -11
  6. package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
  7. package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
  8. package/.github/copilot-instructions.md +146 -146
  9. package/.github/workflows/build-image.yml +65 -65
  10. package/.github/workflows/ci-premerge-check.yml +23 -23
  11. package/.github/workflows/e2e.yml +63 -63
  12. package/.github/workflows/lint-and-format.yml +32 -32
  13. package/.prettierignore +64 -64
  14. package/CHANGELOG.md +44 -44
  15. package/CLAUDE_PLUGIN.md +104 -104
  16. package/CODE_OF_CONDUCT.md +128 -128
  17. package/CONTRIBUTING.md +125 -125
  18. package/Dockerfile +30 -30
  19. package/GITHUB_OAUTH_SETUP.md +49 -49
  20. package/GOOGLE_OAUTH_SETUP.md +148 -148
  21. package/LICENSE +201 -201
  22. package/README.md +182 -182
  23. package/assets/Dark.svg +23 -23
  24. package/auth/package.json +28 -28
  25. package/auth/src/lib/broadcastService.ts +117 -115
  26. package/auth/src/pages/SignInPage.tsx +60 -57
  27. package/auth/src/pages/SignUpPage.tsx +60 -57
  28. package/auth/tsconfig.json +32 -32
  29. package/auth/tsconfig.node.json +11 -11
  30. package/backend/package.json +78 -75
  31. package/backend/src/api/routes/ai/index.routes.ts +3 -3
  32. package/backend/src/api/routes/auth/index.routes.ts +667 -570
  33. package/backend/src/api/routes/auth/oauth.routes.ts +473 -448
  34. package/backend/src/api/routes/database/advance.routes.ts +37 -16
  35. package/backend/src/api/routes/database/index.routes.ts +78 -1
  36. package/backend/src/api/routes/database/records.routes.ts +10 -10
  37. package/backend/src/api/routes/database/tables.routes.ts +0 -14
  38. package/backend/src/api/routes/docs/index.routes.ts +75 -76
  39. package/backend/src/api/routes/email/index.routes.ts +35 -0
  40. package/backend/src/api/routes/functions/index.routes.ts +18 -12
  41. package/backend/src/api/routes/metadata/index.routes.ts +12 -0
  42. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  43. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  44. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  45. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  46. package/backend/src/api/routes/storage/index.routes.ts +18 -12
  47. package/backend/src/api/routes/usage/index.routes.ts +6 -4
  48. package/backend/src/infra/database/database.manager.ts +14 -1
  49. package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
  50. package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
  51. package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
  52. package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
  53. package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
  54. package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
  55. package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
  56. package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
  57. package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
  58. package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
  59. package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
  60. package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
  61. package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
  62. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
  63. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
  64. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
  65. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
  66. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  67. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  68. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  69. package/backend/src/infra/security/token.manager.ts +219 -125
  70. package/backend/src/infra/socket/socket.manager.ts +198 -64
  71. package/backend/src/providers/ai/openrouter.provider.ts +12 -9
  72. package/backend/src/providers/email/base.provider.ts +4 -7
  73. package/backend/src/providers/email/cloud.provider.ts +84 -0
  74. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  75. package/backend/src/providers/oauth/index.ts +1 -0
  76. package/backend/src/server.ts +317 -284
  77. package/backend/src/services/ai/ai-model.service.ts +5 -5
  78. package/backend/src/services/ai/chat-completion.service.ts +4 -4
  79. package/backend/src/services/ai/image-generation.service.ts +3 -3
  80. package/backend/src/services/auth/auth.service.ts +14 -0
  81. package/backend/src/services/database/database-table.service.ts +0 -9
  82. package/backend/src/services/database/database.service.ts +127 -0
  83. package/backend/src/services/email/email.service.ts +5 -7
  84. package/backend/src/services/realtime/index.ts +3 -0
  85. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  86. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  87. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  88. package/backend/src/types/auth.ts +11 -0
  89. package/backend/src/types/realtime.ts +18 -0
  90. package/backend/src/types/socket.ts +7 -31
  91. package/backend/src/utils/cookies.ts +35 -0
  92. package/backend/src/utils/s3-config-loader.ts +64 -0
  93. package/backend/src/utils/seed.ts +301 -298
  94. package/backend/src/utils/sql-parser.ts +90 -0
  95. package/backend/tests/README.md +133 -133
  96. package/backend/tests/cleanup-all-test-data.sh +230 -230
  97. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  98. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  99. package/backend/tests/local/test-ai-config.sh +129 -129
  100. package/backend/tests/local/test-ai-usage.sh +80 -80
  101. package/backend/tests/local/test-auth-router.sh +143 -143
  102. package/backend/tests/local/test-database-router.sh +222 -222
  103. package/backend/tests/local/test-e2e.sh +240 -240
  104. package/backend/tests/local/test-fk-errors.sh +96 -96
  105. package/backend/tests/local/test-functions.sh +123 -123
  106. package/backend/tests/local/test-id-field.sh +200 -200
  107. package/backend/tests/local/test-logs.sh +132 -132
  108. package/backend/tests/local/test-public-bucket.sh +264 -264
  109. package/backend/tests/local/test-secrets.sh +249 -249
  110. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  111. package/backend/tests/local/test-traditional-rest.sh +208 -208
  112. package/backend/tests/manual/README.md +50 -50
  113. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  114. package/backend/tests/manual/seed-large-table.sql +100 -100
  115. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  116. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  117. package/backend/tests/manual/test-database-advance.sh +296 -296
  118. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  119. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  120. package/backend/tests/manual/test-rawsql-modes.sh +244 -244
  121. package/backend/tests/manual/test-universal-storage.sh +263 -263
  122. package/backend/tests/manual/test-users.sql +17 -17
  123. package/backend/tests/run-all-tests.sh +139 -139
  124. package/backend/tests/setup.ts +0 -0
  125. package/backend/tests/test-config.sh +338 -338
  126. package/backend/tests/unit/analyze-query.test.ts +697 -0
  127. package/backend/tsconfig.json +22 -22
  128. package/claude-plugin/.claude-plugin/plugin.json +24 -24
  129. package/claude-plugin/README.md +133 -133
  130. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -270
  131. package/docker-compose.prod.yml +204 -200
  132. package/docker-compose.yml +232 -228
  133. package/docker-init/db/db-init.sql +97 -97
  134. package/docker-init/db/jwt.sql +5 -5
  135. package/docker-init/db/postgresql.conf +16 -16
  136. package/docker-init/logs/vector.yml +236 -236
  137. package/docs/README.md +44 -44
  138. package/docs/agent-docs/real-time.md +269 -0
  139. package/docs/changelog.mdx +119 -67
  140. package/docs/core-concepts/ai/architecture.mdx +372 -372
  141. package/docs/core-concepts/ai/sdk.mdx +213 -213
  142. package/docs/core-concepts/authentication/architecture.mdx +278 -278
  143. package/docs/core-concepts/authentication/sdk.mdx +414 -414
  144. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -529
  145. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -221
  146. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -184
  147. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -129
  148. package/docs/core-concepts/database/architecture.mdx +255 -255
  149. package/docs/core-concepts/database/sdk.mdx +382 -382
  150. package/docs/core-concepts/email/architecture.mdx +101 -0
  151. package/docs/core-concepts/email/sdk.mdx +53 -0
  152. package/docs/core-concepts/functions/architecture.mdx +105 -105
  153. package/docs/core-concepts/functions/sdk.mdx +184 -184
  154. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  155. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  156. package/docs/core-concepts/storage/architecture.mdx +243 -243
  157. package/docs/core-concepts/storage/sdk.mdx +253 -253
  158. package/docs/deployment/README.md +94 -94
  159. package/docs/deployment/deploy-to-aws-ec2.md +564 -564
  160. package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
  161. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
  162. package/docs/deployment/deploy-to-render.md +441 -441
  163. package/docs/deprecated/insforge-auth-api.md +214 -214
  164. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  165. package/docs/deprecated/insforge-db-api.md +358 -358
  166. package/docs/deprecated/insforge-db-sdk.md +139 -139
  167. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  168. package/docs/deprecated/insforge-debug.md +64 -64
  169. package/docs/deprecated/insforge-instructions.md +123 -123
  170. package/docs/deprecated/insforge-project.md +117 -117
  171. package/docs/deprecated/insforge-storage-api.md +278 -278
  172. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  173. package/docs/docs.json +232 -210
  174. package/docs/examples/framework-guides/nextjs.mdx +131 -131
  175. package/docs/examples/framework-guides/nuxt.mdx +165 -165
  176. package/docs/examples/framework-guides/react.mdx +165 -165
  177. package/docs/examples/framework-guides/svelte.mdx +153 -153
  178. package/docs/examples/framework-guides/vue.mdx +159 -159
  179. package/docs/examples/overview.mdx +67 -67
  180. package/docs/favicon.svg +19 -19
  181. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  182. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  183. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  184. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  185. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  186. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  187. package/docs/images/icons/ai.svg +4 -4
  188. package/docs/images/logos/nextjs.svg +4 -4
  189. package/docs/images/logos/nuxt.svg +4 -4
  190. package/docs/images/logos/react.svg +5 -5
  191. package/docs/images/logos/svelte.svg +4 -4
  192. package/docs/images/logos/vue.svg +5 -5
  193. package/docs/insforge-instructions-sdk.md +89 -88
  194. package/docs/introduction.mdx +45 -45
  195. package/docs/logo/dark.svg +22 -22
  196. package/docs/logo/light.svg +20 -20
  197. package/docs/partnership.mdx +651 -646
  198. package/docs/quickstart.mdx +82 -82
  199. package/docs/showcase.mdx +52 -52
  200. package/docs/snippets/sdk-installation.mdx +21 -21
  201. package/docs/snippets/service-icons.mdx +27 -27
  202. package/examples/oauth/frontend-oauth-example.html +250 -250
  203. package/examples/response-examples.md +443 -443
  204. package/frontend/components.json +17 -17
  205. package/frontend/package.json +69 -69
  206. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  207. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  208. package/frontend/src/assets/icons/checked.svg +3 -3
  209. package/frontend/src/assets/icons/connected.svg +3 -3
  210. package/frontend/src/assets/icons/error.svg +3 -3
  211. package/frontend/src/assets/icons/loader.svg +9 -9
  212. package/frontend/src/assets/icons/pencil.svg +4 -4
  213. package/frontend/src/assets/icons/refresh.svg +4 -4
  214. package/frontend/src/assets/icons/step_active.svg +3 -3
  215. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  216. package/frontend/src/assets/icons/warning.svg +3 -3
  217. package/frontend/src/assets/logos/apple.svg +3 -3
  218. package/frontend/src/assets/logos/claude_code.svg +3 -3
  219. package/frontend/src/assets/logos/cline.svg +6 -6
  220. package/frontend/src/assets/logos/cursor.svg +20 -20
  221. package/frontend/src/assets/logos/discord.svg +8 -8
  222. package/frontend/src/assets/logos/facebook.svg +3 -3
  223. package/frontend/src/assets/logos/gemini.svg +19 -19
  224. package/frontend/src/assets/logos/github.svg +5 -5
  225. package/frontend/src/assets/logos/google.svg +13 -13
  226. package/frontend/src/assets/logos/grok.svg +10 -10
  227. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  228. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  229. package/frontend/src/assets/logos/instagram.svg +1 -1
  230. package/frontend/src/assets/logos/linkedin.svg +3 -3
  231. package/frontend/src/assets/logos/openai.svg +10 -10
  232. package/frontend/src/assets/logos/roo_code.svg +9 -9
  233. package/frontend/src/assets/logos/spotify.svg +16 -16
  234. package/frontend/src/assets/logos/tiktok.svg +5 -5
  235. package/frontend/src/assets/logos/trae.svg +3 -3
  236. package/frontend/src/assets/logos/windsurf.svg +10 -10
  237. package/frontend/src/assets/logos/x.svg +3 -3
  238. package/frontend/src/components/layout/AppHeader.tsx +9 -10
  239. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
  240. package/frontend/src/features/auth/components/UsersDataGrid.tsx +6 -0
  241. package/frontend/src/features/auth/helpers.tsx +8 -0
  242. package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
  243. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  244. package/frontend/src/features/database/components/TableForm.tsx +0 -4
  245. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  246. package/frontend/src/features/database/hooks/useTables.ts +32 -28
  247. package/frontend/src/features/database/index.ts +1 -0
  248. package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -37
  249. package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +35 -47
  250. package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +43 -54
  251. package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
  252. package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +35 -47
  253. package/frontend/src/features/database/services/advance.service.ts +0 -26
  254. package/frontend/src/features/database/services/database.service.ts +55 -0
  255. package/frontend/src/features/database/services/table.service.ts +0 -6
  256. package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
  257. package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +11 -9
  258. package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
  259. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  260. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  261. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  262. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  263. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  264. package/frontend/src/features/realtime/index.ts +11 -0
  265. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  266. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  267. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  268. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  269. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
  270. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +3 -3
  271. package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +1 -35
  272. package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
  273. package/frontend/src/lib/routing/AppRoutes.tsx +35 -20
  274. package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
  275. package/frontend/src/lib/utils/menuItems.ts +24 -0
  276. package/frontend/src/lib/utils/utils.ts +14 -1
  277. package/frontend/tsconfig.json +25 -25
  278. package/frontend/tsconfig.node.json +9 -9
  279. package/functions/deno.json +24 -24
  280. package/functions/server.ts +315 -315
  281. package/i18n/README.ar.md +130 -130
  282. package/i18n/README.de.md +130 -130
  283. package/i18n/README.es.md +154 -154
  284. package/i18n/README.fr.md +134 -134
  285. package/i18n/README.hi.md +129 -129
  286. package/i18n/README.ja.md +174 -174
  287. package/i18n/README.ko.md +136 -136
  288. package/i18n/README.pt-BR.md +131 -131
  289. package/i18n/README.ru.md +129 -129
  290. package/i18n/README.zh-CN.md +133 -133
  291. package/openapi/ai.yaml +715 -715
  292. package/openapi/auth.yaml +1244 -1244
  293. package/openapi/email.yaml +158 -0
  294. package/openapi/functions.yaml +475 -475
  295. package/openapi/health.yaml +29 -29
  296. package/openapi/logs.yaml +223 -223
  297. package/openapi/metadata.yaml +177 -177
  298. package/openapi/realtime.yaml +699 -0
  299. package/openapi/records.yaml +381 -381
  300. package/openapi/secrets.yaml +370 -370
  301. package/openapi/storage.yaml +875 -875
  302. package/openapi/tables.yaml +463 -463
  303. package/package.json +97 -97
  304. package/shared-schemas/package.json +31 -31
  305. package/shared-schemas/src/ai.schema.ts +63 -59
  306. package/shared-schemas/src/auth-api.schema.ts +352 -339
  307. package/shared-schemas/src/auth.schema.ts +1 -1
  308. package/shared-schemas/src/database-api.schema.ts +32 -1
  309. package/shared-schemas/src/database.schema.ts +39 -0
  310. package/shared-schemas/src/docs.schema.ts +26 -0
  311. package/shared-schemas/src/email-api.schema.ts +30 -0
  312. package/shared-schemas/src/index.ts +4 -0
  313. package/shared-schemas/src/metadata.schema.ts +9 -0
  314. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  315. package/shared-schemas/src/realtime.schema.ts +143 -0
  316. package/shared-schemas/tsconfig.json +21 -21
  317. package/tsconfig.json +7 -7
  318. package/zeabur/README.md +13 -13
  319. package/zeabur/template.yml +1032 -1032
  320. package/.cursor/rules/cursor-rules.mdc +0 -94
  321. package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
  322. package/test-gemini.sh +0 -35
  323. package/test-usage-admin.sh +0 -57
  324. package/test-usage.sh +0 -50
  325. /package/frontend/src/features/ai/{page → pages}/AIPage.tsx +0 -0
  326. /package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +0 -0
  327. /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
  328. /package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +0 -0
  329. /package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +0 -0
  330. /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
  331. /package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +0 -0
  332. /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
  333. /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
  334. /package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +0 -0
  335. /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
@@ -1,412 +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
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
412
  exit_with_status