insforge 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/.dockerignore +58 -0
  2. package/.env.example +49 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.yml +79 -0
  6. package/.github/copilot-instructions.md +147 -0
  7. package/.github/workflows/build-image.yml +65 -0
  8. package/.github/workflows/ci-premerge-check.yml +24 -0
  9. package/.github/workflows/deploy-aws.yml +130 -0
  10. package/.github/workflows/lint-and-format.yml +33 -0
  11. package/.prettierignore +65 -0
  12. package/.prettierrc +9 -0
  13. package/CHANGELOG.md +3 -0
  14. package/CONTRIBUTING.md +126 -0
  15. package/Dockerfile +27 -0
  16. package/GITHUB_OAUTH_SETUP.md +49 -0
  17. package/GOOGLE_OAUTH_SETUP.md +148 -0
  18. package/LICENSE +201 -0
  19. package/README.md +134 -0
  20. package/assets/Dark.svg +23 -0
  21. package/assets/archDiagram.png +0 -0
  22. package/assets/banner.png +0 -0
  23. package/assets/mcpInstallv2.png +0 -0
  24. package/assets/sampleResponse.png +0 -0
  25. package/assets/signin.png +0 -0
  26. package/assets/userflow.png +0 -0
  27. package/backend/migrations/000_create-base-tables.sql +142 -0
  28. package/backend/migrations/001_create-helper-functions.sql +41 -0
  29. package/backend/migrations/002_rename-auth-tables.sql +30 -0
  30. package/backend/migrations/003_create-users-table.sql +56 -0
  31. package/backend/migrations/004_add-reload-postgrest-func.sql +24 -0
  32. package/backend/migrations/005_enable-project-admin-modify-users.sql +30 -0
  33. package/backend/migrations/006_modify-ai-usage-table.sql +25 -0
  34. package/backend/migrations/007_drop-metadata-table.sql +2 -0
  35. package/backend/migrations/008_add-system-tables.sql +77 -0
  36. package/backend/migrations/009_add-function-secrets.sql +24 -0
  37. package/backend/migrations/010_modify-ai-config-modalities.sql +93 -0
  38. package/backend/migrations/011_refactor-secrets-table.sql +15 -0
  39. package/backend/migrations/012_add-storage-uploaded-by.sql +8 -0
  40. package/backend/package.json +75 -0
  41. package/backend/src/api/middleware/auth.ts +240 -0
  42. package/backend/src/api/middleware/error.ts +231 -0
  43. package/backend/src/api/middleware/upload.ts +59 -0
  44. package/backend/src/api/routes/agent.ts +29 -0
  45. package/backend/src/api/routes/ai.ts +472 -0
  46. package/backend/src/api/routes/auth.oauth.ts +482 -0
  47. package/backend/src/api/routes/auth.ts +386 -0
  48. package/backend/src/api/routes/database.advance.ts +275 -0
  49. package/backend/src/api/routes/database.records.ts +246 -0
  50. package/backend/src/api/routes/database.tables.ts +161 -0
  51. package/backend/src/api/routes/docs.ts +66 -0
  52. package/backend/src/api/routes/functions.ts +183 -0
  53. package/backend/src/api/routes/logs.ts +150 -0
  54. package/backend/src/api/routes/metadata.ts +160 -0
  55. package/backend/src/api/routes/openapi.ts +82 -0
  56. package/backend/src/api/routes/secrets.ts +199 -0
  57. package/backend/src/api/routes/storage.ts +547 -0
  58. package/backend/src/api/routes/usage.ts +96 -0
  59. package/backend/src/core/ai/chat.ts +207 -0
  60. package/backend/src/core/ai/client.ts +242 -0
  61. package/backend/src/core/ai/config.ts +187 -0
  62. package/backend/src/core/ai/image.ts +156 -0
  63. package/backend/src/core/ai/model.ts +117 -0
  64. package/backend/src/core/ai/usage.ts +290 -0
  65. package/backend/src/core/auth/auth.ts +781 -0
  66. package/backend/src/core/auth/oauth.ts +398 -0
  67. package/backend/src/core/database/advance.ts +1074 -0
  68. package/backend/src/core/database/manager.ts +178 -0
  69. package/backend/src/core/database/table.ts +772 -0
  70. package/backend/src/core/documentation/agent.ts +689 -0
  71. package/backend/src/core/documentation/openapi.ts +856 -0
  72. package/backend/src/core/functions/functions.ts +310 -0
  73. package/backend/src/core/logs/analytics.ts +76 -0
  74. package/backend/src/core/logs/audit.ts +255 -0
  75. package/backend/src/core/logs/providers/base.provider.ts +83 -0
  76. package/backend/src/core/logs/providers/cloudwatch.provider.ts +510 -0
  77. package/backend/src/core/logs/providers/localdb.provider.ts +246 -0
  78. package/backend/src/core/secrets/encryption.ts +58 -0
  79. package/backend/src/core/secrets/secrets.ts +410 -0
  80. package/backend/src/core/socket/socket.ts +388 -0
  81. package/backend/src/core/socket/types.ts +79 -0
  82. package/backend/src/core/storage/storage.ts +923 -0
  83. package/backend/src/server.ts +288 -0
  84. package/backend/src/types/ai.ts +46 -0
  85. package/backend/src/types/auth.ts +90 -0
  86. package/backend/src/types/database.ts +136 -0
  87. package/backend/src/types/error-constants.ts +86 -0
  88. package/backend/src/types/logs.ts +47 -0
  89. package/backend/src/types/profile.ts +55 -0
  90. package/backend/src/types/storage.ts +23 -0
  91. package/backend/src/utils/cloud-token.ts +39 -0
  92. package/backend/src/utils/constants.ts +1 -0
  93. package/backend/src/utils/environment.ts +35 -0
  94. package/backend/src/utils/helpers.ts +49 -0
  95. package/backend/src/utils/logger.ts +13 -0
  96. package/backend/src/utils/response.ts +62 -0
  97. package/backend/src/utils/seed.ts +205 -0
  98. package/backend/src/utils/sql-parser.ts +63 -0
  99. package/backend/src/utils/uuid.ts +9 -0
  100. package/backend/src/utils/validations.ts +129 -0
  101. package/backend/tests/README.md +134 -0
  102. package/backend/tests/cleanup-all-test-data.sh +231 -0
  103. package/backend/tests/cloud/test-s3-multitenant.sh +132 -0
  104. package/backend/tests/local/comprehensive-curl-tests.sh +156 -0
  105. package/backend/tests/local/test-auth-router.sh +144 -0
  106. package/backend/tests/local/test-database-router.sh +222 -0
  107. package/backend/tests/local/test-e2e.sh +241 -0
  108. package/backend/tests/local/test-fk-errors.sh +97 -0
  109. package/backend/tests/local/test-id-field.sh +201 -0
  110. package/backend/tests/local/test-public-bucket.sh +265 -0
  111. package/backend/tests/local/test-secrets.sh +248 -0
  112. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -0
  113. package/backend/tests/local/test-traditional-rest.sh +209 -0
  114. package/backend/tests/manual/README.md +51 -0
  115. package/backend/tests/manual/create-large-table-simple.sql +11 -0
  116. package/backend/tests/manual/seed-large-table.sql +101 -0
  117. package/backend/tests/manual/setup-large-table-extras.sql +34 -0
  118. package/backend/tests/manual/test-better-auth.sh +303 -0
  119. package/backend/tests/manual/test-bulk-upsert.sh +410 -0
  120. package/backend/tests/manual/test-database-advance.sh +297 -0
  121. package/backend/tests/manual/test-postgrest-stability.sh +192 -0
  122. package/backend/tests/manual/test-rawsql-export-import.sh +412 -0
  123. package/backend/tests/manual/test-universal-storage.sh +264 -0
  124. package/backend/tests/manual/test-users.sql +18 -0
  125. package/backend/tests/run-all-tests.sh +140 -0
  126. package/backend/tests/setup.ts +22 -0
  127. package/backend/tests/test-config.sh +303 -0
  128. package/backend/tsconfig.json +23 -0
  129. package/backend/tsup.config.ts +18 -0
  130. package/backend/vitest.config.ts +22 -0
  131. package/docker-compose.prod.yml +145 -0
  132. package/docker-compose.yml +167 -0
  133. package/docker-init/db/db-init.sql +125 -0
  134. package/docker-init/db/jwt.sql +5 -0
  135. package/docker-init/db/logs.sql +9 -0
  136. package/docker-init/db/postgresql.conf +17 -0
  137. package/docs/deprecated/insforge-auth-api.md +215 -0
  138. package/docs/deprecated/insforge-auth-sdk.md +100 -0
  139. package/docs/deprecated/insforge-db-api.md +359 -0
  140. package/docs/deprecated/insforge-db-sdk.md +140 -0
  141. package/docs/deprecated/insforge-debug-sdk.md +157 -0
  142. package/docs/deprecated/insforge-debug.md +65 -0
  143. package/docs/deprecated/insforge-instructions.md +124 -0
  144. package/docs/deprecated/insforge-project.md +118 -0
  145. package/docs/deprecated/insforge-storage-api.md +279 -0
  146. package/docs/deprecated/insforge-storage-sdk.md +159 -0
  147. package/docs/insforge-instructions-sdk.md +407 -0
  148. package/eslint.config.js +317 -0
  149. package/examples/oauth/frontend-oauth-example.html +251 -0
  150. package/examples/response-examples.md +444 -0
  151. package/frontend/README.md +112 -0
  152. package/frontend/components.json +17 -0
  153. package/frontend/index.html +13 -0
  154. package/frontend/package.json +63 -0
  155. package/frontend/public/favicon.ico +0 -0
  156. package/frontend/src/App.tsx +106 -0
  157. package/frontend/src/assets/icons/checkbox_checked.svg +6 -0
  158. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -0
  159. package/frontend/src/assets/icons/checked.svg +3 -0
  160. package/frontend/src/assets/icons/error.svg +3 -0
  161. package/frontend/src/assets/icons/pencil.svg +4 -0
  162. package/frontend/src/assets/icons/refresh.svg +4 -0
  163. package/frontend/src/assets/icons/step_active.svg +3 -0
  164. package/frontend/src/assets/icons/step_inactive.svg +11 -0
  165. package/frontend/src/assets/icons/warning.svg +3 -0
  166. package/frontend/src/assets/logos/amazon.svg +1 -0
  167. package/frontend/src/assets/logos/claude_code.svg +3 -0
  168. package/frontend/src/assets/logos/cline.svg +6 -0
  169. package/frontend/src/assets/logos/cursor.svg +20 -0
  170. package/frontend/src/assets/logos/discord.svg +9 -0
  171. package/frontend/src/assets/logos/gemini.svg +19 -0
  172. package/frontend/src/assets/logos/github.svg +5 -0
  173. package/frontend/src/assets/logos/google.svg +13 -0
  174. package/frontend/src/assets/logos/grok.svg +10 -0
  175. package/frontend/src/assets/logos/insforge_dark.svg +15 -0
  176. package/frontend/src/assets/logos/insforge_light.svg +15 -0
  177. package/frontend/src/assets/logos/openai.svg +10 -0
  178. package/frontend/src/assets/logos/roo_code.svg +9 -0
  179. package/frontend/src/assets/logos/trae.svg +3 -0
  180. package/frontend/src/assets/logos/windsurf.svg +10 -0
  181. package/frontend/src/components/ButtonWithLoading.tsx +27 -0
  182. package/frontend/src/components/Checkbox.tsx +61 -0
  183. package/frontend/src/components/CodeBlock.tsx +32 -0
  184. package/frontend/src/components/ConfirmDialog.tsx +96 -0
  185. package/frontend/src/components/CopyButton.tsx +69 -0
  186. package/frontend/src/components/DeleteActionButton.tsx +42 -0
  187. package/frontend/src/components/EmptyState.tsx +41 -0
  188. package/frontend/src/components/ErrorState.tsx +35 -0
  189. package/frontend/src/components/FeatureSidebar.tsx +126 -0
  190. package/frontend/src/components/FeatureSidebarItem.tsx +101 -0
  191. package/frontend/src/components/JsonHighlight.tsx +61 -0
  192. package/frontend/src/components/LoadingState.tsx +16 -0
  193. package/frontend/src/components/PaginationControls.tsx +54 -0
  194. package/frontend/src/components/PromptDialog.tsx +68 -0
  195. package/frontend/src/components/SearchInput.tsx +90 -0
  196. package/frontend/src/components/SelectionClearButton.tsx +26 -0
  197. package/frontend/src/components/Stepper.tsx +139 -0
  198. package/frontend/src/components/ThemeToggle.tsx +58 -0
  199. package/frontend/src/components/TypeBadge.tsx +20 -0
  200. package/frontend/src/components/datagrid/DataGrid.tsx +264 -0
  201. package/frontend/src/components/datagrid/DefaultCellRenderer.tsx +114 -0
  202. package/frontend/src/components/datagrid/IdCell.tsx +44 -0
  203. package/frontend/src/components/datagrid/SortableHeader.tsx +74 -0
  204. package/frontend/src/components/datagrid/cell-editors/BooleanCellEditor.tsx +54 -0
  205. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +483 -0
  206. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +362 -0
  207. package/frontend/src/components/datagrid/cell-editors/TextCellEditor.tsx +38 -0
  208. package/frontend/src/components/datagrid/cell-editors/index.ts +14 -0
  209. package/frontend/src/components/datagrid/cell-editors/types.ts +43 -0
  210. package/frontend/src/components/datagrid/datagridTypes.tsx +72 -0
  211. package/frontend/src/components/datagrid/index.tsx +20 -0
  212. package/frontend/src/components/index.ts +39 -0
  213. package/frontend/src/components/layout/AppHeader.tsx +146 -0
  214. package/frontend/src/components/layout/AppSidebar.tsx +190 -0
  215. package/frontend/src/components/layout/CloudLayout.tsx +95 -0
  216. package/frontend/src/components/layout/Layout.tsx +43 -0
  217. package/frontend/src/components/radix/Alert.tsx +45 -0
  218. package/frontend/src/components/radix/AlertDialog.tsx +115 -0
  219. package/frontend/src/components/radix/Avatar.tsx +45 -0
  220. package/frontend/src/components/radix/Badge.tsx +33 -0
  221. package/frontend/src/components/radix/Button.tsx +50 -0
  222. package/frontend/src/components/radix/Card.tsx +58 -0
  223. package/frontend/src/components/radix/Dialog.tsx +98 -0
  224. package/frontend/src/components/radix/DropdownMenu.tsx +185 -0
  225. package/frontend/src/components/radix/Form.tsx +167 -0
  226. package/frontend/src/components/radix/Input.tsx +22 -0
  227. package/frontend/src/components/radix/Label.tsx +19 -0
  228. package/frontend/src/components/radix/Popover.tsx +29 -0
  229. package/frontend/src/components/radix/ScrollArea.tsx +44 -0
  230. package/frontend/src/components/radix/Select.tsx +151 -0
  231. package/frontend/src/components/radix/Separator.tsx +26 -0
  232. package/frontend/src/components/radix/Sheet.tsx +119 -0
  233. package/frontend/src/components/radix/Skeleton.tsx +7 -0
  234. package/frontend/src/components/radix/Switch.tsx +29 -0
  235. package/frontend/src/components/radix/Tabs.tsx +50 -0
  236. package/frontend/src/components/radix/Textarea.tsx +21 -0
  237. package/frontend/src/components/radix/Tooltip.tsx +28 -0
  238. package/frontend/src/features/ai/components/AIConfigCard.tsx +154 -0
  239. package/frontend/src/features/ai/components/AIConfigDialog.tsx +76 -0
  240. package/frontend/src/features/ai/components/AIConfigForm.tsx +222 -0
  241. package/frontend/src/features/ai/components/AIEmptyState.tsx +18 -0
  242. package/frontend/src/features/ai/components/fields/ModalityField.tsx +87 -0
  243. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +134 -0
  244. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +33 -0
  245. package/frontend/src/features/ai/helpers.ts +155 -0
  246. package/frontend/src/features/ai/hooks/useAIConfigs.ts +221 -0
  247. package/frontend/src/features/ai/hooks/useAIUsage.ts +77 -0
  248. package/frontend/src/features/ai/page/AIPage.tsx +178 -0
  249. package/frontend/src/features/ai/services/ai.service.ts +148 -0
  250. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +106 -0
  251. package/frontend/src/features/auth/components/AuthMethodTab.tsx +238 -0
  252. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +303 -0
  253. package/frontend/src/features/auth/components/OAuthEmptyState.tsx +15 -0
  254. package/frontend/src/features/auth/components/UserFormDialog.tsx +248 -0
  255. package/frontend/src/features/auth/components/UsersDataGrid.tsx +183 -0
  256. package/frontend/src/features/auth/components/UsersTab.tsx +114 -0
  257. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +129 -0
  258. package/frontend/src/features/auth/hooks/useUsers.ts +57 -0
  259. package/frontend/src/features/auth/index.ts +9 -0
  260. package/frontend/src/features/auth/page/AuthenticationPage.tsx +169 -0
  261. package/frontend/src/features/auth/services/auth.service.ts +112 -0
  262. package/frontend/src/features/auth/services/oauth.service.ts +49 -0
  263. package/frontend/src/features/dashboard/page/DashboardPage.tsx +194 -0
  264. package/frontend/src/features/database/components/ColumnTypeSelect.tsx +64 -0
  265. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +282 -0
  266. package/frontend/src/features/database/components/ForeignKeyCell.tsx +187 -0
  267. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +378 -0
  268. package/frontend/src/features/database/components/LinkRecordModal.tsx +288 -0
  269. package/frontend/src/features/database/components/RecordFormDialog.tsx +164 -0
  270. package/frontend/src/features/database/components/RecordFormField.tsx +568 -0
  271. package/frontend/src/features/database/components/TableEmptyState.tsx +21 -0
  272. package/frontend/src/features/database/components/TableForm.tsx +656 -0
  273. package/frontend/src/features/database/components/TableFormColumn.tsx +137 -0
  274. package/frontend/src/features/database/components/TableListSkeleton.tsx +9 -0
  275. package/frontend/src/features/database/components/TableSidebar.tsx +47 -0
  276. package/frontend/src/features/database/constants.ts +26 -0
  277. package/frontend/src/features/database/helpers.ts +125 -0
  278. package/frontend/src/features/database/hooks/UseLinkModal.tsx +78 -0
  279. package/frontend/src/features/database/index.ts +12 -0
  280. package/frontend/src/features/database/page/DatabasePage.tsx +626 -0
  281. package/frontend/src/features/database/schema.ts +25 -0
  282. package/frontend/src/features/database/services/database.service.ts +216 -0
  283. package/frontend/src/features/functions/components/FunctionEmptyState.tsx +15 -0
  284. package/frontend/src/features/functions/components/FunctionRow.tsx +71 -0
  285. package/frontend/src/features/functions/components/FunctionViewer.tsx +46 -0
  286. package/frontend/src/features/functions/components/FunctionsContent.tsx +88 -0
  287. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -0
  288. package/frontend/src/features/functions/components/SecretEmptyState.tsx +23 -0
  289. package/frontend/src/features/functions/components/SecretRow.tsx +68 -0
  290. package/frontend/src/features/functions/components/SecretsContent.tsx +120 -0
  291. package/frontend/src/features/functions/hooks/useFunctions.ts +106 -0
  292. package/frontend/src/features/functions/page/FunctionsPage.tsx +28 -0
  293. package/frontend/src/features/functions/services/functions.service.ts +48 -0
  294. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +87 -0
  295. package/frontend/src/features/login/components/PrivateRoute.tsx +24 -0
  296. package/frontend/src/features/login/page/CloudLoginPage.tsx +93 -0
  297. package/frontend/src/features/login/page/LoginPage.tsx +174 -0
  298. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +313 -0
  299. package/frontend/src/features/logs/components/LogsTable.tsx +199 -0
  300. package/frontend/src/features/logs/hooks/useAuditLogs.ts +39 -0
  301. package/frontend/src/features/logs/index.ts +5 -0
  302. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +530 -0
  303. package/frontend/src/features/logs/page/AuditsPage.tsx +192 -0
  304. package/frontend/src/features/logs/services/log.service.ts +171 -0
  305. package/frontend/src/features/metadata/hooks/useMetadata.ts +53 -0
  306. package/frontend/src/features/metadata/index.ts +0 -0
  307. package/frontend/src/features/metadata/page/MetadataPage.tsx +136 -0
  308. package/frontend/src/features/metadata/services/metadata.service.ts +17 -0
  309. package/frontend/src/features/onboard/components/CompletionCard.tsx +41 -0
  310. package/frontend/src/features/onboard/components/OnboardButton.tsx +84 -0
  311. package/frontend/src/features/onboard/components/StepContent.tsx +91 -0
  312. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +53 -0
  313. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +35 -0
  314. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +144 -0
  315. package/frontend/src/features/onboard/components/mcp/index.ts +4 -0
  316. package/frontend/src/features/onboard/components/mcp/mcp-helper.tsx +98 -0
  317. package/frontend/src/features/onboard/index.ts +3 -0
  318. package/frontend/src/features/onboard/page/OnBoardPage.tsx +104 -0
  319. package/frontend/src/features/onboard/types.ts +8 -0
  320. package/frontend/src/features/secrets/hooks/useSecrets.ts +139 -0
  321. package/frontend/src/features/secrets/services/secrets.service.ts +57 -0
  322. package/frontend/src/features/storage/components/BucketEmptyState.tsx +19 -0
  323. package/frontend/src/features/storage/components/BucketFormDialog.tsx +194 -0
  324. package/frontend/src/features/storage/components/BucketListSkeleton.tsx +17 -0
  325. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +287 -0
  326. package/frontend/src/features/storage/components/StorageDataGrid.tsx +239 -0
  327. package/frontend/src/features/storage/components/StorageManager.tsx +236 -0
  328. package/frontend/src/features/storage/components/StorageSidebar.tsx +44 -0
  329. package/frontend/src/features/storage/components/UploadToast.tsx +46 -0
  330. package/frontend/src/features/storage/index.ts +3 -0
  331. package/frontend/src/features/storage/page/StoragePage.tsx +553 -0
  332. package/frontend/src/features/storage/services/storage.service.ts +144 -0
  333. package/frontend/src/features/visualizer/components/AuthNode.tsx +107 -0
  334. package/frontend/src/features/visualizer/components/BucketNode.tsx +34 -0
  335. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +359 -0
  336. package/frontend/src/features/visualizer/components/TableNode.tsx +152 -0
  337. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +24 -0
  338. package/frontend/src/features/visualizer/components/index.ts +5 -0
  339. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +127 -0
  340. package/frontend/src/index.css +248 -0
  341. package/frontend/src/lib/api/client.ts +163 -0
  342. package/frontend/src/lib/contexts/AuthContext.tsx +157 -0
  343. package/frontend/src/lib/contexts/OnboardStepContext.tsx +68 -0
  344. package/frontend/src/lib/contexts/SocketContext.tsx +303 -0
  345. package/frontend/src/lib/contexts/ThemeContext.tsx +125 -0
  346. package/frontend/src/lib/hooks/useAuth.ts +4 -0
  347. package/frontend/src/lib/hooks/useConfirm.ts +55 -0
  348. package/frontend/src/lib/hooks/useInterval.ts +27 -0
  349. package/frontend/src/lib/hooks/useMediaQuery.ts +59 -0
  350. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +29 -0
  351. package/frontend/src/lib/hooks/usePagination.ts +27 -0
  352. package/frontend/src/lib/hooks/useTimeout.ts +27 -0
  353. package/frontend/src/lib/hooks/useToast.tsx +229 -0
  354. package/frontend/src/lib/utils/constants.ts +38 -0
  355. package/frontend/src/lib/utils/utils.ts +165 -0
  356. package/frontend/src/lib/utils/validation-schemas.ts +126 -0
  357. package/frontend/src/main.tsx +16 -0
  358. package/frontend/src/rdg.css +194 -0
  359. package/frontend/src/vite-env.d.ts +12 -0
  360. package/frontend/tailwind.config.js +97 -0
  361. package/frontend/tsconfig.json +26 -0
  362. package/frontend/tsconfig.node.json +10 -0
  363. package/frontend/vite.config.ts +37 -0
  364. package/frontend/vitest.config.ts +36 -0
  365. package/functions/deno.json +25 -0
  366. package/functions/server.ts +290 -0
  367. package/functions/worker-template.js +126 -0
  368. package/openapi/ai.yaml +689 -0
  369. package/openapi/auth.yaml +563 -0
  370. package/openapi/functions.yaml +476 -0
  371. package/openapi/health.yaml +30 -0
  372. package/openapi/logs.yaml +224 -0
  373. package/openapi/metadata.yaml +178 -0
  374. package/openapi/records.yaml +382 -0
  375. package/openapi/secrets.yaml +371 -0
  376. package/openapi/storage.yaml +876 -0
  377. package/openapi/tables.yaml +464 -0
  378. package/package.json +88 -0
  379. package/shared-schemas/package.json +31 -0
  380. package/shared-schemas/src/ai-api.schema.ts +167 -0
  381. package/shared-schemas/src/ai.schema.ts +54 -0
  382. package/shared-schemas/src/auth-api.schema.ts +193 -0
  383. package/shared-schemas/src/auth.schema.ts +94 -0
  384. package/shared-schemas/src/database-api.schema.ts +259 -0
  385. package/shared-schemas/src/database.schema.ts +69 -0
  386. package/shared-schemas/src/functions-api.schema.ts +25 -0
  387. package/shared-schemas/src/functions.schema.ts +16 -0
  388. package/shared-schemas/src/index.ts +13 -0
  389. package/shared-schemas/src/logs-api.schema.ts +49 -0
  390. package/shared-schemas/src/logs.schema.ts +14 -0
  391. package/shared-schemas/src/metadata.schema.ts +56 -0
  392. package/shared-schemas/src/storage-api.schema.ts +65 -0
  393. package/shared-schemas/src/storage.schema.ts +19 -0
  394. package/shared-schemas/tsconfig.json +21 -0
  395. package/tsconfig.json +8 -0
@@ -0,0 +1,398 @@
1
+ import { Pool } from 'pg';
2
+ import { DatabaseManager } from '@/core/database/manager.js';
3
+ import { SecretsService } from '@/core/secrets/secrets.js';
4
+ import { AppError } from '@/api/middleware/error.js';
5
+ import { ERROR_CODES } from '@/types/error-constants.js';
6
+ import logger from '@/utils/logger.js';
7
+ import { OAuthConfigSchema } from '@insforge/shared-schemas';
8
+
9
+ export interface CreateOAuthConfigInput {
10
+ provider: string;
11
+ clientId?: string;
12
+ clientSecret?: string;
13
+ redirectUri?: string;
14
+ scopes?: string[];
15
+ useSharedKey?: boolean;
16
+ }
17
+
18
+ export interface UpdateOAuthConfigInput {
19
+ clientId?: string;
20
+ clientSecret?: string;
21
+ redirectUri?: string;
22
+ scopes?: string[];
23
+ useSharedKey?: boolean;
24
+ }
25
+
26
+ export class OAuthConfigService {
27
+ private static instance: OAuthConfigService;
28
+ private pool: Pool | null = null;
29
+ private secretsService: SecretsService;
30
+
31
+ private constructor() {
32
+ this.secretsService = new SecretsService();
33
+ logger.info('OAuthService initialized');
34
+ }
35
+
36
+ public static getInstance(): OAuthConfigService {
37
+ if (!OAuthConfigService.instance) {
38
+ OAuthConfigService.instance = new OAuthConfigService();
39
+ }
40
+ return OAuthConfigService.instance;
41
+ }
42
+
43
+ private getPool(): Pool {
44
+ if (!this.pool) {
45
+ this.pool = DatabaseManager.getInstance().getPool();
46
+ }
47
+ return this.pool;
48
+ }
49
+
50
+ /**
51
+ * Get all OAuth configurations
52
+ */
53
+ async getAllConfigs(): Promise<OAuthConfigSchema[]> {
54
+ const client = await this.getPool().connect();
55
+ try {
56
+ const result = await client.query(
57
+ `SELECT
58
+ provider,
59
+ client_id as "clientId",
60
+ redirect_uri as "redirectUri",
61
+ scopes,
62
+ use_shared_key as "useSharedKey"
63
+ FROM _oauth_configs
64
+ ORDER BY provider ASC`
65
+ );
66
+
67
+ return result.rows;
68
+ } catch (error) {
69
+ logger.error('Failed to get OAuth configs', { error });
70
+ throw new AppError('Failed to get OAuth configurations', 500, ERROR_CODES.INTERNAL_ERROR);
71
+ } finally {
72
+ client.release();
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Get OAuth configuration by provider name
78
+ */
79
+ async getConfigByProvider(provider: string): Promise<OAuthConfigSchema | null> {
80
+ const client = await this.getPool().connect();
81
+ try {
82
+ const result = await client.query(
83
+ `SELECT
84
+ provider,
85
+ client_id as "clientId",
86
+ redirect_uri as "redirectUri",
87
+ scopes,
88
+ use_shared_key as "useSharedKey"
89
+ FROM _oauth_configs
90
+ WHERE LOWER(provider) = LOWER($1)
91
+ LIMIT 1`,
92
+ [provider]
93
+ );
94
+
95
+ if (result.rows.length === 0) {
96
+ return null;
97
+ }
98
+
99
+ return result.rows[0];
100
+ } catch (error) {
101
+ logger.error('Failed to get OAuth config by provider', { error, provider });
102
+ throw new AppError('Failed to get OAuth configuration', 500, ERROR_CODES.INTERNAL_ERROR);
103
+ } finally {
104
+ client.release();
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Get OAuth provider secret
110
+ */
111
+ async getClientSecretByProvider(provider: string): Promise<string | null> {
112
+ const client = await this.getPool().connect();
113
+ try {
114
+ const result = await client.query(
115
+ `SELECT
116
+ secret_id as "secretId"
117
+ FROM _oauth_configs
118
+ WHERE LOWER(provider) = LOWER($1)
119
+ LIMIT 1`,
120
+ [provider]
121
+ );
122
+
123
+ if (result.rows.length === 0) {
124
+ return null;
125
+ }
126
+
127
+ const config = result.rows[0];
128
+ const clientSecret = await this.secretsService.getSecretById(config.secretId);
129
+ if (!clientSecret) {
130
+ logger.warn('OAuth config exists but secret not found', { provider });
131
+ return null;
132
+ }
133
+
134
+ return clientSecret;
135
+ } catch (error) {
136
+ logger.error('Failed to get OAuth config with secret', { error, provider });
137
+ throw new AppError('Failed to get OAuth configuration', 500, ERROR_CODES.INTERNAL_ERROR);
138
+ } finally {
139
+ client.release();
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Create OAuth configuration
145
+ */
146
+ async createConfig(input: CreateOAuthConfigInput): Promise<OAuthConfigSchema> {
147
+ const client = await this.getPool().connect();
148
+ try {
149
+ await client.query('BEGIN');
150
+
151
+ // Check if config already exists for this provider
152
+ const existingConfig = await client.query(
153
+ 'SELECT id FROM _oauth_configs WHERE LOWER(provider) = LOWER($1)',
154
+ [input.provider]
155
+ );
156
+
157
+ if (existingConfig.rows.length > 0) {
158
+ throw new AppError(
159
+ `OAuth configuration for ${input.provider} already exists`,
160
+ 409,
161
+ ERROR_CODES.ALREADY_EXISTS
162
+ );
163
+ }
164
+
165
+ let secretId: string | null = null;
166
+
167
+ // Only create secret if clientSecret is provided and not using shared key
168
+ if (input.clientSecret && !input.useSharedKey) {
169
+ // Create new secret
170
+ const secret = await this.secretsService.createSecret({
171
+ key: `${input.provider.toUpperCase()}_CLIENT_SECRET`,
172
+ value: input.clientSecret,
173
+ });
174
+ secretId = secret.id;
175
+ }
176
+
177
+ // Set default scopes if not provided
178
+ let scopes = input.scopes;
179
+ if (!scopes) {
180
+ const provider = input.provider.toLowerCase();
181
+ if (provider === 'google') {
182
+ scopes = ['openid', 'email', 'profile'];
183
+ } else if (provider === 'github') {
184
+ scopes = ['user:email'];
185
+ }
186
+ }
187
+
188
+ // Create new OAuth config
189
+ const result = await client.query(
190
+ `INSERT INTO _oauth_configs (provider, client_id, secret_id, redirect_uri, scopes, use_shared_key)
191
+ VALUES ($1, $2, $3, $4, $5, $6)
192
+ RETURNING
193
+ provider,
194
+ client_id as "clientId",
195
+ redirect_uri as "redirectUri",
196
+ scopes,
197
+ use_shared_key as "useSharedKey"`,
198
+ [
199
+ input.provider.toLowerCase(),
200
+ input.clientId || null,
201
+ secretId,
202
+ null, // Deprecating redirect_uri
203
+ scopes,
204
+ input.useSharedKey || false,
205
+ ]
206
+ );
207
+
208
+ await client.query('COMMIT');
209
+ logger.info('OAuth config created', { provider: input.provider });
210
+
211
+ return result.rows[0];
212
+ } catch (error) {
213
+ await client.query('ROLLBACK');
214
+ logger.error('Failed to create OAuth config', { error, provider: input.provider });
215
+ if (error instanceof AppError) {
216
+ throw error;
217
+ }
218
+ throw new AppError('Failed to create OAuth configuration', 500, ERROR_CODES.INTERNAL_ERROR);
219
+ } finally {
220
+ client.release();
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Update OAuth configuration
226
+ */
227
+ async updateConfig(provider: string, input: UpdateOAuthConfigInput): Promise<OAuthConfigSchema> {
228
+ const client = await this.getPool().connect();
229
+ try {
230
+ await client.query('BEGIN');
231
+
232
+ // Get existing config with secret_id
233
+ const existingResult = await client.query(
234
+ `SELECT id, secret_id as "secretId" FROM _oauth_configs WHERE LOWER(provider) = LOWER($1)`,
235
+ [provider]
236
+ );
237
+
238
+ if (existingResult.rows.length === 0) {
239
+ throw new AppError('OAuth configuration not found', 404, ERROR_CODES.NOT_FOUND);
240
+ }
241
+
242
+ const existingConfig = existingResult.rows[0];
243
+
244
+ // Update or create secret if provided
245
+ if (input.clientSecret !== undefined) {
246
+ if (existingConfig.secretId) {
247
+ // Update existing secret
248
+ await this.secretsService.updateSecret(existingConfig.secretId, {
249
+ value: input.clientSecret,
250
+ });
251
+ } else {
252
+ // Create new secret if it doesn't exist
253
+ const secret = await this.secretsService.createSecret({
254
+ key: `${provider.toUpperCase()}_CLIENT_SECRET`,
255
+ value: input.clientSecret,
256
+ });
257
+ // Add secret_id to the update query
258
+ await client.query(`UPDATE _oauth_configs SET secret_id = $1 WHERE id = $2`, [
259
+ secret.id,
260
+ existingConfig.id,
261
+ ]);
262
+ }
263
+ }
264
+
265
+ // Build update query
266
+ const updates: string[] = [];
267
+ const values: (string | string[] | boolean | null)[] = [];
268
+ let paramCount = 1;
269
+
270
+ if (input.clientId !== undefined) {
271
+ updates.push(`client_id = $${paramCount++}`);
272
+ values.push(input.clientId);
273
+ }
274
+
275
+ if (input.redirectUri !== undefined) {
276
+ updates.push(`redirect_uri = $${paramCount++}`);
277
+ values.push(input.redirectUri);
278
+ }
279
+
280
+ if (input.scopes !== undefined) {
281
+ updates.push(`scopes = $${paramCount++}`);
282
+ values.push(input.scopes);
283
+ }
284
+
285
+ if (input.useSharedKey !== undefined) {
286
+ updates.push(`use_shared_key = $${paramCount++}`);
287
+ values.push(input.useSharedKey);
288
+ }
289
+
290
+ if (updates.length === 0 && input.clientSecret === undefined) {
291
+ await client.query('COMMIT');
292
+ // Return the config in the correct format
293
+ const config = await this.getConfigByProvider(provider);
294
+ if (!config) {
295
+ throw new AppError('Failed to retrieve configuration', 500, ERROR_CODES.INTERNAL_ERROR);
296
+ }
297
+ return config;
298
+ }
299
+
300
+ if (updates.length > 0) {
301
+ updates.push('updated_at = NOW()');
302
+ values.push(provider.toLowerCase());
303
+
304
+ const result = await client.query(
305
+ `UPDATE _oauth_configs
306
+ SET ${updates.join(', ')}
307
+ WHERE LOWER(provider) = $${paramCount}
308
+ RETURNING
309
+ provider,
310
+ client_id as "clientId",
311
+ redirect_uri as "redirectUri",
312
+ scopes,
313
+ use_shared_key as "useSharedKey"`,
314
+ values
315
+ );
316
+
317
+ await client.query('COMMIT');
318
+ logger.info('OAuth config updated', { provider });
319
+ return result.rows[0];
320
+ } else {
321
+ // Only secret was updated
322
+ await client.query('COMMIT');
323
+ const updatedConfig = await this.getConfigByProvider(provider);
324
+ if (!updatedConfig) {
325
+ throw new AppError(
326
+ 'Failed to retrieve updated configuration',
327
+ 500,
328
+ ERROR_CODES.INTERNAL_ERROR
329
+ );
330
+ }
331
+ return updatedConfig;
332
+ }
333
+ } catch (error) {
334
+ await client.query('ROLLBACK');
335
+ logger.error('Failed to update OAuth config', { error, provider });
336
+ if (error instanceof AppError) {
337
+ throw error;
338
+ }
339
+ throw new AppError('Failed to update OAuth configuration', 500, ERROR_CODES.INTERNAL_ERROR);
340
+ } finally {
341
+ client.release();
342
+ }
343
+ }
344
+
345
+ /**
346
+ * Delete OAuth configuration
347
+ */
348
+ async deleteConfig(provider: string): Promise<boolean> {
349
+ const client = await this.getPool().connect();
350
+ try {
351
+ await client.query('BEGIN');
352
+
353
+ // Get existing config with secret_id
354
+ const existingResult = await client.query(
355
+ `SELECT id, secret_id as "secretId" FROM _oauth_configs WHERE LOWER(provider) = LOWER($1)`,
356
+ [provider]
357
+ );
358
+
359
+ if (existingResult.rows.length === 0) {
360
+ await client.query('ROLLBACK');
361
+ return false;
362
+ }
363
+
364
+ const existingConfig = existingResult.rows[0];
365
+
366
+ // Delete OAuth config (secret will be restricted due to foreign key)
367
+ const result = await client.query(
368
+ 'DELETE FROM _oauth_configs WHERE LOWER(provider) = LOWER($1)',
369
+ [provider]
370
+ );
371
+
372
+ // Try to delete the associated secret (will fail if still referenced)
373
+ try {
374
+ await client.query('DELETE FROM _secrets WHERE id = $1', [existingConfig.secretId]);
375
+ logger.info('Associated secret deleted', { secretId: existingConfig.secretId });
376
+ } catch {
377
+ logger.warn('Could not delete associated secret, it may be in use elsewhere', {
378
+ provider,
379
+ secretId: existingConfig.secretId,
380
+ });
381
+ }
382
+
383
+ await client.query('COMMIT');
384
+
385
+ const success = (result.rowCount ?? 0) > 0;
386
+ if (success) {
387
+ logger.info('OAuth config deleted', { provider });
388
+ }
389
+ return success;
390
+ } catch (error) {
391
+ await client.query('ROLLBACK');
392
+ logger.error('Failed to delete OAuth config', { error, provider });
393
+ throw new AppError('Failed to delete OAuth configuration', 500, ERROR_CODES.INTERNAL_ERROR);
394
+ } finally {
395
+ client.release();
396
+ }
397
+ }
398
+ }