@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,18 @@
1
+ import type { Mail } from '../../mail/index.js';
2
+ import type { EmailLogOptions } from '../contracts/index.js';
3
+ /**
4
+ * Sends each serialized error/fatal log through Mail once, in arrival order.
5
+ * Pending sends live in memory; flush/close drains them. Provider failures go to
6
+ * stderr without recursive logging, retry, cooldown, grouping or suppression of later records.
7
+ */
8
+ export declare class EmailLogTransport {
9
+ #private;
10
+ readonly options: EmailLogOptions;
11
+ readonly mail: () => Mail;
12
+ /** Resolves Mail lazily so constructing an application logger does not initialize mail providers. */
13
+ constructor(options: EmailLogOptions, mail: () => Mail);
14
+ /** Accepts Pino JSON lines after serialization and configured field redaction. */
15
+ write(line: string): void;
16
+ /** Waits for all accepted sends, including records appended while a flush is in progress. */
17
+ flush(): Promise<void>;
18
+ }
@@ -0,0 +1,47 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { formatLogEmail } from '../formatLogEmail.js';
3
+ const deliveringEmail = new AsyncLocalStorage();
4
+ /**
5
+ * Sends each serialized error/fatal log through Mail once, in arrival order.
6
+ * Pending sends live in memory; flush/close drains them. Provider failures go to
7
+ * stderr without recursive logging, retry, cooldown, grouping or suppression of later records.
8
+ */
9
+ export class EmailLogTransport {
10
+ options;
11
+ mail;
12
+ #pending = Promise.resolve();
13
+ /** Resolves Mail lazily so constructing an application logger does not initialize mail providers. */
14
+ constructor(options, mail) {
15
+ this.options = options;
16
+ this.mail = mail;
17
+ }
18
+ /** Accepts Pino JSON lines after serialization and configured field redaction. */
19
+ write(line) {
20
+ if (deliveringEmail.getStore())
21
+ return;
22
+ try {
23
+ const record = JSON.parse(line);
24
+ const message = formatLogEmail(record, this.options);
25
+ this.#pending = this.#pending.then(() => deliveringEmail.run(true, async () => {
26
+ try {
27
+ await this.mail().send(message);
28
+ }
29
+ catch {
30
+ // Never include provider errors here: they can contain credentials or request bodies.
31
+ process.stderr.write('[logging] Error email delivery failed; original record remains in configured log destinations.\n');
32
+ }
33
+ }));
34
+ }
35
+ catch {
36
+ process.stderr.write('[logging] Error email formatting failed; original record remains in configured log destinations.\n');
37
+ }
38
+ }
39
+ /** Waits for all accepted sends, including records appended while a flush is in progress. */
40
+ async flush() {
41
+ let pending;
42
+ do {
43
+ pending = this.#pending;
44
+ await pending;
45
+ } while (pending !== this.#pending);
46
+ }
47
+ }
@@ -12,6 +12,8 @@ export interface MailMessage {
12
12
  html?: string;
13
13
  /** Extra message headers; File and Resend preserve them, Mailgun currently does not. */
14
14
  headers?: Record<string, string>;
15
+ /** Stable request identity for provider retries. Resend deduplicates identical requests for 24 hours; other built-in transports ignore this value. */
16
+ idempotencyKey?: string;
15
17
  }
16
18
  /** Transport input with a default sender resolved and recipients normalized to an array. */
17
19
  export interface ResolvedMailMessage extends Omit<MailMessage, 'from' | 'to'> {
package/dist/mail/Mail.js CHANGED
@@ -18,6 +18,9 @@ export class Mail {
18
18
  }
19
19
  /** Resolves the sender and recipient list without changing application content. */
20
20
  resolveMessage(message) {
21
+ if (message.idempotencyKey !== undefined && !/^[\x21-\x7e]{1,256}$/.test(message.idempotencyKey)) {
22
+ throw new Error('Mail idempotencyKey must contain 1 to 256 printable non-space ASCII characters.');
23
+ }
21
24
  const to = Array.isArray(message.to) ? message.to : [message.to];
22
25
  if (to.length === 0) {
23
26
  throw new Error('Mail requires at least one recipient.');
@@ -0,0 +1,9 @@
1
+ /** Structured provider refusal; consumers decide retry policy without parsing diagnostic messages. */
2
+ export declare class MailDeliveryError extends Error {
3
+ readonly provider: string;
4
+ readonly status: number;
5
+ readonly code: string | null;
6
+ readonly retryAt: Date | null;
7
+ /** Creates a refusal retaining the provider code, HTTP status and optional validated retry time. */
8
+ constructor(message: string, provider: string, status: number, code: string | null, retryAt?: Date | null);
9
+ }
@@ -0,0 +1,16 @@
1
+ /** Structured provider refusal; consumers decide retry policy without parsing diagnostic messages. */
2
+ export class MailDeliveryError extends Error {
3
+ provider;
4
+ status;
5
+ code;
6
+ retryAt;
7
+ /** Creates a refusal retaining the provider code, HTTP status and optional validated retry time. */
8
+ constructor(message, provider, status, code, retryAt = null) {
9
+ super(message);
10
+ this.provider = provider;
11
+ this.status = status;
12
+ this.code = code;
13
+ this.retryAt = retryAt;
14
+ this.name = 'MailDeliveryError';
15
+ }
16
+ }
@@ -2,3 +2,4 @@ export * from './Mail.js';
2
2
  export * from './transports/FileMailTransport.js';
3
3
  export * from './transports/MailgunTransport.js';
4
4
  export * from './transports/ResendTransport.js';
5
+ export * from './MailDeliveryError.js';
@@ -2,3 +2,4 @@ export * from './Mail.js';
2
2
  export * from './transports/FileMailTransport.js';
3
3
  export * from './transports/MailgunTransport.js';
4
4
  export * from './transports/ResendTransport.js';
5
+ export * from './MailDeliveryError.js';
@@ -35,6 +35,8 @@ export class MailgunTransport {
35
35
  }
36
36
  const response = await fetch(`${this.baseUrl}/${this.domain}/messages`, {
37
37
  method: 'POST',
38
+ signal: AbortSignal.timeout(15000),
39
+ redirect: 'error',
38
40
  headers: {
39
41
  authorization: `Basic ${Buffer.from(`api:${this.apiKey}`).toString('base64')}`,
40
42
  },
@@ -7,8 +7,9 @@ export interface ResendTransportOptions {
7
7
  * Resend API transport.
8
8
  */
9
9
  export declare class ResendTransport implements MailTransport {
10
- private readonly apiKey;
11
- private readonly baseUrl;
10
+ #private;
11
+ /** Creates a bounded Resend transport; credentials remain private to this instance. */
12
12
  constructor(options: ResendTransportOptions);
13
+ /** Sends one message, forwarding a stable retry identity as an API header rather than an email header. */
13
14
  send(message: ResolvedMailMessage): Promise<MailDelivery>;
14
15
  }
@@ -1,20 +1,17 @@
1
- import { formatMailAddress, mailAddressEmail, } from '../Mail.js';
2
- class ResendTransportError extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = 'ResendTransportError';
6
- }
7
- }
1
+ import { MailDeliveryError } from '../MailDeliveryError.js';
2
+ import { formatMailAddress, mailAddressEmail } from '../Mail.js';
8
3
  /**
9
4
  * Resend API transport.
10
5
  */
11
6
  export class ResendTransport {
12
- apiKey;
13
- baseUrl;
7
+ #apiKey;
8
+ #baseUrl;
9
+ /** Creates a bounded Resend transport; credentials remain private to this instance. */
14
10
  constructor(options) {
15
- this.apiKey = options.apiKey;
16
- this.baseUrl = (options.baseUrl || 'https://api.resend.com').replace(/\/+$/, '');
11
+ this.#apiKey = options.apiKey;
12
+ this.#baseUrl = (options.baseUrl || 'https://api.resend.com').replace(/\/+$/, '');
17
13
  }
14
+ /** Sends one message, forwarding a stable retry identity as an API header rather than an email header. */
18
15
  async send(message) {
19
16
  const payload = {
20
17
  from: formatMailAddress(message.from),
@@ -30,11 +27,14 @@ export class ResendTransport {
30
27
  if (message.headers) {
31
28
  payload.headers = message.headers;
32
29
  }
33
- const response = await fetch(`${this.baseUrl}/emails`, {
30
+ const response = await fetch(`${this.#baseUrl}/emails`, {
34
31
  method: 'POST',
32
+ signal: AbortSignal.timeout(15000),
33
+ redirect: 'error',
35
34
  headers: {
36
- authorization: `Bearer ${this.apiKey}`,
35
+ authorization: `Bearer ${this.#apiKey}`,
37
36
  'content-type': 'application/json',
37
+ ...(message.idempotencyKey ? { 'Idempotency-Key': message.idempotencyKey } : {}),
38
38
  },
39
39
  body: JSON.stringify(payload),
40
40
  });
@@ -43,7 +43,8 @@ export class ResendTransport {
43
43
  const detail = typeof result?.message === 'string'
44
44
  ? result.message
45
45
  : response.statusText;
46
- throw new ResendTransportError(`Resend rejected the message: ${detail}`);
46
+ const code = typeof result?.name === 'string' && /^[a-z_]{1,100}$/.test(result.name) ? result.name : null;
47
+ throw new MailDeliveryError(`Resend rejected the message: ${detail}`, 'resend', response.status, code, retryTime(response.headers.get('retry-after')));
47
48
  }
48
49
  return {
49
50
  id: typeof result?.id === 'string' ? result.id : '',
@@ -53,3 +54,10 @@ export class ResendTransport {
53
54
  };
54
55
  }
55
56
  }
57
+ /** Parses standard Retry-After seconds or HTTP dates, ignoring malformed, overflowing and past values. */
58
+ function retryTime(value) {
59
+ if (!value)
60
+ return null;
61
+ const milliseconds = /^\d+$/.test(value) ? Date.now() + Number(value) * 1000 : Date.parse(value);
62
+ return Number.isFinite(milliseconds) && milliseconds > Date.now() && milliseconds <= 8640000000000000 ? new Date(milliseconds) : null;
63
+ }
@@ -26,6 +26,7 @@ export declare class MediaManager {
26
26
  constructor(storage: Storage, options?: MediaOptions, imageProcessor?: ImageProcessor);
27
27
  /**
28
28
  * Finds or creates the media library for an application-owned scope.
29
+ * Concurrent creators reuse the winning row without overwriting its defaults.
29
30
  *
30
31
  * @param input - Scope identity and defaults for a new library.
31
32
  * @returns Existing or newly-created media library.
@@ -111,14 +112,15 @@ export declare class MediaManager {
111
112
  */
112
113
  deleteFile(fileOrId: MediaFile | string): Promise<void>;
113
114
  /**
114
- * Finds or creates the root browser item for a library.
115
+ * Finds or creates the root browser item for a library, including concurrent writers.
115
116
  *
116
117
  * @param libraryOrId - Media library row or id.
117
118
  * @returns Root browser item for the library.
118
119
  */
119
120
  rootFor(libraryOrId: MediaLibraryInput): Promise<MediaItem>;
120
121
  /**
121
- * Finds or creates a slash-prefixed browser folder path.
122
+ * Finds or creates a slash-prefixed browser folder path. Concurrent creators
123
+ * reuse the winning directory without replacing its metadata.
122
124
  *
123
125
  * @param input - Library and folder path to ensure.
124
126
  * @returns Folder item for the requested path, or the root for `/`.
@@ -1,4 +1,4 @@
1
- import { mimeTypeFromPath } from '../storage/mime.js';
1
+ import { mimeTypeFromPath } from '../storage/mimeTypeFromPath.js';
2
2
  import { normalizeStoragePath } from '../storage/path.js';
3
3
  import { MEDIA_FILE_VISIBILITY, MEDIA_ITEM_TYPE, MEDIA_LIBRARY_DEFAULT_KEY } from './constants.js';
4
4
  import { ImageReconstructionError, ImageVariantRenderer, SharpImageProcessor } from './image/index.js';
@@ -38,6 +38,7 @@ export class MediaManager {
38
38
  }
39
39
  /**
40
40
  * Finds or creates the media library for an application-owned scope.
41
+ * Concurrent creators reuse the winning row without overwriting its defaults.
41
42
  *
42
43
  * @param input - Scope identity and defaults for a new library.
43
44
  * @returns Existing or newly-created media library.
@@ -72,8 +73,18 @@ export class MediaManager {
72
73
  pathPrefix: input.pathPrefix ?? null,
73
74
  meta: input.meta ?? null,
74
75
  });
75
- await library.save();
76
- return library;
76
+ try {
77
+ await library.save();
78
+ return library;
79
+ }
80
+ catch (error) {
81
+ if (!isUniqueConstraintError(error) && !isRetriableTransactionConflict(error))
82
+ throw error;
83
+ const raced = await MediaLibrary.where({ scopeType, scopeId, key }).first();
84
+ if (!raced)
85
+ throw error;
86
+ return raced;
87
+ }
77
88
  }
78
89
  /**
79
90
  * Loads one media library by id.
@@ -181,7 +192,7 @@ export class MediaManager {
181
192
  await file.delete();
182
193
  }
183
194
  /**
184
- * Finds or creates the root browser item for a library.
195
+ * Finds or creates the root browser item for a library, including concurrent writers.
185
196
  *
186
197
  * @param libraryOrId - Media library row or id.
187
198
  * @returns Root browser item for the library.
@@ -204,11 +215,22 @@ export class MediaManager {
204
215
  path: '/',
205
216
  meta: null,
206
217
  });
207
- await root.save();
208
- return root;
218
+ try {
219
+ await root.save();
220
+ return root;
221
+ }
222
+ catch (error) {
223
+ if (!isUniqueConstraintError(error) && !isRetriableTransactionConflict(error))
224
+ throw error;
225
+ const raced = await MediaItem.where({ library, path: '/', type: MEDIA_ITEM_TYPE.root }).first();
226
+ if (!raced)
227
+ throw error;
228
+ return raced;
229
+ }
209
230
  }
210
231
  /**
211
- * Finds or creates a slash-prefixed browser folder path.
232
+ * Finds or creates a slash-prefixed browser folder path. Concurrent creators
233
+ * reuse the winning directory without replacing its metadata.
212
234
  *
213
235
  * @param input - Library and folder path to ensure.
214
236
  * @returns Folder item for the requested path, or the root for `/`.
@@ -249,7 +271,17 @@ export class MediaManager {
249
271
  path: currentPath,
250
272
  meta: currentPath === path ? input.meta ?? null : null,
251
273
  });
252
- await folder.save();
274
+ try {
275
+ await folder.save();
276
+ }
277
+ catch (error) {
278
+ if (!isUniqueConstraintError(error) && !isRetriableTransactionConflict(error))
279
+ throw error;
280
+ const raced = await MediaItem.where({ library, path: currentPath, type: MEDIA_ITEM_TYPE.directory }).first();
281
+ if (!raced)
282
+ throw error;
283
+ folder = raced;
284
+ }
253
285
  }
254
286
  parent = folder;
255
287
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Raised when an outbound request targets a URL the network guard refuses.
3
+ *
4
+ * The message is safe to show to the user who supplied the URL: it names the
5
+ * rule that failed without revealing resolved internal addresses. Callers
6
+ * typically catch it to turn a blocked crawl, webhook or preview into a
7
+ * validation error instead of a server failure.
8
+ */
9
+ export declare class BlockedUrlError extends Error {
10
+ /**
11
+ * Creates a blocked-URL error with a public explanation.
12
+ *
13
+ * @param message - Caller-safe reason the URL was refused.
14
+ */
15
+ constructor(message?: string);
16
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Raised when an outbound request targets a URL the network guard refuses.
3
+ *
4
+ * The message is safe to show to the user who supplied the URL: it names the
5
+ * rule that failed without revealing resolved internal addresses. Callers
6
+ * typically catch it to turn a blocked crawl, webhook or preview into a
7
+ * validation error instead of a server failure.
8
+ */
9
+ export class BlockedUrlError extends Error {
10
+ /**
11
+ * Creates a blocked-URL error with a public explanation.
12
+ *
13
+ * @param message - Caller-safe reason the URL was refused.
14
+ */
15
+ constructor(message = 'This URL is not allowed.') {
16
+ super(message);
17
+ this.name = 'BlockedUrlError';
18
+ }
19
+ }
@@ -0,0 +1,22 @@
1
+ import type * as network from './contracts/index.js';
2
+ /**
3
+ * Validates that a URL is an HTTP(S) address on the public internet.
4
+ *
5
+ * This is a pre-flight check that gives users a clear error before any
6
+ * connection is attempted. It is not sufficient on its own: DNS can return a
7
+ * different address when the request connects (DNS rebinding). Send requests
8
+ * through {@link guardedFetch}, or pass {@link publicAddressLookup} to the HTTP
9
+ * client, so the connected address is checked as well.
10
+ *
11
+ * @param rawUrl - Absolute URL supplied by a user, crawler or redirect.
12
+ * @param options - Destination policy; private hosts are refused by default.
13
+ * @throws {BlockedUrlError} When the URL is malformed, not HTTP(S), or reaches
14
+ * a private, local or reserved address.
15
+ *
16
+ * @example
17
+ * await assertPublicUrl('https://example.com/feed.xml');
18
+ * await assertPublicUrl('http://169.254.169.254/'); // throws BlockedUrlError
19
+ */
20
+ export declare function assertPublicUrl(rawUrl: string, options?: network.PublicUrlOptions): Promise<void>;
21
+ /** Public explanation used for every private, local or reserved destination. */
22
+ export declare const PRIVATE_DESTINATION_MESSAGE = "Private, local, or reserved URLs are not allowed.";
@@ -0,0 +1,67 @@
1
+ import { lookup } from 'node:dns/promises';
2
+ import { isIP } from 'node:net';
3
+ import { BlockedUrlError } from './BlockedUrlError.js';
4
+ import { isPrivateHostname, isPrivateIpAddress, normalizedUrlHostname } from './privateNetworkAddresses.js';
5
+ /**
6
+ * Validates that a URL is an HTTP(S) address on the public internet.
7
+ *
8
+ * This is a pre-flight check that gives users a clear error before any
9
+ * connection is attempted. It is not sufficient on its own: DNS can return a
10
+ * different address when the request connects (DNS rebinding). Send requests
11
+ * through {@link guardedFetch}, or pass {@link publicAddressLookup} to the HTTP
12
+ * client, so the connected address is checked as well.
13
+ *
14
+ * @param rawUrl - Absolute URL supplied by a user, crawler or redirect.
15
+ * @param options - Destination policy; private hosts are refused by default.
16
+ * @throws {BlockedUrlError} When the URL is malformed, not HTTP(S), or reaches
17
+ * a private, local or reserved address.
18
+ *
19
+ * @example
20
+ * await assertPublicUrl('https://example.com/feed.xml');
21
+ * await assertPublicUrl('http://169.254.169.254/'); // throws BlockedUrlError
22
+ */
23
+ export async function assertPublicUrl(rawUrl, options = {}) {
24
+ const hostname = publicUrlHostname(rawUrl, options);
25
+ if (hostname === null || isIP(hostname))
26
+ return;
27
+ let addresses;
28
+ try {
29
+ addresses = await lookup(hostname, { all: true, verbatim: true });
30
+ }
31
+ catch {
32
+ throw new BlockedUrlError('Unable to resolve the URL hostname.');
33
+ }
34
+ if (addresses.length === 0 || addresses.some(entry => isPrivateIpAddress(entry.address))) {
35
+ throw new BlockedUrlError(PRIVATE_DESTINATION_MESSAGE);
36
+ }
37
+ }
38
+ /** Public explanation used for every private, local or reserved destination. */
39
+ export const PRIVATE_DESTINATION_MESSAGE = 'Private, local, or reserved URLs are not allowed.';
40
+ /**
41
+ * Performs the synchronous part of URL validation.
42
+ *
43
+ * @param rawUrl - Absolute URL to validate.
44
+ * @param options - Destination policy.
45
+ * @returns Normalized hostname still requiring DNS validation, or null when no
46
+ * further checks are needed because private destinations are allowed.
47
+ * @throws {BlockedUrlError} When the URL fails a synchronous rule.
48
+ */
49
+ function publicUrlHostname(rawUrl, options) {
50
+ let parsed;
51
+ try {
52
+ parsed = new URL(rawUrl);
53
+ }
54
+ catch {
55
+ throw new BlockedUrlError('The URL is not valid.');
56
+ }
57
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
58
+ throw new BlockedUrlError('Only http and https URLs are allowed.');
59
+ }
60
+ if (options.allowPrivate)
61
+ return null;
62
+ const hostname = normalizedUrlHostname(parsed.hostname);
63
+ if (isPrivateHostname(hostname) || (isIP(hostname) && isPrivateIpAddress(hostname))) {
64
+ throw new BlockedUrlError(PRIVATE_DESTINATION_MESSAGE);
65
+ }
66
+ return hostname;
67
+ }
@@ -0,0 +1,35 @@
1
+ import type { PublicUrlOptions } from './PublicUrlOptions.js';
2
+ /**
3
+ * Options for one guarded outbound HTTP request.
4
+ *
5
+ * `init` is passed to `fetch` unchanged except that redirects are always
6
+ * handled by the guard and the connection dispatcher is always replaced with
7
+ * one that re-validates the addresses DNS returns at connect time.
8
+ */
9
+ export interface GuardedFetchOptions extends PublicUrlOptions {
10
+ /** Standard fetch options such as method, headers, body and abort signal. */
11
+ init?: RequestInit;
12
+ /**
13
+ * Maximum redirects followed before the request fails with `BlockedUrlError`.
14
+ *
15
+ * Every redirect target is validated as a new destination. Defaults to 4.
16
+ */
17
+ maxRedirects?: number;
18
+ /**
19
+ * How redirects are handled.
20
+ *
21
+ * `follow` (default) validates and follows each hop. `manual` returns the
22
+ * first 3xx response unchanged so a caller such as a browser can follow it
23
+ * through its own guarded request path.
24
+ */
25
+ redirect?: 'follow' | 'manual';
26
+ }
27
+ /**
28
+ * Response returned by a guarded outbound request.
29
+ */
30
+ export interface GuardedFetchResult {
31
+ /** Final response after any followed redirects. */
32
+ response: Response;
33
+ /** Absolute URL that produced `response`, after followed redirects. */
34
+ finalUrl: string;
35
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Destination policy shared by every outbound network guard.
3
+ *
4
+ * Applications decide the policy (for example from their environment) and pass
5
+ * it to each guarded operation. The guard itself never reads environment
6
+ * variables, so a request handler cannot widen the policy through input.
7
+ */
8
+ export interface PublicUrlOptions {
9
+ /**
10
+ * Allows private, loopback and reserved destinations.
11
+ *
12
+ * Intended for interactive local development, where integrations are often
13
+ * tested against `localhost` receivers. Production code should leave this
14
+ * unset so user-supplied URLs can only reach public internet hosts.
15
+ */
16
+ allowPrivate?: boolean;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './GuardedFetch.js';
2
+ export * from './PublicUrlOptions.js';
@@ -0,0 +1,2 @@
1
+ export * from './GuardedFetch.js';
2
+ export * from './PublicUrlOptions.js';
@@ -0,0 +1,29 @@
1
+ import type * as network from './contracts/index.js';
2
+ /**
3
+ * Fetches a user-supplied URL without allowing it to reach private networks.
4
+ *
5
+ * Each hop is validated before it is requested, and the connection itself uses
6
+ * {@link publicAddressLookup}, so the address DNS returns at connect time is
7
+ * the address that was checked. Redirects are followed manually: every target
8
+ * is validated, `303` (and `301`/`302` after `POST`) switch to `GET` without a
9
+ * body as `fetch` does, and credentials (`Authorization`, `Cookie`) are removed
10
+ * when a redirect leaves the original origin.
11
+ *
12
+ * `allowPrivate` permits private destinations without weakening TLS certificate
13
+ * verification. Local HTTPS receivers must present a certificate trusted by Node.
14
+ *
15
+ * The request is sent with the runtime's global `fetch`, so test doubles that
16
+ * replace `globalThis.fetch` continue to work.
17
+ *
18
+ * @param rawUrl - Absolute HTTP(S) URL to request.
19
+ * @param options - Fetch init, redirect handling and destination policy.
20
+ * @returns Final response and the URL that produced it.
21
+ * @throws {BlockedUrlError} When any hop targets a refused destination or the
22
+ * redirect limit is exceeded.
23
+ *
24
+ * @example
25
+ * const { response, finalUrl } = await guardedFetch('https://example.com/', {
26
+ * init: { headers: { accept: 'text/html' }, signal: AbortSignal.timeout(10_000) },
27
+ * });
28
+ */
29
+ export declare function guardedFetch(rawUrl: string, options?: network.GuardedFetchOptions): Promise<network.GuardedFetchResult>;