insforge 1.3.0 → 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 (269) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/auth/package.json +5 -3
  3. package/auth/src/lib/broadcastService.ts +115 -117
  4. package/auth/src/lib/insforge.ts +8 -0
  5. package/auth/src/main.tsx +2 -4
  6. package/auth/src/pages/SignInPage.tsx +60 -60
  7. package/auth/src/pages/SignUpPage.tsx +60 -60
  8. package/auth/src/pages/VerifyEmailPage.tsx +18 -0
  9. package/auth/tsconfig.json +2 -1
  10. package/backend/package.json +10 -6
  11. package/backend/src/api/middlewares/rate-limiters.ts +127 -127
  12. package/backend/src/api/routes/ai/index.routes.ts +475 -468
  13. package/backend/src/api/routes/auth/index.routes.ts +85 -32
  14. package/backend/src/api/routes/auth/oauth.routes.ts +11 -6
  15. package/backend/src/api/routes/database/index.routes.ts +2 -0
  16. package/backend/src/api/routes/database/records.routes.ts +39 -175
  17. package/backend/src/api/routes/database/rpc.routes.ts +69 -0
  18. package/backend/src/api/routes/deployments/index.routes.ts +192 -0
  19. package/backend/src/api/routes/docs/index.routes.ts +3 -2
  20. package/backend/src/api/routes/email/index.routes.ts +35 -35
  21. package/backend/src/api/routes/functions/index.routes.ts +3 -3
  22. package/backend/src/api/routes/metadata/index.routes.ts +26 -0
  23. package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
  24. package/backend/src/infra/database/database.manager.ts +0 -10
  25. package/backend/src/infra/database/migrations/018_schema-rework.sql +441 -0
  26. package/backend/src/infra/database/migrations/019_create-deployments-table.sql +36 -0
  27. package/backend/src/infra/database/migrations/020_add-audio-modality.sql +11 -0
  28. package/backend/src/infra/database/migrations/bootstrap/bootstrap-migrations.js +103 -0
  29. package/backend/src/infra/security/token.manager.ts +1 -4
  30. package/backend/src/providers/ai/openrouter.provider.ts +12 -3
  31. package/backend/src/providers/database/base.provider.ts +39 -0
  32. package/backend/src/providers/database/cloud.provider.ts +159 -0
  33. package/backend/src/providers/deployments/vercel.provider.ts +516 -0
  34. package/backend/src/server.ts +19 -7
  35. package/backend/src/services/ai/ai-config.service.ts +6 -6
  36. package/backend/src/services/ai/ai-model.service.ts +60 -60
  37. package/backend/src/services/ai/ai-usage.service.ts +7 -7
  38. package/backend/src/services/ai/chat-completion.service.ts +415 -220
  39. package/backend/src/services/ai/helpers.ts +64 -64
  40. package/backend/src/services/ai/index.ts +13 -13
  41. package/backend/src/services/auth/auth-config.service.ts +4 -4
  42. package/backend/src/services/auth/auth-otp.service.ts +6 -6
  43. package/backend/src/services/auth/auth.service.ts +134 -74
  44. package/backend/src/services/auth/index.ts +4 -4
  45. package/backend/src/services/auth/oauth-config.service.ts +12 -12
  46. package/backend/src/services/database/database-advance.service.ts +19 -55
  47. package/backend/src/services/database/database-table.service.ts +38 -85
  48. package/backend/src/services/database/postgrest-proxy.service.ts +165 -0
  49. package/backend/src/services/deployments/deployment.service.ts +693 -0
  50. package/backend/src/services/functions/function.service.ts +61 -41
  51. package/backend/src/services/logs/audit.service.ts +10 -10
  52. package/backend/src/services/secrets/secret.service.ts +101 -27
  53. package/backend/src/services/storage/storage.service.ts +30 -30
  54. package/backend/src/services/usage/usage.service.ts +6 -6
  55. package/backend/src/types/ai.ts +8 -0
  56. package/backend/src/types/auth.ts +5 -1
  57. package/backend/src/types/database.ts +2 -0
  58. package/backend/src/types/deployments.ts +33 -0
  59. package/backend/src/types/storage.ts +1 -1
  60. package/backend/src/types/webhooks.ts +45 -0
  61. package/backend/src/utils/cookies.ts +34 -35
  62. package/backend/src/utils/environment.ts +0 -14
  63. package/backend/src/utils/s3-config-loader.ts +64 -64
  64. package/backend/src/utils/seed.ts +334 -301
  65. package/backend/src/utils/sql-parser.ts +126 -0
  66. package/backend/src/utils/utils.ts +114 -114
  67. package/backend/src/utils/validations.ts +10 -10
  68. package/backend/tests/local/test-rpc.sh +141 -0
  69. package/backend/tests/local/test-secrets.sh +1 -1
  70. package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
  71. package/backend/tests/manual/test-rawsql-modes.sh +24 -24
  72. package/backend/tests/unit/database-advance.test.ts +326 -0
  73. package/backend/tests/unit/helpers.test.ts +2 -2
  74. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +13 -10
  75. package/docker-compose.prod.yml +1 -1
  76. package/docker-compose.yml +1 -1
  77. package/docs/agent-docs/deployment.md +79 -0
  78. package/docs/changelog.mdx +165 -72
  79. package/docs/core-concepts/ai/architecture.mdx +1 -23
  80. package/docs/core-concepts/ai/sdk.mdx +26 -1
  81. package/docs/core-concepts/authentication/architecture.mdx +6 -8
  82. package/docs/core-concepts/authentication/sdk.mdx +387 -91
  83. package/docs/core-concepts/authentication/ui-components/customization.mdx +460 -256
  84. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +50 -24
  85. package/docs/core-concepts/authentication/ui-components/react-router.mdx +18 -19
  86. package/docs/core-concepts/authentication/ui-components/react.mdx +26 -19
  87. package/docs/core-concepts/database/architecture.mdx +58 -21
  88. package/docs/core-concepts/database/pgvector.mdx +138 -0
  89. package/docs/core-concepts/database/sdk.mdx +17 -17
  90. package/docs/core-concepts/deployments/architecture.mdx +152 -0
  91. package/docs/core-concepts/email/architecture.mdx +4 -2
  92. package/docs/core-concepts/functions/architecture.mdx +1 -1
  93. package/docs/core-concepts/functions/sdk.mdx +0 -1
  94. package/docs/core-concepts/realtime/architecture.mdx +1 -1
  95. package/docs/core-concepts/storage/architecture.mdx +1 -1
  96. package/docs/core-concepts/storage/sdk.mdx +25 -25
  97. package/docs/docs.json +14 -6
  98. package/docs/favicon.png +0 -0
  99. package/docs/favicon.svg +3 -18
  100. package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
  101. package/docs/images/changelog/dec-2025/moreModels.png +0 -0
  102. package/docs/images/changelog/dec-2025/multi-region.webp +0 -0
  103. package/docs/images/changelog/dec-2025/postgres-connection.webp +0 -0
  104. package/docs/images/changelog/dec-2025/realtime2.png +0 -0
  105. package/docs/images/mcp-setup/CC-MCP-1.mp4 +0 -0
  106. package/docs/images/mcp-setup/CC-MCP-2.mp4 +0 -0
  107. package/docs/images/mcp-setup/Cursor-MCP-1.mp4 +0 -0
  108. package/docs/images/mcp-setup/Cursor-MCP-2.mp4 +0 -0
  109. package/docs/images/mcp-setup/Cursor-MCP-3.mp4 +0 -0
  110. package/docs/images/mcp-setup/claude-code-connect.png +0 -0
  111. package/docs/images/mcp-setup/cline-1.png +0 -0
  112. package/docs/images/mcp-setup/cline-2.png +0 -0
  113. package/docs/images/mcp-setup/cline-3.png +0 -0
  114. package/docs/images/mcp-setup/connect-project.png +0 -0
  115. package/docs/images/mcp-setup/copilot-1.png +0 -0
  116. package/docs/images/mcp-setup/copilot-2.png +0 -0
  117. package/docs/images/mcp-setup/copilot-3.png +0 -0
  118. package/docs/images/mcp-setup/mcp-json-1.png +0 -0
  119. package/docs/images/mcp-setup/mcp-json-2.png +0 -0
  120. package/docs/images/mcp-setup/qoder-1.png +0 -0
  121. package/docs/images/mcp-setup/qoder-2.png +0 -0
  122. package/docs/images/mcp-setup/roocode-1.png +0 -0
  123. package/docs/images/mcp-setup/roocode-2.png +0 -0
  124. package/docs/images/mcp-setup/trae-1.png +0 -0
  125. package/docs/images/mcp-setup/trae-2.png +0 -0
  126. package/docs/images/mcp-setup/trae-3.png +0 -0
  127. package/docs/images/mcp-setup/trae-4.png +0 -0
  128. package/docs/images/mcp-setup/trae-5.png +0 -0
  129. package/docs/images/mcp-setup/windsurf-1.png +0 -0
  130. package/docs/images/mcp-setup/windsurf-2.png +0 -0
  131. package/docs/insforge-instructions-sdk.md +7 -3
  132. package/docs/introduction.mdx +9 -8
  133. package/docs/mcp-setup.mdx +332 -0
  134. package/docs/oauth-server.mdx +563 -0
  135. package/docs/partnership.mdx +79 -10
  136. package/docs/quickstart.mdx +1 -1
  137. package/docs/vscode-extension.mdx +74 -0
  138. package/eslint.config.js +1 -0
  139. package/examples/response-examples.md +1 -1
  140. package/frontend/package.json +1 -1
  141. package/frontend/src/App.tsx +8 -3
  142. package/frontend/src/assets/logos/antigravity.svg +1 -0
  143. package/frontend/src/assets/logos/copilot.svg +10 -0
  144. package/frontend/src/assets/logos/deepseek.svg +139 -0
  145. package/frontend/src/assets/logos/kiro.svg +9 -0
  146. package/frontend/src/assets/logos/qoder.svg +4 -0
  147. package/frontend/src/assets/logos/qwen.svg +15 -0
  148. package/frontend/src/components/CodeBlock.tsx +2 -2
  149. package/frontend/src/components/ConnectCTA.tsx +3 -2
  150. package/frontend/src/components/datagrid/DataGrid.tsx +90 -62
  151. package/frontend/src/components/datagrid/datagridTypes.tsx +2 -1
  152. package/frontend/src/components/datagrid/index.ts +1 -1
  153. package/frontend/src/components/index.ts +0 -1
  154. package/frontend/src/components/layout/AppHeader.tsx +4 -27
  155. package/frontend/src/components/layout/AppSidebar.tsx +85 -100
  156. package/frontend/src/components/layout/Layout.tsx +34 -32
  157. package/frontend/src/components/layout/PrimaryMenu.tsx +12 -4
  158. package/frontend/src/components/radix/Select.tsx +151 -151
  159. package/frontend/src/features/ai/components/AIConfigCard.tsx +200 -200
  160. package/frontend/src/features/ai/components/AIEmptyState.tsx +23 -23
  161. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +102 -101
  162. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -135
  163. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -51
  164. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -118
  165. package/frontend/src/features/ai/components/index.ts +6 -6
  166. package/frontend/src/features/ai/helpers.ts +147 -141
  167. package/frontend/src/features/ai/pages/AIPage.tsx +166 -166
  168. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
  169. package/frontend/src/features/auth/components/UsersDataGrid.tsx +55 -31
  170. package/frontend/src/features/auth/components/index.ts +5 -5
  171. package/frontend/src/features/auth/pages/AuthMethodsPage.tsx +275 -275
  172. package/frontend/src/features/dashboard/pages/DashboardPage.tsx +1 -1
  173. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +0 -2
  174. package/frontend/src/features/database/components/ForeignKeyCell.tsx +38 -11
  175. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +18 -8
  176. package/frontend/src/features/database/components/LinkRecordModal.tsx +61 -13
  177. package/frontend/src/features/database/components/RecordFormField.tsx +1 -1
  178. package/frontend/src/features/database/components/TableSidebar.tsx +0 -3
  179. package/frontend/src/features/database/components/TablesEmptyState.tsx +1 -1
  180. package/frontend/src/features/database/components/TemplatePreview.tsx +1 -2
  181. package/frontend/src/features/database/constants.ts +16 -28
  182. package/frontend/src/features/database/hooks/useCSVImport.ts +3 -2
  183. package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
  184. package/frontend/src/features/database/hooks/useTables.ts +5 -7
  185. package/frontend/src/features/database/pages/FunctionsPage.tsx +0 -5
  186. package/frontend/src/features/database/pages/IndexesPage.tsx +0 -5
  187. package/frontend/src/features/database/pages/PoliciesPage.tsx +0 -5
  188. package/frontend/src/features/database/pages/SQLEditorPage.tsx +2 -2
  189. package/frontend/src/features/database/pages/TriggersPage.tsx +0 -5
  190. package/frontend/src/features/database/services/advance.service.ts +1 -15
  191. package/frontend/src/features/database/services/record.service.ts +4 -20
  192. package/frontend/src/features/database/services/table.service.ts +1 -4
  193. package/frontend/src/features/database/templates/ai-chatbot.ts +6 -6
  194. package/frontend/src/features/database/templates/ecommerce-platform.ts +2 -2
  195. package/frontend/src/features/database/templates/instagram-clone.ts +10 -10
  196. package/frontend/src/features/database/templates/notion-clone.ts +8 -8
  197. package/frontend/src/features/database/templates/reddit-clone.ts +10 -10
  198. package/frontend/src/features/deployments/components/DeploymentRow.tsx +93 -0
  199. package/frontend/src/features/deployments/components/DeploymentsEmptyState.tsx +15 -0
  200. package/frontend/src/features/deployments/hooks/useDeployments.ts +157 -0
  201. package/frontend/src/features/deployments/pages/DeploymentsPage.tsx +318 -0
  202. package/frontend/src/features/deployments/services/deployments.service.ts +63 -0
  203. package/frontend/src/features/functions/components/FunctionRow.tsx +72 -72
  204. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -56
  205. package/frontend/src/features/functions/components/SecretRow.tsx +3 -3
  206. package/frontend/src/features/functions/components/index.ts +5 -5
  207. package/frontend/src/features/functions/hooks/useFunctions.ts +5 -4
  208. package/frontend/src/features/functions/hooks/useSecrets.ts +6 -9
  209. package/frontend/src/features/functions/pages/SecretsPage.tsx +118 -118
  210. package/frontend/src/features/functions/services/function.service.ts +8 -25
  211. package/frontend/src/features/functions/services/secret.service.ts +23 -41
  212. package/frontend/src/features/login/pages/CloudLoginPage.tsx +125 -118
  213. package/frontend/src/features/logs/components/LogDetailPanel.tsx +41 -0
  214. package/frontend/src/features/logs/components/LogsDataGrid.tsx +32 -1
  215. package/frontend/src/features/logs/components/index.ts +1 -0
  216. package/frontend/src/features/logs/pages/LogsPage.tsx +36 -6
  217. package/frontend/src/features/onboard/components/ApiCredentialsSection.tsx +59 -0
  218. package/frontend/src/features/onboard/components/ConnectionStringSection.tsx +180 -0
  219. package/frontend/src/features/onboard/components/McpConnectionSection.tsx +159 -0
  220. package/frontend/src/features/onboard/components/OnboardingController.tsx +68 -0
  221. package/frontend/src/features/onboard/components/OnboardingModal.tsx +121 -267
  222. package/frontend/src/features/onboard/components/ShowPasswordButton.tsx +21 -0
  223. package/frontend/src/features/onboard/components/index.ts +9 -4
  224. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +1 -1
  225. package/frontend/src/features/onboard/components/mcp/QoderDeeplinkGenerator.tsx +36 -0
  226. package/frontend/src/features/onboard/components/mcp/helpers.tsx +123 -98
  227. package/frontend/src/features/onboard/components/mcp/index.ts +4 -3
  228. package/frontend/src/features/onboard/index.ts +17 -13
  229. package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
  230. package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
  231. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +21 -8
  232. package/frontend/src/features/visualizer/pages/VisualizerPage.tsx +10 -1
  233. package/frontend/src/index.css +249 -249
  234. package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
  235. package/frontend/src/lib/hooks/useMetadata.ts +45 -1
  236. package/frontend/src/lib/hooks/useModal.tsx +2 -0
  237. package/frontend/src/lib/routing/AppRoutes.tsx +103 -99
  238. package/frontend/src/lib/services/metadata.service.ts +20 -3
  239. package/frontend/src/lib/utils/menuItems.ts +223 -207
  240. package/frontend/src/lib/utils/utils.ts +196 -196
  241. package/functions/server.ts +315 -315
  242. package/functions/worker-template.js +1 -1
  243. package/openapi/ai.yaml +115 -5
  244. package/openapi/auth.yaml +97 -17
  245. package/openapi/logs.yaml +0 -2
  246. package/openapi/metadata.yaml +0 -2
  247. package/openapi/records.yaml +21 -21
  248. package/openapi/tables.yaml +1 -2
  249. package/package.json +1 -1
  250. package/shared-schemas/package.json +1 -1
  251. package/shared-schemas/src/ai-api.schema.ts +251 -143
  252. package/shared-schemas/src/ai.schema.ts +63 -63
  253. package/shared-schemas/src/auth-api.schema.ts +34 -6
  254. package/shared-schemas/src/auth.schema.ts +17 -10
  255. package/shared-schemas/src/cloud-events.schema.ts +26 -0
  256. package/shared-schemas/src/deployments-api.schema.ts +55 -0
  257. package/shared-schemas/src/deployments.schema.ts +30 -0
  258. package/shared-schemas/src/docs.schema.ts +8 -2
  259. package/shared-schemas/src/email-api.schema.ts +30 -30
  260. package/shared-schemas/src/functions-api.schema.ts +13 -4
  261. package/shared-schemas/src/functions.schema.ts +1 -1
  262. package/shared-schemas/src/index.ts +22 -18
  263. package/shared-schemas/src/metadata.schema.ts +30 -4
  264. package/shared-schemas/src/secrets-api.schema.ts +44 -0
  265. package/shared-schemas/src/secrets.schema.ts +15 -0
  266. package/zeabur/README.md +13 -0
  267. package/zeabur/template.yml +20 -51
  268. package/backend/src/types/profile.ts +0 -55
  269. package/frontend/src/components/ProjectInfoModal.tsx +0 -128
@@ -1,143 +1,251 @@
1
- import { z } from 'zod';
2
- import { aiConfigurationSchema, aiUsageRecordSchema, modalitySchema } from './ai.schema';
3
-
4
- // ============= Chat Completion Schemas =============
5
-
6
- // OpenAI-compatible content schemas
7
- export const textContentSchema = z.object({
8
- type: z.literal('text'),
9
- text: z.string(),
10
- });
11
-
12
- export const imageContentSchema = z.object({
13
- type: z.literal('image_url'),
14
- // eslint-disable-next-line @typescript-eslint/naming-convention
15
- image_url: z.object({
16
- // URL can be either a public URL or base64-encoded data URI
17
- // Examples:
18
- // - Public URL: "https://example.com/image.jpg"
19
- // - Base64: "data:image/jpeg;base64,/9j/4AAQ..."
20
- url: z.string(),
21
- detail: z.enum(['auto', 'low', 'high']).optional(),
22
- }),
23
- });
24
-
25
- export const contentSchema = z.union([textContentSchema, imageContentSchema]);
26
-
27
- // Chat message supports both OpenAI format and legacy format for backward compatibility
28
- export const chatMessageSchema = z.object({
29
- role: z.enum(['user', 'assistant', 'system']),
30
- // New format: content can be string or array of content parts (OpenAI-compatible)
31
- content: z.union([z.string(), z.array(contentSchema)]),
32
- // Legacy format: separate images field (deprecated but supported for backward compatibility)
33
- images: z.array(z.object({ url: z.string() })).optional(),
34
- });
35
-
36
- export const chatCompletionRequestSchema = z.object({
37
- model: z.string(),
38
- messages: z.array(chatMessageSchema),
39
- temperature: z.number().min(0).max(2).optional(),
40
- maxTokens: z.number().positive().optional(),
41
- topP: z.number().min(0).max(1).optional(),
42
- stream: z.boolean().optional(),
43
- });
44
-
45
- export const chatCompletionResponseSchema = z.object({
46
- text: z.string(),
47
- metadata: z
48
- .object({
49
- model: z.string(),
50
- usage: z
51
- .object({
52
- promptTokens: z.number().optional(),
53
- completionTokens: z.number().optional(),
54
- totalTokens: z.number().optional(),
55
- })
56
- .optional(),
57
- })
58
- .optional(),
59
- });
60
-
61
- // ============= Image Generation Schemas =============
62
-
63
- export const imageGenerationRequestSchema = z.object({
64
- model: z.string(),
65
- prompt: z.string(),
66
- images: z
67
- .array(
68
- z.object({
69
- url: z.string(),
70
- })
71
- )
72
- .optional(),
73
- });
74
-
75
- export const imageGenerationResponseSchema = z.object({
76
- text: z.string().optional(),
77
- images: z.array(
78
- z.object({
79
- type: z.literal('imageUrl'),
80
- imageUrl: z.string(),
81
- })
82
- ),
83
- metadata: z
84
- .object({
85
- model: z.string(),
86
- usage: z
87
- .object({
88
- promptTokens: z.number().optional(),
89
- completionTokens: z.number().optional(),
90
- totalTokens: z.number().optional(),
91
- })
92
- .optional(),
93
- })
94
- .optional(),
95
- });
96
-
97
- export const aiModelSchema = z.object({
98
- id: z.string(),
99
- inputModality: z.array(modalitySchema).min(1),
100
- outputModality: z.array(modalitySchema).min(1),
101
- provider: z.string(),
102
- modelId: z.string(),
103
- priceLevel: z.number().min(0).max(3).optional(),
104
- });
105
-
106
- export const createAIConfigurationRequestSchema = aiConfigurationSchema.omit({
107
- id: true,
108
- });
109
-
110
- export const updateAIConfigurationRequestSchema = z.object({
111
- systemPrompt: z.string().nullable(),
112
- });
113
-
114
- export const listAIUsageResponseSchema = z.object({
115
- records: z.array(aiUsageRecordSchema),
116
- total: z.number(),
117
- });
118
-
119
- export const getAIUsageRequestSchema = z.object({
120
- startDate: z.string().datetime().optional(),
121
- endDate: z.string().datetime().optional(),
122
- limit: z.string().regex(/^\d+$/).default('50'),
123
- offset: z.string().regex(/^\d+$/).default('0'),
124
- });
125
-
126
- export const getAIUsageSummaryRequestSchema = z.object({
127
- configId: z.string().uuid().optional(),
128
- startDate: z.string().datetime().optional(),
129
- endDate: z.string().datetime().optional(),
130
- });
131
-
132
- // Export types
133
- export type ChatMessageSchema = z.infer<typeof chatMessageSchema>;
134
- export type ChatCompletionRequest = z.infer<typeof chatCompletionRequestSchema>;
135
- export type ChatCompletionResponse = z.infer<typeof chatCompletionResponseSchema>;
136
- export type ImageGenerationRequest = z.infer<typeof imageGenerationRequestSchema>;
137
- export type ImageGenerationResponse = z.infer<typeof imageGenerationResponseSchema>;
138
- export type AIModelSchema = z.infer<typeof aiModelSchema>;
139
- export type CreateAIConfigurationRequest = z.infer<typeof createAIConfigurationRequestSchema>;
140
- export type UpdateAIConfigurationRequest = z.infer<typeof updateAIConfigurationRequestSchema>;
141
- export type ListAIUsageResponse = z.infer<typeof listAIUsageResponseSchema>;
142
- export type GetAIUsageRequest = z.infer<typeof getAIUsageRequestSchema>;
143
- export type GetAIUsageSummaryRequest = z.infer<typeof getAIUsageSummaryRequestSchema>;
1
+ import { z } from 'zod';
2
+ import { aiConfigurationSchema, aiUsageRecordSchema, modalitySchema } from './ai.schema';
3
+
4
+ // ============= Chat Completion Schemas =============
5
+
6
+ // OpenAI-compatible content schemas
7
+ export const textContentSchema = z.object({
8
+ type: z.literal('text'),
9
+ text: z.string(),
10
+ });
11
+
12
+ export const imageContentSchema = z.object({
13
+ type: z.literal('image_url'),
14
+ // eslint-disable-next-line @typescript-eslint/naming-convention
15
+ image_url: z.object({
16
+ // URL can be either a public URL or base64-encoded data URI
17
+ // Examples:
18
+ // - Public URL: "https://example.com/image.jpg"
19
+ // - Base64: "data:image/jpeg;base64,/9j/4AAQ..."
20
+ url: z.string(),
21
+ detail: z.enum(['auto', 'low', 'high']).optional(),
22
+ }),
23
+ });
24
+
25
+ export const audioContentSchema = z.object({
26
+ type: z.literal('input_audio'),
27
+ // eslint-disable-next-line @typescript-eslint/naming-convention
28
+ input_audio: z.object({
29
+ // Base64-encoded audio data (direct URLs not supported for audio)
30
+ data: z.string(),
31
+ format: z.enum(['wav', 'mp3', 'aiff', 'aac', 'ogg', 'flac', 'm4a']),
32
+ }),
33
+ });
34
+
35
+ // File content schema for PDFs and other documents (OpenRouter format)
36
+ export const fileContentSchema = z.object({
37
+ type: z.literal('file'),
38
+ file: z.object({
39
+ // Filename with extension (e.g., "document.pdf")
40
+ filename: z.string(),
41
+ // File data can be:
42
+ // - Public URL: "https://example.com/document.pdf"
43
+ // - Base64 data URL: "data:application/pdf;base64,..."
44
+ // eslint-disable-next-line @typescript-eslint/naming-convention
45
+ file_data: z.string(),
46
+ }),
47
+ });
48
+
49
+ export const contentSchema = z.union([
50
+ textContentSchema,
51
+ imageContentSchema,
52
+ audioContentSchema,
53
+ fileContentSchema,
54
+ ]);
55
+
56
+ // Chat message supports both OpenAI format and legacy format for backward compatibility
57
+ export const chatMessageSchema = z.object({
58
+ role: z.enum(['user', 'assistant', 'system']),
59
+ // New format: content can be string or array of content parts (OpenAI-compatible)
60
+ content: z.union([z.string(), z.array(contentSchema)]),
61
+ // Legacy format: separate images field (deprecated but supported for backward compatibility)
62
+ images: z.array(z.object({ url: z.string() })).optional(),
63
+ });
64
+
65
+ // Web Search Plugin configuration for OpenRouter
66
+ export const webSearchPluginSchema = z.object({
67
+ enabled: z.boolean(),
68
+ // Engine selection:
69
+ // - "native": Always use provider's built-in web search (OpenAI, Anthropic, Perplexity, xAI)
70
+ // - "exa": Use Exa's search API
71
+ // - undefined: Auto-select (native if available, otherwise Exa)
72
+ engine: z.enum(['native', 'exa']).optional(),
73
+ // Maximum number of search results (1-10, default: 5)
74
+ maxResults: z.number().min(1).max(10).optional(),
75
+ // Custom prompt for attaching search results to the message
76
+ searchPrompt: z.string().optional(),
77
+ });
78
+
79
+ // File Parser Plugin configuration for OpenRouter PDF processing
80
+ export const fileParserPluginSchema = z.object({
81
+ enabled: z.boolean(),
82
+ pdf: z
83
+ .object({
84
+ // PDF processing engine:
85
+ // - "pdf-text": Best for well-structured PDFs with clear text content (Free)
86
+ // - "mistral-ocr": Best for scanned documents or PDFs with images ($2 per 1,000 pages)
87
+ // - "native": Only available for models that support file input natively (charged as input tokens)
88
+ // If not specified, defaults to native if available, otherwise mistral-ocr
89
+ engine: z.enum(['pdf-text', 'mistral-ocr', 'native']).optional(),
90
+ })
91
+ .optional(),
92
+ });
93
+
94
+ export const chatCompletionRequestSchema = z.object({
95
+ model: z.string(),
96
+ messages: z.array(chatMessageSchema),
97
+ temperature: z.number().min(0).max(2).optional(),
98
+ maxTokens: z.number().positive().optional(),
99
+ topP: z.number().min(0).max(1).optional(),
100
+ stream: z.boolean().optional(),
101
+ // Web Search: Incorporate relevant web search results into the response
102
+ // Results are returned in the annotations field
103
+ webSearch: webSearchPluginSchema.optional(),
104
+ // File Parser: Configure PDF processing for file content in messages
105
+ // When files are included in messages, this controls how PDFs are parsed
106
+ fileParser: fileParserPluginSchema.optional(),
107
+ // Thinking/Reasoning mode: Enable extended reasoning capabilities
108
+ // Appends ":thinking" to the model ID for chain-of-thought reasoning
109
+ thinking: z.boolean().optional(),
110
+ });
111
+
112
+ // URL citation annotation from web search results
113
+ export const urlCitationAnnotationSchema = z.object({
114
+ type: z.literal('url_citation'),
115
+ urlCitation: z.object({
116
+ url: z.string(),
117
+ title: z.string().optional(),
118
+ content: z.string().optional(),
119
+ // Character indices in the response text where this citation applies
120
+ startIndex: z.number().optional(),
121
+ endIndex: z.number().optional(),
122
+ }),
123
+ });
124
+
125
+ // File annotation from PDF parsing results
126
+ // Can be passed back in subsequent requests to skip re-parsing costs
127
+ export const fileAnnotationSchema = z.object({
128
+ type: z.literal('file'),
129
+ file: z.object({
130
+ filename: z.string(),
131
+ // Parsed content from the PDF (used for caching)
132
+ parsedContent: z.string().optional(),
133
+ // Additional metadata from the parser
134
+ metadata: z.record(z.unknown()).optional(),
135
+ }),
136
+ });
137
+
138
+ // Combined annotation schema for all annotation types
139
+ export const annotationSchema = z.union([urlCitationAnnotationSchema, fileAnnotationSchema]);
140
+
141
+ export const chatCompletionResponseSchema = z.object({
142
+ text: z.string(),
143
+ // Annotations from web search or file parsing (can be URL citations or file annotations)
144
+ annotations: z.array(annotationSchema).optional(),
145
+ metadata: z
146
+ .object({
147
+ model: z.string(),
148
+ usage: z
149
+ .object({
150
+ promptTokens: z.number().optional(),
151
+ completionTokens: z.number().optional(),
152
+ totalTokens: z.number().optional(),
153
+ })
154
+ .optional(),
155
+ })
156
+ .optional(),
157
+ });
158
+
159
+ // ============= Image Generation Schemas =============
160
+
161
+ export const imageGenerationRequestSchema = z.object({
162
+ model: z.string(),
163
+ prompt: z.string(),
164
+ images: z
165
+ .array(
166
+ z.object({
167
+ url: z.string(),
168
+ })
169
+ )
170
+ .optional(),
171
+ });
172
+
173
+ export const imageGenerationResponseSchema = z.object({
174
+ text: z.string().optional(),
175
+ images: z.array(
176
+ z.object({
177
+ type: z.literal('imageUrl'),
178
+ imageUrl: z.string(),
179
+ })
180
+ ),
181
+ metadata: z
182
+ .object({
183
+ model: z.string(),
184
+ usage: z
185
+ .object({
186
+ promptTokens: z.number().optional(),
187
+ completionTokens: z.number().optional(),
188
+ totalTokens: z.number().optional(),
189
+ })
190
+ .optional(),
191
+ })
192
+ .optional(),
193
+ });
194
+
195
+ export const aiModelSchema = z.object({
196
+ id: z.string(),
197
+ inputModality: z.array(modalitySchema).min(1),
198
+ outputModality: z.array(modalitySchema).min(1),
199
+ provider: z.string(),
200
+ modelId: z.string(),
201
+ priceLevel: z.number().min(0).max(3).optional(),
202
+ });
203
+
204
+ export const createAIConfigurationRequestSchema = aiConfigurationSchema.omit({
205
+ id: true,
206
+ });
207
+
208
+ export const updateAIConfigurationRequestSchema = z.object({
209
+ systemPrompt: z.string().nullable(),
210
+ });
211
+
212
+ export const listAIUsageResponseSchema = z.object({
213
+ records: z.array(aiUsageRecordSchema),
214
+ total: z.number(),
215
+ });
216
+
217
+ export const getAIUsageRequestSchema = z.object({
218
+ startDate: z.string().datetime().optional(),
219
+ endDate: z.string().datetime().optional(),
220
+ limit: z.string().regex(/^\d+$/).default('50'),
221
+ offset: z.string().regex(/^\d+$/).default('0'),
222
+ });
223
+
224
+ export const getAIUsageSummaryRequestSchema = z.object({
225
+ configId: z.string().uuid().optional(),
226
+ startDate: z.string().datetime().optional(),
227
+ endDate: z.string().datetime().optional(),
228
+ });
229
+
230
+ // Export types
231
+ export type TextContentSchema = z.infer<typeof textContentSchema>;
232
+ export type ImageContentSchema = z.infer<typeof imageContentSchema>;
233
+ export type AudioContentSchema = z.infer<typeof audioContentSchema>;
234
+ export type FileContentSchema = z.infer<typeof fileContentSchema>;
235
+ export type ContentSchema = z.infer<typeof contentSchema>;
236
+ export type ChatMessageSchema = z.infer<typeof chatMessageSchema>;
237
+ export type WebSearchPlugin = z.infer<typeof webSearchPluginSchema>;
238
+ export type FileParserPlugin = z.infer<typeof fileParserPluginSchema>;
239
+ export type UrlCitationAnnotation = z.infer<typeof urlCitationAnnotationSchema>;
240
+ export type FileAnnotation = z.infer<typeof fileAnnotationSchema>;
241
+ export type Annotation = z.infer<typeof annotationSchema>;
242
+ export type ChatCompletionRequest = z.infer<typeof chatCompletionRequestSchema>;
243
+ export type ChatCompletionResponse = z.infer<typeof chatCompletionResponseSchema>;
244
+ export type ImageGenerationRequest = z.infer<typeof imageGenerationRequestSchema>;
245
+ export type ImageGenerationResponse = z.infer<typeof imageGenerationResponseSchema>;
246
+ export type AIModelSchema = z.infer<typeof aiModelSchema>;
247
+ export type CreateAIConfigurationRequest = z.infer<typeof createAIConfigurationRequestSchema>;
248
+ export type UpdateAIConfigurationRequest = z.infer<typeof updateAIConfigurationRequestSchema>;
249
+ export type ListAIUsageResponse = z.infer<typeof listAIUsageResponseSchema>;
250
+ export type GetAIUsageRequest = z.infer<typeof getAIUsageRequestSchema>;
251
+ export type GetAIUsageSummaryRequest = z.infer<typeof getAIUsageSummaryRequestSchema>;
@@ -1,63 +1,63 @@
1
- import { z } from 'zod';
2
-
3
- // Core schemas - only text and image supported currently
4
- export const modalitySchema = z.enum(['text', 'image']);
5
-
6
- export const aiConfigurationInputSchema = z.object({
7
- inputModality: z.array(modalitySchema).min(1),
8
- outputModality: z.array(modalitySchema).min(1),
9
- provider: z.string(),
10
- modelId: z.string(),
11
- systemPrompt: z.string().optional(),
12
- });
13
-
14
- export const aiConfigurationSchema = aiConfigurationInputSchema.extend({
15
- id: z.string().uuid(),
16
- });
17
-
18
- export const aiConfigurationWithUsageSchema = aiConfigurationSchema.extend({
19
- usageStats: z
20
- .object({
21
- totalInputTokens: z.number(),
22
- totalOutputTokens: z.number(),
23
- totalTokens: z.number(),
24
- totalImageCount: z.number(),
25
- totalRequests: z.number(),
26
- })
27
- .optional(),
28
- });
29
-
30
- export const aiUsageDataSchema = z.object({
31
- configId: z.string().uuid(),
32
- inputTokens: z.number().int().optional(),
33
- outputTokens: z.number().int().optional(),
34
- imageCount: z.number().int().optional(),
35
- imageResolution: z.string().optional(),
36
- });
37
-
38
- export const aiUsageRecordSchema = aiUsageDataSchema.extend({
39
- id: z.string().uuid(),
40
- createdAt: z.date(),
41
- modelId: z.string().nullable().optional(),
42
- model: z.string().nullable(),
43
- provider: z.string().nullable(),
44
- inputModality: z.array(modalitySchema).nullable(),
45
- outputModality: z.array(modalitySchema).nullable(),
46
- });
47
-
48
- export const aiUsageSummarySchema = z.object({
49
- totalInputTokens: z.number(),
50
- totalOutputTokens: z.number(),
51
- totalTokens: z.number(),
52
- totalImageCount: z.number(),
53
- totalRequests: z.number(),
54
- });
55
-
56
- // Export types
57
- export type ModalitySchema = z.infer<typeof modalitySchema>;
58
- export type AIConfigurationInputSchema = z.infer<typeof aiConfigurationInputSchema>;
59
- export type AIConfigurationSchema = z.infer<typeof aiConfigurationSchema>;
60
- export type AIConfigurationWithUsageSchema = z.infer<typeof aiConfigurationWithUsageSchema>;
61
- export type AIUsageDataSchema = z.infer<typeof aiUsageDataSchema>;
62
- export type AIUsageRecordSchema = z.infer<typeof aiUsageRecordSchema>;
63
- export type AIUsageSummarySchema = z.infer<typeof aiUsageSummarySchema>;
1
+ import { z } from 'zod';
2
+
3
+ // Core schemas - text, image, and audio supported
4
+ export const modalitySchema = z.enum(['text', 'image', 'audio']);
5
+
6
+ export const aiConfigurationInputSchema = z.object({
7
+ inputModality: z.array(modalitySchema).min(1),
8
+ outputModality: z.array(modalitySchema).min(1),
9
+ provider: z.string(),
10
+ modelId: z.string(),
11
+ systemPrompt: z.string().optional(),
12
+ });
13
+
14
+ export const aiConfigurationSchema = aiConfigurationInputSchema.extend({
15
+ id: z.string().uuid(),
16
+ });
17
+
18
+ export const aiConfigurationWithUsageSchema = aiConfigurationSchema.extend({
19
+ usageStats: z
20
+ .object({
21
+ totalInputTokens: z.number(),
22
+ totalOutputTokens: z.number(),
23
+ totalTokens: z.number(),
24
+ totalImageCount: z.number(),
25
+ totalRequests: z.number(),
26
+ })
27
+ .optional(),
28
+ });
29
+
30
+ export const aiUsageDataSchema = z.object({
31
+ configId: z.string().uuid(),
32
+ inputTokens: z.number().int().optional(),
33
+ outputTokens: z.number().int().optional(),
34
+ imageCount: z.number().int().optional(),
35
+ imageResolution: z.string().optional(),
36
+ });
37
+
38
+ export const aiUsageRecordSchema = aiUsageDataSchema.extend({
39
+ id: z.string().uuid(),
40
+ createdAt: z.date(),
41
+ modelId: z.string().nullable().optional(),
42
+ model: z.string().nullable(),
43
+ provider: z.string().nullable(),
44
+ inputModality: z.array(modalitySchema).nullable(),
45
+ outputModality: z.array(modalitySchema).nullable(),
46
+ });
47
+
48
+ export const aiUsageSummarySchema = z.object({
49
+ totalInputTokens: z.number(),
50
+ totalOutputTokens: z.number(),
51
+ totalTokens: z.number(),
52
+ totalImageCount: z.number(),
53
+ totalRequests: z.number(),
54
+ });
55
+
56
+ // Export types
57
+ export type ModalitySchema = z.infer<typeof modalitySchema>;
58
+ export type AIConfigurationInputSchema = z.infer<typeof aiConfigurationInputSchema>;
59
+ export type AIConfigurationSchema = z.infer<typeof aiConfigurationSchema>;
60
+ export type AIConfigurationWithUsageSchema = z.infer<typeof aiConfigurationWithUsageSchema>;
61
+ export type AIUsageDataSchema = z.infer<typeof aiUsageDataSchema>;
62
+ export type AIUsageRecordSchema = z.infer<typeof aiUsageRecordSchema>;
63
+ export type AIUsageSummarySchema = z.infer<typeof aiUsageSummarySchema>;
@@ -4,8 +4,8 @@ import {
4
4
  passwordSchema,
5
5
  nameSchema,
6
6
  userIdSchema,
7
- roleSchema,
8
7
  userSchema,
8
+ profileSchema,
9
9
  oAuthConfigSchema,
10
10
  oAuthProvidersSchema,
11
11
  authConfigSchema,
@@ -23,6 +23,15 @@ export const paginationSchema = z.object({
23
23
  offset: z.string().optional(),
24
24
  });
25
25
 
26
+ /**
27
+ * Shared options for auth requests (extensible for future parameters)
28
+ */
29
+ export const authOptionsSchema = z
30
+ .object({
31
+ emailRedirectTo: z.string().url().optional(),
32
+ })
33
+ .optional();
34
+
26
35
  /**
27
36
  * POST /api/auth/users - Create user
28
37
  */
@@ -30,6 +39,7 @@ export const createUserRequestSchema = z.object({
30
39
  email: emailSchema,
31
40
  password: passwordSchema,
32
41
  name: nameSchema.optional(),
42
+ options: authOptionsSchema,
33
43
  });
34
44
 
35
45
  /**
@@ -65,11 +75,19 @@ export const deleteUsersRequestSchema = z.object({
65
75
  userIds: z.array(userIdSchema).min(1, 'At least one user ID is required'),
66
76
  });
67
77
 
78
+ /**
79
+ * PATCH /api/auth/profiles/current - Update current user's profile
80
+ */
81
+ export const updateProfileRequestSchema = z.object({
82
+ profile: z.record(z.unknown()),
83
+ });
84
+
68
85
  /**
69
86
  * POST /api/auth/email/send-verification - Send verification email (code or link based on config)
70
87
  */
71
88
  export const sendVerificationEmailRequestSchema = z.object({
72
89
  email: emailSchema,
90
+ options: authOptionsSchema,
73
91
  });
74
92
 
75
93
  /**
@@ -189,11 +207,15 @@ export const createAdminSessionResponseSchema = createUserResponseSchema;
189
207
  * Response for GET /api/auth/sessions/current
190
208
  */
191
209
  export const getCurrentSessionResponseSchema = z.object({
192
- user: z.object({
193
- id: userIdSchema,
194
- email: emailSchema,
195
- role: roleSchema,
196
- }),
210
+ user: userSchema,
211
+ });
212
+
213
+ /**
214
+ * Response for GET /api/auth/profiles/:userId - Get user profile
215
+ */
216
+ export const getProfileResponseSchema = z.object({
217
+ id: userIdSchema,
218
+ profile: profileSchema.nullable(),
197
219
  });
198
220
 
199
221
  /**
@@ -315,12 +337,16 @@ export const authErrorResponseSchema = z.object({
315
337
  // Type exports
316
338
  // ============================================================================
317
339
 
340
+ // Shared options type
341
+ export type AuthOptions = z.infer<typeof authOptionsSchema>;
342
+
318
343
  // Request types for type-safe request handling
319
344
  export type CreateUserRequest = z.infer<typeof createUserRequestSchema>;
320
345
  export type CreateSessionRequest = z.infer<typeof createSessionRequestSchema>;
321
346
  export type CreateAdminSessionRequest = z.infer<typeof createAdminSessionRequestSchema>;
322
347
  export type ListUsersRequest = z.infer<typeof listUsersRequestSchema>;
323
348
  export type DeleteUsersRequest = z.infer<typeof deleteUsersRequestSchema>;
349
+ export type UpdateProfileRequest = z.infer<typeof updateProfileRequestSchema>;
324
350
  export type CreateOAuthConfigRequest = z.infer<typeof createOAuthConfigRequestSchema>;
325
351
  export type UpdateOAuthConfigRequest = z.infer<typeof updateOAuthConfigRequestSchema>;
326
352
  export type UpdateAuthConfigRequest = z.infer<typeof updateAuthConfigRequestSchema>;
@@ -339,9 +365,11 @@ export type VerifyEmailResponse = z.infer<typeof verifyEmailResponseSchema>;
339
365
  export type ExchangeResetPasswordTokenResponse = z.infer<
340
366
  typeof exchangeResetPasswordTokenResponseSchema
341
367
  >;
368
+ export type RefreshSessionResponse = z.infer<typeof refreshSessionResponseSchema>;
342
369
  export type ResetPasswordResponse = z.infer<typeof resetPasswordResponseSchema>;
343
370
  export type CreateAdminSessionResponse = z.infer<typeof createAdminSessionResponseSchema>;
344
371
  export type GetCurrentSessionResponse = z.infer<typeof getCurrentSessionResponseSchema>;
372
+ export type GetProfileResponse = z.infer<typeof getProfileResponseSchema>;
345
373
  export type ListUsersResponse = z.infer<typeof listUsersResponseSchema>;
346
374
  export type DeleteUsersResponse = z.infer<typeof deleteUsersResponseSchema>;
347
375
  export type GetOauthUrlResponse = z.infer<typeof getOauthUrlResponseSchema>;