insforge 1.2.10 → 1.4.8

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 (506) 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 +46 -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 +30 -28
  25. package/auth/src/lib/broadcastService.ts +4 -4
  26. package/auth/src/lib/insforge.ts +8 -0
  27. package/auth/src/main.tsx +2 -4
  28. package/auth/src/pages/SignInPage.tsx +5 -2
  29. package/auth/src/pages/SignUpPage.tsx +5 -2
  30. package/auth/src/pages/VerifyEmailPage.tsx +18 -0
  31. package/auth/tsconfig.json +33 -32
  32. package/auth/tsconfig.node.json +11 -11
  33. package/backend/package.json +82 -75
  34. package/backend/src/api/middlewares/rate-limiters.ts +127 -127
  35. package/backend/src/api/routes/ai/index.routes.ts +475 -468
  36. package/backend/src/api/routes/auth/index.routes.ts +720 -570
  37. package/backend/src/api/routes/auth/oauth.routes.ts +478 -448
  38. package/backend/src/api/routes/database/advance.routes.ts +37 -16
  39. package/backend/src/api/routes/database/index.routes.ts +80 -1
  40. package/backend/src/api/routes/database/records.routes.ts +48 -184
  41. package/backend/src/api/routes/database/rpc.routes.ts +69 -0
  42. package/backend/src/api/routes/database/tables.routes.ts +0 -14
  43. package/backend/src/api/routes/deployments/index.routes.ts +192 -0
  44. package/backend/src/api/routes/docs/index.routes.ts +76 -76
  45. package/backend/src/api/routes/email/index.routes.ts +35 -0
  46. package/backend/src/api/routes/functions/index.routes.ts +21 -15
  47. package/backend/src/api/routes/metadata/index.routes.ts +38 -0
  48. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  49. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  50. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  51. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  52. package/backend/src/api/routes/storage/index.routes.ts +18 -12
  53. package/backend/src/api/routes/usage/index.routes.ts +6 -4
  54. package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
  55. package/backend/src/infra/database/database.manager.ts +14 -11
  56. package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
  57. package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
  58. package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
  59. package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
  60. package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
  61. package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
  62. package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
  63. package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
  64. package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
  65. package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
  66. package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
  67. package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
  68. package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
  69. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
  70. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
  71. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
  72. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
  73. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  74. package/backend/src/infra/database/migrations/018_schema-rework.sql +441 -0
  75. package/backend/src/infra/database/migrations/019_create-deployments-table.sql +36 -0
  76. package/backend/src/infra/database/migrations/020_add-audio-modality.sql +11 -0
  77. package/backend/src/infra/database/migrations/bootstrap/bootstrap-migrations.js +103 -0
  78. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  79. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  80. package/backend/src/infra/security/token.manager.ts +216 -125
  81. package/backend/src/infra/socket/socket.manager.ts +198 -64
  82. package/backend/src/providers/ai/openrouter.provider.ts +24 -12
  83. package/backend/src/providers/database/base.provider.ts +39 -0
  84. package/backend/src/providers/database/cloud.provider.ts +159 -0
  85. package/backend/src/providers/deployments/vercel.provider.ts +516 -0
  86. package/backend/src/providers/email/base.provider.ts +4 -7
  87. package/backend/src/providers/email/cloud.provider.ts +84 -0
  88. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  89. package/backend/src/providers/oauth/index.ts +1 -0
  90. package/backend/src/server.ts +329 -284
  91. package/backend/src/services/ai/ai-config.service.ts +6 -6
  92. package/backend/src/services/ai/ai-model.service.ts +60 -60
  93. package/backend/src/services/ai/ai-usage.service.ts +7 -7
  94. package/backend/src/services/ai/chat-completion.service.ts +415 -220
  95. package/backend/src/services/ai/helpers.ts +64 -64
  96. package/backend/src/services/ai/image-generation.service.ts +3 -3
  97. package/backend/src/services/ai/index.ts +13 -13
  98. package/backend/src/services/auth/auth-config.service.ts +4 -4
  99. package/backend/src/services/auth/auth-otp.service.ts +6 -6
  100. package/backend/src/services/auth/auth.service.ts +148 -74
  101. package/backend/src/services/auth/index.ts +4 -4
  102. package/backend/src/services/auth/oauth-config.service.ts +12 -12
  103. package/backend/src/services/database/database-advance.service.ts +19 -55
  104. package/backend/src/services/database/database-table.service.ts +38 -94
  105. package/backend/src/services/database/database.service.ts +127 -0
  106. package/backend/src/services/database/postgrest-proxy.service.ts +165 -0
  107. package/backend/src/services/deployments/deployment.service.ts +693 -0
  108. package/backend/src/services/email/email.service.ts +5 -7
  109. package/backend/src/services/functions/function.service.ts +61 -41
  110. package/backend/src/services/logs/audit.service.ts +10 -10
  111. package/backend/src/services/realtime/index.ts +3 -0
  112. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  113. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  114. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  115. package/backend/src/services/secrets/secret.service.ts +101 -27
  116. package/backend/src/services/storage/storage.service.ts +30 -30
  117. package/backend/src/services/usage/usage.service.ts +6 -6
  118. package/backend/src/types/ai.ts +8 -0
  119. package/backend/src/types/auth.ts +16 -1
  120. package/backend/src/types/database.ts +2 -0
  121. package/backend/src/types/deployments.ts +33 -0
  122. package/backend/src/types/realtime.ts +18 -0
  123. package/backend/src/types/socket.ts +7 -31
  124. package/backend/src/types/storage.ts +1 -1
  125. package/backend/src/types/webhooks.ts +45 -0
  126. package/backend/src/utils/cookies.ts +34 -0
  127. package/backend/src/utils/environment.ts +0 -14
  128. package/backend/src/utils/s3-config-loader.ts +64 -0
  129. package/backend/src/utils/seed.ts +79 -43
  130. package/backend/src/utils/sql-parser.ts +216 -0
  131. package/backend/src/utils/utils.ts +114 -114
  132. package/backend/src/utils/validations.ts +10 -10
  133. package/backend/tests/README.md +133 -133
  134. package/backend/tests/cleanup-all-test-data.sh +230 -230
  135. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  136. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  137. package/backend/tests/local/test-ai-config.sh +129 -129
  138. package/backend/tests/local/test-ai-usage.sh +80 -80
  139. package/backend/tests/local/test-auth-router.sh +143 -143
  140. package/backend/tests/local/test-database-router.sh +222 -222
  141. package/backend/tests/local/test-e2e.sh +240 -240
  142. package/backend/tests/local/test-fk-errors.sh +96 -96
  143. package/backend/tests/local/test-functions.sh +123 -123
  144. package/backend/tests/local/test-id-field.sh +200 -200
  145. package/backend/tests/local/test-logs.sh +132 -132
  146. package/backend/tests/local/test-public-bucket.sh +264 -264
  147. package/backend/tests/local/test-rpc.sh +141 -0
  148. package/backend/tests/local/test-secrets.sh +249 -249
  149. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  150. package/backend/tests/local/test-traditional-rest.sh +208 -208
  151. package/backend/tests/manual/README.md +50 -50
  152. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  153. package/backend/tests/manual/seed-large-table.sql +100 -100
  154. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  155. package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
  156. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  157. package/backend/tests/manual/test-database-advance.sh +296 -296
  158. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  159. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  160. package/backend/tests/manual/test-rawsql-modes.sh +244 -244
  161. package/backend/tests/manual/test-universal-storage.sh +263 -263
  162. package/backend/tests/manual/test-users.sql +17 -17
  163. package/backend/tests/run-all-tests.sh +139 -139
  164. package/backend/tests/setup.ts +0 -0
  165. package/backend/tests/test-config.sh +338 -338
  166. package/backend/tests/unit/analyze-query.test.ts +697 -0
  167. package/backend/tests/unit/database-advance.test.ts +326 -0
  168. package/backend/tests/unit/helpers.test.ts +2 -2
  169. package/backend/tsconfig.json +22 -22
  170. package/claude-plugin/.claude-plugin/plugin.json +24 -24
  171. package/claude-plugin/README.md +133 -133
  172. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +273 -270
  173. package/docker-compose.prod.yml +204 -200
  174. package/docker-compose.yml +232 -228
  175. package/docker-init/db/db-init.sql +97 -97
  176. package/docker-init/db/jwt.sql +5 -5
  177. package/docker-init/db/postgresql.conf +16 -16
  178. package/docker-init/logs/vector.yml +236 -236
  179. package/docs/README.md +44 -44
  180. package/docs/agent-docs/deployment.md +79 -0
  181. package/docs/agent-docs/real-time.md +269 -0
  182. package/docs/changelog.mdx +212 -67
  183. package/docs/core-concepts/ai/architecture.mdx +350 -372
  184. package/docs/core-concepts/ai/sdk.mdx +238 -213
  185. package/docs/core-concepts/authentication/architecture.mdx +276 -278
  186. package/docs/core-concepts/authentication/sdk.mdx +710 -414
  187. package/docs/core-concepts/authentication/ui-components/customization.mdx +733 -529
  188. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +247 -221
  189. package/docs/core-concepts/authentication/ui-components/react-router.mdx +183 -184
  190. package/docs/core-concepts/authentication/ui-components/react.mdx +136 -129
  191. package/docs/core-concepts/database/architecture.mdx +292 -255
  192. package/docs/core-concepts/database/pgvector.mdx +138 -0
  193. package/docs/core-concepts/database/sdk.mdx +382 -382
  194. package/docs/core-concepts/deployments/architecture.mdx +152 -0
  195. package/docs/core-concepts/email/architecture.mdx +103 -0
  196. package/docs/core-concepts/email/sdk.mdx +53 -0
  197. package/docs/core-concepts/functions/architecture.mdx +105 -105
  198. package/docs/core-concepts/functions/sdk.mdx +183 -184
  199. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  200. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  201. package/docs/core-concepts/storage/architecture.mdx +243 -243
  202. package/docs/core-concepts/storage/sdk.mdx +253 -253
  203. package/docs/deployment/README.md +94 -94
  204. package/docs/deployment/deploy-to-aws-ec2.md +564 -564
  205. package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
  206. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
  207. package/docs/deployment/deploy-to-render.md +441 -441
  208. package/docs/deprecated/insforge-auth-api.md +214 -214
  209. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  210. package/docs/deprecated/insforge-db-api.md +358 -358
  211. package/docs/deprecated/insforge-db-sdk.md +139 -139
  212. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  213. package/docs/deprecated/insforge-debug.md +64 -64
  214. package/docs/deprecated/insforge-instructions.md +123 -123
  215. package/docs/deprecated/insforge-project.md +117 -117
  216. package/docs/deprecated/insforge-storage-api.md +278 -278
  217. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  218. package/docs/docs.json +240 -210
  219. package/docs/examples/framework-guides/nextjs.mdx +131 -131
  220. package/docs/examples/framework-guides/nuxt.mdx +165 -165
  221. package/docs/examples/framework-guides/react.mdx +165 -165
  222. package/docs/examples/framework-guides/svelte.mdx +153 -153
  223. package/docs/examples/framework-guides/vue.mdx +159 -159
  224. package/docs/examples/overview.mdx +67 -67
  225. package/docs/favicon.png +0 -0
  226. package/docs/favicon.svg +4 -19
  227. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  228. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  229. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  230. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  231. package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
  232. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  233. package/docs/images/changelog/dec-2025/moreModels.png +0 -0
  234. package/docs/images/changelog/dec-2025/multi-region.webp +0 -0
  235. package/docs/images/changelog/dec-2025/postgres-connection.webp +0 -0
  236. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  237. package/docs/images/changelog/dec-2025/realtime2.png +0 -0
  238. package/docs/images/icons/ai.svg +4 -4
  239. package/docs/images/logos/nextjs.svg +4 -4
  240. package/docs/images/logos/nuxt.svg +4 -4
  241. package/docs/images/logos/react.svg +5 -5
  242. package/docs/images/logos/svelte.svg +4 -4
  243. package/docs/images/logos/vue.svg +5 -5
  244. package/docs/images/mcp-setup/CC-MCP-1.mp4 +0 -0
  245. package/docs/images/mcp-setup/CC-MCP-2.mp4 +0 -0
  246. package/docs/images/mcp-setup/Cursor-MCP-1.mp4 +0 -0
  247. package/docs/images/mcp-setup/Cursor-MCP-2.mp4 +0 -0
  248. package/docs/images/mcp-setup/Cursor-MCP-3.mp4 +0 -0
  249. package/docs/images/mcp-setup/claude-code-connect.png +0 -0
  250. package/docs/images/mcp-setup/cline-1.png +0 -0
  251. package/docs/images/mcp-setup/cline-2.png +0 -0
  252. package/docs/images/mcp-setup/cline-3.png +0 -0
  253. package/docs/images/mcp-setup/connect-project.png +0 -0
  254. package/docs/images/mcp-setup/copilot-1.png +0 -0
  255. package/docs/images/mcp-setup/copilot-2.png +0 -0
  256. package/docs/images/mcp-setup/copilot-3.png +0 -0
  257. package/docs/images/mcp-setup/mcp-json-1.png +0 -0
  258. package/docs/images/mcp-setup/mcp-json-2.png +0 -0
  259. package/docs/images/mcp-setup/qoder-1.png +0 -0
  260. package/docs/images/mcp-setup/qoder-2.png +0 -0
  261. package/docs/images/mcp-setup/roocode-1.png +0 -0
  262. package/docs/images/mcp-setup/roocode-2.png +0 -0
  263. package/docs/images/mcp-setup/trae-1.png +0 -0
  264. package/docs/images/mcp-setup/trae-2.png +0 -0
  265. package/docs/images/mcp-setup/trae-3.png +0 -0
  266. package/docs/images/mcp-setup/trae-4.png +0 -0
  267. package/docs/images/mcp-setup/trae-5.png +0 -0
  268. package/docs/images/mcp-setup/windsurf-1.png +0 -0
  269. package/docs/images/mcp-setup/windsurf-2.png +0 -0
  270. package/docs/insforge-instructions-sdk.md +93 -88
  271. package/docs/introduction.mdx +46 -45
  272. package/docs/logo/dark.svg +22 -22
  273. package/docs/logo/light.svg +20 -20
  274. package/docs/mcp-setup.mdx +332 -0
  275. package/docs/oauth-server.mdx +563 -0
  276. package/docs/partnership.mdx +720 -646
  277. package/docs/quickstart.mdx +82 -82
  278. package/docs/showcase.mdx +52 -52
  279. package/docs/snippets/sdk-installation.mdx +21 -21
  280. package/docs/snippets/service-icons.mdx +27 -27
  281. package/docs/vscode-extension.mdx +74 -0
  282. package/eslint.config.js +1 -0
  283. package/examples/oauth/frontend-oauth-example.html +250 -250
  284. package/examples/response-examples.md +443 -443
  285. package/frontend/components.json +17 -17
  286. package/frontend/package.json +69 -69
  287. package/frontend/src/App.tsx +8 -3
  288. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  289. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  290. package/frontend/src/assets/icons/checked.svg +3 -3
  291. package/frontend/src/assets/icons/connected.svg +3 -3
  292. package/frontend/src/assets/icons/error.svg +3 -3
  293. package/frontend/src/assets/icons/loader.svg +9 -9
  294. package/frontend/src/assets/icons/pencil.svg +4 -4
  295. package/frontend/src/assets/icons/refresh.svg +4 -4
  296. package/frontend/src/assets/icons/step_active.svg +3 -3
  297. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  298. package/frontend/src/assets/icons/warning.svg +3 -3
  299. package/frontend/src/assets/logos/antigravity.svg +1 -0
  300. package/frontend/src/assets/logos/apple.svg +3 -3
  301. package/frontend/src/assets/logos/claude_code.svg +3 -3
  302. package/frontend/src/assets/logos/cline.svg +6 -6
  303. package/frontend/src/assets/logos/copilot.svg +10 -0
  304. package/frontend/src/assets/logos/cursor.svg +20 -20
  305. package/frontend/src/assets/logos/deepseek.svg +139 -0
  306. package/frontend/src/assets/logos/discord.svg +8 -8
  307. package/frontend/src/assets/logos/facebook.svg +3 -3
  308. package/frontend/src/assets/logos/gemini.svg +19 -19
  309. package/frontend/src/assets/logos/github.svg +5 -5
  310. package/frontend/src/assets/logos/google.svg +13 -13
  311. package/frontend/src/assets/logos/grok.svg +10 -10
  312. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  313. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  314. package/frontend/src/assets/logos/instagram.svg +1 -1
  315. package/frontend/src/assets/logos/kiro.svg +9 -0
  316. package/frontend/src/assets/logos/linkedin.svg +3 -3
  317. package/frontend/src/assets/logos/openai.svg +10 -10
  318. package/frontend/src/assets/logos/qoder.svg +4 -0
  319. package/frontend/src/assets/logos/qwen.svg +15 -0
  320. package/frontend/src/assets/logos/roo_code.svg +9 -9
  321. package/frontend/src/assets/logos/spotify.svg +16 -16
  322. package/frontend/src/assets/logos/tiktok.svg +5 -5
  323. package/frontend/src/assets/logos/trae.svg +3 -3
  324. package/frontend/src/assets/logos/windsurf.svg +10 -10
  325. package/frontend/src/assets/logos/x.svg +3 -3
  326. package/frontend/src/components/CodeBlock.tsx +2 -2
  327. package/frontend/src/components/ConnectCTA.tsx +3 -2
  328. package/frontend/src/components/datagrid/DataGrid.tsx +90 -62
  329. package/frontend/src/components/datagrid/datagridTypes.tsx +2 -1
  330. package/frontend/src/components/datagrid/index.ts +1 -1
  331. package/frontend/src/components/index.ts +0 -1
  332. package/frontend/src/components/layout/AppHeader.tsx +13 -37
  333. package/frontend/src/components/layout/AppSidebar.tsx +85 -100
  334. package/frontend/src/components/layout/Layout.tsx +34 -32
  335. package/frontend/src/components/layout/PrimaryMenu.tsx +12 -4
  336. package/frontend/src/components/radix/Select.tsx +151 -151
  337. package/frontend/src/features/ai/components/AIConfigCard.tsx +200 -200
  338. package/frontend/src/features/ai/components/AIEmptyState.tsx +23 -23
  339. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +102 -101
  340. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -135
  341. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -51
  342. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -118
  343. package/frontend/src/features/ai/components/index.ts +6 -6
  344. package/frontend/src/features/ai/helpers.ts +147 -141
  345. package/frontend/src/features/ai/{page → pages}/AIPage.tsx +166 -166
  346. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
  347. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
  348. package/frontend/src/features/auth/components/UsersDataGrid.tsx +61 -31
  349. package/frontend/src/features/auth/components/index.ts +5 -5
  350. package/frontend/src/features/auth/helpers.tsx +8 -0
  351. package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +275 -275
  352. package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
  353. package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +1 -1
  354. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +0 -2
  355. package/frontend/src/features/database/components/ForeignKeyCell.tsx +38 -11
  356. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +18 -8
  357. package/frontend/src/features/database/components/LinkRecordModal.tsx +61 -13
  358. package/frontend/src/features/database/components/RecordFormField.tsx +1 -1
  359. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  360. package/frontend/src/features/database/components/TableForm.tsx +0 -4
  361. package/frontend/src/features/database/components/TableSidebar.tsx +0 -3
  362. package/frontend/src/features/database/components/TablesEmptyState.tsx +1 -1
  363. package/frontend/src/features/database/components/TemplatePreview.tsx +1 -2
  364. package/frontend/src/features/database/constants.ts +16 -28
  365. package/frontend/src/features/database/hooks/useCSVImport.ts +3 -2
  366. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  367. package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
  368. package/frontend/src/features/database/hooks/useTables.ts +30 -28
  369. package/frontend/src/features/database/index.ts +1 -0
  370. package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -42
  371. package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +34 -51
  372. package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +42 -58
  373. package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +2 -2
  374. package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
  375. package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +34 -51
  376. package/frontend/src/features/database/services/advance.service.ts +1 -41
  377. package/frontend/src/features/database/services/database.service.ts +55 -0
  378. package/frontend/src/features/database/services/record.service.ts +4 -20
  379. package/frontend/src/features/database/services/table.service.ts +1 -10
  380. package/frontend/src/features/database/templates/ai-chatbot.ts +6 -6
  381. package/frontend/src/features/database/templates/ecommerce-platform.ts +2 -2
  382. package/frontend/src/features/database/templates/instagram-clone.ts +10 -10
  383. package/frontend/src/features/database/templates/notion-clone.ts +8 -8
  384. package/frontend/src/features/database/templates/reddit-clone.ts +10 -10
  385. package/frontend/src/features/deployments/components/DeploymentRow.tsx +93 -0
  386. package/frontend/src/features/deployments/components/DeploymentsEmptyState.tsx +15 -0
  387. package/frontend/src/features/deployments/hooks/useDeployments.ts +157 -0
  388. package/frontend/src/features/deployments/pages/DeploymentsPage.tsx +318 -0
  389. package/frontend/src/features/deployments/services/deployments.service.ts +63 -0
  390. package/frontend/src/features/functions/components/FunctionRow.tsx +72 -72
  391. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -56
  392. package/frontend/src/features/functions/components/SecretRow.tsx +3 -3
  393. package/frontend/src/features/functions/components/index.ts +5 -5
  394. package/frontend/src/features/functions/hooks/useFunctions.ts +5 -4
  395. package/frontend/src/features/functions/hooks/useSecrets.ts +6 -9
  396. package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
  397. package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +118 -116
  398. package/frontend/src/features/functions/services/function.service.ts +8 -25
  399. package/frontend/src/features/functions/services/secret.service.ts +23 -41
  400. package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +125 -118
  401. package/frontend/src/features/logs/components/LogDetailPanel.tsx +41 -0
  402. package/frontend/src/features/logs/components/LogsDataGrid.tsx +32 -1
  403. package/frontend/src/features/logs/components/index.ts +1 -0
  404. package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
  405. package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +36 -6
  406. package/frontend/src/features/onboard/components/ApiCredentialsSection.tsx +59 -0
  407. package/frontend/src/features/onboard/components/ConnectionStringSection.tsx +180 -0
  408. package/frontend/src/features/onboard/components/McpConnectionSection.tsx +159 -0
  409. package/frontend/src/features/onboard/components/OnboardingController.tsx +68 -0
  410. package/frontend/src/features/onboard/components/OnboardingModal.tsx +121 -267
  411. package/frontend/src/features/onboard/components/ShowPasswordButton.tsx +21 -0
  412. package/frontend/src/features/onboard/components/index.ts +9 -4
  413. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +1 -1
  414. package/frontend/src/features/onboard/components/mcp/QoderDeeplinkGenerator.tsx +36 -0
  415. package/frontend/src/features/onboard/components/mcp/helpers.tsx +123 -98
  416. package/frontend/src/features/onboard/components/mcp/index.ts +4 -3
  417. package/frontend/src/features/onboard/index.ts +17 -13
  418. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  419. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  420. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  421. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  422. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  423. package/frontend/src/features/realtime/index.ts +11 -0
  424. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  425. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  426. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  427. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  428. package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
  429. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
  430. package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
  431. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +24 -11
  432. package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +11 -36
  433. package/frontend/src/index.css +249 -249
  434. package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
  435. package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
  436. package/frontend/src/lib/hooks/useMetadata.ts +45 -1
  437. package/frontend/src/lib/hooks/useModal.tsx +2 -0
  438. package/frontend/src/lib/routing/AppRoutes.tsx +103 -84
  439. package/frontend/src/lib/services/metadata.service.ts +20 -3
  440. package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
  441. package/frontend/src/lib/utils/menuItems.ts +223 -183
  442. package/frontend/src/lib/utils/utils.ts +196 -183
  443. package/frontend/tsconfig.json +25 -25
  444. package/frontend/tsconfig.node.json +9 -9
  445. package/functions/deno.json +24 -24
  446. package/functions/server.ts +6 -6
  447. package/functions/worker-template.js +1 -1
  448. package/i18n/README.ar.md +130 -130
  449. package/i18n/README.de.md +130 -130
  450. package/i18n/README.es.md +154 -154
  451. package/i18n/README.fr.md +134 -134
  452. package/i18n/README.hi.md +129 -129
  453. package/i18n/README.ja.md +174 -174
  454. package/i18n/README.ko.md +136 -136
  455. package/i18n/README.pt-BR.md +131 -131
  456. package/i18n/README.ru.md +129 -129
  457. package/i18n/README.zh-CN.md +133 -133
  458. package/openapi/ai.yaml +825 -715
  459. package/openapi/auth.yaml +1324 -1244
  460. package/openapi/email.yaml +158 -0
  461. package/openapi/functions.yaml +475 -475
  462. package/openapi/health.yaml +29 -29
  463. package/openapi/logs.yaml +221 -223
  464. package/openapi/metadata.yaml +175 -177
  465. package/openapi/realtime.yaml +699 -0
  466. package/openapi/records.yaml +381 -381
  467. package/openapi/secrets.yaml +370 -370
  468. package/openapi/storage.yaml +875 -875
  469. package/openapi/tables.yaml +462 -463
  470. package/package.json +97 -97
  471. package/shared-schemas/package.json +31 -31
  472. package/shared-schemas/src/ai-api.schema.ts +251 -143
  473. package/shared-schemas/src/ai.schema.ts +8 -4
  474. package/shared-schemas/src/auth-api.schema.ts +380 -339
  475. package/shared-schemas/src/auth.schema.ts +18 -11
  476. package/shared-schemas/src/cloud-events.schema.ts +26 -0
  477. package/shared-schemas/src/database-api.schema.ts +32 -1
  478. package/shared-schemas/src/database.schema.ts +39 -0
  479. package/shared-schemas/src/deployments-api.schema.ts +55 -0
  480. package/shared-schemas/src/deployments.schema.ts +30 -0
  481. package/shared-schemas/src/docs.schema.ts +32 -0
  482. package/shared-schemas/src/email-api.schema.ts +30 -0
  483. package/shared-schemas/src/functions-api.schema.ts +13 -4
  484. package/shared-schemas/src/functions.schema.ts +1 -1
  485. package/shared-schemas/src/index.ts +22 -14
  486. package/shared-schemas/src/metadata.schema.ts +39 -4
  487. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  488. package/shared-schemas/src/realtime.schema.ts +143 -0
  489. package/shared-schemas/src/secrets-api.schema.ts +44 -0
  490. package/shared-schemas/src/secrets.schema.ts +15 -0
  491. package/shared-schemas/tsconfig.json +21 -21
  492. package/tsconfig.json +7 -7
  493. package/zeabur/README.md +26 -13
  494. package/zeabur/template.yml +1001 -1032
  495. package/.cursor/rules/cursor-rules.mdc +0 -94
  496. package/backend/src/types/profile.ts +0 -55
  497. package/frontend/src/components/ProjectInfoModal.tsx +0 -128
  498. package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
  499. package/test-gemini.sh +0 -35
  500. package/test-usage-admin.sh +0 -57
  501. package/test-usage.sh +0 -50
  502. /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
  503. /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
  504. /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
  505. /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
  506. /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
@@ -1,7 +1,223 @@
1
1
  import splitSqlQuery from '@databases/split-sql-query';
2
2
  import sql from '@databases/sql';
3
+ import { parseSync, loadModule } from 'libpg-query';
3
4
  import logger from './logger.js';
4
5
 
6
+ let initialized = false;
7
+
8
+ /**
9
+ * Initialize the SQL parser WASM module.
10
+ * Must be called and awaited before using analyzeQuery().
11
+ */
12
+ export async function initSqlParser(): Promise<void> {
13
+ if (initialized) {
14
+ return;
15
+ }
16
+ await loadModule();
17
+ initialized = true;
18
+ logger.info('SQL parser initialized');
19
+ }
20
+
21
+ export interface DatabaseResourceUpdate {
22
+ type: 'tables' | 'table' | 'records' | 'index' | 'trigger' | 'policy' | 'function' | 'extension';
23
+ name?: string;
24
+ }
25
+
26
+ const STMT_TYPES: Record<string, DatabaseResourceUpdate['type']> = {
27
+ InsertStmt: 'records',
28
+ UpdateStmt: 'records',
29
+ DeleteStmt: 'records',
30
+ CreateStmt: 'tables',
31
+ AlterTableStmt: 'table',
32
+ RenameStmt: 'table',
33
+ IndexStmt: 'index',
34
+ CreateTrigStmt: 'trigger',
35
+ CreatePolicyStmt: 'policy',
36
+ AlterPolicyStmt: 'policy',
37
+ CreateFunctionStmt: 'function',
38
+ CreateExtensionStmt: 'extension',
39
+ };
40
+
41
+ const DROP_TYPES: Record<string, DatabaseResourceUpdate['type']> = {
42
+ OBJECT_TABLE: 'tables',
43
+ OBJECT_INDEX: 'index',
44
+ OBJECT_TRIGGER: 'trigger',
45
+ OBJECT_POLICY: 'policy',
46
+ OBJECT_FUNCTION: 'function',
47
+ OBJECT_EXTENSION: 'extension',
48
+ };
49
+
50
+ export function analyzeQuery(query: string): DatabaseResourceUpdate[] {
51
+ try {
52
+ const { stmts } = parseSync(query);
53
+ const changes = stmts
54
+ .map((s: { stmt: Record<string, unknown> }) => extractChange(s.stmt))
55
+ .filter((c: DatabaseResourceUpdate | null): c is DatabaseResourceUpdate => c !== null);
56
+
57
+ // Deduplicate by type+name
58
+ const seen = new Set<string>();
59
+ return changes.filter((c: DatabaseResourceUpdate) => {
60
+ const key = `${c.type}:${c.name ?? ''}`;
61
+ if (seen.has(key)) {
62
+ return false;
63
+ }
64
+ seen.add(key);
65
+ return true;
66
+ });
67
+ } catch (e) {
68
+ logger.warn('SQL parse error:', e);
69
+ return [];
70
+ }
71
+ }
72
+
73
+ function extractChange(stmt: Record<string, unknown>): DatabaseResourceUpdate | null {
74
+ const [stmtType, data] = Object.entries(stmt)[0] as [string, Record<string, unknown>];
75
+
76
+ if (stmtType === 'DropStmt') {
77
+ const type = DROP_TYPES[data.removeType as string];
78
+ return type ? { type } : null;
79
+ }
80
+
81
+ const type = STMT_TYPES[stmtType];
82
+ if (!type) {
83
+ return null;
84
+ }
85
+
86
+ // Only include name for 'table' (ALTER) and 'records' (DML)
87
+ if (type === 'table' || type === 'records') {
88
+ const name = (data.relation as Record<string, unknown>)?.relname as string;
89
+ return { type, name };
90
+ }
91
+
92
+ return { type };
93
+ }
94
+
95
+ /**
96
+ * Extract schema name from a relation/RangeVar node in the AST
97
+ */
98
+ function getSchemaName(relation: Record<string, unknown> | undefined): string | null {
99
+ if (!relation) {
100
+ return null;
101
+ }
102
+
103
+ // Direct schemaname property (for DeleteStmt.relation)
104
+ if (relation.schemaname) {
105
+ return relation.schemaname as string;
106
+ }
107
+
108
+ // RangeVar structure (for TruncateStmt.relations)
109
+ if (relation.RangeVar) {
110
+ const rangeVar = relation.RangeVar as Record<string, unknown>;
111
+ if (rangeVar.schemaname) {
112
+ return rangeVar.schemaname as string;
113
+ }
114
+ }
115
+
116
+ return null;
117
+ }
118
+
119
+ /**
120
+ * Check if a query contains dangerous operations on the auth schema
121
+ * Returns an error message if blocked, null if allowed
122
+ */
123
+ export function checkAuthSchemaOperations(query: string): string | null {
124
+ try {
125
+ const { stmts } = parseSync(query);
126
+
127
+ for (const stmtWrapper of stmts) {
128
+ const stmt = stmtWrapper.stmt as Record<string, unknown>;
129
+ const [stmtType, data] = Object.entries(stmt)[0] as [string, Record<string, unknown>];
130
+
131
+ // Check DELETE statements
132
+ if (stmtType === 'DeleteStmt') {
133
+ const relation = data.relation as Record<string, unknown> | undefined;
134
+ const schemaName = getSchemaName(relation);
135
+ if (schemaName?.toLowerCase() === 'auth') {
136
+ return 'DELETE operations on auth schema are not allowed. User deletion must be done through dedicated authentication APIs.';
137
+ }
138
+ }
139
+
140
+ // Check TRUNCATE statements
141
+ if (stmtType === 'TruncateStmt') {
142
+ const relations = (data.relations as Array<Record<string, unknown>>) || [];
143
+ for (const relation of relations) {
144
+ const schemaName = getSchemaName(relation);
145
+ if (schemaName?.toLowerCase() === 'auth') {
146
+ return 'TRUNCATE operations on auth schema are not allowed. This would delete all users and must be done through dedicated authentication APIs.';
147
+ }
148
+ }
149
+ }
150
+
151
+ // Check DROP statements
152
+ if (stmtType === 'DropStmt') {
153
+ const objects = (data.objects as Array<unknown>) || [];
154
+ for (const obj of objects) {
155
+ if (typeof obj === 'object' && obj !== null) {
156
+ const objRecord = obj as Record<string, unknown>;
157
+ let schemaName: string | null = null;
158
+
159
+ // DROP SCHEMA: direct String object
160
+ if (objRecord.String) {
161
+ const stringObj = objRecord.String as Record<string, unknown>;
162
+ if (stringObj.sval) {
163
+ schemaName = stringObj.sval as string;
164
+ }
165
+ }
166
+ // DROP TABLE/INDEX/VIEW/etc: List with [schema, name] items
167
+ else if (objRecord.List) {
168
+ const list = objRecord.List as Record<string, unknown>;
169
+ const items = (list.items as Array<Record<string, unknown>>) || [];
170
+ // First item is typically the schema name
171
+ if (items.length > 0) {
172
+ const firstItem = items[0];
173
+ if (firstItem.String) {
174
+ const stringObj = firstItem.String as Record<string, unknown>;
175
+ schemaName = stringObj.sval as string;
176
+ }
177
+ }
178
+ }
179
+ // DROP FUNCTION/PROCEDURE: ObjectWithArgs with objname array
180
+ else if (objRecord.ObjectWithArgs) {
181
+ const objectWithArgs = objRecord.ObjectWithArgs as Record<string, unknown>;
182
+ const objname = (objectWithArgs.objname as Array<Record<string, unknown>>) || [];
183
+ // First item is typically the schema name
184
+ if (objname.length > 0) {
185
+ const firstItem = objname[0];
186
+ if (firstItem.String) {
187
+ const stringObj = firstItem.String as Record<string, unknown>;
188
+ schemaName = stringObj.sval as string;
189
+ }
190
+ }
191
+ }
192
+ // DROP TYPE/DOMAIN: TypeName with names array
193
+ else if (objRecord.TypeName) {
194
+ const typeName = objRecord.TypeName as Record<string, unknown>;
195
+ const names = (typeName.names as Array<Record<string, unknown>>) || [];
196
+ // First item is typically the schema name
197
+ if (names.length > 0) {
198
+ const firstItem = names[0];
199
+ if (firstItem.String) {
200
+ const stringObj = firstItem.String as Record<string, unknown>;
201
+ schemaName = stringObj.sval as string;
202
+ }
203
+ }
204
+ }
205
+
206
+ if (schemaName?.toLowerCase() === 'auth') {
207
+ return 'DROP operations on auth schema are not allowed. This would destroy authentication resources and break the system.';
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ return null; // No dangerous operations found
215
+ } catch (parseError) {
216
+ logger.warn('SQL parse error in checkAuthSchemaOperations, letting query through:', parseError);
217
+ return null;
218
+ }
219
+ }
220
+
5
221
  /**
6
222
  * Parse a SQL string into individual statements, properly handling:
7
223
  * - String literals with embedded semicolons
@@ -1,114 +1,114 @@
1
- import crypto from 'crypto';
2
- import { ColumnType, type AuthConfigSchema } from '@insforge/shared-schemas';
3
-
4
- /**
5
- * Generates a user-friendly error message listing all password requirements
6
- * @param config - Authentication configuration with password requirements
7
- * @returns A formatted message listing all enabled password requirements
8
- */
9
- export function getPasswordRequirementsMessage(config: AuthConfigSchema): string {
10
- const requirements: string[] = [];
11
-
12
- requirements.push(`at least ${config.passwordMinLength} characters long`);
13
-
14
- if (config.requireNumber) {
15
- requirements.push('at least one number');
16
- }
17
-
18
- if (config.requireLowercase) {
19
- requirements.push('at least one lowercase letter');
20
- }
21
-
22
- if (config.requireUppercase) {
23
- requirements.push('at least one uppercase letter');
24
- }
25
-
26
- if (config.requireSpecialChar) {
27
- requirements.push('at least one special character');
28
- }
29
-
30
- return `Password must contain ${requirements.join(', ')}`;
31
- }
32
-
33
- export const convertSqlTypeToColumnType = (sqlType: string): ColumnType | string => {
34
- switch (sqlType.toLowerCase()) {
35
- case 'uuid':
36
- return ColumnType.UUID;
37
- case 'timestamptz':
38
- case 'timestamp with time zone':
39
- return ColumnType.DATETIME;
40
- case 'date':
41
- return ColumnType.DATE;
42
- case 'integer':
43
- case 'bigint':
44
- case 'smallint':
45
- case 'int':
46
- case 'int2':
47
- case 'int4':
48
- case 'serial':
49
- case 'serial2':
50
- case 'serial4':
51
- case 'serial8':
52
- case 'smallserial':
53
- case 'bigserial':
54
- return ColumnType.INTEGER;
55
- case 'double precision':
56
- case 'real':
57
- case 'numeric':
58
- case 'float':
59
- case 'float4':
60
- case 'float8':
61
- case 'decimal':
62
- return ColumnType.FLOAT;
63
- case 'boolean':
64
- case 'bool':
65
- return ColumnType.BOOLEAN;
66
- case 'json':
67
- case 'jsonb':
68
- case 'array':
69
- return ColumnType.JSON;
70
- case 'text':
71
- case 'varchar':
72
- case 'char':
73
- case 'character varying':
74
- case 'character':
75
- return ColumnType.STRING;
76
- default:
77
- return sqlType.slice(0, 5);
78
- }
79
- };
80
-
81
- /**
82
- * Generate a UUID v4
83
- * @returns A UUID v4 string
84
- */
85
- export function generateUUID(): string {
86
- return crypto.randomUUID();
87
- }
88
-
89
- /**
90
- * Generate a random numeric string of specified length
91
- * @param length - The length of the numeric string to generate
92
- * @returns A random string containing only digits (0-9)
93
- */
94
- export function generateNumericCode(length: number): string {
95
- // Generate each digit independently
96
- let result = '';
97
- for (let i = 0; i < length; i++) {
98
- result += crypto.randomInt(0, 10).toString();
99
- }
100
-
101
- return result;
102
- }
103
-
104
- /**
105
- * Generate a cryptographically secure random token
106
- * @param bytes - Number of random bytes to generate (default: 32)
107
- * @returns Hex-encoded string (length = bytes * 2 characters)
108
- * @example
109
- * generateSecureToken(32) // Returns 64-character hex string (256 bits entropy)
110
- * generateSecureToken(16) // Returns 32-character hex string (128 bits entropy)
111
- */
112
- export function generateSecureToken(bytes: number = 32): string {
113
- return crypto.randomBytes(bytes).toString('hex');
114
- }
1
+ import crypto from 'crypto';
2
+ import { ColumnType, type AuthConfigSchema } from '@insforge/shared-schemas';
3
+
4
+ /**
5
+ * Generates a user-friendly error message listing all password requirements
6
+ * @param config - Authentication configuration with password requirements
7
+ * @returns A formatted message listing all enabled password requirements
8
+ */
9
+ export function getPasswordRequirementsMessage(config: AuthConfigSchema): string {
10
+ const requirements: string[] = [];
11
+
12
+ requirements.push(`at least ${config.passwordMinLength} characters long`);
13
+
14
+ if (config.requireNumber) {
15
+ requirements.push('at least one number');
16
+ }
17
+
18
+ if (config.requireLowercase) {
19
+ requirements.push('at least one lowercase letter');
20
+ }
21
+
22
+ if (config.requireUppercase) {
23
+ requirements.push('at least one uppercase letter');
24
+ }
25
+
26
+ if (config.requireSpecialChar) {
27
+ requirements.push('at least one special character');
28
+ }
29
+
30
+ return `Password must contain ${requirements.join(', ')}`;
31
+ }
32
+
33
+ export const convertSqlTypeToColumnType = (sqlType: string): ColumnType | string => {
34
+ switch (sqlType.toLowerCase()) {
35
+ case 'uuid':
36
+ return ColumnType.UUID;
37
+ case 'timestamptz':
38
+ case 'timestamp with time zone':
39
+ return ColumnType.DATETIME;
40
+ case 'date':
41
+ return ColumnType.DATE;
42
+ case 'integer':
43
+ case 'bigint':
44
+ case 'smallint':
45
+ case 'int':
46
+ case 'int2':
47
+ case 'int4':
48
+ case 'serial':
49
+ case 'serial2':
50
+ case 'serial4':
51
+ case 'serial8':
52
+ case 'smallserial':
53
+ case 'bigserial':
54
+ return ColumnType.INTEGER;
55
+ case 'double precision':
56
+ case 'real':
57
+ case 'numeric':
58
+ case 'float':
59
+ case 'float4':
60
+ case 'float8':
61
+ case 'decimal':
62
+ return ColumnType.FLOAT;
63
+ case 'boolean':
64
+ case 'bool':
65
+ return ColumnType.BOOLEAN;
66
+ case 'json':
67
+ case 'jsonb':
68
+ case 'array':
69
+ return ColumnType.JSON;
70
+ case 'text':
71
+ case 'varchar':
72
+ case 'char':
73
+ case 'character varying':
74
+ case 'character':
75
+ return ColumnType.STRING;
76
+ default:
77
+ return sqlType.slice(0, 8);
78
+ }
79
+ };
80
+
81
+ /**
82
+ * Generate a UUID v4
83
+ * @returns A UUID v4 string
84
+ */
85
+ export function generateUUID(): string {
86
+ return crypto.randomUUID();
87
+ }
88
+
89
+ /**
90
+ * Generate a random numeric string of specified length
91
+ * @param length - The length of the numeric string to generate
92
+ * @returns A random string containing only digits (0-9)
93
+ */
94
+ export function generateNumericCode(length: number): string {
95
+ // Generate each digit independently
96
+ let result = '';
97
+ for (let i = 0; i < length; i++) {
98
+ result += crypto.randomInt(0, 10).toString();
99
+ }
100
+
101
+ return result;
102
+ }
103
+
104
+ /**
105
+ * Generate a cryptographically secure random token
106
+ * @param bytes - Number of random bytes to generate (default: 32)
107
+ * @returns Hex-encoded string (length = bytes * 2 characters)
108
+ * @example
109
+ * generateSecureToken(32) // Returns 64-character hex string (256 bits entropy)
110
+ * generateSecureToken(16) // Returns 32-character hex string (128 bits entropy)
111
+ */
112
+ export function generateSecureToken(bytes: number = 32): string {
113
+ return crypto.randomBytes(bytes).toString('hex');
114
+ }
@@ -100,17 +100,17 @@ export function isValidIdentifier(identifier: string): boolean {
100
100
  */
101
101
  export function validateTableName(tableName: string): boolean {
102
102
  validateIdentifier(tableName, 'table');
103
+ return true;
104
+ }
103
105
 
104
- // Prevent access to all other system tables (starting with _)
105
- if (tableName.startsWith('_')) {
106
- throw new AppError(
107
- 'Access to system tables is not allowed',
108
- 403,
109
- ERROR_CODES.FORBIDDEN,
110
- 'System tables (starting with _) cannot be accessed directly'
111
- );
112
- }
113
-
106
+ /**
107
+ * Validates PostgreSQL function name for RPC calls
108
+ * @param functionName - The function name to validate
109
+ * @returns true if valid
110
+ * @throws AppError if invalid
111
+ */
112
+ export function validateFunctionName(functionName: string): boolean {
113
+ validateIdentifier(functionName, 'function');
114
114
  return true;
115
115
  }
116
116