@db3.ai/app 0.1.0-beta.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (653) hide show
  1. package/README.md +75 -17
  2. package/agent-instructions.md +76 -0
  3. package/dist/ai/AIErrors.d.ts +7 -1
  4. package/dist/ai/AIErrors.js +8 -1
  5. package/dist/ai/AIFailover.d.ts +10 -0
  6. package/dist/ai/AIFailover.js +3 -2
  7. package/dist/ai/AIProviderAdmission.d.ts +101 -0
  8. package/dist/ai/AIProviderAdmission.js +336 -0
  9. package/dist/ai/AIRateLimiter.d.ts +11 -2
  10. package/dist/ai/AIRateLimiter.js +125 -10
  11. package/dist/ai/AIRequestTrackingError.d.ts +22 -0
  12. package/dist/ai/AIRequestTrackingError.js +33 -0
  13. package/dist/ai/Agent.d.ts +7 -7
  14. package/dist/ai/Agent.js +84 -56
  15. package/dist/ai/Ai.d.ts +11 -3
  16. package/dist/ai/Ai.js +94 -44
  17. package/dist/ai/OpenAIProviderError.js +1 -1
  18. package/dist/ai/ProviderSseObserver.d.ts +19 -0
  19. package/dist/ai/ProviderSseObserver.js +98 -0
  20. package/dist/ai/aiServiceTier.d.ts +5 -0
  21. package/dist/ai/aiServiceTier.js +14 -0
  22. package/dist/ai/chunkEmbeddingText.d.ts +14 -0
  23. package/dist/ai/chunkEmbeddingText.js +147 -0
  24. package/dist/ai/contracts/AI.d.ts +16 -0
  25. package/dist/ai/contracts/AIRequestErrorDiagnostics.d.ts +12 -0
  26. package/dist/ai/contracts/AIRequestErrorDiagnostics.js +1 -0
  27. package/dist/ai/contracts/AIServiceTier.d.ts +2 -0
  28. package/dist/ai/contracts/AIServiceTier.js +1 -0
  29. package/dist/ai/contracts/Agent.d.ts +3 -0
  30. package/dist/ai/contracts/EmbeddingTextChunk.d.ts +25 -0
  31. package/dist/ai/contracts/EmbeddingTextChunk.js +1 -0
  32. package/dist/ai/contracts/Pricing.d.ts +7 -1
  33. package/dist/ai/contracts/Providers.d.ts +2 -0
  34. package/dist/ai/contracts/index.d.ts +2 -0
  35. package/dist/ai/contracts/index.js +1 -0
  36. package/dist/ai/index.d.ts +8 -2
  37. package/dist/ai/index.js +5 -2
  38. package/dist/ai/{Models.d.ts → modelPricing.d.ts} +2 -2
  39. package/dist/ai/{Models.js → modelPricing.js} +38 -4
  40. package/dist/apps/AppInstallation.d.ts +21 -0
  41. package/dist/apps/AppInstallation.js +16 -0
  42. package/dist/apps/AppRouteError.d.ts +6 -0
  43. package/dist/apps/AppRouteError.js +10 -0
  44. package/dist/apps/AppService.d.ts +24 -0
  45. package/dist/apps/AppService.js +21 -0
  46. package/dist/apps/Apps.d.ts +59 -0
  47. package/dist/apps/Apps.js +566 -0
  48. package/dist/apps/appsPlugin.d.ts +3 -0
  49. package/dist/apps/appsPlugin.js +36 -0
  50. package/dist/apps/commands/disableApp.d.ts +2 -0
  51. package/dist/apps/commands/disableApp.js +5 -0
  52. package/dist/apps/commands/enableApp.d.ts +2 -0
  53. package/dist/apps/commands/enableApp.js +5 -0
  54. package/dist/apps/commands/index.d.ts +10 -0
  55. package/dist/apps/commands/index.js +27 -0
  56. package/dist/apps/commands/installApp.d.ts +2 -0
  57. package/dist/apps/commands/installApp.js +5 -0
  58. package/dist/apps/commands/listApps.d.ts +2 -0
  59. package/dist/apps/commands/listApps.js +5 -0
  60. package/dist/apps/commands/makeAppMigration.d.ts +2 -0
  61. package/dist/apps/commands/makeAppMigration.js +9 -0
  62. package/dist/apps/commands/rollbackApp.d.ts +2 -0
  63. package/dist/apps/commands/rollbackApp.js +5 -0
  64. package/dist/apps/commands/uninstallApp.d.ts +2 -0
  65. package/dist/apps/commands/uninstallApp.js +5 -0
  66. package/dist/apps/contracts/AppAction.d.ts +2 -0
  67. package/dist/apps/contracts/AppAction.js +1 -0
  68. package/dist/apps/contracts/AppDefinition.d.ts +45 -0
  69. package/dist/apps/contracts/AppDefinition.js +1 -0
  70. package/dist/apps/contracts/AppDescription.d.ts +32 -0
  71. package/dist/apps/contracts/AppDescription.js +1 -0
  72. package/dist/apps/contracts/AppManifest.d.ts +30 -0
  73. package/dist/apps/contracts/AppManifest.js +1 -0
  74. package/dist/apps/contracts/AppNavigation.d.ts +9 -0
  75. package/dist/apps/contracts/AppNavigation.js +1 -0
  76. package/dist/apps/contracts/AppNavigationBadge.d.ts +6 -0
  77. package/dist/apps/contracts/AppNavigationBadge.js +1 -0
  78. package/dist/apps/contracts/AppNavigationContext.d.ts +8 -0
  79. package/dist/apps/contracts/AppNavigationContext.js +1 -0
  80. package/dist/apps/contracts/AppNavigationResult.d.ts +12 -0
  81. package/dist/apps/contracts/AppNavigationResult.js +1 -0
  82. package/dist/apps/contracts/AppRoute.d.ts +19 -0
  83. package/dist/apps/contracts/AppRoute.js +1 -0
  84. package/dist/apps/contracts/DiscoveredApp.d.ts +10 -0
  85. package/dist/apps/contracts/DiscoveredApp.js +1 -0
  86. package/dist/apps/contracts/InstalledApps.d.ts +3 -0
  87. package/dist/apps/contracts/InstalledApps.js +1 -0
  88. package/dist/apps/contracts/index.d.ts +11 -0
  89. package/dist/apps/contracts/index.js +1 -0
  90. package/dist/apps/defineApp.d.ts +7 -0
  91. package/dist/apps/defineApp.js +8 -0
  92. package/dist/apps/discoverApps.d.ts +3 -0
  93. package/dist/apps/discoverApps.js +62 -0
  94. package/dist/apps/fastify.d.ts +1 -0
  95. package/dist/apps/fastify.js +1 -0
  96. package/dist/apps/index.d.ts +7 -0
  97. package/dist/apps/index.js +7 -0
  98. package/dist/apps/normalizeAppNavigation.d.ts +3 -0
  99. package/dist/apps/normalizeAppNavigation.js +30 -0
  100. package/dist/apps/registerAppRoutes.d.ts +6 -0
  101. package/dist/apps/registerAppRoutes.js +52 -0
  102. package/dist/apps/validateAppDefinitions.d.ts +3 -0
  103. package/dist/apps/validateAppDefinitions.js +65 -0
  104. package/dist/apps/vite.d.ts +1 -0
  105. package/dist/apps/vite.js +1 -0
  106. package/dist/apps/writeAppTypes.d.ts +2 -0
  107. package/dist/apps/writeAppTypes.js +13 -0
  108. package/dist/auth/Auth.d.ts +18 -0
  109. package/dist/auth/Auth.js +89 -13
  110. package/dist/auth/PasswordLoginAttempt.d.ts +50 -0
  111. package/dist/auth/PasswordLoginAttempt.js +60 -0
  112. package/dist/auth/PasswordSuspendedError.d.ts +10 -0
  113. package/dist/auth/PasswordSuspendedError.js +13 -0
  114. package/dist/auth/contracts/PasswordAuthProviderOptions.d.ts +26 -0
  115. package/dist/auth/contracts/PasswordAuthProviderOptions.js +1 -0
  116. package/dist/auth/contracts/PasswordSuspension.d.ts +7 -0
  117. package/dist/auth/contracts/PasswordSuspension.js +1 -0
  118. package/dist/auth/contracts/PasswordSuspensionOptions.d.ts +10 -0
  119. package/dist/auth/contracts/PasswordSuspensionOptions.js +1 -0
  120. package/dist/auth/contracts/index.d.ts +3 -0
  121. package/dist/auth/contracts/index.js +3 -0
  122. package/dist/auth/index.d.ts +2 -0
  123. package/dist/auth/index.js +2 -0
  124. package/dist/auth/providers/PasswordAuthProvider.d.ts +19 -23
  125. package/dist/auth/providers/PasswordAuthProvider.js +96 -8
  126. package/dist/auth/providers/resolveAuthProviders.js +1 -0
  127. package/dist/cli/Cli.d.ts +2 -0
  128. package/dist/cli/Cli.js +8 -0
  129. package/dist/cli/commands/repl.js +2 -1
  130. package/dist/cli/contracts/CliCommand.d.ts +2 -0
  131. package/dist/cli/contracts/CliCommandInfo.d.ts +12 -0
  132. package/dist/cli/contracts/CliCommandInfo.js +1 -0
  133. package/dist/cli/contracts/index.d.ts +1 -0
  134. package/dist/cli/index.d.ts +1 -0
  135. package/dist/cli/index.js +1 -0
  136. package/dist/cli/listDb3Commands.d.ts +8 -0
  137. package/dist/cli/listDb3Commands.js +10 -0
  138. package/dist/cli/runDb3.d.ts +3 -6
  139. package/dist/cli/runDb3.js +5 -59
  140. package/dist/cli/withDb3Cli.d.ts +4 -0
  141. package/dist/cli/withDb3Cli.js +60 -0
  142. package/dist/db/ActiveQueryBuilder.d.ts +8 -0
  143. package/dist/db/ActiveQueryBuilder.js +11 -0
  144. package/dist/db/ActiveRecord.d.ts +6 -0
  145. package/dist/db/ActiveRecord.js +8 -0
  146. package/dist/db/connection.js +14 -2
  147. package/dist/db/fields/TimestampField.d.ts +1 -1
  148. package/dist/db/fields/TimestampField.js +7 -12
  149. package/dist/db/migrations/DatabaseMigrationManager.d.ts +3 -1
  150. package/dist/db/migrations/DatabaseMigrationManager.js +9 -3
  151. package/dist/db/migrations/contracts/DatabaseMigration.d.ts +7 -0
  152. package/dist/db/migrations/index.d.ts +1 -1
  153. package/dist/db/migrations/index.js +1 -1
  154. package/dist/db/migrations/{KnexMigrationRenderer.d.ts → renderKnexMigration.d.ts} +4 -3
  155. package/dist/db/migrations/{KnexMigrationRenderer.js → renderKnexMigration.js} +7 -6
  156. package/dist/flows/FlowCompiler.js +1 -1
  157. package/dist/flows/Flows.js +1 -1
  158. package/dist/flows/index.d.ts +1 -1
  159. package/dist/flows/index.js +1 -1
  160. package/dist/health/Health.d.ts +41 -0
  161. package/dist/health/Health.js +153 -0
  162. package/dist/health/contracts/Health.d.ts +36 -0
  163. package/dist/health/contracts/Health.js +1 -0
  164. package/dist/health/contracts/HealthHttp.d.ts +15 -0
  165. package/dist/health/contracts/HealthHttp.js +1 -0
  166. package/dist/health/contracts/index.d.ts +2 -0
  167. package/dist/health/contracts/index.js +1 -0
  168. package/dist/health/databaseHealthCheck.d.ts +15 -0
  169. package/dist/health/databaseHealthCheck.js +18 -0
  170. package/dist/health/fastify.d.ts +13 -0
  171. package/dist/health/fastify.js +44 -0
  172. package/dist/health/index.d.ts +3 -0
  173. package/dist/health/index.js +2 -0
  174. package/dist/in-app/InApp.d.ts +33 -0
  175. package/dist/in-app/InApp.js +191 -0
  176. package/dist/in-app/InAppError.d.ts +6 -0
  177. package/dist/in-app/InAppError.js +10 -0
  178. package/dist/in-app/InAppRecord.d.ts +36 -0
  179. package/dist/in-app/InAppRecord.js +24 -0
  180. package/dist/in-app/contracts/InAppInbox.d.ts +45 -0
  181. package/dist/in-app/contracts/InAppInbox.js +1 -0
  182. package/dist/in-app/contracts/InAppMessage.d.ts +22 -0
  183. package/dist/in-app/contracts/InAppMessage.js +1 -0
  184. package/dist/in-app/contracts/InAppScope.d.ts +17 -0
  185. package/dist/in-app/contracts/InAppScope.js +1 -0
  186. package/dist/in-app/contracts/index.d.ts +3 -0
  187. package/dist/in-app/contracts/index.js +3 -0
  188. package/dist/in-app/index.d.ts +4 -0
  189. package/dist/in-app/index.js +4 -0
  190. package/dist/in-app/validation.d.ts +21 -0
  191. package/dist/in-app/validation.js +50 -0
  192. package/dist/index.d.ts +2 -14
  193. package/dist/index.js +2 -5
  194. package/dist/logging/DevelopmentConsole.d.ts +42 -0
  195. package/dist/logging/DevelopmentConsole.js +162 -0
  196. package/dist/logging/Log.d.ts +3 -1
  197. package/dist/logging/Log.js +5 -2
  198. package/dist/logging/PrettyLogFormatter.d.ts +16 -0
  199. package/dist/logging/PrettyLogFormatter.js +151 -0
  200. package/dist/logging/acquireDevelopmentConsole.d.ts +6 -0
  201. package/dist/logging/acquireDevelopmentConsole.js +21 -0
  202. package/dist/logging/contracts/DevelopmentConsoleOptions.d.ts +16 -0
  203. package/dist/logging/contracts/DevelopmentConsoleOptions.js +1 -0
  204. package/dist/logging/contracts/EmailLogOptions.d.ts +8 -0
  205. package/dist/logging/contracts/EmailLogOptions.js +1 -0
  206. package/dist/logging/contracts/HttpExchangeMonitorOptions.d.ts +12 -0
  207. package/dist/logging/contracts/HttpExchangeMonitorOptions.js +1 -0
  208. package/dist/logging/contracts/LogTransportOptions.d.ts +19 -0
  209. package/dist/logging/contracts/LogTransportOptions.js +1 -0
  210. package/dist/logging/contracts/LoggingOptions.d.ts +12 -1
  211. package/dist/logging/contracts/index.d.ts +4 -0
  212. package/dist/logging/contracts/index.js +4 -0
  213. package/dist/logging/drivers/PinoLoggerDriver.d.ts +3 -1
  214. package/dist/logging/drivers/PinoLoggerDriver.js +75 -16
  215. package/dist/logging/formatLogEmail.d.ts +4 -0
  216. package/dist/logging/formatLogEmail.js +21 -0
  217. package/dist/logging/highlightQueueMessage.d.ts +11 -0
  218. package/dist/logging/highlightQueueMessage.js +36 -0
  219. package/dist/logging/httpBodyCapture.d.ts +24 -0
  220. package/dist/logging/httpBodyCapture.js +321 -0
  221. package/dist/logging/index.d.ts +2 -0
  222. package/dist/logging/index.js +2 -0
  223. package/dist/logging/redactLogEmail.d.ts +2 -0
  224. package/dist/logging/redactLogEmail.js +12 -0
  225. package/dist/logging/registerHttpExchangeMonitor.d.ts +10 -0
  226. package/dist/logging/registerHttpExchangeMonitor.js +43 -0
  227. package/dist/logging/transports/EmailLogTransport.d.ts +18 -0
  228. package/dist/logging/transports/EmailLogTransport.js +47 -0
  229. package/dist/mail/Mail.d.ts +2 -0
  230. package/dist/mail/Mail.js +3 -0
  231. package/dist/mail/MailDeliveryError.d.ts +9 -0
  232. package/dist/mail/MailDeliveryError.js +16 -0
  233. package/dist/mail/index.d.ts +1 -0
  234. package/dist/mail/index.js +1 -0
  235. package/dist/mail/transports/MailgunTransport.js +2 -0
  236. package/dist/mail/transports/ResendTransport.d.ts +3 -2
  237. package/dist/mail/transports/ResendTransport.js +22 -14
  238. package/dist/media/MediaManager.d.ts +4 -2
  239. package/dist/media/MediaManager.js +40 -8
  240. package/dist/network/BlockedUrlError.d.ts +16 -0
  241. package/dist/network/BlockedUrlError.js +19 -0
  242. package/dist/network/assertPublicUrl.d.ts +22 -0
  243. package/dist/network/assertPublicUrl.js +67 -0
  244. package/dist/network/contracts/GuardedFetch.d.ts +35 -0
  245. package/dist/network/contracts/GuardedFetch.js +1 -0
  246. package/dist/network/contracts/PublicUrlOptions.d.ts +17 -0
  247. package/dist/network/contracts/PublicUrlOptions.js +1 -0
  248. package/dist/network/contracts/index.d.ts +2 -0
  249. package/dist/network/contracts/index.js +2 -0
  250. package/dist/network/guardedFetch.d.ts +29 -0
  251. package/dist/network/guardedFetch.js +133 -0
  252. package/dist/network/index.d.ts +6 -0
  253. package/dist/network/index.js +6 -0
  254. package/dist/network/playwright/GuardedBrowserProxy.d.ts +32 -0
  255. package/dist/network/playwright/GuardedBrowserProxy.js +172 -0
  256. package/dist/network/playwright/contracts/GuardedBrowserContextOptions.d.ts +37 -0
  257. package/dist/network/playwright/contracts/GuardedBrowserContextOptions.js +1 -0
  258. package/dist/network/playwright/contracts/index.d.ts +1 -0
  259. package/dist/network/playwright/contracts/index.js +1 -0
  260. package/dist/network/playwright/index.d.ts +2 -0
  261. package/dist/network/playwright/index.js +2 -0
  262. package/dist/network/playwright/newGuardedBrowserContext.d.ts +21 -0
  263. package/dist/network/playwright/newGuardedBrowserContext.js +86 -0
  264. package/dist/network/privateNetworkAddresses.d.ts +44 -0
  265. package/dist/network/privateNetworkAddresses.js +157 -0
  266. package/dist/network/publicAddressLookup.d.ts +26 -0
  267. package/dist/network/publicAddressLookup.js +42 -0
  268. package/dist/notifications/Notifications.d.ts +27 -0
  269. package/dist/notifications/Notifications.js +99 -0
  270. package/dist/notifications/contracts/Notification.d.ts +56 -0
  271. package/dist/notifications/contracts/Notification.js +1 -0
  272. package/dist/notifications/contracts/NotificationDelivery.d.ts +11 -0
  273. package/dist/notifications/contracts/NotificationDelivery.js +1 -0
  274. package/dist/notifications/contracts/index.d.ts +2 -0
  275. package/dist/notifications/contracts/index.js +2 -0
  276. package/dist/notifications/index.d.ts +2 -0
  277. package/dist/notifications/index.js +2 -0
  278. package/dist/queue/JobRunAttempt.d.ts +16 -0
  279. package/dist/queue/JobRunAttempt.js +17 -0
  280. package/dist/queue/JobRunEvent.d.ts +15 -0
  281. package/dist/queue/JobRunEvent.js +16 -0
  282. package/dist/queue/JobRunStoppedError.d.ts +6 -0
  283. package/dist/queue/JobRunStoppedError.js +10 -0
  284. package/dist/queue/Queue.d.ts +19 -4
  285. package/dist/queue/Queue.js +122 -9
  286. package/dist/queue/QueueTerminalError.d.ts +9 -0
  287. package/dist/queue/QueueTerminalError.js +12 -0
  288. package/dist/queue/QueueWorker.d.ts +12 -5
  289. package/dist/queue/QueueWorker.js +94 -9
  290. package/dist/queue/QueueWorkerReporter.d.ts +17 -0
  291. package/dist/queue/QueueWorkerReporter.js +71 -0
  292. package/dist/queue/QueueableJob.d.ts +2 -2
  293. package/dist/queue/RunnableJob.d.ts +78 -0
  294. package/dist/queue/RunnableJob.js +284 -0
  295. package/dist/queue/console.d.ts +8 -0
  296. package/dist/queue/console.js +53 -19
  297. package/dist/queue/contracts/QueueDriver.d.ts +8 -0
  298. package/dist/queue/contracts/QueueJobRunner.d.ts +4 -0
  299. package/dist/queue/contracts/QueueJobRunner.js +1 -0
  300. package/dist/queue/contracts/QueuePayload.d.ts +1 -1
  301. package/dist/queue/contracts/QueueSelection.d.ts +11 -0
  302. package/dist/queue/contracts/QueueSelection.js +1 -0
  303. package/dist/queue/contracts/QueueService.d.ts +18 -4
  304. package/dist/queue/contracts/QueueWorkerLifecycle.d.ts +2 -2
  305. package/dist/queue/contracts/QueueWorkerSnapshot.d.ts +14 -0
  306. package/dist/queue/contracts/QueueWorkerSnapshot.js +1 -0
  307. package/dist/queue/contracts/QueueableJob.d.ts +7 -3
  308. package/dist/queue/contracts/QueueableJobContract.d.ts +12 -0
  309. package/dist/queue/contracts/QueueableJobContract.js +1 -0
  310. package/dist/queue/contracts/index.d.ts +4 -0
  311. package/dist/queue/contracts/index.js +2 -0
  312. package/dist/queue/drivers/DatabaseQueueDriver.d.ts +4 -0
  313. package/dist/queue/drivers/DatabaseQueueDriver.js +27 -3
  314. package/dist/queue/drivers/RedisQueueDriver.d.ts +7 -0
  315. package/dist/queue/drivers/RedisQueueDriver.js +37 -0
  316. package/dist/queue/index.d.ts +5 -0
  317. package/dist/queue/index.js +5 -0
  318. package/dist/queue/jobEnvelopeHasPrefix.d.ts +3 -0
  319. package/dist/queue/jobEnvelopeHasPrefix.js +4 -0
  320. package/dist/scheduler/ScheduledEvent.d.ts +8 -4
  321. package/dist/scheduler/ScheduledEvent.js +17 -3
  322. package/dist/scheduler/ScheduledJob.d.ts +1 -1
  323. package/dist/scheduler/Scheduler.d.ts +5 -0
  324. package/dist/scheduler/Scheduler.js +92 -28
  325. package/dist/scheduler/SchedulerCheckpointRecord.d.ts +16 -0
  326. package/dist/scheduler/SchedulerCheckpointRecord.js +53 -0
  327. package/dist/scheduler/SchedulerWorker.d.ts +3 -5
  328. package/dist/scheduler/SchedulerWorker.js +58 -14
  329. package/dist/scheduler/console.js +3 -1
  330. package/dist/scheduler/contracts/Schedule.d.ts +19 -0
  331. package/dist/scheduler/contracts/Schedule.js +1 -0
  332. package/dist/scheduler/contracts/Scheduler.d.ts +18 -6
  333. package/dist/scheduler/contracts/SchedulerCheckpoint.d.ts +23 -0
  334. package/dist/scheduler/contracts/SchedulerCheckpoint.js +1 -0
  335. package/dist/scheduler/contracts/SchedulerConsole.d.ts +5 -0
  336. package/dist/scheduler/contracts/SchedulerWorker.d.ts +6 -1
  337. package/dist/scheduler/contracts/index.d.ts +2 -0
  338. package/dist/scheduler/contracts/index.js +2 -0
  339. package/dist/scheduler/index.d.ts +1 -0
  340. package/dist/scheduler/index.js +1 -0
  341. package/dist/server/App.d.ts +36 -4
  342. package/dist/server/App.js +57 -7
  343. package/dist/server/contracts/HttpErrorHandlerOptions.d.ts +29 -0
  344. package/dist/server/contracts/HttpErrorHandlerOptions.js +1 -0
  345. package/dist/server/contracts/index.d.ts +1 -0
  346. package/dist/server/contracts/index.js +1 -0
  347. package/dist/server/index.d.ts +4 -0
  348. package/dist/server/index.js +4 -0
  349. package/dist/server/publicServerErrorMessage.d.ts +11 -0
  350. package/dist/server/publicServerErrorMessage.js +16 -0
  351. package/dist/server/registerBrowserJsonFormatting.d.ts +16 -0
  352. package/dist/server/registerBrowserJsonFormatting.js +100 -0
  353. package/dist/server/registerHttpErrorHandler.d.ts +20 -0
  354. package/dist/server/registerHttpErrorHandler.js +93 -0
  355. package/dist/ssr/vite/contracts/ViteSsrOptions.d.ts +2 -0
  356. package/dist/ssr/vite/fastifyViteSsr.js +4 -3
  357. package/dist/storage/drivers/FlystorageDisk.js +2 -2
  358. package/dist/storage/index.d.ts +2 -2
  359. package/dist/storage/index.js +2 -2
  360. package/dist/websocket/WebSocketChannels.d.ts +18 -0
  361. package/dist/websocket/WebSocketChannels.js +129 -0
  362. package/dist/websocket/WebSocketConnection.d.ts +25 -0
  363. package/dist/websocket/WebSocketConnection.js +244 -0
  364. package/dist/websocket/WebSockets.d.ts +41 -0
  365. package/dist/websocket/WebSockets.js +194 -0
  366. package/dist/websocket/client/WebSocketClient.d.ts +21 -0
  367. package/dist/websocket/client/WebSocketClient.js +230 -0
  368. package/dist/websocket/client/index.d.ts +3 -0
  369. package/dist/websocket/client/index.js +1 -0
  370. package/dist/websocket/contracts/WebSocketChannel.d.ts +20 -0
  371. package/dist/websocket/contracts/WebSocketChannel.js +1 -0
  372. package/dist/websocket/contracts/WebSocketClient.d.ts +45 -0
  373. package/dist/websocket/contracts/WebSocketClient.js +1 -0
  374. package/dist/websocket/contracts/WebSocketEndpoint.d.ts +43 -0
  375. package/dist/websocket/contracts/WebSocketEndpoint.js +1 -0
  376. package/dist/websocket/contracts/WebSocketOptions.d.ts +48 -0
  377. package/dist/websocket/contracts/WebSocketOptions.js +1 -0
  378. package/dist/websocket/contracts/WebSocketPresence.d.ts +6 -0
  379. package/dist/websocket/contracts/WebSocketPresence.js +1 -0
  380. package/dist/websocket/contracts/WebSocketServiceOptions.d.ts +12 -0
  381. package/dist/websocket/contracts/WebSocketServiceOptions.js +1 -0
  382. package/dist/websocket/contracts/index.d.ts +6 -0
  383. package/dist/websocket/contracts/index.js +1 -0
  384. package/dist/websocket/defineChannel.d.ts +8 -0
  385. package/dist/websocket/defineChannel.js +13 -0
  386. package/dist/websocket/defineWebSocket.d.ts +14 -0
  387. package/dist/websocket/defineWebSocket.js +4 -0
  388. package/dist/websocket/fastify.d.ts +11 -0
  389. package/dist/websocket/fastify.js +38 -0
  390. package/dist/websocket/index.d.ts +5 -0
  391. package/dist/websocket/index.js +4 -0
  392. package/package.json +108 -7
  393. package/src/ai/AIErrors.ts +10 -0
  394. package/src/ai/AIFailover.ts +3 -2
  395. package/src/ai/AIProviderAdmission.ts +329 -0
  396. package/src/ai/AIRateLimiter.ts +134 -10
  397. package/src/ai/AIRequestTrackingError.ts +37 -0
  398. package/src/ai/Agent.ts +85 -71
  399. package/src/ai/Ai.ts +104 -48
  400. package/src/ai/OpenAIProviderError.ts +1 -1
  401. package/src/ai/ProviderSseObserver.ts +89 -0
  402. package/src/ai/README.md +216 -11
  403. package/src/ai/aiServiceTier.ts +14 -0
  404. package/src/ai/chunkEmbeddingText.ts +137 -0
  405. package/src/ai/contracts/AI.ts +17 -0
  406. package/src/ai/contracts/AIRequestErrorDiagnostics.ts +12 -0
  407. package/src/ai/contracts/AIServiceTier.ts +2 -0
  408. package/src/ai/contracts/Agent.ts +3 -0
  409. package/src/ai/contracts/EmbeddingTextChunk.ts +26 -0
  410. package/src/ai/contracts/Pricing.ts +7 -1
  411. package/src/ai/contracts/Providers.ts +2 -0
  412. package/src/ai/contracts/index.ts +2 -0
  413. package/src/ai/examples/prepareDocumentEmbeddings.ts +20 -0
  414. package/src/ai/index.ts +9 -2
  415. package/src/ai/{Models.ts → modelPricing.ts} +37 -4
  416. package/src/apps/AppInstallation.ts +25 -0
  417. package/src/apps/AppRouteError.ts +8 -0
  418. package/src/apps/AppService.ts +30 -0
  419. package/src/apps/Apps.ts +508 -0
  420. package/src/apps/README.md +354 -0
  421. package/src/apps/appsPlugin.ts +34 -0
  422. package/src/apps/commands/disableApp.ts +6 -0
  423. package/src/apps/commands/enableApp.ts +6 -0
  424. package/src/apps/commands/index.ts +29 -0
  425. package/src/apps/commands/installApp.ts +6 -0
  426. package/src/apps/commands/listApps.ts +6 -0
  427. package/src/apps/commands/makeAppMigration.ts +9 -0
  428. package/src/apps/commands/rollbackApp.ts +6 -0
  429. package/src/apps/commands/uninstallApp.ts +6 -0
  430. package/src/apps/contracts/AppAction.ts +2 -0
  431. package/src/apps/contracts/AppDefinition.ts +49 -0
  432. package/src/apps/contracts/AppDescription.ts +27 -0
  433. package/src/apps/contracts/AppManifest.ts +32 -0
  434. package/src/apps/contracts/AppNavigation.ts +10 -0
  435. package/src/apps/contracts/AppNavigationBadge.ts +6 -0
  436. package/src/apps/contracts/AppNavigationContext.ts +6 -0
  437. package/src/apps/contracts/AppNavigationResult.ts +9 -0
  438. package/src/apps/contracts/AppRoute.ts +18 -0
  439. package/src/apps/contracts/DiscoveredApp.ts +11 -0
  440. package/src/apps/contracts/InstalledApps.ts +2 -0
  441. package/src/apps/contracts/index.ts +11 -0
  442. package/src/apps/defineApp.ts +10 -0
  443. package/src/apps/discoverApps.ts +56 -0
  444. package/src/apps/fastify.ts +1 -0
  445. package/src/apps/index.ts +7 -0
  446. package/src/apps/normalizeAppNavigation.ts +29 -0
  447. package/src/apps/registerAppRoutes.ts +48 -0
  448. package/src/apps/validateAppDefinitions.ts +52 -0
  449. package/src/apps/vite.ts +1 -0
  450. package/src/apps/writeAppTypes.ts +14 -0
  451. package/src/auth/Auth.ts +89 -23
  452. package/src/auth/PasswordLoginAttempt.ts +72 -0
  453. package/src/auth/PasswordSuspendedError.ts +13 -0
  454. package/src/auth/README.md +94 -4
  455. package/src/auth/contracts/PasswordAuthProviderOptions.ts +30 -0
  456. package/src/auth/contracts/PasswordSuspension.ts +7 -0
  457. package/src/auth/contracts/PasswordSuspensionOptions.ts +10 -0
  458. package/src/auth/contracts/index.ts +3 -0
  459. package/src/auth/examples/runPasswordAuth.ts +6 -6
  460. package/src/auth/index.ts +2 -0
  461. package/src/auth/providers/PasswordAuthProvider.ts +96 -30
  462. package/src/auth/providers/resolveAuthProviders.ts +1 -0
  463. package/src/cli/Cli.ts +9 -0
  464. package/src/cli/README.md +19 -0
  465. package/src/cli/commands/repl.ts +2 -1
  466. package/src/cli/contracts/CliCommand.ts +2 -0
  467. package/src/cli/contracts/CliCommandInfo.ts +13 -0
  468. package/src/cli/contracts/index.ts +1 -0
  469. package/src/cli/index.ts +1 -0
  470. package/src/cli/listDb3Commands.ts +12 -0
  471. package/src/cli/runDb3.ts +5 -51
  472. package/src/cli/withDb3Cli.ts +55 -0
  473. package/src/db/ActiveQueryBuilder.ts +12 -0
  474. package/src/db/ActiveRecord.ts +9 -0
  475. package/src/db/README.md +45 -1
  476. package/src/db/connection.ts +12 -1
  477. package/src/db/examples/FieldNote.ts +7 -13
  478. package/src/db/examples/KnowledgeNote.ts +7 -13
  479. package/src/db/examples/runNoteMigrations.ts +11 -11
  480. package/src/db/fields/TimestampField.ts +8 -17
  481. package/src/db/migrations/DatabaseMigrationManager.ts +12 -4
  482. package/src/db/migrations/contracts/DatabaseMigration.ts +9 -0
  483. package/src/db/migrations/index.ts +1 -1
  484. package/src/db/migrations/{KnexMigrationRenderer.ts → renderKnexMigration.ts} +8 -14
  485. package/src/flows/FlowCompiler.ts +1 -1
  486. package/src/flows/Flows.ts +1 -1
  487. package/src/flows/index.ts +1 -1
  488. package/src/health/Health.ts +163 -0
  489. package/src/health/README.md +46 -0
  490. package/src/health/contracts/Health.ts +47 -0
  491. package/src/health/contracts/HealthHttp.ts +19 -0
  492. package/src/health/contracts/index.ts +2 -0
  493. package/src/health/databaseHealthCheck.ts +21 -0
  494. package/src/health/fastify.ts +49 -0
  495. package/src/health/index.ts +3 -0
  496. package/src/in-app/InApp.ts +173 -0
  497. package/src/in-app/InAppError.ts +8 -0
  498. package/src/in-app/InAppRecord.ts +41 -0
  499. package/src/in-app/README.md +193 -0
  500. package/src/in-app/contracts/InAppInbox.ts +51 -0
  501. package/src/in-app/contracts/InAppMessage.ts +19 -0
  502. package/src/in-app/contracts/InAppScope.ts +12 -0
  503. package/src/in-app/contracts/index.ts +3 -0
  504. package/src/in-app/examples/sendReportReady.ts +14 -0
  505. package/src/in-app/index.ts +4 -0
  506. package/src/in-app/validation.ts +49 -0
  507. package/src/index.ts +2 -22
  508. package/src/logging/DevelopmentConsole.ts +154 -0
  509. package/src/logging/Log.ts +5 -2
  510. package/src/logging/PrettyLogFormatter.ts +165 -0
  511. package/src/logging/README.md +52 -109
  512. package/src/logging/acquireDevelopmentConsole.ts +19 -0
  513. package/src/logging/contracts/DevelopmentConsoleOptions.ts +13 -0
  514. package/src/logging/contracts/EmailLogOptions.ts +9 -0
  515. package/src/logging/contracts/HttpExchangeMonitorOptions.ts +13 -0
  516. package/src/logging/contracts/LogTransportOptions.ts +10 -0
  517. package/src/logging/contracts/LoggingOptions.ts +12 -1
  518. package/src/logging/contracts/index.ts +4 -0
  519. package/src/logging/development/README.md +88 -0
  520. package/src/logging/drivers/PinoLoggerDriver.ts +72 -20
  521. package/src/logging/examples/runDevelopmentLogs.ts +36 -0
  522. package/src/logging/formatLogEmail.ts +24 -0
  523. package/src/logging/highlightQueueMessage.ts +38 -0
  524. package/src/logging/httpBodyCapture.ts +393 -0
  525. package/src/logging/index.ts +2 -0
  526. package/src/logging/redactLogEmail.ts +12 -0
  527. package/src/logging/registerHttpExchangeMonitor.ts +45 -0
  528. package/src/logging/transports/EmailLogTransport.ts +46 -0
  529. package/src/mail/Mail.ts +5 -0
  530. package/src/mail/MailDeliveryError.ts +8 -0
  531. package/src/mail/README.md +11 -1
  532. package/src/mail/index.ts +1 -0
  533. package/src/mail/transports/MailgunTransport.ts +2 -0
  534. package/src/mail/transports/ResendTransport.ts +24 -22
  535. package/src/media/MediaManager.ts +31 -10
  536. package/src/media/README.md +4 -0
  537. package/src/media/examples/runPrivateFiles.ts +2 -2
  538. package/src/network/BlockedUrlError.ts +19 -0
  539. package/src/network/README.md +133 -0
  540. package/src/network/assertPublicUrl.ts +77 -0
  541. package/src/network/contracts/GuardedFetch.ts +40 -0
  542. package/src/network/contracts/PublicUrlOptions.ts +17 -0
  543. package/src/network/contracts/index.ts +2 -0
  544. package/src/network/examples/runGuardedFetch.ts +35 -0
  545. package/src/network/guardedFetch.ts +150 -0
  546. package/src/network/index.ts +6 -0
  547. package/src/network/playwright/GuardedBrowserProxy.ts +172 -0
  548. package/src/network/playwright/contracts/GuardedBrowserContextOptions.ts +43 -0
  549. package/src/network/playwright/contracts/index.ts +1 -0
  550. package/src/network/playwright/index.ts +2 -0
  551. package/src/network/playwright/newGuardedBrowserContext.ts +74 -0
  552. package/src/network/privateNetworkAddresses.ts +166 -0
  553. package/src/network/publicAddressLookup.ts +49 -0
  554. package/src/notifications/Notifications.ts +105 -0
  555. package/src/notifications/README.md +59 -0
  556. package/src/notifications/contracts/Notification.ts +65 -0
  557. package/src/notifications/contracts/NotificationDelivery.ts +11 -0
  558. package/src/notifications/contracts/index.ts +2 -0
  559. package/src/notifications/examples/ReportReadyNotification.ts +31 -0
  560. package/src/notifications/index.ts +2 -0
  561. package/src/queue/JobRunAttempt.ts +17 -0
  562. package/src/queue/JobRunEvent.ts +16 -0
  563. package/src/queue/JobRunStoppedError.ts +8 -0
  564. package/src/queue/Queue.ts +112 -11
  565. package/src/queue/QueueTerminalError.ts +12 -0
  566. package/src/queue/QueueWorker.ts +86 -7
  567. package/src/queue/QueueWorkerReporter.ts +59 -0
  568. package/src/queue/QueueableJob.ts +2 -2
  569. package/src/queue/README.md +142 -1
  570. package/src/queue/RunnableJob.ts +272 -0
  571. package/src/queue/console.ts +54 -21
  572. package/src/queue/contracts/QueueDriver.ts +9 -0
  573. package/src/queue/contracts/QueueJobRunner.ts +4 -0
  574. package/src/queue/contracts/QueuePayload.ts +1 -1
  575. package/src/queue/contracts/QueueSelection.ts +11 -0
  576. package/src/queue/contracts/QueueService.ts +19 -4
  577. package/src/queue/contracts/QueueWorkerLifecycle.ts +2 -2
  578. package/src/queue/contracts/QueueWorkerSnapshot.ts +15 -0
  579. package/src/queue/contracts/QueueableJob.ts +7 -3
  580. package/src/queue/contracts/QueueableJobContract.ts +13 -0
  581. package/src/queue/contracts/index.ts +6 -0
  582. package/src/queue/drivers/DatabaseQueueDriver.ts +25 -3
  583. package/src/queue/drivers/RedisQueueDriver.ts +36 -0
  584. package/src/queue/examples/runQueueSelection.ts +34 -0
  585. package/src/queue/index.ts +7 -0
  586. package/src/queue/jobEnvelopeHasPrefix.ts +6 -0
  587. package/src/scheduler/README.md +50 -9
  588. package/src/scheduler/ScheduledEvent.ts +20 -5
  589. package/src/scheduler/ScheduledJob.ts +1 -1
  590. package/src/scheduler/Scheduler.ts +73 -27
  591. package/src/scheduler/SchedulerCheckpointRecord.ts +51 -0
  592. package/src/scheduler/SchedulerWorker.ts +54 -19
  593. package/src/scheduler/console.ts +3 -1
  594. package/src/scheduler/contracts/Schedule.ts +22 -0
  595. package/src/scheduler/contracts/Scheduler.ts +21 -6
  596. package/src/scheduler/contracts/SchedulerCheckpoint.ts +23 -0
  597. package/src/scheduler/contracts/SchedulerConsole.ts +5 -0
  598. package/src/scheduler/contracts/SchedulerWorker.ts +6 -1
  599. package/src/scheduler/contracts/index.ts +2 -0
  600. package/src/scheduler/examples/runSchedulerWindow.ts +54 -0
  601. package/src/scheduler/index.ts +1 -0
  602. package/src/server/App.ts +73 -10
  603. package/src/server/README.md +95 -2
  604. package/src/server/contracts/HttpErrorHandlerOptions.ts +29 -0
  605. package/src/server/contracts/index.ts +1 -0
  606. package/src/server/examples/createFirstServer.ts +5 -3
  607. package/src/server/index.ts +4 -0
  608. package/src/server/publicServerErrorMessage.ts +17 -0
  609. package/src/server/registerBrowserJsonFormatting.ts +94 -0
  610. package/src/server/registerHttpErrorHandler.ts +96 -0
  611. package/src/ssr/README.md +6 -0
  612. package/src/ssr/vite/contracts/ViteSsrOptions.ts +2 -0
  613. package/src/ssr/vite/fastifyViteSsr.ts +4 -3
  614. package/src/storage/drivers/FlystorageDisk.ts +2 -2
  615. package/src/storage/index.ts +2 -2
  616. package/src/websocket/README.md +458 -0
  617. package/src/websocket/WebSocketChannels.ts +99 -0
  618. package/src/websocket/WebSocketConnection.ts +162 -0
  619. package/src/websocket/WebSockets.ts +157 -0
  620. package/src/websocket/client/WebSocketClient.ts +188 -0
  621. package/src/websocket/client/index.ts +3 -0
  622. package/src/websocket/contracts/WebSocketChannel.ts +23 -0
  623. package/src/websocket/contracts/WebSocketClient.ts +48 -0
  624. package/src/websocket/contracts/WebSocketEndpoint.ts +46 -0
  625. package/src/websocket/contracts/WebSocketOptions.ts +50 -0
  626. package/src/websocket/contracts/WebSocketPresence.ts +6 -0
  627. package/src/websocket/contracts/WebSocketServiceOptions.ts +12 -0
  628. package/src/websocket/contracts/index.ts +6 -0
  629. package/src/websocket/defineChannel.ts +14 -0
  630. package/src/websocket/defineWebSocket.ts +15 -0
  631. package/src/websocket/examples/board/LiveBoard.ts +97 -0
  632. package/src/websocket/examples/board/SummarizeBoardJob.ts +52 -0
  633. package/src/websocket/examples/board/boardSnapshot.ts +16 -0
  634. package/src/websocket/examples/board/createBoardClient.ts +43 -0
  635. package/src/websocket/examples/board/createBoardStore.ts +58 -0
  636. package/src/websocket/examples/board/registerBoardRoutes.ts +31 -0
  637. package/src/websocket/examples/createChannelSync.ts +66 -0
  638. package/src/websocket/examples/deploymentEndpoint.ts +13 -0
  639. package/src/websocket/examples/deploymentSnapshot.ts +36 -0
  640. package/src/websocket/examples/resourceChannels.ts +18 -0
  641. package/src/websocket/examples/userEndpoint.ts +27 -0
  642. package/src/websocket/fastify.ts +39 -0
  643. package/src/websocket/index.ts +5 -0
  644. package/templates/AGENTS.md +33 -2
  645. /package/dist/flows/{FlowValueValidator.d.ts → flowValueValidator.d.ts} +0 -0
  646. /package/dist/flows/{FlowValueValidator.js → flowValueValidator.js} +0 -0
  647. /package/dist/storage/{mime.d.ts → mimeTypeFromPath.d.ts} +0 -0
  648. /package/dist/storage/{mime.js → mimeTypeFromPath.js} +0 -0
  649. /package/dist/storage/{contents.d.ts → storageContentsToBuffer.d.ts} +0 -0
  650. /package/dist/storage/{contents.js → storageContentsToBuffer.js} +0 -0
  651. /package/src/flows/{FlowValueValidator.ts → flowValueValidator.ts} +0 -0
  652. /package/src/storage/{mime.ts → mimeTypeFromPath.ts} +0 -0
  653. /package/src/storage/{contents.ts → storageContentsToBuffer.ts} +0 -0
@@ -15,6 +15,9 @@ server/
15
15
  App.ts
16
16
  appContext.ts
17
17
  RequestContext.ts
18
+ registerBrowserJsonFormatting.ts
19
+ registerHttpErrorHandler.ts
20
+ publicServerErrorMessage.ts
18
21
  tests/
19
22
  index.ts
20
23
  README.md
@@ -22,7 +25,7 @@ server/
22
25
 
23
26
  `App` composes framework services but leaves their behavior in the owning
24
27
  service modules. It currently discovers database, auth, request context, cache,
25
- events, logging, URL, queue, scheduler, security, serialization, storage, and
28
+ events, health, logging, URL, queue, scheduler, security, serialization, storage, and
26
29
  media services. Application-specific capabilities belong on an application
27
30
  subclass and can reuse `service(...)` for lazy singleton ownership.
28
31
 
@@ -44,6 +47,15 @@ The public surface includes:
44
47
  - `activeAppDatabase()` and `activeAppRequestContext()`, which expose optional
45
48
  low-level context to framework internals.
46
49
  - `RequestContext` and `RequestContextValues` for request-isolated values.
50
+ - `registerHttpErrorHandler(...)` for the shared Fastify error boundary and
51
+ `publicServerErrorMessage(...)` for other server-owned error renderers.
52
+ - `registerBrowserJsonFormatting(...)` for servers with their own error handler;
53
+ the shared error boundary installs it automatically.
54
+
55
+ Standalone HTTP hosts can import the formatting hook from
56
+ `@db3.ai/app/server/browser-json`. This narrow entry point does not load `App`
57
+ or its database, AI, storage, and queue dependencies when the host bundles only
58
+ the hook into an isolated website runtime.
47
59
 
48
60
  Normal application code should use `app().db`, `app().queue`, and the other
49
61
  service getters. `activeAppDatabase()` is a framework escape hatch, not a
@@ -164,7 +176,78 @@ request-owned store.
164
176
 
165
177
  ## Shutdown And Failure Behaviour
166
178
 
167
- `App.close()` clears the active reference when it owns it, detaches the Scheduler recorder,
179
+ ### Browser JSON navigation
180
+
181
+ Visit a JSON route such as `/health` directly in a browser to see indented
182
+ JSON. `registerHttpErrorHandler(server)` installs this behavior once for every
183
+ route on that Fastify server. A server with its own error handler can use the
184
+ framework hook independently before registering routes:
185
+
186
+ ```ts
187
+ import { registerBrowserJsonFormatting } from '@db3.ai/app/server';
188
+
189
+ registerBrowserJsonFormatting(server);
190
+ ```
191
+
192
+ Only a GET request with `Sec-Fetch-Mode: navigate` receives readable spacing.
193
+ A browser `fetch()`, POST, API client, or request without navigation metadata
194
+ keeps compact JSON. Detection does not depend on `User-Agent` or `Accept`, which
195
+ cannot reliably distinguish a page visit from a JavaScript request. The body
196
+ remains `application/json` with the same data and HTTP status.
197
+
198
+ The send hook runs after Fastify's response schema has filtered the payload and,
199
+ when registered through the shared error boundary, after its production error
200
+ sanitizer. It preserves existing `Vary` fields and adds `Sec-Fetch-Mode` so a
201
+ cache keeps the two representations separate. Streams, encoded responses,
202
+ attachments, responses with integrity headers, and JSON bodies over 1,000,000
203
+ characters remain untouched. Depth and formatted-size limits also bound this
204
+ browser-only work. Formatting removes a pre-set `Content-Length` so Fastify can
205
+ write the correct length.
206
+
207
+ ### HTTP errors
208
+
209
+ Install the framework boundary immediately after creating Fastify, **before any
210
+ routes or plugins** (including awaited plugin registration):
211
+
212
+ ```ts
213
+ import Fastify from 'fastify';
214
+ import { registerHttpErrorHandler } from '@db3.ai/app/server';
215
+
216
+ const server = Fastify({ logger: true });
217
+ registerHttpErrorHandler(server);
218
+ ```
219
+
220
+ Production, staging, unknown and unset `NODE_ENV` values receive only
221
+ `{ error: 'server_error', message: 'Unexpected server error', reference }` for
222
+ 5xx responses. The final send hook replaces serialized bodies as well as thrown
223
+ errors, including bodies returned by child-plugin error handlers or shaped by
224
+ route response schemas. It preserves the HTTP failure status and disables caching.
225
+ Captured SQL exceptions remain 500 errors even if a child handler tries to
226
+ return them with a client or success status.
227
+ SQL text, driver codes, provider payloads, stacks and nested exception metadata
228
+ are never copied into that public envelope.
229
+
230
+ Explicit `dev`, `develop`, `development`, `local` and `test` environments retain
231
+ diagnostic messages. The original exception is logged through `request.log`
232
+ with the same generated reference in every environment. Applications must enable
233
+ and retain their server logs; Fastify with logging disabled has no log sink.
234
+ The optional `onServerError(error, context)` observer can retain a support record.
235
+ Explicitly returned 5xx bodies are retained in the server-only `responseBody`
236
+ context/log field. Observer failures are logged without changing the public body.
237
+
238
+ Fastify request-validation/parsing failures retain their 4xx status and message;
239
+ missing ActiveRecord records return 404. Use `mapError` only for known application
240
+ errors with deliberately public client messages. A third-party `statusCode: 400`
241
+ does not make an exception safe. Mapped 5xx messages are still hidden in production.
242
+
243
+ This boundary protects the ordinary Fastify reply lifecycle. Responses written
244
+ directly to the raw socket, already-started streams, errors embedded inside
245
+ successful 2xx data, and later send hooks that rewrite the body need their own
246
+ safe public protocol. Do not return raw exceptions through those paths. CLI and
247
+ worker exceptions keep their server-side diagnostics; database errors themselves
248
+ are never mutated or stripped of information.
249
+
250
+ `App.close()` first closes mounted WebSocket connections, then clears the active reference when it owns it, detaches the Scheduler recorder,
168
251
  clears Events listeners, awaits Cache and Log shutdown, closes the
169
252
  framework-owned default database, and clears cached service instances.
170
253
  Application subclasses remain responsible for closing any additional resources
@@ -217,3 +300,13 @@ specific real framework component they need, then call `close()` or
217
300
  and [`RequestContext.ts`](./RequestContext.ts). Behavioural tests live at
218
301
  `packages/app/src/server/tests/` in the source repository and are not included
219
302
  in the installed runtime package.
303
+
304
+ ## Composing feature apps
305
+
306
+ Set the host directory and call `await application.apps.boot()` before serving
307
+ requests. DB3 discovers apps/{id}/manifest.json and marked direct npm dependencies.
308
+ A root App.ts extends AppService; app().social resolves the optional service.
309
+ Generated declarations preserve its type. Explicit defineApp maps are supported
310
+ for programmatic composition; an empty map disables discovery. App.close()
311
+ releases app-owned resources before shared services. See [Apps](../apps/README.md)
312
+ for local folders, npm packaging, owned migrations and administrator controls.
@@ -0,0 +1,29 @@
1
+ import type { FastifyRequest } from 'fastify';
2
+
3
+ /** Application-owned mapping for deliberate HTTP failures, never arbitrary provider errors. */
4
+ export interface HttpErrorResponse {
5
+ /** HTTP failure status between 400 and 599. */
6
+ statusCode: number;
7
+ /** Public client-error copy. Production 5xx bodies are always replaced. */
8
+ body: { error: string; message: string };
9
+ }
10
+
11
+ /** Server-only diagnostics passed to an application's support-record store. */
12
+ export interface HttpServerErrorContext {
13
+ /** Request whose logger and ID correlate the failure. */
14
+ request: FastifyRequest;
15
+ /** Actual HTTP response status. */
16
+ statusCode: number;
17
+ /** Framework-generated reference shared by logs and the public response. */
18
+ reference: string;
19
+ /** Explicitly returned error body, if no exception reached the handler. Never public in production. */
20
+ responseBody?: string;
21
+ }
22
+
23
+ /** Application integration points for the framework's HTTP error boundary. */
24
+ export interface HttpErrorHandlerOptions {
25
+ /** Map only known application errors; returning undefined uses framework classification. */
26
+ mapError?: (error: unknown) => HttpErrorResponse | undefined;
27
+ /** Retain extra support records after framework logging. Failures here cannot leak diagnostics. */
28
+ onServerError?: (error: unknown, context: HttpServerErrorContext) => void;
29
+ }
@@ -0,0 +1 @@
1
+ export type { HttpErrorHandlerOptions, HttpErrorResponse, HttpServerErrorContext } from './HttpErrorHandlerOptions';
@@ -1,5 +1,6 @@
1
1
  import Fastify, { type FastifyInstance } from 'fastify';
2
- import { App } from '@db3.ai/app/server';
2
+ import { App, registerHttpErrorHandler } from '@db3.ai/app/server';
3
+ import { registerHealthRoute } from '@db3.ai/app/health/fastify';
3
4
 
4
5
  /**
5
6
  * Creates a small HTTP application without opening a port or database.
@@ -11,10 +12,11 @@ import { App } from '@db3.ai/app/server';
11
12
  * @returns HTTP server with framework cleanup attached to its close lifecycle.
12
13
  */
13
14
  export function createFirstServer(greeting = 'Hello'): FastifyInstance {
14
- const application = new App({ config: { greeting } });
15
+ const application = new App({ config: { greeting }, health: { service: 'first-application' } });
15
16
  const server = Fastify();
17
+ registerHttpErrorHandler(server);
16
18
  server.addHook('onClose', async () => { await application.close(); });
17
- server.get('/health', async () => ({ status: 'ready' }));
19
+ registerHealthRoute(server, { app: application });
18
20
  server.get<{ Params: { name: string } }>('/hello/:name', {
19
21
  schema: { params: { type: 'object', required: ['name'], properties: { name: { type: 'string', minLength: 1, maxLength: 80 } } } },
20
22
  }, async request => application.requestContext.run(async () => {
@@ -1,3 +1,7 @@
1
+ export * from './contracts';
2
+ export { publicServerErrorMessage } from './publicServerErrorMessage';
3
+ export { registerBrowserJsonFormatting } from './registerBrowserJsonFormatting';
4
+ export { registerHttpErrorHandler } from './registerHttpErrorHandler';
1
5
  export {
2
6
  App,
3
7
  type AppOptions,
@@ -0,0 +1,17 @@
1
+ import { isDevelopmentEnvironment, unknownErrorMessage } from '@db3.ai/pure';
2
+
3
+ /**
4
+ * Returns internal diagnostics only for explicitly named development environments.
5
+ *
6
+ * Production, staging, unknown and unset environments fail closed. This policy
7
+ * applies to every exception, without relying on database-specific signatures.
8
+ *
9
+ * @param error - Original server-side failure; never modified by this function.
10
+ * @param environment - Runtime environment, defaulting to NODE_ENV.
11
+ * @returns Detailed development message or the generic public failure message.
12
+ */
13
+ export function publicServerErrorMessage(error: unknown, environment = process.env.NODE_ENV): string {
14
+ return isDevelopmentEnvironment(environment)
15
+ ? unknownErrorMessage(error) || 'Unexpected server error'
16
+ : 'Unexpected server error';
17
+ }
@@ -0,0 +1,94 @@
1
+ import type { FastifyInstance, FastifyReply } from 'fastify';
2
+
3
+ const MAX_PRETTY_JSON_CHARS = 1_000_000;
4
+ const MAX_PRETTY_JSON_DEPTH = 64;
5
+ const MAX_FORMATTED_JSON_CHARS = 4_000_000;
6
+ const JSON_CONTENT_TYPE = /^application\/json(?:\s*;|$)/i;
7
+ const JSON_TOKENS = /"(?:\\.|[^"\\])*"|[{}\[\],:]|[^\s{}\[\],:"]+/g;
8
+ const BODY_PRESERVING_HEADERS = ['content-encoding', 'content-disposition', 'etag', 'content-digest', 'digest', 'content-md5'];
9
+
10
+ /**
11
+ * Formats small JSON responses for browser page navigations across a Fastify server.
12
+ *
13
+ * Register before routes and plugins so their replies inherit the send hook. The
14
+ * hook runs after Fastify response-schema serialization and only reformats GET
15
+ * requests with `Sec-Fetch-Mode: navigate`. Browser fetches, other methods,
16
+ * streams, encoded bodies, and responses with integrity headers retain their
17
+ * original bytes. Large JSON bodies remain compact to bound browser-only work.
18
+ *
19
+ * @param server - Fastify server that owns the response lifecycle.
20
+ * @example
21
+ * const server = Fastify();
22
+ * registerBrowserJsonFormatting(server);
23
+ */
24
+ export function registerBrowserJsonFormatting(server: FastifyInstance): void {
25
+ server.addHook('onSend', (request, reply, payload, done) => {
26
+ if (request.method !== 'GET' || typeof payload !== 'string' || payload.length > MAX_PRETTY_JSON_CHARS) return done(null, payload);
27
+ const contentType = reply.getHeader('content-type');
28
+ if (typeof contentType !== 'string' || !JSON_CONTENT_TYPE.test(contentType)) return done(null, payload);
29
+ if (BODY_PRESERVING_HEADERS.some(header => reply.hasHeader(header))) return done(null, payload);
30
+
31
+ varyByFetchMode(reply);
32
+ if (request.headers['sec-fetch-mode'] !== 'navigate') return done(null, payload);
33
+
34
+ try {
35
+ JSON.parse(payload);
36
+ const formatted = formatJsonTokens(payload);
37
+ if (formatted === payload) return done(null, payload);
38
+ reply.removeHeader('content-length');
39
+ return done(null, formatted);
40
+ } catch {
41
+ return done(null, payload);
42
+ }
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Inserts spacing around validated JSON tokens without changing numeric or string literals.
48
+ *
49
+ * @param source - Valid serialized JSON whose original value tokens must be retained.
50
+ * @returns Indented JSON, or the original body when depth or output limits are reached.
51
+ */
52
+ function formatJsonTokens(source: string): string {
53
+ const tokens = source.match(JSON_TOKENS);
54
+ if (!tokens) return source;
55
+ let depth = 0;
56
+ let formatted = '';
57
+
58
+ for (let index = 0; index < tokens.length; index++) {
59
+ const token = tokens[index]!;
60
+ if (token === '{' || token === '[') {
61
+ const next = tokens[index + 1];
62
+ if (next === (token === '{' ? '}' : ']')) {
63
+ formatted += token + next;
64
+ index++;
65
+ } else {
66
+ if (depth >= MAX_PRETTY_JSON_DEPTH) return source;
67
+ formatted += token + '\n' + ' '.repeat(++depth);
68
+ }
69
+ } else if (token === '}' || token === ']') {
70
+ formatted += '\n' + ' '.repeat(--depth) + token;
71
+ } else if (token === ',') {
72
+ formatted += ',\n' + ' '.repeat(depth);
73
+ } else if (token === ':') {
74
+ formatted += ': ';
75
+ } else {
76
+ formatted += token;
77
+ }
78
+ if (formatted.length > MAX_FORMATTED_JSON_CHARS) return source;
79
+ }
80
+
81
+ return formatted;
82
+ }
83
+
84
+ /**
85
+ * Keeps cached compact and browser-readable JSON variants separate.
86
+ *
87
+ * @param reply - Response whose existing Vary fields must be preserved.
88
+ */
89
+ function varyByFetchMode(reply: FastifyReply): void {
90
+ const existing = reply.getHeader('vary');
91
+ const values = existing === undefined ? '' : String(existing);
92
+ if (values === '*' || values.split(',').some(value => value.trim().toLowerCase() === 'sec-fetch-mode')) return;
93
+ reply.header('vary', values ? `${values}, Sec-Fetch-Mode` : 'Sec-Fetch-Mode');
94
+ }
@@ -0,0 +1,96 @@
1
+ import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
2
+ import { errorCodeForStatus, isDevelopmentEnvironment, isSqlError } from '@db3.ai/pure';
3
+ import { ulid } from '@db3.ai/pure/ulid';
4
+ import { RecordNotFoundError } from '../db';
5
+ import { publicServerErrorMessage } from './publicServerErrorMessage';
6
+ import { registerBrowserJsonFormatting } from './registerBrowserJsonFormatting';
7
+ import type * as server from './contracts';
8
+
9
+ /**
10
+ * Installs framework error logging and production-safe HTTP responses.
11
+ *
12
+ * Call immediately after constructing Fastify, before registering any routes or
13
+ * plugins. The inherited send hook also sanitizes explicit 5xx responses and
14
+ * child-plugin error handlers. Only deliberate mapped client errors and Fastify
15
+ * request errors retain public messages. Browser JSON formatting is installed
16
+ * after this boundary so it only sees the safe serialized response. Never send
17
+ * internal errors as 2xx data.
18
+ *
19
+ * @param fastify - HTTP host, still owned and closed by the caller.
20
+ * @param options - Application error classification and support-record observer.
21
+ * @example
22
+ * const server = Fastify({ logger: true });
23
+ * registerHttpErrorHandler(server);
24
+ * server.get('/example', async () => loadExample());
25
+ */
26
+ export function registerHttpErrorHandler(fastify: FastifyInstance, options: server.HttpErrorHandlerOptions = {}): void {
27
+ const failures = new WeakMap<FastifyReply, { error: unknown; reference?: string }>();
28
+
29
+ /** Records the original exception once, keeping support-store failures private. */
30
+ function recordFailure(request: FastifyRequest, reply: FastifyReply, error: unknown, responseBody?: string): string {
31
+ const existing = failures.get(reply);
32
+ if (existing?.reference) return existing.reference;
33
+ const reference = ulid();
34
+ failures.set(reply, { error, reference });
35
+ const context = { request, statusCode: reply.statusCode, reference, responseBody };
36
+ request.log.error({ err: error, requestMethod: request.method, requestUrl: request.url, statusCode: reply.statusCode, reference, responseBody }, 'Request failed with server error');
37
+ try {
38
+ options.onServerError?.(error, context);
39
+ } catch (observerError) {
40
+ request.log.error({ err: observerError, reference }, 'Server error observer failed');
41
+ }
42
+ return reference;
43
+ }
44
+
45
+ fastify.addHook('onError', (_request, reply, error, done) => {
46
+ failures.set(reply, { error });
47
+ done();
48
+ });
49
+
50
+ fastify.setErrorHandler((error, request, reply) => {
51
+ const mapped = isSqlError(error) ? undefined : options.mapError?.(error);
52
+ const response = mapped && Number.isInteger(mapped.statusCode) && mapped.statusCode >= 400 && mapped.statusCode <= 599
53
+ ? mapped
54
+ : defaultErrorResponse(error);
55
+ reply.type('application/json').code(response.statusCode);
56
+ if (response.statusCode < 500) return reply.send(response.body);
57
+ const reference = recordFailure(request, reply, error);
58
+ return reply.send({ ...response.body, reference });
59
+ });
60
+
61
+ fastify.addHook('onSend', (request, reply, payload, done) => {
62
+ const failure = failures.get(reply);
63
+ if (reply.statusCode < 500) {
64
+ if (!isSqlError(failure?.error)) return done(null, payload);
65
+ // A child handler cannot make a database failure public by labelling
66
+ // it a client error or a successful response.
67
+ reply.code(500);
68
+ }
69
+ const responseBody = typeof payload === 'string' ? payload : Buffer.isBuffer(payload) ? payload.toString('utf8') : undefined;
70
+ const reference = recordFailure(request, reply, failure?.error ?? new Error(`HTTP ${reply.statusCode} response`), responseBody);
71
+ if (isDevelopmentEnvironment(process.env.NODE_ENV)) return done(null, payload);
72
+
73
+ // Replace the serialized body too: route schemas and child handlers must
74
+ // not reintroduce stack traces, SQL, provider codes or arbitrary metadata.
75
+ if (payload && typeof payload === 'object' && 'destroy' in payload && typeof payload.destroy === 'function') payload.destroy();
76
+ reply.removeHeader('content-length');
77
+ reply.removeHeader('content-encoding');
78
+ reply.type('application/json').header('cache-control', 'no-store');
79
+ return done(null, JSON.stringify({ error: 'server_error', message: publicServerErrorMessage(failure?.error), reference }));
80
+ });
81
+ registerBrowserJsonFormatting(fastify);
82
+ }
83
+
84
+ /** Classifies framework client errors without trusting third-party status codes. */
85
+ function defaultErrorResponse(error: unknown): server.HttpErrorResponse {
86
+ if (!isSqlError(error) && error instanceof RecordNotFoundError) {
87
+ return { statusCode: 404, body: { error: 'not_found', message: error.message } };
88
+ }
89
+ if (!isSqlError(error) && error instanceof Error) {
90
+ const { code, statusCode } = error as Error & { code?: unknown; statusCode?: unknown };
91
+ if (typeof code === 'string' && code.startsWith('FST_') && typeof statusCode === 'number' && Number.isInteger(statusCode) && statusCode >= 400 && statusCode < 500) {
92
+ return { statusCode, body: { error: errorCodeForStatus(statusCode), message: error.message } };
93
+ }
94
+ }
95
+ return { statusCode: 500, body: { error: 'server_error', message: publicServerErrorMessage(error) } };
96
+ }
package/src/ssr/README.md CHANGED
@@ -147,6 +147,12 @@ In development the adapter uses Vite middleware mode, transforms the HTML shell
147
147
  per request, hot-loads `/src/entry-server.ts`, and makes Vite's source, module,
148
148
  dependency, filesystem, and HMR URL namespaces available to the browser. Unknown
149
149
  page URLs still fall through to the application's ordinary not-found boundary.
150
+ For a site organized into `client/` and feature folders, set
151
+ `developmentEntry: '/client/entry-server.ts'` and
152
+ `developmentAssetRoutes: ['/client/*', '/apps/*']`. These explicit source routes
153
+ extend Vite's built-in development namespaces. They do not change page routing
154
+ or expose those source directories in production. Keep API routes with the host;
155
+ do not include them in `developmentAssetRoutes`.
150
156
  In production it reads `dist/client/index.html`, imports
151
157
  `dist/server/entry-server.js`, serves the configured asset directory, and maps
152
158
  `context.modules` through Vite's SSR manifest. Set `preloadJavaScript: false`
@@ -31,6 +31,8 @@ export interface FastifyViteSsrOptions<TState extends object = SsrState> {
31
31
  template?: string;
32
32
  /** Vite development server-entry module id. */
33
33
  developmentEntry?: string;
34
+ /** Additional development-only Vite source routes, for example ['/client/*', '/apps/*']. */
35
+ developmentAssetRoutes?: readonly string[];
34
36
  /** Production client build directory containing the transformed template. */
35
37
  clientOutDir?: string;
36
38
  /** Production server bundle exporting the application renderer. */
@@ -59,7 +59,7 @@ export function fastifyViteSsr<TState extends object = SsrState>(
59
59
 
60
60
  await server.register((await import('@fastify/middie')).default);
61
61
  server.use(runtime.vite.middlewares);
62
- registerDevelopmentAssetRoutes(server);
62
+ registerDevelopmentAssetRoutes(server, options.developmentAssetRoutes);
63
63
  server.addHook('onClose', async () => {
64
64
  await runtime.vite.close();
65
65
  });
@@ -100,9 +100,10 @@ export function fastifyViteSsr<TState extends object = SsrState>(
100
100
  * application's ordinary not-found boundary remains authoritative.
101
101
  *
102
102
  * @param server - Encapsulated Fastify instance hosting the Vite middleware.
103
+ * @param additionalRoutes - Explicit browser source namespaces owned by this application.
103
104
  */
104
- function registerDevelopmentAssetRoutes(server: Parameters<FastifyPluginAsync>[0]): void {
105
- for (const route of DEVELOPMENT_ASSET_ROUTES) {
105
+ function registerDevelopmentAssetRoutes(server: Parameters<FastifyPluginAsync>[0], additionalRoutes: readonly string[] = []): void {
106
+ for (const route of new Set([...DEVELOPMENT_ASSET_ROUTES, ...additionalRoutes])) {
106
107
  server.get(route, (_request, reply) => reply.callNotFound());
107
108
  }
108
109
  }
@@ -1,8 +1,8 @@
1
1
  import type { FileStorage } from '@flystorage/file-storage';
2
2
  import type { Readable } from 'node:stream';
3
3
 
4
- import { storageContentsToBuffer } from '../contents';
5
- import { mimeTypeFromPath } from '../mime';
4
+ import { storageContentsToBuffer } from '../storageContentsToBuffer';
5
+ import { mimeTypeFromPath } from '../mimeTypeFromPath';
6
6
  import { normalizeStorageDirectoryPath, normalizeStoragePath } from '../path';
7
7
  import type { StorageListing, StorageListOptions } from '../contracts';
8
8
  import type { StorageContents, StorageDisk, StoragePutOptions } from '../types';
@@ -1,7 +1,7 @@
1
1
  export * from './Storage';
2
- export * from './contents';
2
+ export * from './storageContentsToBuffer';
3
3
  export * from './contracts';
4
4
  export * from './drivers';
5
- export * from './mime';
5
+ export * from './mimeTypeFromPath';
6
6
  export * from './path';
7
7
  export * from './types';