@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
@@ -0,0 +1,191 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { ActiveRecord } from '../db/index.js';
3
+ import { UserIdentity } from '../auth/index.js';
4
+ import { app } from '../server/appContext.js';
5
+ import { InAppRecord } from './InAppRecord.js';
6
+ import { InAppError } from './InAppError.js';
7
+ import { normalizeMessage, normalizeQuery, normalizeRecipients, normalizeScope, normalizeSend } from './validation.js';
8
+ /** Persistent in-app inbox independent of notification classes, email and live delivery. */
9
+ export class InApp {
10
+ options;
11
+ identityModel;
12
+ #commits = new WeakMap();
13
+ /** Creates the service; ordinary applications use app().inApp and App's configured Auth identity model. */
14
+ constructor(options = {}, identityModel = UserIdentity) {
15
+ this.options = options;
16
+ this.identityModel = identityModel;
17
+ }
18
+ /**
19
+ * Atomically accepts one message for up to 100 distinct recipients.
20
+ * Trusted server code owns sender authorization. The service validates identities and receive-scope policy.
21
+ * @param recipients - User ID or IDs; an empty list creates no work.
22
+ * @param message - Inbox content with a required plain-text fallback and optional rich body.
23
+ * @param options - Explicit scope, notification type and optional deduplication key.
24
+ * @returns Per-recipient durable acceptance, never a claim of browser delivery.
25
+ * @example await app().inApp.send(userId, { title: 'Ready', body: 'Your report is ready.' }, { scope: { type: 'account' }, type: 'report.ready' });
26
+ */
27
+ async send(recipients, message, options) {
28
+ const ids = normalizeRecipients(recipients);
29
+ const content = normalizeMessage(message);
30
+ const input = normalizeSend(options);
31
+ const contentHash = hash(content);
32
+ if (!ids.length)
33
+ return [];
34
+ const connection = InAppRecord.getDb();
35
+ const committed = this.#committed(connection);
36
+ const accepted = await connection.transaction(transaction => ActiveRecord.withDb(transaction, async () => {
37
+ // Lock in stable order so concurrent batches and retries cannot deadlock by recipient order.
38
+ const canonicalIds = new Map();
39
+ for (const userId of [...ids].sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase()))) {
40
+ const row = await this.identityModel.where(this.identityModel.primaryKey, userId).toKnex().forUpdate().first();
41
+ if (!row)
42
+ throw new InAppError('forbidden', 'Notification recipient is unavailable.');
43
+ const canonicalId = String(this.identityModel.fromDb(row).get(this.identityModel.primaryKey));
44
+ canonicalIds.set(userId, canonicalId);
45
+ await this.#authorize(canonicalId, input.scope, 'receive');
46
+ }
47
+ const results = [];
48
+ for (const userId of new Set(ids.map(id => canonicalIds.get(id)))) {
49
+ const deduplicationHash = input.key === undefined ? null : hash([userId, input.scope.type, scopeId(input.scope), input.type, input.key]);
50
+ // Request a current read; stale outer snapshots may require a caller-owned transaction retry.
51
+ const existingRow = deduplicationHash ? await InAppRecord.where('deduplicationHash', deduplicationHash).toKnex().forUpdate().first() : null;
52
+ const existing = existingRow ? InAppRecord.fromDb(existingRow) : null;
53
+ if (existing) {
54
+ if (existing.contentHash !== contentHash)
55
+ throw new InAppError('conflict', 'This notification key already has different content.');
56
+ results.push({ userId, id: existing.id, status: 'existing' });
57
+ continue;
58
+ }
59
+ const record = InAppRecord.create({ userId, scopeType: input.scope.type, scopeId: scopeId(input.scope), type: input.type, message: content, presentation: content.presentation, deduplicationHash, contentHash });
60
+ await record.save();
61
+ results.push({ userId, id: record.id, status: 'created' });
62
+ }
63
+ return results;
64
+ }));
65
+ await this.#changed(accepted.filter(item => item.status === 'created').map(item => item.userId), committed);
66
+ return accepted;
67
+ }
68
+ /**
69
+ * Lists only the authenticated user's unarchived items in an authorized scope.
70
+ * @param query - Scope, page size, optional position and inbox/banner view.
71
+ * @returns Safe content, unread count and next-page position. Reading a page changes no state.
72
+ */
73
+ async inbox(query) {
74
+ const input = normalizeQuery(query);
75
+ const userId = await this.#reader(input.scope, 'read');
76
+ const rows = this.#query(userId, input.scope).whereNull('archivedAt');
77
+ if (input.view === 'banners')
78
+ rows.where('presentation', 'banner').whereNull('dismissedAt');
79
+ if (input.before)
80
+ rows.where('id', '<', input.before);
81
+ const records = await rows.orderBy('id', 'desc').limit(input.limit + 1).all();
82
+ const unreadCount = await this.#query(userId, input.scope).whereNull('archivedAt').whereNull('readAt').count();
83
+ const items = records.slice(0, input.limit).map(itemView);
84
+ return { items, unreadCount, nextBefore: records.length > input.limit ? items.at(-1).id : null };
85
+ }
86
+ /**
87
+ * Changes one owned item's read, dismissal or archive state without coupling those states.
88
+ * @param id - Inbox item ID; a foreign or missing ID returns the same not-found error.
89
+ * @param transition - Explicit recipient action.
90
+ * @param scope - Currently authorized scope, never inferred from the target item.
91
+ */
92
+ async update(id, transition, scope) {
93
+ const input = normalizeScope(scope);
94
+ if (!/^[0-9A-HJKMNP-TV-Z]{26}$/.test(id) || !['read', 'unread', 'dismiss', 'archive'].includes(transition))
95
+ throw new InAppError('invalid', 'Invalid inbox state change.');
96
+ const userId = await this.#reader(input, 'update');
97
+ const query = this.#query(userId, input).where('id', id);
98
+ if (!await query.first())
99
+ throw new InAppError('not_found', 'Inbox item not found.');
100
+ const field = transition === 'dismiss' ? 'dismissedAt' : transition === 'archive' ? 'archivedAt' : 'readAt';
101
+ const committed = this.#committed(InAppRecord.getDb());
102
+ const update = this.#query(userId, input).where('id', id);
103
+ if (transition !== 'unread')
104
+ update.whereNull(field);
105
+ const count = await update.patch({ [field]: transition === 'unread' ? null : new Date() });
106
+ if (count)
107
+ await this.#changed([userId], committed);
108
+ }
109
+ /** Observes all surrounding savepoints and the outer commit, including explicit rollback without an error. */
110
+ #committed(connection) {
111
+ if (!this.options.onChanged || !connection.isTransaction)
112
+ return;
113
+ const transactions = [];
114
+ let current = connection;
115
+ while (current) {
116
+ const transaction = current;
117
+ let result = this.#commits.get(transaction);
118
+ if (!result) {
119
+ let rolledBack = false;
120
+ /** The final control statement distinguishes silent rollback from commit or savepoint release. */
121
+ const query = (event) => {
122
+ if (/^ROLLBACK/i.test(event.sql))
123
+ rolledBack = true;
124
+ else if (/^(COMMIT|RELEASE SAVEPOINT)/i.test(event.sql))
125
+ rolledBack = false;
126
+ };
127
+ transaction.on('query', query);
128
+ result = transaction.executionPromise.then(() => !rolledBack, () => false).finally(() => transaction.off('query', query));
129
+ this.#commits.set(transaction, result);
130
+ }
131
+ transactions.push(result);
132
+ current = transaction.parentTransaction;
133
+ }
134
+ return Promise.all(transactions).then(results => results.every(Boolean));
135
+ }
136
+ /** Publishes only committed recipient changes; nested transactions defer without blocking their own commit. */
137
+ async #changed(userIds, committed) {
138
+ if (!this.options.onChanged || !userIds.length)
139
+ return;
140
+ const connection = app().db.knex;
141
+ /** Contains push failures so retrying notification delivery cannot duplicate an accepted message. */
142
+ const deliver = async () => ActiveRecord.withDb(connection, async () => {
143
+ await Promise.all([...new Set(userIds)].map(async (userId) => {
144
+ try {
145
+ await this.options.onChanged(userId);
146
+ }
147
+ catch (error) {
148
+ try {
149
+ this.options.onDeliveryError?.(error);
150
+ }
151
+ catch { /* Reporting cannot undo the write. */ }
152
+ }
153
+ }));
154
+ });
155
+ if (committed) {
156
+ void committed.then(success => { if (success)
157
+ return deliver(); });
158
+ }
159
+ else
160
+ await deliver();
161
+ }
162
+ /** Builds an ownership-scoped query; callers never accept a reader ID from a browser. */
163
+ #query(userId, scope) {
164
+ return InAppRecord.where('userId', userId).where('scopeType', scope.type).where('scopeId', scopeId(scope));
165
+ }
166
+ /** Requires isolated request authentication and current scope authorization on every operation. */
167
+ async #reader(scope, operation) {
168
+ const application = app();
169
+ const user = application.requestContext.active ? application.auth.user : null;
170
+ if (!user)
171
+ throw new InAppError('unauthenticated', 'Sign in to access your inbox.');
172
+ const userId = String(user.get(this.identityModel.primaryKey));
173
+ await this.#authorize(userId, scope, operation);
174
+ return userId;
175
+ }
176
+ /** Account ownership is built in; application scopes require an explicit policy. */
177
+ async #authorize(userId, scope, operation) {
178
+ if (scope.type === 'account' && !this.options.authorizeScope)
179
+ return;
180
+ if (!await this.options.authorizeScope?.(userId, scope, operation))
181
+ throw new InAppError('forbidden', 'Notification scope is unavailable.');
182
+ }
183
+ }
184
+ /** Uses a nonempty sentinel only for the explicitly typed account scope. */
185
+ function scopeId(scope) { return scope.type === 'account' ? 'account' : scope.id; }
186
+ /** Hashes a normalized value; array envelopes avoid ambiguous delimiter concatenation. */
187
+ function hash(value) { return createHash('sha256').update(JSON.stringify(value)).digest('hex'); }
188
+ /** Serializes only the public inbox contract, never routing or deduplication internals. */
189
+ function itemView(record) {
190
+ return { id: record.id, type: record.type, message: record.message, createdAt: record.createdAt.toISOString(), readAt: record.readAt?.toISOString() ?? null, dismissedAt: record.dismissedAt?.toISOString() ?? null, archivedAt: record.archivedAt?.toISOString() ?? null };
191
+ }
@@ -0,0 +1,6 @@
1
+ /** Stable service errors that HTTP adapters may translate without exposing storage details. */
2
+ export declare class InAppError extends Error {
3
+ readonly code: 'invalid' | 'unauthenticated' | 'forbidden' | 'not_found' | 'conflict';
4
+ /** Creates a validation, access, missing-item or conflicting-retry error. */
5
+ constructor(code: 'invalid' | 'unauthenticated' | 'forbidden' | 'not_found' | 'conflict', message: string);
6
+ }
@@ -0,0 +1,10 @@
1
+ /** Stable service errors that HTTP adapters may translate without exposing storage details. */
2
+ export class InAppError extends Error {
3
+ code;
4
+ /** Creates a validation, access, missing-item or conflicting-retry error. */
5
+ constructor(code, message) {
6
+ super(message);
7
+ this.code = code;
8
+ this.name = 'InAppError';
9
+ }
10
+ }
@@ -0,0 +1,36 @@
1
+ import { ActiveRecord, type FieldBuilder } from '../db/index.js';
2
+ import type { InAppMessage } from './contracts/index.js';
3
+ /** Durable inbox item and independent state for one recipient; install through app migrations. */
4
+ export declare class InAppRecord extends ActiveRecord {
5
+ static table: string;
6
+ static requestFillable: string[];
7
+ /** Defines inbox ownership, deduplication and recipient-state storage. */
8
+ static fields(field: FieldBuilder): {
9
+ id: import("../db/index.js").UlidField;
10
+ userId: import("../db/index.js").StringField;
11
+ scopeType: import("../db/index.js").StringField;
12
+ scopeId: import("../db/index.js").StringField;
13
+ type: import("../db/index.js").StringField;
14
+ message: import("../db/index.js").JsonField<InAppMessage | null>;
15
+ deduplicationHash: import("../db/index.js").StringField;
16
+ contentHash: import("../db/index.js").StringField;
17
+ presentation: import("../db/index.js").StringField;
18
+ readAt: import("../db/index.js").TimestampField;
19
+ dismissedAt: import("../db/index.js").TimestampField;
20
+ archivedAt: import("../db/index.js").TimestampField;
21
+ createdAt: import("../db/index.js").TimestampField;
22
+ };
23
+ id: string;
24
+ userId: string;
25
+ scopeType: string;
26
+ scopeId: string;
27
+ type: string;
28
+ message: InAppMessage;
29
+ deduplicationHash: string | null;
30
+ contentHash: string;
31
+ presentation: string;
32
+ readAt: Date | null;
33
+ dismissedAt: Date | null;
34
+ archivedAt: Date | null;
35
+ createdAt: Date;
36
+ }
@@ -0,0 +1,24 @@
1
+ import { ActiveRecord } from '../db/index.js';
2
+ /** Durable inbox item and independent state for one recipient; install through app migrations. */
3
+ export class InAppRecord extends ActiveRecord {
4
+ static table = 'in_app_messages';
5
+ static requestFillable = [];
6
+ /** Defines inbox ownership, deduplication and recipient-state storage. */
7
+ static fields(field) {
8
+ return {
9
+ id: field.ulid(),
10
+ userId: field.string({ column: 'user_id', required: true, length: 255, maxLength: 255, indexes: [{ name: 'in_app_recipient_scope', columns: ['user_id', 'scope_type', 'scope_id'] }] }),
11
+ scopeType: field.string({ column: 'scope_type', required: true, length: 80, maxLength: 80 }),
12
+ scopeId: field.string({ column: 'scope_id', required: true, length: 255, maxLength: 255 }),
13
+ type: field.string({ required: true, length: 120, maxLength: 120 }),
14
+ message: field.json({ required: true }),
15
+ deduplicationHash: field.string({ column: 'deduplication_hash', length: 64, maxLength: 64, unique: true, hidden: true }),
16
+ contentHash: field.string({ column: 'content_hash', required: true, length: 64, maxLength: 64, hidden: true }),
17
+ presentation: field.string({ required: true, length: 16, maxLength: 16 }),
18
+ readAt: field.timestamp({ column: 'read_at' }),
19
+ dismissedAt: field.timestamp({ column: 'dismissed_at' }),
20
+ archivedAt: field.timestamp({ column: 'archived_at' }),
21
+ createdAt: field.timestamp({ column: 'created_at', auto: 'create' }),
22
+ };
23
+ }
24
+ }
@@ -0,0 +1,45 @@
1
+ import type { InAppMessage } from './InAppMessage.js';
2
+ import type { InAppScope } from './InAppScope.js';
3
+ /** A safe recipient-facing view; internal deduplication hashes are never exposed. */
4
+ export interface InAppItem {
5
+ id: string;
6
+ type: string;
7
+ message: InAppMessage;
8
+ createdAt: string;
9
+ readAt: string | null;
10
+ /** Dismissal hides a banner without removing its inbox item or implying it was read. */
11
+ dismissedAt: string | null;
12
+ archivedAt: string | null;
13
+ }
14
+ /** Trusted server dispatch metadata. Sending is not a public browser-authorized operation. */
15
+ export interface InAppSendOptions {
16
+ scope: InAppScope;
17
+ /** Stable notification type, for example content-plan.ready. */
18
+ type: string;
19
+ /** Retry identity, unique within type, scope and recipient. Omit to create a new occurrence. */
20
+ key?: string;
21
+ }
22
+ /** One result per distinct recipient, in first-input order. Empty input returns an empty array. */
23
+ export interface InAppAcceptance {
24
+ userId: string;
25
+ id: string;
26
+ status: 'created' | 'existing';
27
+ }
28
+ /** Query for the authenticated user's inbox in one explicit scope. */
29
+ export interface InAppInboxQuery {
30
+ scope: InAppScope;
31
+ /** Defaults to 25; maximum 100. */
32
+ limit?: number;
33
+ /** ID from nextBefore. Pagination is an inbox position, not a realtime/replay cursor. */
34
+ before?: string;
35
+ /** Defaults to inbox; banners excludes dismissed items. All views exclude archived items. */
36
+ view?: 'inbox' | 'banners';
37
+ }
38
+ /** Paginated items and the unread count for the whole unarchived scoped inbox. */
39
+ export interface InAppInboxPage {
40
+ items: InAppItem[];
41
+ unreadCount: number;
42
+ nextBefore: string | null;
43
+ }
44
+ /** Explicit independent recipient state transitions. */
45
+ export type InAppTransition = 'read' | 'unread' | 'dismiss' | 'archive';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ /** Recipient-facing content stored in an inbox. */
2
+ export interface InAppMessage {
3
+ title: string;
4
+ /** Plain-text fallback used by compact, accessibility and non-HTML renderers. */
5
+ body: string;
6
+ /**
7
+ * Optional rich body authored by trusted application code.
8
+ *
9
+ * The framework validates and stores this value but does not sanitize it because
10
+ * permitted markup is an application policy. Every HTML renderer must sanitize it.
11
+ */
12
+ bodyHtml?: string;
13
+ /** Defaults to info. Severity does not determine persistence or prominence. */
14
+ severity?: 'info' | 'success' | 'warning' | 'error';
15
+ /** Defaults to toast. Every presentation remains in the durable inbox. */
16
+ presentation?: 'inbox' | 'toast' | 'banner';
17
+ /** Root-relative or HTTP(S) action; the destination must enforce its own authorization. */
18
+ action?: {
19
+ label: string;
20
+ href: string;
21
+ };
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ /** Explicit account or application-owned scope; tenant scopes require an authorization policy. */
2
+ export type InAppScope = {
3
+ type: 'account';
4
+ id?: never;
5
+ } | {
6
+ type: string;
7
+ id: string;
8
+ };
9
+ /** Scope policy invoked for recipients and authenticated readers, including state mutations. */
10
+ export interface InAppOptions {
11
+ /** Best-effort invalidation after committed writes. Failures never undo durable acceptance. */
12
+ onChanged?: (userId: string) => void | Promise<void>;
13
+ /** Reports failed invalidations; inbox state remains authoritative. */
14
+ onDeliveryError?: (error: unknown) => void;
15
+ /** Non-account scopes fail closed when this policy is absent. Check current membership and write permissions. */
16
+ authorizeScope?: (userId: string, scope: InAppScope, operation: 'receive' | 'read' | 'update') => boolean | Promise<boolean>;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './InAppMessage.js';
2
+ export * from './InAppScope.js';
3
+ export * from './InAppInbox.js';
@@ -0,0 +1,3 @@
1
+ export * from './InAppMessage.js';
2
+ export * from './InAppScope.js';
3
+ export * from './InAppInbox.js';
@@ -0,0 +1,4 @@
1
+ export * from './contracts/index.js';
2
+ export { InApp } from './InApp.js';
3
+ export { InAppRecord } from './InAppRecord.js';
4
+ export { InAppError } from './InAppError.js';
@@ -0,0 +1,4 @@
1
+ export * from './contracts/index.js';
2
+ export { InApp } from './InApp.js';
3
+ export { InAppRecord } from './InAppRecord.js';
4
+ export { InAppError } from './InAppError.js';
@@ -0,0 +1,21 @@
1
+ import type * as inbox from './contracts/index.js';
2
+ /** Copies and validates content before it can be persisted. */
3
+ export declare function normalizeMessage(value: inbox.InAppMessage): inbox.InAppMessage;
4
+ /** Validates the explicit dispatch scope, type and retry identity. */
5
+ export declare function normalizeSend(value: inbox.InAppSendOptions): inbox.InAppSendOptions;
6
+ /** Validates a scoped inbox query and resolves pagination defaults. */
7
+ export declare function normalizeQuery(value: inbox.InAppInboxQuery): {
8
+ scope: {
9
+ type: "account";
10
+ } | {
11
+ type: string;
12
+ id: string;
13
+ };
14
+ limit: number;
15
+ view: "inbox" | "banners";
16
+ before?: string | undefined;
17
+ };
18
+ /** Validates a scope for state-changing operations. */
19
+ export declare function normalizeScope(value: inbox.InAppScope): inbox.InAppScope;
20
+ /** Validates the bounded recipient list and removes repeated identities. */
21
+ export declare function normalizeRecipients(value: string | readonly string[]): string[];
@@ -0,0 +1,50 @@
1
+ import { z } from 'zod';
2
+ import { InAppError } from './InAppError.js';
3
+ const identifier = z.string().min(1).max(255).regex(/^\S+$/u);
4
+ const scopeSchema = z.union([
5
+ z.object({ type: z.literal('account') }).strict(),
6
+ z.object({ type: z.string().min(1).max(80).regex(/^[a-zA-Z][a-zA-Z0-9_.-]*$/).refine(value => value !== 'account'), id: identifier }).strict(),
7
+ ]);
8
+ const messageSchema = z.object({
9
+ title: z.string().trim().min(1).max(255),
10
+ body: z.string().trim().min(1).max(10_000),
11
+ bodyHtml: z.string().trim().min(1).max(50_000).optional(),
12
+ severity: z.enum(['info', 'success', 'warning', 'error']).default('info'),
13
+ presentation: z.enum(['inbox', 'toast', 'banner']).default('toast'),
14
+ action: z.object({ label: z.string().trim().min(1).max(120), href: z.string().min(1).max(2048).refine(safeAction) }).strict().optional(),
15
+ }).strict();
16
+ const sendSchema = z.object({ scope: scopeSchema, type: z.string().min(1).max(120).regex(/^[a-zA-Z0-9_.-]+$/), key: z.string().min(1).max(255).optional() }).strict();
17
+ const querySchema = z.object({ scope: scopeSchema, limit: z.number().int().min(1).max(100).default(25), before: z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/).optional(), view: z.enum(['inbox', 'banners']).default('inbox') }).strict();
18
+ /** Accepts local absolute paths and credential-free HTTP(S) URLs, rejecting executable and ambiguous forms. */
19
+ function safeAction(value) {
20
+ if (/[\s\\\u0000-\u001f\u007f]/u.test(value))
21
+ return false;
22
+ if (value.startsWith('/') && !value.startsWith('//'))
23
+ return true;
24
+ try {
25
+ const url = new URL(value);
26
+ return ['http:', 'https:'].includes(url.protocol) && !url.username && !url.password;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /** Parses public input without leaking database or recipient information. */
33
+ function parse(schema, value) {
34
+ const result = schema.safeParse(value);
35
+ if (!result.success)
36
+ throw new InAppError('invalid', 'Invalid in-app message input.');
37
+ return result.data;
38
+ }
39
+ /** Copies and validates content before it can be persisted. */
40
+ export function normalizeMessage(value) { return parse(messageSchema, value); }
41
+ /** Validates the explicit dispatch scope, type and retry identity. */
42
+ export function normalizeSend(value) { return parse(sendSchema, value); }
43
+ /** Validates a scoped inbox query and resolves pagination defaults. */
44
+ export function normalizeQuery(value) { return parse(querySchema, value); }
45
+ /** Validates a scope for state-changing operations. */
46
+ export function normalizeScope(value) { return parse(scopeSchema, value); }
47
+ /** Validates the bounded recipient list and removes repeated identities. */
48
+ export function normalizeRecipients(value) {
49
+ return [...new Set(parse(z.array(identifier).max(100), typeof value === 'string' ? [value] : value))];
50
+ }
package/dist/index.d.ts CHANGED
@@ -3,23 +3,11 @@ export { RequestContext, type RequestContextValues, } from './server/index.js';
3
3
  export * from './cache/index.js';
4
4
  export * from './config/index.js';
5
5
  export * from './events/index.js';
6
+ export * from './health/index.js';
6
7
  export * from './logging/index.js';
7
8
  export * from './media/index.js';
8
9
  export * from './security/index.js';
9
10
  export * from './serialization/index.js';
10
11
  export * from './url/index.js';
11
12
  export * from './validation/index.js';
12
- export interface AppManifest {
13
- id: string;
14
- name: string;
15
- version: string;
16
- description?: string;
17
- icon?: string;
18
- entry?: string;
19
- adminPath?: string;
20
- capabilities?: string[];
21
- }
22
- export interface AppDefinition<TManifest extends AppManifest = AppManifest> {
23
- manifest: TManifest;
24
- }
25
- export declare function defineApp<TManifest extends AppManifest>(manifest: TManifest): AppDefinition<TManifest>;
13
+ export * from './apps/index.js';
package/dist/index.js CHANGED
@@ -3,14 +3,11 @@ export { RequestContext, } from './server/index.js';
3
3
  export * from './cache/index.js';
4
4
  export * from './config/index.js';
5
5
  export * from './events/index.js';
6
+ export * from './health/index.js';
6
7
  export * from './logging/index.js';
7
8
  export * from './media/index.js';
8
9
  export * from './security/index.js';
9
10
  export * from './serialization/index.js';
10
11
  export * from './url/index.js';
11
12
  export * from './validation/index.js';
12
- export function defineApp(manifest) {
13
- return {
14
- manifest,
15
- };
16
- }
13
+ export * from './apps/index.js';
@@ -0,0 +1,42 @@
1
+ import { Writable } from 'node:stream';
2
+ import type * as logging from './contracts/index.js';
3
+ /**
4
+ * Owns grouped log output and a bounded live pending area in one terminal.
5
+ * Multi-process launchers must pipe every child's output through this owner;
6
+ * unrelated processes writing directly to the same TTY cannot be coordinated.
7
+ */
8
+ export declare class DevelopmentConsole {
9
+ #private;
10
+ /**
11
+ * Creates a console owner without starting an HTTP server or taking stream ownership.
12
+ * @param options - Destination, terminal capability and stdio coordination.
13
+ */
14
+ constructor(options?: logging.DevelopmentConsoleOptions);
15
+ /** Accepts a complete Pino JSON line, retaining ordinary non-log text verbatim. */
16
+ write(line: string): void;
17
+ /** Writes tool output above pending rows, removing controls that clear terminal history. */
18
+ writeText(text: string): void;
19
+ /**
20
+ * Creates a separately buffered child stdout/stderr sink, handling split UTF-8
21
+ * and final unterminated lines. Long non-JSON lines are forwarded in bounded chunks.
22
+ * @returns A writable input; end it when its child stream closes.
23
+ */
24
+ createInput(): Writable;
25
+ /** Finalizes pending work from an exited child without disturbing other children. */
26
+ endSource(pid: number): void;
27
+ /** Waits for previously rendered output to reach the caller-owned destination. */
28
+ flush(): Promise<void>;
29
+ /** Clears only owned rows, releases timers/listeners and restores patched stdio. */
30
+ close(): void;
31
+ }
32
+ /**
33
+ * Whether the pretty console uses colour. `NO_COLOR` turns it off; a set
34
+ * `FORCE_COLOR` (other than `0` or `false`) turns it on even without a TTY, as
35
+ * when a process manager pipes output into its own terminal view; otherwise a
36
+ * TTY decides.
37
+ *
38
+ * @param isTTY - Whether the output stream is a terminal.
39
+ * @param env - Process environment.
40
+ * @returns Whether to emit ANSI colours.
41
+ */
42
+ export declare function consoleColor(isTTY: boolean, env: NodeJS.ProcessEnv): boolean;