@sixthsummit/ship-api 0.0.0-stage → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (556) hide show
  1. package/CHANGELOG.md +605 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +4 -0
  4. package/README.md +58 -2
  5. package/cli/commands/add.js +537 -0
  6. package/cli/commands/contract.js +2 -0
  7. package/cli/commands/create.js +250 -0
  8. package/cli/commands/dev.js +227 -0
  9. package/cli/commands/doctor.js +286 -0
  10. package/cli/commands/generate.js +937 -0
  11. package/cli/commands/graph.js +2 -0
  12. package/cli/commands/migrate-orm.js +1171 -0
  13. package/cli/commands/update.js +37 -0
  14. package/cli/ship-api.js +285 -0
  15. package/lib/app/auth/AuthProvider.d.ts +91 -0
  16. package/lib/app/auth/AuthProvider.d.ts.map +1 -0
  17. package/lib/app/auth/AuthProvider.js +13 -0
  18. package/lib/app/auth/AuthProvider.js.map +1 -0
  19. package/lib/app/auth/adapters/firebase.d.ts +79 -0
  20. package/lib/app/auth/adapters/firebase.d.ts.map +1 -0
  21. package/lib/app/auth/adapters/firebase.js +122 -0
  22. package/lib/app/auth/adapters/firebase.js.map +1 -0
  23. package/lib/app/auth/adapters/jwtCookie.d.ts +55 -0
  24. package/lib/app/auth/adapters/jwtCookie.d.ts.map +1 -0
  25. package/lib/app/auth/adapters/jwtCookie.js +120 -0
  26. package/lib/app/auth/adapters/jwtCookie.js.map +1 -0
  27. package/lib/app/auth/index.d.ts +8 -0
  28. package/lib/app/auth/index.d.ts.map +1 -0
  29. package/lib/app/auth/index.js +7 -0
  30. package/lib/app/auth/index.js.map +1 -0
  31. package/lib/app/auth/jwt/AuthFlow.d.ts +94 -0
  32. package/lib/app/auth/jwt/AuthFlow.d.ts.map +1 -0
  33. package/lib/app/auth/jwt/AuthFlow.js +127 -0
  34. package/lib/app/auth/jwt/AuthFlow.js.map +1 -0
  35. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts +80 -0
  36. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts.map +1 -0
  37. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js +134 -0
  38. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js.map +1 -0
  39. package/lib/app/auth/jwt/JwtSigner.d.ts +123 -0
  40. package/lib/app/auth/jwt/JwtSigner.d.ts.map +1 -0
  41. package/lib/app/auth/jwt/JwtSigner.js +118 -0
  42. package/lib/app/auth/jwt/JwtSigner.js.map +1 -0
  43. package/lib/app/auth/jwt/RefreshTokenStore.d.ts +97 -0
  44. package/lib/app/auth/jwt/RefreshTokenStore.d.ts.map +1 -0
  45. package/lib/app/auth/jwt/RefreshTokenStore.js +122 -0
  46. package/lib/app/auth/jwt/RefreshTokenStore.js.map +1 -0
  47. package/lib/app/auth/permissionDefinition.d.ts +20 -0
  48. package/lib/app/auth/permissionDefinition.d.ts.map +1 -0
  49. package/lib/app/auth/permissionDefinition.js +2 -0
  50. package/lib/app/auth/permissionDefinition.js.map +1 -0
  51. package/lib/app/context/RequestContext.d.ts +59 -0
  52. package/lib/app/context/RequestContext.d.ts.map +1 -0
  53. package/lib/app/context/RequestContext.js +25 -0
  54. package/lib/app/context/RequestContext.js.map +1 -0
  55. package/lib/app/db/QueryOptions.d.ts +82 -0
  56. package/lib/app/db/QueryOptions.d.ts.map +1 -0
  57. package/lib/app/db/QueryOptions.js +37 -0
  58. package/lib/app/db/QueryOptions.js.map +1 -0
  59. package/lib/app/db/baseFields.d.ts +60 -0
  60. package/lib/app/db/baseFields.d.ts.map +1 -0
  61. package/lib/app/db/baseFields.js +54 -0
  62. package/lib/app/db/baseFields.js.map +1 -0
  63. package/lib/app/db/buildWhere.d.ts +22 -0
  64. package/lib/app/db/buildWhere.d.ts.map +1 -0
  65. package/lib/app/db/buildWhere.js +75 -0
  66. package/lib/app/db/buildWhere.js.map +1 -0
  67. package/lib/app/db/client.d.ts +111 -0
  68. package/lib/app/db/client.d.ts.map +1 -0
  69. package/lib/app/db/client.js +99 -0
  70. package/lib/app/db/client.js.map +1 -0
  71. package/lib/app/db/tenantScoped.d.ts +59 -0
  72. package/lib/app/db/tenantScoped.d.ts.map +1 -0
  73. package/lib/app/db/tenantScoped.js +54 -0
  74. package/lib/app/db/tenantScoped.js.map +1 -0
  75. package/lib/app/db/transaction.d.ts +58 -0
  76. package/lib/app/db/transaction.d.ts.map +1 -0
  77. package/lib/app/db/transaction.js +106 -0
  78. package/lib/app/db/transaction.js.map +1 -0
  79. package/lib/app/health/HealthCheck.d.ts +121 -0
  80. package/lib/app/health/HealthCheck.d.ts.map +1 -0
  81. package/lib/app/health/HealthCheck.js +151 -0
  82. package/lib/app/health/HealthCheck.js.map +1 -0
  83. package/lib/app/health/redisHealthCheck.d.ts +14 -0
  84. package/lib/app/health/redisHealthCheck.d.ts.map +1 -0
  85. package/lib/app/health/redisHealthCheck.js +21 -0
  86. package/lib/app/health/redisHealthCheck.js.map +1 -0
  87. package/lib/app/lifecycle/Bootstrapper.d.ts +92 -0
  88. package/lib/app/lifecycle/Bootstrapper.d.ts.map +1 -0
  89. package/lib/app/lifecycle/Bootstrapper.js +99 -0
  90. package/lib/app/lifecycle/Bootstrapper.js.map +1 -0
  91. package/lib/app/registry/routes.d.ts +89 -0
  92. package/lib/app/registry/routes.d.ts.map +1 -0
  93. package/lib/app/registry/routes.js +72 -0
  94. package/lib/app/registry/routes.js.map +1 -0
  95. package/lib/app/services/DrizzleEntityService.d.ts +123 -0
  96. package/lib/app/services/DrizzleEntityService.d.ts.map +1 -0
  97. package/lib/app/services/DrizzleEntityService.js +342 -0
  98. package/lib/app/services/DrizzleEntityService.js.map +1 -0
  99. package/lib/app/services/RedisProvider.d.ts +52 -0
  100. package/lib/app/services/RedisProvider.d.ts.map +1 -0
  101. package/lib/app/services/RedisProvider.js +75 -0
  102. package/lib/app/services/RedisProvider.js.map +1 -0
  103. package/lib/app/services/cache/Cache.d.ts +70 -0
  104. package/lib/app/services/cache/Cache.d.ts.map +1 -0
  105. package/lib/app/services/cache/Cache.js +18 -0
  106. package/lib/app/services/cache/Cache.js.map +1 -0
  107. package/lib/app/services/cache/InMemoryCache.d.ts +35 -0
  108. package/lib/app/services/cache/InMemoryCache.d.ts.map +1 -0
  109. package/lib/app/services/cache/InMemoryCache.js +76 -0
  110. package/lib/app/services/cache/InMemoryCache.js.map +1 -0
  111. package/lib/app/services/cache/RedisCache.d.ts +99 -0
  112. package/lib/app/services/cache/RedisCache.d.ts.map +1 -0
  113. package/lib/app/services/cache/RedisCache.js +150 -0
  114. package/lib/app/services/cache/RedisCache.js.map +1 -0
  115. package/lib/app/services/cache/cached.d.ts +30 -0
  116. package/lib/app/services/cache/cached.d.ts.map +1 -0
  117. package/lib/app/services/cache/cached.js +38 -0
  118. package/lib/app/services/cache/cached.js.map +1 -0
  119. package/lib/app/services/cache/index.d.ts +5 -0
  120. package/lib/app/services/cache/index.d.ts.map +1 -0
  121. package/lib/app/services/cache/index.js +4 -0
  122. package/lib/app/services/cache/index.js.map +1 -0
  123. package/lib/app/services/cron/defineCron.d.ts +57 -0
  124. package/lib/app/services/cron/defineCron.d.ts.map +1 -0
  125. package/lib/app/services/cron/defineCron.js +15 -0
  126. package/lib/app/services/cron/defineCron.js.map +1 -0
  127. package/lib/app/services/cron/index.d.ts +2 -0
  128. package/lib/app/services/cron/index.d.ts.map +1 -0
  129. package/lib/app/services/cron/index.js +2 -0
  130. package/lib/app/services/cron/index.js.map +1 -0
  131. package/lib/app/services/hooks/LifecycleHooks.d.ts +61 -0
  132. package/lib/app/services/hooks/LifecycleHooks.d.ts.map +1 -0
  133. package/lib/app/services/hooks/LifecycleHooks.js +85 -0
  134. package/lib/app/services/hooks/LifecycleHooks.js.map +1 -0
  135. package/lib/app/services/jobs/JobsManager.d.ts +67 -0
  136. package/lib/app/services/jobs/JobsManager.d.ts.map +1 -0
  137. package/lib/app/services/jobs/JobsManager.js +121 -0
  138. package/lib/app/services/jobs/JobsManager.js.map +1 -0
  139. package/lib/app/services/jobs/bullBoard.d.ts +72 -0
  140. package/lib/app/services/jobs/bullBoard.d.ts.map +1 -0
  141. package/lib/app/services/jobs/bullBoard.js +96 -0
  142. package/lib/app/services/jobs/bullBoard.js.map +1 -0
  143. package/lib/app/services/jobs/defineJob.d.ts +81 -0
  144. package/lib/app/services/jobs/defineJob.d.ts.map +1 -0
  145. package/lib/app/services/jobs/defineJob.js +49 -0
  146. package/lib/app/services/jobs/defineJob.js.map +1 -0
  147. package/lib/app/services/jobs/index.d.ts +4 -0
  148. package/lib/app/services/jobs/index.d.ts.map +1 -0
  149. package/lib/app/services/jobs/index.js +4 -0
  150. package/lib/app/services/jobs/index.js.map +1 -0
  151. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts +23 -0
  152. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts.map +1 -0
  153. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js +51 -0
  154. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js.map +1 -0
  155. package/lib/app/services/rateLimit/RateLimitBackend.d.ts +41 -0
  156. package/lib/app/services/rateLimit/RateLimitBackend.d.ts.map +1 -0
  157. package/lib/app/services/rateLimit/RateLimitBackend.js +19 -0
  158. package/lib/app/services/rateLimit/RateLimitBackend.js.map +1 -0
  159. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts +16 -0
  160. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts.map +1 -0
  161. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js +80 -0
  162. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js.map +1 -0
  163. package/lib/app/services/rateLimit/index.d.ts +4 -0
  164. package/lib/app/services/rateLimit/index.d.ts.map +1 -0
  165. package/lib/app/services/rateLimit/index.js +3 -0
  166. package/lib/app/services/rateLimit/index.js.map +1 -0
  167. package/lib/app/services/storage/DiskStorageAdapter.d.ts +62 -0
  168. package/lib/app/services/storage/DiskStorageAdapter.d.ts.map +1 -0
  169. package/lib/app/services/storage/DiskStorageAdapter.js +295 -0
  170. package/lib/app/services/storage/DiskStorageAdapter.js.map +1 -0
  171. package/lib/app/services/storage/GCSStorageAdapter.d.ts +44 -0
  172. package/lib/app/services/storage/GCSStorageAdapter.d.ts.map +1 -0
  173. package/lib/app/services/storage/GCSStorageAdapter.js +133 -0
  174. package/lib/app/services/storage/GCSStorageAdapter.js.map +1 -0
  175. package/lib/app/services/storage/S3StorageAdapter.d.ts +57 -0
  176. package/lib/app/services/storage/S3StorageAdapter.d.ts.map +1 -0
  177. package/lib/app/services/storage/S3StorageAdapter.js +162 -0
  178. package/lib/app/services/storage/S3StorageAdapter.js.map +1 -0
  179. package/lib/app/services/storage/StorageService.d.ts +88 -0
  180. package/lib/app/services/storage/StorageService.d.ts.map +1 -0
  181. package/lib/app/services/storage/StorageService.js +18 -0
  182. package/lib/app/services/storage/StorageService.js.map +1 -0
  183. package/lib/app/services/storage/index.d.ts +5 -0
  184. package/lib/app/services/storage/index.d.ts.map +1 -0
  185. package/lib/app/services/storage/index.js +4 -0
  186. package/lib/app/services/storage/index.js.map +1 -0
  187. package/lib/app/utils/ContextValidators.d.ts +46 -0
  188. package/lib/app/utils/ContextValidators.d.ts.map +1 -0
  189. package/lib/app/utils/ContextValidators.js +81 -0
  190. package/lib/app/utils/ContextValidators.js.map +1 -0
  191. package/lib/app/utils/defineEnv.d.ts +80 -0
  192. package/lib/app/utils/defineEnv.d.ts.map +1 -0
  193. package/lib/app/utils/defineEnv.js +95 -0
  194. package/lib/app/utils/defineEnv.js.map +1 -0
  195. package/lib/client.d.ts +139 -0
  196. package/lib/client.d.ts.map +1 -0
  197. package/lib/client.js +98 -0
  198. package/lib/client.js.map +1 -0
  199. package/lib/contract/application.d.ts +3 -0
  200. package/lib/contract/application.d.ts.map +1 -0
  201. package/lib/contract/application.js +2 -0
  202. package/lib/contract/application.js.map +1 -0
  203. package/lib/contract/client.d.ts +3 -0
  204. package/lib/contract/client.d.ts.map +1 -0
  205. package/lib/contract/client.js +3 -0
  206. package/lib/contract/client.js.map +1 -0
  207. package/lib/contract/index.d.ts +3 -0
  208. package/lib/contract/index.d.ts.map +1 -0
  209. package/lib/contract/index.js +3 -0
  210. package/lib/contract/index.js.map +1 -0
  211. package/lib/contract/manifest.d.ts +3 -0
  212. package/lib/contract/manifest.d.ts.map +1 -0
  213. package/lib/contract/manifest.js +2 -0
  214. package/lib/contract/manifest.js.map +1 -0
  215. package/lib/contract/openapi.d.ts +3 -0
  216. package/lib/contract/openapi.d.ts.map +1 -0
  217. package/lib/contract/openapi.js +3 -0
  218. package/lib/contract/openapi.js.map +1 -0
  219. package/lib/contract/project.d.ts +3 -0
  220. package/lib/contract/project.d.ts.map +1 -0
  221. package/lib/contract/project.js +3 -0
  222. package/lib/contract/project.js.map +1 -0
  223. package/lib/contract/schema.d.ts +3 -0
  224. package/lib/contract/schema.d.ts.map +1 -0
  225. package/lib/contract/schema.js +3 -0
  226. package/lib/contract/schema.js.map +1 -0
  227. package/lib/drizzle/index.d.ts +3 -0
  228. package/lib/drizzle/index.d.ts.map +1 -0
  229. package/lib/drizzle/index.js +3 -0
  230. package/lib/drizzle/index.js.map +1 -0
  231. package/lib/hono/auth.d.ts +6 -0
  232. package/lib/hono/auth.d.ts.map +1 -0
  233. package/lib/hono/auth.js +54 -0
  234. package/lib/hono/auth.js.map +1 -0
  235. package/lib/hono/index.d.ts +4 -0
  236. package/lib/hono/index.d.ts.map +1 -0
  237. package/lib/hono/index.js +4 -0
  238. package/lib/hono/index.js.map +1 -0
  239. package/lib/http/app/createApp.d.ts +132 -0
  240. package/lib/http/app/createApp.d.ts.map +1 -0
  241. package/lib/http/app/createApp.js +215 -0
  242. package/lib/http/app/createApp.js.map +1 -0
  243. package/lib/http/app/devRoutes.d.ts +31 -0
  244. package/lib/http/app/devRoutes.d.ts.map +1 -0
  245. package/lib/http/app/devRoutes.js +145 -0
  246. package/lib/http/app/devRoutes.js.map +1 -0
  247. package/lib/http/app/errors.d.ts +45 -0
  248. package/lib/http/app/errors.d.ts.map +1 -0
  249. package/lib/http/app/errors.js +93 -0
  250. package/lib/http/app/errors.js.map +1 -0
  251. package/lib/http/app/health.d.ts +66 -0
  252. package/lib/http/app/health.d.ts.map +1 -0
  253. package/lib/http/app/health.js +104 -0
  254. package/lib/http/app/health.js.map +1 -0
  255. package/lib/http/errors/AppError.d.ts +10 -0
  256. package/lib/http/errors/AppError.d.ts.map +1 -0
  257. package/lib/http/errors/AppError.js +19 -0
  258. package/lib/http/errors/AppError.js.map +1 -0
  259. package/lib/http/errors/AuthenticationError.d.ts +8 -0
  260. package/lib/http/errors/AuthenticationError.d.ts.map +1 -0
  261. package/lib/http/errors/AuthenticationError.js +10 -0
  262. package/lib/http/errors/AuthenticationError.js.map +1 -0
  263. package/lib/http/errors/AuthorizationError.d.ts +8 -0
  264. package/lib/http/errors/AuthorizationError.d.ts.map +1 -0
  265. package/lib/http/errors/AuthorizationError.js +10 -0
  266. package/lib/http/errors/AuthorizationError.js.map +1 -0
  267. package/lib/http/errors/BadRequestError.d.ts +8 -0
  268. package/lib/http/errors/BadRequestError.d.ts.map +1 -0
  269. package/lib/http/errors/BadRequestError.js +10 -0
  270. package/lib/http/errors/BadRequestError.js.map +1 -0
  271. package/lib/http/errors/ConflictError.d.ts +8 -0
  272. package/lib/http/errors/ConflictError.d.ts.map +1 -0
  273. package/lib/http/errors/ConflictError.js +10 -0
  274. package/lib/http/errors/ConflictError.js.map +1 -0
  275. package/lib/http/errors/InternalServerError.d.ts +8 -0
  276. package/lib/http/errors/InternalServerError.d.ts.map +1 -0
  277. package/lib/http/errors/InternalServerError.js +10 -0
  278. package/lib/http/errors/InternalServerError.js.map +1 -0
  279. package/lib/http/errors/NotFoundError.d.ts +8 -0
  280. package/lib/http/errors/NotFoundError.d.ts.map +1 -0
  281. package/lib/http/errors/NotFoundError.js +10 -0
  282. package/lib/http/errors/NotFoundError.js.map +1 -0
  283. package/lib/http/errors/RateLimitError.d.ts +13 -0
  284. package/lib/http/errors/RateLimitError.d.ts.map +1 -0
  285. package/lib/http/errors/RateLimitError.js +16 -0
  286. package/lib/http/errors/RateLimitError.js.map +1 -0
  287. package/lib/http/errors/ServiceUnavailableError.d.ts +8 -0
  288. package/lib/http/errors/ServiceUnavailableError.d.ts.map +1 -0
  289. package/lib/http/errors/ServiceUnavailableError.js +10 -0
  290. package/lib/http/errors/ServiceUnavailableError.js.map +1 -0
  291. package/lib/http/errors/ValidationError.d.ts +9 -0
  292. package/lib/http/errors/ValidationError.d.ts.map +1 -0
  293. package/lib/http/errors/ValidationError.js +12 -0
  294. package/lib/http/errors/ValidationError.js.map +1 -0
  295. package/lib/http/errors/index.d.ts +11 -0
  296. package/lib/http/errors/index.d.ts.map +1 -0
  297. package/lib/http/errors/index.js +12 -0
  298. package/lib/http/errors/index.js.map +1 -0
  299. package/lib/http/middleware/apiKey.d.ts +9 -0
  300. package/lib/http/middleware/apiKey.d.ts.map +1 -0
  301. package/lib/http/middleware/apiKey.js +71 -0
  302. package/lib/http/middleware/apiKey.js.map +1 -0
  303. package/lib/http/middleware/csrf.d.ts +63 -0
  304. package/lib/http/middleware/csrf.d.ts.map +1 -0
  305. package/lib/http/middleware/csrf.js +169 -0
  306. package/lib/http/middleware/csrf.js.map +1 -0
  307. package/lib/http/middleware/httpLogger.d.ts +39 -0
  308. package/lib/http/middleware/httpLogger.d.ts.map +1 -0
  309. package/lib/http/middleware/httpLogger.js +118 -0
  310. package/lib/http/middleware/httpLogger.js.map +1 -0
  311. package/lib/http/middleware/idempotency.d.ts +48 -0
  312. package/lib/http/middleware/idempotency.d.ts.map +1 -0
  313. package/lib/http/middleware/idempotency.js +180 -0
  314. package/lib/http/middleware/idempotency.js.map +1 -0
  315. package/lib/http/middleware/rateLimit.d.ts +105 -0
  316. package/lib/http/middleware/rateLimit.d.ts.map +1 -0
  317. package/lib/http/middleware/rateLimit.js +84 -0
  318. package/lib/http/middleware/rateLimit.js.map +1 -0
  319. package/lib/http/middleware/requireAuth.d.ts +58 -0
  320. package/lib/http/middleware/requireAuth.d.ts.map +1 -0
  321. package/lib/http/middleware/requireAuth.js +63 -0
  322. package/lib/http/middleware/requireAuth.js.map +1 -0
  323. package/lib/http/middleware/requirePermission.d.ts +23 -0
  324. package/lib/http/middleware/requirePermission.d.ts.map +1 -0
  325. package/lib/http/middleware/requirePermission.js +50 -0
  326. package/lib/http/middleware/requirePermission.js.map +1 -0
  327. package/lib/http/middleware/resolveTenant.d.ts +41 -0
  328. package/lib/http/middleware/resolveTenant.d.ts.map +1 -0
  329. package/lib/http/middleware/resolveTenant.js +17 -0
  330. package/lib/http/middleware/resolveTenant.js.map +1 -0
  331. package/lib/http/streaming/sse.d.ts +31 -0
  332. package/lib/http/streaming/sse.d.ts.map +1 -0
  333. package/lib/http/streaming/sse.js +11 -0
  334. package/lib/http/streaming/sse.js.map +1 -0
  335. package/lib/http/streaming/streamLLM.d.ts +94 -0
  336. package/lib/http/streaming/streamLLM.d.ts.map +1 -0
  337. package/lib/http/streaming/streamLLM.js +94 -0
  338. package/lib/http/streaming/streamLLM.js.map +1 -0
  339. package/lib/http/utils/authCookies.d.ts +74 -0
  340. package/lib/http/utils/authCookies.d.ts.map +1 -0
  341. package/lib/http/utils/authCookies.js +102 -0
  342. package/lib/http/utils/authCookies.js.map +1 -0
  343. package/lib/http/utils/clientIp.d.ts +85 -0
  344. package/lib/http/utils/clientIp.d.ts.map +1 -0
  345. package/lib/http/utils/clientIp.js +249 -0
  346. package/lib/http/utils/clientIp.js.map +1 -0
  347. package/lib/http/utils/index.d.ts +4 -0
  348. package/lib/http/utils/index.d.ts.map +1 -0
  349. package/lib/http/utils/index.js +5 -0
  350. package/lib/http/utils/index.js.map +1 -0
  351. package/lib/http/utils/metaTags.d.ts +49 -0
  352. package/lib/http/utils/metaTags.d.ts.map +1 -0
  353. package/lib/http/utils/metaTags.js +32 -0
  354. package/lib/http/utils/metaTags.js.map +1 -0
  355. package/lib/http/utils/publicSuffix.d.ts +34 -0
  356. package/lib/http/utils/publicSuffix.d.ts.map +1 -0
  357. package/lib/http/utils/publicSuffix.js +276 -0
  358. package/lib/http/utils/publicSuffix.js.map +1 -0
  359. package/lib/http/utils/uploads.d.ts +92 -0
  360. package/lib/http/utils/uploads.d.ts.map +1 -0
  361. package/lib/http/utils/uploads.js +126 -0
  362. package/lib/http/utils/uploads.js.map +1 -0
  363. package/lib/http/utils/validate.d.ts +41 -0
  364. package/lib/http/utils/validate.d.ts.map +1 -0
  365. package/lib/http/utils/validate.js +55 -0
  366. package/lib/http/utils/validate.js.map +1 -0
  367. package/lib/http/utils/webhooks.d.ts +63 -0
  368. package/lib/http/utils/webhooks.d.ts.map +1 -0
  369. package/lib/http/utils/webhooks.js +133 -0
  370. package/lib/http/utils/webhooks.js.map +1 -0
  371. package/lib/http/ws/auth.d.ts +46 -0
  372. package/lib/http/ws/auth.d.ts.map +1 -0
  373. package/lib/http/ws/auth.js +123 -0
  374. package/lib/http/ws/auth.js.map +1 -0
  375. package/lib/index.d.ts +80 -0
  376. package/lib/index.d.ts.map +1 -0
  377. package/lib/index.js +61 -0
  378. package/lib/index.js.map +1 -0
  379. package/lib/kernel/index.d.ts +3 -0
  380. package/lib/kernel/index.d.ts.map +1 -0
  381. package/lib/kernel/index.js +3 -0
  382. package/lib/kernel/index.js.map +1 -0
  383. package/lib/libraries/.gitkeep +0 -0
  384. package/lib/libraries/ai/CHANGELOG.md +17 -0
  385. package/lib/libraries/ai/README.md +164 -0
  386. package/lib/libraries/ai/adapters/AnthropicAdapter.ts +382 -0
  387. package/lib/libraries/ai/adapters/LLMProvider.ts +76 -0
  388. package/lib/libraries/ai/adapters/OpenAIAdapter.ts +466 -0
  389. package/lib/libraries/ai/experimental/index.ts +20 -0
  390. package/lib/libraries/ai/index.ts +128 -0
  391. package/lib/libraries/ai/library.json +19 -0
  392. package/lib/libraries/ai/loop/agentLoop.ts +377 -0
  393. package/lib/libraries/ai/prompts/definePrompt.ts +0 -0
  394. package/lib/libraries/ai/rag/retrieveAndAnswer.ts +177 -0
  395. package/lib/libraries/ai/streaming/streamLLM.ts +94 -0
  396. package/lib/libraries/ai/structured/completeStructured.ts +143 -0
  397. package/lib/libraries/ai/tokens/Tokenizer.ts +216 -0
  398. package/lib/libraries/ai/tools/defineTool.ts +208 -0
  399. package/lib/libraries/ai/types.ts +260 -0
  400. package/lib/libraries/chunking/ChunkingService.ts +103 -0
  401. package/lib/libraries/chunking/README.md +104 -0
  402. package/lib/libraries/chunking/docs/api-reference.md +549 -0
  403. package/lib/libraries/chunking/docs/best-practices.md +321 -0
  404. package/lib/libraries/chunking/docs/code-organization.md +538 -0
  405. package/lib/libraries/chunking/docs/configuration.md +418 -0
  406. package/lib/libraries/chunking/docs/index.md +236 -0
  407. package/lib/libraries/chunking/docs/quick-start.md +298 -0
  408. package/lib/libraries/chunking/docs/strategies.md +407 -0
  409. package/lib/libraries/chunking/docs/summary.md +258 -0
  410. package/lib/libraries/chunking/docs/troubleshooting.md +527 -0
  411. package/lib/libraries/chunking/index.ts +17 -0
  412. package/lib/libraries/chunking/library.json +16 -0
  413. package/lib/libraries/chunking/strategies/ChunkingStrategy.ts +13 -0
  414. package/lib/libraries/chunking/strategies/FixedLengthChunkingStrategy.ts +88 -0
  415. package/lib/libraries/chunking/strategies/SemanticChunkingStrategy.ts +389 -0
  416. package/lib/libraries/chunking/strategies/SlidingWindowChunkingStrategy.ts +258 -0
  417. package/lib/libraries/chunking/types/index.ts +63 -0
  418. package/lib/libraries/email/EmailService.ts +591 -0
  419. package/lib/libraries/email/README.md +777 -0
  420. package/lib/libraries/email/TemplateRegistry.ts +148 -0
  421. package/lib/libraries/email/TemplateRenderer.ts +273 -0
  422. package/lib/libraries/email/index.ts +4 -0
  423. package/lib/libraries/email/initializeEmailService.ts +60 -0
  424. package/lib/libraries/email/library.json +12 -0
  425. package/lib/libraries/email/types/EmailAddress.ts +4 -0
  426. package/lib/libraries/email/types/EmailAttachment.ts +11 -0
  427. package/lib/libraries/email/types/EmailTag.ts +9 -0
  428. package/lib/libraries/email/types/EmailTemplate.ts +124 -0
  429. package/lib/libraries/email/types/SendBatchEmailsOptions.ts +9 -0
  430. package/lib/libraries/email/types/SendBatchEmailsResult.ts +9 -0
  431. package/lib/libraries/email/types/SendEmailOptions.ts +33 -0
  432. package/lib/libraries/email/types/SendEmailResult.ts +9 -0
  433. package/lib/libraries/email/types/index.ts +8 -0
  434. package/lib/libraries/weaviate/QueryBuilder.ts +292 -0
  435. package/lib/libraries/weaviate/README.md +284 -0
  436. package/lib/libraries/weaviate/Weaviate.ts +1419 -0
  437. package/lib/libraries/weaviate/WeaviateConfig.ts +268 -0
  438. package/lib/libraries/weaviate/docs/.gitkeep +1 -0
  439. package/lib/libraries/weaviate/docs/API_REFERENCE.md +1067 -0
  440. package/lib/libraries/weaviate/docs/CONFIGURATION.md +320 -0
  441. package/lib/libraries/weaviate/docs/ERROR_HANDLING.md +271 -0
  442. package/lib/libraries/weaviate/docs/MULTI_TENANCY.md +348 -0
  443. package/lib/libraries/weaviate/docs/PERFORMANCE.md +602 -0
  444. package/lib/libraries/weaviate/docs/PLUGIN_DEVELOPMENT.md +547 -0
  445. package/lib/libraries/weaviate/docs/QUICK_START.md +443 -0
  446. package/lib/libraries/weaviate/docs/README.md +269 -0
  447. package/lib/libraries/weaviate/docs/SCHEMA_GUIDE.md +630 -0
  448. package/lib/libraries/weaviate/docs/WEAVIATE_README.md +520 -0
  449. package/lib/libraries/weaviate/errors/WeaviateError.ts +92 -0
  450. package/lib/libraries/weaviate/errors/index.ts +1 -0
  451. package/lib/libraries/weaviate/index.ts +35 -0
  452. package/lib/libraries/weaviate/library.json +26 -0
  453. package/lib/libraries/weaviate/plugins/index.ts +2 -0
  454. package/lib/libraries/weaviate/schemas/SchemaRegistry.ts +284 -0
  455. package/lib/libraries/weaviate/schemas/index.ts +2 -0
  456. package/lib/libraries/weaviate/types/BM25SearchOptions.ts +9 -0
  457. package/lib/libraries/weaviate/types/ExtendedWeaviateClient.ts +7 -0
  458. package/lib/libraries/weaviate/types/HybridSearchOptions.ts +11 -0
  459. package/lib/libraries/weaviate/types/MultiTenancy.ts +81 -0
  460. package/lib/libraries/weaviate/types/Plugin.ts +17 -0
  461. package/lib/libraries/weaviate/types/SchemaConfig.ts +25 -0
  462. package/lib/libraries/weaviate/types/SearchMethod.ts +8 -0
  463. package/lib/libraries/weaviate/types/SearchOptions.ts +16 -0
  464. package/lib/libraries/weaviate/types/SearchRequest.ts +19 -0
  465. package/lib/libraries/weaviate/types/SearchResult.ts +16 -0
  466. package/lib/libraries/weaviate/types/SearchableField.ts +87 -0
  467. package/lib/libraries/weaviate/types/VectorIndexConfig.ts +19 -0
  468. package/lib/libraries/weaviate/types/VectorSearchOptions.ts +18 -0
  469. package/lib/libraries/weaviate/types/VectorizerConfig.ts +8 -0
  470. package/lib/libraries/weaviate/types/index.ts +29 -0
  471. package/lib/libraries/weaviate/utils/TenantContextManager.ts +94 -0
  472. package/lib/modules/accounts/index.ts +47 -0
  473. package/lib/modules/accounts/module.json +15 -0
  474. package/lib/modules/accounts/permissions.ts +33 -0
  475. package/lib/modules/accounts/routes.ts +200 -0
  476. package/lib/modules/accounts/schema.ts +219 -0
  477. package/lib/modules/accounts/services/AccountService.ts +44 -0
  478. package/lib/modules/accounts/validation/schemas.ts +70 -0
  479. package/lib/modules/oauth/adapters/GmailOAuthAdapter.ts +35 -0
  480. package/lib/modules/oauth/adapters/GoogleOAuthAdapter.ts +278 -0
  481. package/lib/modules/oauth/adapters/MicrosoftOAuthAdapter.ts +269 -0
  482. package/lib/modules/oauth/adapters/MockOAuthAdapter.ts +138 -0
  483. package/lib/modules/oauth/adapters/OAuthAdapter.ts +211 -0
  484. package/lib/modules/oauth/adapters/OAuthAdapterRegistry.ts +77 -0
  485. package/lib/modules/oauth/adapters/OutlookOAuthAdapter.ts +38 -0
  486. package/lib/modules/oauth/index.ts +79 -0
  487. package/lib/modules/oauth/module.json +23 -0
  488. package/lib/modules/oauth/permissions.ts +39 -0
  489. package/lib/modules/oauth/routes.ts +497 -0
  490. package/lib/modules/oauth/schema.ts +127 -0
  491. package/lib/modules/oauth/services/OAuthConnectionService.ts +147 -0
  492. package/lib/modules/oauth/state.ts +234 -0
  493. package/lib/modules/oauth/stateJtiCache.ts +85 -0
  494. package/lib/modules/oauth/verifyIdToken.ts +178 -0
  495. package/lib/modules/outbox/EventEmitter.ts +106 -0
  496. package/lib/modules/outbox/OutboxDrainer.ts +163 -0
  497. package/lib/modules/outbox/handlers/EventHandler.ts +115 -0
  498. package/lib/modules/outbox/index.ts +43 -0
  499. package/lib/modules/outbox/module.json +15 -0
  500. package/lib/modules/outbox/permissions.ts +36 -0
  501. package/lib/modules/outbox/routes.ts +219 -0
  502. package/lib/modules/outbox/schema.ts +207 -0
  503. package/lib/modules/outbox/services/OutboxEventService.ts +223 -0
  504. package/lib/observability/logger.d.ts +30 -0
  505. package/lib/observability/logger.d.ts.map +1 -0
  506. package/lib/observability/logger.js +110 -0
  507. package/lib/observability/logger.js.map +1 -0
  508. package/lib/observability/metrics.d.ts +3 -0
  509. package/lib/observability/metrics.d.ts.map +1 -0
  510. package/lib/observability/metrics.js +3 -0
  511. package/lib/observability/metrics.js.map +1 -0
  512. package/lib/observability/otel.d.ts +3 -0
  513. package/lib/observability/otel.d.ts.map +1 -0
  514. package/lib/observability/otel.js +3 -0
  515. package/lib/observability/otel.js.map +1 -0
  516. package/lib/observability/safeErrorFields.d.ts +14 -0
  517. package/lib/observability/safeErrorFields.d.ts.map +1 -0
  518. package/lib/observability/safeErrorFields.js +14 -0
  519. package/lib/observability/safeErrorFields.js.map +1 -0
  520. package/lib/observability/tracing.d.ts +3 -0
  521. package/lib/observability/tracing.d.ts.map +1 -0
  522. package/lib/observability/tracing.js +3 -0
  523. package/lib/observability/tracing.js.map +1 -0
  524. package/lib/package.json +4 -0
  525. package/lib/testing.d.ts +3 -0
  526. package/lib/testing.d.ts.map +1 -0
  527. package/lib/testing.js +3 -0
  528. package/lib/testing.js.map +1 -0
  529. package/package.json +193 -3
  530. package/templates/default/.claude/agents/qa-brief.md +106 -0
  531. package/templates/default/.claude/commands/sherpa-brief.md +23 -0
  532. package/templates/default/.cursor/rules/api.mdc +80 -0
  533. package/templates/default/.cursor/rules/commits.mdc +88 -0
  534. package/templates/default/.cursor/rules/security.mdc +92 -0
  535. package/templates/default/.cursor/rules/testing.mdc +123 -0
  536. package/templates/default/.cursor/rules/typescript.mdc +86 -0
  537. package/templates/default/.env.example +79 -0
  538. package/templates/default/.github/workflows/sherpa-brief.yml +180 -0
  539. package/templates/default/AGENTS.md +166 -0
  540. package/templates/default/CLAUDE.md +17 -0
  541. package/templates/default/README.md +97 -0
  542. package/templates/default/_gitignore +27 -0
  543. package/templates/default/docker-compose.yml +83 -0
  544. package/templates/default/drizzle.config.ts +34 -0
  545. package/templates/default/eslint.config.mjs +106 -0
  546. package/templates/default/package.json +57 -0
  547. package/templates/default/ship-api.config.ts +21 -0
  548. package/templates/default/src/client.ts +34 -0
  549. package/templates/default/src/config/modules.ts +23 -0
  550. package/templates/default/src/db/schema.ts +26 -0
  551. package/templates/default/src/environment.ts +81 -0
  552. package/templates/default/src/index.test.ts +53 -0
  553. package/templates/default/src/index.ts +11 -0
  554. package/templates/default/src/instrumentation.ts +13 -0
  555. package/templates/default/src/server.ts +90 -0
  556. package/templates/default/tsconfig.json +24 -0
@@ -0,0 +1,105 @@
1
+ import type { Context, MiddlewareHandler } from "hono";
2
+ import type { RateLimitBackend } from "../../app/services/rateLimit/RateLimitBackend.js";
3
+ import { logger as defaultLogger } from "../../observability/logger.js";
4
+ /**
5
+ * `rateLimit({ windowMs, max, ... })` — Hono middleware factory.
6
+ *
7
+ * Replaces v3's in-memory `RateLimitMiddleware`. Production-default backend
8
+ * is `RedisSlidingWindowBackend` (atomic Lua sliding-window log); v4.0 also
9
+ * ships `InMemorySlidingWindowBackend` for tests + dev fallback.
10
+ *
11
+ * Headers (RFC-draft `RateLimit-*`):
12
+ * - `RateLimit-Limit: <max>`
13
+ * - `RateLimit-Remaining: <max - used>`
14
+ * - `RateLimit-Policy: <max>;w=<window-seconds>`
15
+ * Optional legacy headers (`X-RateLimit-Limit/Remaining/Reset`) emitted when
16
+ * `legacyHeaders: true` for clients that haven't moved to the draft yet.
17
+ *
18
+ * On rejection: throws `RateLimitError` (mapped to 429 by registerErrorHandlers)
19
+ * after setting `Retry-After: <seconds>`. The middleware sets headers on the
20
+ * outgoing response *before* throwing so the 429 response carries them.
21
+ *
22
+ * Redis-unavailable behavior is configurable, NOT a silent fallback:
23
+ * - `'deny'` (default, fail-closed) — returns RateLimitError as if the
24
+ * ceiling were exceeded. Safer default; the user gets a real 429
25
+ * instead of unintentional unlimited access.
26
+ * - `'allow'` (fail-open) — calls next() without enforcement. Logs a
27
+ * warning so operators can detect Redis flapping.
28
+ *
29
+ * Tagged `RATE_LIMIT_META` so `createApp` populates the route registry.
30
+ */
31
+ export interface RateLimitOptions {
32
+ /** Window length in milliseconds. */
33
+ windowMs: number;
34
+ /** Maximum requests per key per window. */
35
+ max: number;
36
+ /** Backend implementation. Default: a shared in-memory backend; production
37
+ * consumers pass a `RedisSlidingWindowBackend`. */
38
+ backend: RateLimitBackend;
39
+ /**
40
+ * Compose the bucket key from the request. Default: authenticated user
41
+ * ID (from `c.get('user').id`) when set, else the client IP. The request
42
+ * path is *not* included by default — for per-route limits, instantiate
43
+ * a separate `rateLimit({...})` per route.
44
+ */
45
+ keyGenerator?: (c: Context) => string;
46
+ /**
47
+ * Namespace appended to the bucket key (e.g., `"login"` for a tighter
48
+ * limiter on `POST /accounts/login`). Default: empty.
49
+ */
50
+ scope?: string;
51
+ /**
52
+ * Behavior when the backend throws (e.g., Redis unreachable):
53
+ * - `'deny'` (default): treat as over-limit, throw RateLimitError.
54
+ * - `'allow'`: log a warning, call next() without enforcement.
55
+ *
56
+ * **F28 — security note on `'allow'`.** `onBackendError: 'allow'`
57
+ * **removes rate limiting entirely** during any window where the
58
+ * backend is unavailable — login / signup / password-reset
59
+ * endpoints become unbounded for the duration of the outage. Don't
60
+ * pick `'allow'` as a workaround for flaky Redis: fix Redis first
61
+ * (HA failover, connection pool tuning, a separate Redis tier
62
+ * for rate-limit state). Choose `'allow'` only with a deliberate
63
+ * threat-model decision that the availability cost of brief
64
+ * unlimited access during outages outweighs the security cost.
65
+ * Common deployments where `'allow'` is defensible: internal-only
66
+ * APIs behind VPN auth where rate limiting is UX-shaping rather
67
+ * than security; public APIs with WAF-layer rate limiting
68
+ * upstream. Public-facing SaaS authentication endpoints are
69
+ * exactly where `'allow'` is wrong.
70
+ */
71
+ onBackendError?: "allow" | "deny";
72
+ /** Emit `X-RateLimit-*` headers in addition to the RFC draft `RateLimit-*` set. */
73
+ legacyHeaders?: boolean;
74
+ /** Override the framework default pino logger. */
75
+ logger?: typeof defaultLogger;
76
+ /**
77
+ * CIDR allowlist for upstream proxies. The default key generator
78
+ * trusts `X-Forwarded-For` **only** when the immediate peer's IP
79
+ * falls inside one of these ranges; otherwise XFF is ignored and
80
+ * the peer IP wins. The framework default is the empty list — the
81
+ * secure, fail-closed posture for adopters who haven't declared
82
+ * their topology.
83
+ *
84
+ * In production, set this to the public CIDR ranges of your CDN /
85
+ * load balancer (Cloudflare, AWS ALB, Fastly, Google Cloud Armor,
86
+ * etc.). The rightmost-untrusted-IP walker then returns the real
87
+ * client IP from XFF, skipping each known proxy hop.
88
+ *
89
+ * Example (Cloudflare, abbreviated):
90
+ * `trustProxy: ["173.245.48.0/20", "103.21.244.0/22", "2400:cb00::/32", ...]`
91
+ *
92
+ * `["0.0.0.0/0", "::/0"]` trusts every peer — useful in unit tests
93
+ * where the peer IP cannot be observed, **never** in production.
94
+ */
95
+ trustProxy?: readonly string[];
96
+ /**
97
+ * Resolve the immediate peer IP from the Hono `Context`. Default:
98
+ * read `c.env.incoming.socket.remoteAddress` (Node adapter). Tests
99
+ * and non-Node runtimes (Cloudflare, Deno, Bun) override this with
100
+ * an env-specific reader.
101
+ */
102
+ resolvePeerIp?: (c: Context) => string | undefined;
103
+ }
104
+ export declare function rateLimit(opts: RateLimitOptions): MiddlewareHandler;
105
+ //# sourceMappingURL=rateLimit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/rateLimit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AACzF,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAKxE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ;wDACoD;IACpD,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACtC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,mFAAmF;IACnF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,aAAa,CAAC;IAC9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACpD;AAiDD,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CA2DnE"}
@@ -0,0 +1,84 @@
1
+ import { logger as defaultLogger } from "../../observability/logger.js";
2
+ import { RateLimitError } from "../errors/RateLimitError.js";
3
+ import { compileTrustProxy, resolveClientIp } from "../utils/clientIp.js";
4
+ import { RATE_LIMIT_META, setMetaTag } from "../utils/metaTags.js";
5
+ function defaultResolvePeerIp(c) {
6
+ // Node adapter exposes the underlying IncomingMessage via `c.env.incoming`.
7
+ // Cloudflare / Deno / Bun runtimes pass `resolvePeerIp` explicitly.
8
+ const env = c.env;
9
+ return env?.incoming?.socket?.remoteAddress;
10
+ }
11
+ function makeDefaultKeyGenerator(trustList, resolvePeerIp) {
12
+ return (c) => {
13
+ // Prefer authenticated user when present — auth-bound limits are
14
+ // never affected by IP trust, since the key is identity-based.
15
+ const user = c.get("user");
16
+ if (user?.id)
17
+ return `user:${user.id}`;
18
+ const peerIp = resolvePeerIp(c);
19
+ const xff = c.req.header("x-forwarded-for");
20
+ return `ip:${resolveClientIp({ peerIp, xff, trustProxy: trustList })}`;
21
+ };
22
+ }
23
+ function setHeaders(c, used, limit, windowMs, resetAtMs, legacy) {
24
+ const remaining = Math.max(0, limit - used);
25
+ const windowSec = Math.ceil(windowMs / 1000);
26
+ const resetEpochSec = Math.ceil(resetAtMs / 1000);
27
+ // RFC-draft headers (draft-ietf-httpapi-ratelimit-headers-10).
28
+ c.header("RateLimit-Limit", String(limit));
29
+ c.header("RateLimit-Remaining", String(remaining));
30
+ c.header("RateLimit-Policy", `${limit};w=${windowSec}`);
31
+ if (legacy) {
32
+ c.header("X-RateLimit-Limit", String(limit));
33
+ c.header("X-RateLimit-Remaining", String(remaining));
34
+ c.header("X-RateLimit-Reset", String(resetEpochSec));
35
+ }
36
+ }
37
+ export function rateLimit(opts) {
38
+ if (opts.windowMs <= 0 || opts.max <= 0) {
39
+ throw new Error("rateLimit(): windowMs and max must be positive");
40
+ }
41
+ const trustList = compileTrustProxy(opts.trustProxy);
42
+ const resolvePeerIp = opts.resolvePeerIp ?? defaultResolvePeerIp;
43
+ const keyGen = opts.keyGenerator ?? makeDefaultKeyGenerator(trustList, resolvePeerIp);
44
+ const onBackendError = opts.onBackendError ?? "deny";
45
+ const log = opts.logger ?? defaultLogger;
46
+ const scopePrefix = opts.scope ? `${opts.scope}:` : "";
47
+ const middleware = async (c, next) => {
48
+ const key = scopePrefix + keyGen(c);
49
+ const now = Date.now();
50
+ let result;
51
+ try {
52
+ result = await opts.backend.check({
53
+ key,
54
+ windowMs: opts.windowMs,
55
+ max: opts.max,
56
+ now,
57
+ });
58
+ }
59
+ catch (err) {
60
+ // Backend failure (e.g., Redis down). Apply the configured policy.
61
+ log.warn({ err, key, policy: onBackendError }, "ratelimit.backend_error");
62
+ if (onBackendError === "allow")
63
+ return next();
64
+ // 'deny' — fail closed
65
+ const retryAfterSec = Math.max(1, Math.ceil(opts.windowMs / 1000));
66
+ throw new RateLimitError(retryAfterSec, "Rate limiter unavailable");
67
+ }
68
+ setHeaders(c, result.used, result.limit, opts.windowMs, result.resetAtMs, opts.legacyHeaders ?? false);
69
+ if (!result.allowed) {
70
+ const retryAfterSec = Math.max(1, Math.ceil((result.resetAtMs - now) / 1000));
71
+ c.header("Retry-After", String(retryAfterSec));
72
+ throw new RateLimitError(retryAfterSec);
73
+ }
74
+ return next();
75
+ };
76
+ const tag = {
77
+ windowMs: opts.windowMs,
78
+ max: opts.max,
79
+ scope: opts.scope,
80
+ };
81
+ setMetaTag(middleware, RATE_LIMIT_META, tag);
82
+ return middleware;
83
+ }
84
+ //# sourceMappingURL=rateLimit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../../src/http/middleware/rateLimit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { MiddlewareHandler } from "hono";
2
+ import type { AuthenticatedAccount, AuthProvider } from "../../app/auth/AuthProvider.js";
3
+ /**
4
+ * `requireAuth({ provider, ... })` — Hono middleware factory that runs the
5
+ * configured `AuthProvider` chain (verify + resolve) and attaches the
6
+ * authenticated `Account` to `c.set('user', ...)`.
7
+ *
8
+ * Replaces v3's `JwtAuthMiddleware`. Key differences:
9
+ *
10
+ * 1. **Pluggable**. Backed by the `AuthProvider` interface; Firebase is
11
+ * adapter #1, but any v4.x adapter (Better-Auth / Clerk / WorkOS / …)
12
+ * drops in without changing this middleware.
13
+ *
14
+ * 2. **Silent fall-through is opt-in**. The v3 default (no token →
15
+ * `next()` without user) was a footgun. v4 throws `AuthenticationError`
16
+ * when a token is missing unless `optional: true` is set explicitly.
17
+ *
18
+ * 3. **Tagged for the route registry**. `createApp`'s interceptor reads
19
+ * the `AUTH_META` tag to populate the route registry with auth state
20
+ * so MCP tools, `ship-reviewer`, and `/dev/routes` know whether each
21
+ * route requires auth.
22
+ *
23
+ * 4. **Throws AppErrors**, not direct responses. `app.onError(...)` formats
24
+ * them — keeps the response shape consistent across the framework.
25
+ *
26
+ * Failure mapping:
27
+ * - `missing-token` + `optional: false` → 401 `AuthenticationError`
28
+ * - `missing-token` + `optional: true` → `next()` with no user / claims
29
+ * - any other verify failure (invalid / expired / revoked / issuer-mismatch)
30
+ * → 401 `AuthenticationError` regardless of `optional` (a present-but-bad
31
+ * token is always rejected)
32
+ * - verify ok + resolve returns null + `onUnknownAccount: 'reject'` (default)
33
+ * → 403 `AuthorizationError`
34
+ * - verify ok + resolve null + `onUnknownAccount: 'next'` → `next()` with
35
+ * `claims` set but no `user`
36
+ *
37
+ * On success: sets `c.set('user', account)` and `c.set('claims', claims)`,
38
+ * publishes `account.id` to `RequestContext.userId` (so audit-stamping and
39
+ * structured logging see the actor), then `next()`.
40
+ */
41
+ export interface RequireAuthOptions<TAccount extends AuthenticatedAccount = AuthenticatedAccount> {
42
+ /** The AuthProvider to use. Required. */
43
+ provider: AuthProvider<TAccount>;
44
+ /**
45
+ * If true, missing tokens fall through to `next()` without throwing. Default
46
+ * `false`. Use this for endpoints that serve unauthenticated traffic with
47
+ * degraded data (e.g., a public profile page that shows extra fields when
48
+ * logged in).
49
+ */
50
+ optional?: boolean;
51
+ }
52
+ /** Hono context-variable keys this middleware sets on success. */
53
+ export declare const AUTH_CONTEXT_KEYS: {
54
+ user: "user";
55
+ claims: "claims";
56
+ };
57
+ export declare function requireAuth<TAccount extends AuthenticatedAccount = AuthenticatedAccount>(opts: RequireAuthOptions<TAccount>): MiddlewareHandler;
58
+ //# sourceMappingURL=requireAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requireAuth.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/requireAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAEV,oBAAoB,EACpB,YAAY,EAEb,MAAM,gCAAgC,CAAC;AAMxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,MAAM,WAAW,kBAAkB,CAAC,QAAQ,SAAS,oBAAoB,GAAG,oBAAoB;IAC9F,yCAAyC;IACzC,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,kEAAkE;AAClE,eAAO,MAAM,iBAAiB;;;CAG7B,CAAC;AAYF,wBAAgB,WAAW,CAAC,QAAQ,SAAS,oBAAoB,GAAG,oBAAoB,EACtF,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACjC,iBAAiB,CAmDnB"}
@@ -0,0 +1,63 @@
1
+ import { setRequestContextField } from "../../app/context/RequestContext.js";
2
+ import { AuthenticationError } from "../errors/AuthenticationError.js";
3
+ import { AuthorizationError } from "../errors/AuthorizationError.js";
4
+ import { AUTH_META, setMetaTag } from "../utils/metaTags.js";
5
+ /** Hono context-variable keys this middleware sets on success. */
6
+ export const AUTH_CONTEXT_KEYS = {
7
+ user: "user",
8
+ claims: "claims",
9
+ };
10
+ function buildProviderContext(c) {
11
+ const headers = {};
12
+ // Hono normalizes header names to lowercase; AuthProvider adapters
13
+ // (firebase) expect lowercase too.
14
+ c.req.raw.headers.forEach((value, key) => {
15
+ headers[key.toLowerCase()] = value;
16
+ });
17
+ return { headers };
18
+ }
19
+ export function requireAuth(opts) {
20
+ const { provider } = opts;
21
+ const optional = opts.optional ?? false;
22
+ const middleware = async (c, next) => {
23
+ const providerCtx = buildProviderContext(c);
24
+ const verifyResult = await provider.verify(providerCtx);
25
+ if (!verifyResult.ok) {
26
+ if (verifyResult.reason === "missing-token") {
27
+ if (optional)
28
+ return next();
29
+ throw new AuthenticationError(verifyResult.message ?? "Authentication required");
30
+ }
31
+ // present-but-bad token is always rejected, even when optional=true
32
+ throw new AuthenticationError(verifyResult.message ?? `Authentication failed (${verifyResult.reason})`);
33
+ }
34
+ const claims = verifyResult.claims;
35
+ const account = await provider.resolve(claims);
36
+ if (account === null) {
37
+ const policy = provider.onUnknownAccount ?? "reject";
38
+ if (policy === "next") {
39
+ c.set(AUTH_CONTEXT_KEYS.claims, claims);
40
+ return next();
41
+ }
42
+ // 'create' is the provider's responsibility — if a provider wants
43
+ // first-sight account creation it does it inside `resolve()` itself.
44
+ // Here we treat 'create' as 'reject' (no-op) since we can't synthesize
45
+ // an account.
46
+ throw new AuthorizationError("No account registered for this credential");
47
+ }
48
+ c.set(AUTH_CONTEXT_KEYS.user, account);
49
+ c.set(AUTH_CONTEXT_KEYS.claims, claims);
50
+ // Publish the resolved account id to the request context so the logger,
51
+ // `DrizzleEntityService` audit-stamping (createdBy / updatedBy), and OTel
52
+ // spans all see the actor. No-op (returns false) outside an active context.
53
+ setRequestContextField("userId", account.id);
54
+ return next();
55
+ };
56
+ const tag = {
57
+ required: !optional,
58
+ providerName: provider.name,
59
+ };
60
+ setMetaTag(middleware, AUTH_META, tag);
61
+ return middleware;
62
+ }
63
+ //# sourceMappingURL=requireAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requireAuth.js","sourceRoot":"","sources":["../../../src/http/middleware/requireAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { MiddlewareHandler } from "hono";
2
+ /**
3
+ * `requirePermission(...slugs)` — Hono middleware factory that enforces
4
+ * the authenticated user has at least one of the supplied permission slugs
5
+ * (OR semantics within a single call).
6
+ *
7
+ * Replaces v3's `@HasPermission` decorator. To express AND across multiple
8
+ * permission groups, chain multiple `requirePermission()` middlewares —
9
+ * `createApp`'s registry interceptor unions slugs across calls so the
10
+ * registry shows the full set, and the runtime checks each call gates
11
+ * independently.
12
+ *
13
+ * Must run *after* a `requireAuth(...)` middleware on the same route — if
14
+ * `c.get('user')` is unset, this throws `AuthenticationError`. The user
15
+ * object must implement `hasPermission(slug)`; if not, this throws an
16
+ * Error (configuration issue → 500).
17
+ *
18
+ * Tagged with `PERMISSION_META` so `createApp`'s interceptor and downstream
19
+ * tooling (MCP `describe_route`, `ship-reviewer`, `/dev/routes`) see the
20
+ * permission slugs the route requires.
21
+ */
22
+ export declare function requirePermission(...slugs: string[]): MiddlewareHandler;
23
+ //# sourceMappingURL=requirePermission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirePermission.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/requirePermission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAM9C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAqCvE"}
@@ -0,0 +1,50 @@
1
+ import { AuthenticationError } from "../errors/AuthenticationError.js";
2
+ import { AuthorizationError } from "../errors/AuthorizationError.js";
3
+ import { PERMISSION_META, setMetaTag } from "../utils/metaTags.js";
4
+ /**
5
+ * `requirePermission(...slugs)` — Hono middleware factory that enforces
6
+ * the authenticated user has at least one of the supplied permission slugs
7
+ * (OR semantics within a single call).
8
+ *
9
+ * Replaces v3's `@HasPermission` decorator. To express AND across multiple
10
+ * permission groups, chain multiple `requirePermission()` middlewares —
11
+ * `createApp`'s registry interceptor unions slugs across calls so the
12
+ * registry shows the full set, and the runtime checks each call gates
13
+ * independently.
14
+ *
15
+ * Must run *after* a `requireAuth(...)` middleware on the same route — if
16
+ * `c.get('user')` is unset, this throws `AuthenticationError`. The user
17
+ * object must implement `hasPermission(slug)`; if not, this throws an
18
+ * Error (configuration issue → 500).
19
+ *
20
+ * Tagged with `PERMISSION_META` so `createApp`'s interceptor and downstream
21
+ * tooling (MCP `describe_route`, `ship-reviewer`, `/dev/routes`) see the
22
+ * permission slugs the route requires.
23
+ */
24
+ export function requirePermission(...slugs) {
25
+ if (slugs.length === 0) {
26
+ throw new Error("requirePermission(): at least one slug must be provided");
27
+ }
28
+ const middleware = async (c, next) => {
29
+ const user = c.get("user");
30
+ if (!user) {
31
+ throw new AuthenticationError("requirePermission: no authenticated user — apply requireAuth(...) before this middleware");
32
+ }
33
+ if (typeof user.hasPermission !== "function") {
34
+ throw new Error("requirePermission: the resolved user does not implement hasPermission(slug). " +
35
+ "Ensure your AuthProvider's resolve() returns an Account that does.");
36
+ }
37
+ for (const slug of slugs) {
38
+ const ok = await user.hasPermission(slug);
39
+ if (ok)
40
+ return next();
41
+ }
42
+ throw new AuthorizationError(slugs.length === 1
43
+ ? `Missing required permission: ${slugs[0]}`
44
+ : `Requires one of: ${slugs.join(", ")}`);
45
+ };
46
+ const tag = { permissions: [...slugs] };
47
+ setMetaTag(middleware, PERMISSION_META, tag);
48
+ return middleware;
49
+ }
50
+ //# sourceMappingURL=requirePermission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirePermission.js","sourceRoot":"","sources":["../../../src/http/middleware/requirePermission.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAuB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,KAAe;IAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,UAAU,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACtD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAe,CAAqC,CAAC;QAExE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,mBAAmB,CAC3B,0FAA0F,CAC3F,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACb,+EAA+E;gBAC7E,oEAAoE,CACvE,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,EAAE;gBAAE,OAAO,IAAI,EAAE,CAAC;QACxB,CAAC;QAED,MAAM,IAAI,kBAAkB,CAC1B,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,gCAAgC,KAAK,CAAC,CAAC,CAAC,EAAE;YAC5C,CAAC,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3C,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,GAAG,GAAmB,EAAE,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;IACxD,UAAU,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;IAE7C,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { Context, MiddlewareHandler } from "hono";
2
+ /**
3
+ * `resolveTenant()` — opt-in middleware that resolves the active tenant for the
4
+ * request and publishes it to `RequestContext.tenantId`.
5
+ *
6
+ * The framework convention is: code reads the active tenant from
7
+ * `RequestContext.tenantId`, NEVER from `account.tenantId` directly. That
8
+ * indirection is what keeps a future one-tenant-per-user → membership move
9
+ * (Model A → B) a one-middleware change — swap this resolver and every
10
+ * downstream read is unaffected.
11
+ *
12
+ * Default (Model A — one tenant per account): read `tenantId` off the
13
+ * authenticated account that `requireAuth` placed on the Hono context. Wire it
14
+ * AFTER `requireAuth`:
15
+ *
16
+ * ```ts
17
+ * app.use("*", requireAuth({ provider }));
18
+ * app.use("*", resolveTenant());
19
+ * ```
20
+ *
21
+ * For custom resolution (a tenant header, a sub-domain, a membership lookup),
22
+ * pass `resolve`:
23
+ *
24
+ * ```ts
25
+ * app.use("*", resolveTenant({ resolve: (c) => c.req.header("x-tenant-id") }));
26
+ * ```
27
+ *
28
+ * This is a thin, opt-in helper — single-tenant products never wire it and
29
+ * `RequestContext.tenantId` stays `undefined`. Tenant *enforcement*
30
+ * (auto-scoping every query) is deferred to V8; this only resolves + publishes.
31
+ */
32
+ export interface ResolveTenantOptions {
33
+ /**
34
+ * Custom resolver. Receives the Hono context and returns the active tenant id
35
+ * (or `undefined` / `null` to leave `RequestContext.tenantId` unset). Default:
36
+ * read `tenantId` off the authenticated account (`c.get("user")`).
37
+ */
38
+ resolve?: (c: Context) => string | null | undefined | Promise<string | null | undefined>;
39
+ }
40
+ export declare function resolveTenant(opts?: ResolveTenantOptions): MiddlewareHandler;
41
+ //# sourceMappingURL=resolveTenant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveTenant.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/resolveTenant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1F;AAED,wBAAgB,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,iBAAiB,CAchF"}
@@ -0,0 +1,17 @@
1
+ import { setRequestContextField } from "../../app/context/RequestContext.js";
2
+ import { AUTH_CONTEXT_KEYS } from "./requireAuth.js";
3
+ export function resolveTenant(opts = {}) {
4
+ const resolve = opts.resolve ??
5
+ ((c) => {
6
+ const account = c.get(AUTH_CONTEXT_KEYS.user);
7
+ return account?.tenantId;
8
+ });
9
+ return async (c, next) => {
10
+ const tenantId = await resolve(c);
11
+ // No-op (returns false) when called outside an active RequestContext.
12
+ if (tenantId)
13
+ setRequestContextField("tenantId", tenantId);
14
+ return next();
15
+ };
16
+ }
17
+ //# sourceMappingURL=resolveTenant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveTenant.js","sourceRoot":"","sources":["../../../src/http/middleware/resolveTenant.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAyCrD,MAAM,UAAU,aAAa,CAAC,OAA6B,EAAE;IAC3D,MAAM,OAAO,GACX,IAAI,CAAC,OAAO;QACZ,CAAC,CAAC,CAAU,EAAE,EAAE;YACd,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAa,CAAsC,CAAC;YAC5F,OAAO,OAAO,EAAE,QAAQ,CAAC;QAC3B,CAAC,CAAC,CAAC;IAEL,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;QAClC,sEAAsE;QACtE,IAAI,QAAQ;YAAE,sBAAsB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3D,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { Context } from "hono";
2
+ import type { SSEStreamingApi } from "hono/streaming";
3
+ /**
4
+ * `streamSSE(c, fn, opts?)` — framework wrapper around `hono/streaming`'s
5
+ * SSE helper. Adds an OTel span around the streaming callback's lifetime
6
+ * and a documented home for v4.x SSE-related helpers (LLM streaming, etc.).
7
+ *
8
+ * Re-exports `SSEStreamingApi` so consumers don't have to import from two
9
+ * paths to type their stream callback.
10
+ *
11
+ * Usage:
12
+ * ```ts
13
+ * import { streamSSE } from "@sixthsummit/ship-api/http/streaming/sse";
14
+ *
15
+ * app.get("/feed", requireAuth({ provider }), (c) =>
16
+ * streamSSE(c, async (stream) => {
17
+ * for await (const event of someEventSource()) {
18
+ * if (stream.aborted) break; // honor client disconnect
19
+ * await stream.writeSSE({ event: event.type, data: JSON.stringify(event) });
20
+ * }
21
+ * }, { spanName: "feed.subscribe" }),
22
+ * );
23
+ * ```
24
+ */
25
+ export type { SSEStreamingApi };
26
+ export interface StreamSSEOptions {
27
+ /** OTel span name. Default `"http.sse"`. */
28
+ spanName?: string;
29
+ }
30
+ export declare function streamSSE(c: Context, fn: (stream: SSEStreamingApi) => Promise<void>, opts?: StreamSSEOptions): Response;
31
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/http/streaming/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CACvB,CAAC,EAAE,OAAO,EACV,EAAE,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9C,IAAI,GAAE,gBAAqB,GAC1B,QAAQ,CAOV"}
@@ -0,0 +1,11 @@
1
+ import { streamSSE as honoStreamSSE } from "hono/streaming";
2
+ import { withSpan } from "../../observability/tracing.js";
3
+ export function streamSSE(c, fn, opts = {}) {
4
+ const spanName = opts.spanName ?? "http.sse";
5
+ return honoStreamSSE(c, async (stream) => {
6
+ await withSpan(spanName, async () => {
7
+ await fn(stream);
8
+ });
9
+ });
10
+ }
11
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../src/http/streaming/sse.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAgC1D,MAAM,UAAU,SAAS,CACvB,CAAU,EACV,EAA8C,EAC9C,OAAyB,EAAE;IAE3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC;IAC7C,OAAO,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACvC,MAAM,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAClC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,94 @@
1
+ import type { Context } from "hono";
2
+ import { logger as defaultLogger } from "../../observability/logger.js";
3
+ /**
4
+ * `streamLLM(c, events, opts?)` — Hono-aware SSE bridge for LLM stream
5
+ * events. Pipes any `AsyncIterable<{ type, ... }>` (typically the
6
+ * `streamComplete()` output of an `LLMProvider` adapter from
7
+ * `libraries/ai`) through `streamSSE`, with client-disconnect
8
+ * propagation upstream.
9
+ *
10
+ * Event format:
11
+ * - `event:` field = the iterator value's `type` field
12
+ * - `data:` field = JSON-serialized rest of the value (everything
13
+ * except `type`)
14
+ *
15
+ * Disconnect handling: when the request client disconnects,
16
+ * `stream.aborted` flips true. We notice between iterator ticks and
17
+ * call `iterator.return?.()` so the upstream generator can run its
18
+ * `finally` (closes provider stream, cancels in-flight HTTP, etc.).
19
+ *
20
+ * Errors: if the iterator throws, the error is forwarded as a final
21
+ * `event: error` SSE event with `{ message }` payload, then the
22
+ * stream closes. The optional `onError` hook is called *before* the
23
+ * error event is written so consumers can log / record without
24
+ * blocking the close.
25
+ *
26
+ * Provider-agnostic by design — no import from `libraries/ai`. The
27
+ * library's `StreamEvent` union (`start` / `text_delta` /
28
+ * `tool_use_*` / `stop`) is just one valid event source; consumers
29
+ * with a different shape (custom event taxonomy) can pipe through
30
+ * unchanged.
31
+ *
32
+ * Usage:
33
+ * ```ts
34
+ * import { streamLLM } from "@sixthsummit/ship-api/http/streaming/streamLLM";
35
+ * import { AnthropicAdapter } from "@sixthsummit/ship-api/libraries/ai";
36
+ *
37
+ * const llm = new AnthropicAdapter({ apiKey: env.ANTHROPIC_API_KEY });
38
+ *
39
+ * app.post("/chat", validate("json", schema), async (c) => {
40
+ * const { prompt } = c.req.valid("json");
41
+ * const stream = llm.streamComplete({
42
+ * model: "claude-opus-4-7",
43
+ * messages: [{ role: "user", content: prompt }],
44
+ * });
45
+ * return streamLLM(c, stream, { spanName: "chat.stream" });
46
+ * });
47
+ * ```
48
+ */
49
+ export interface StreamLLMOptions {
50
+ /** OTel span name. Default `"llm.stream"`. */
51
+ spanName?: string;
52
+ /**
53
+ * Called once if the upstream iterator throws, before the final
54
+ * `event: error` SSE write. Use to log / record the failure;
55
+ * throwing here is swallowed so the close still completes.
56
+ */
57
+ onError?: (err: Error) => Promise<void> | void;
58
+ /**
59
+ * Override how the SSE event id field is generated. Defaults to a
60
+ * monotonically-incrementing counter — sufficient for replay scope
61
+ * within a single response.
62
+ */
63
+ generateEventId?: (event: LLMStreamEvent, index: number) => string;
64
+ /**
65
+ * Maximum serialized bytes per event payload (F15). Events whose
66
+ * `JSON.stringify(payload)` exceeds this are skipped + logged +
67
+ * counted on the `stream.event.dropped_oversized` OTel counter.
68
+ * Default 256 KB. A misbehaving upstream provider that emits
69
+ * multi-megabyte single events (e.g. a duplicated tool-call
70
+ * argument) would otherwise amplify into a bandwidth + client-
71
+ * memory DoS at the consumer.
72
+ */
73
+ maxEventBytes?: number;
74
+ /**
75
+ * Tag attached to the `dropped_oversized` counter and the warn
76
+ * line emitted on oversize. Useful for distinguishing "Anthropic
77
+ * stream went wild" from "OpenAI stream went wild" in dashboards.
78
+ * Defaults to the event's `type` field at log time.
79
+ */
80
+ provider?: string;
81
+ /** Override the framework default pino logger (tests). */
82
+ logger?: typeof defaultLogger;
83
+ }
84
+ /**
85
+ * Minimum shape `streamLLM` requires. Any object with a string `type`
86
+ * and arbitrary other JSON-serializable fields fits — including the
87
+ * full `StreamEvent` union from `libraries/ai`.
88
+ */
89
+ export interface LLMStreamEvent {
90
+ type: string;
91
+ [key: string]: unknown;
92
+ }
93
+ export declare function streamLLM(c: Context, events: AsyncIterable<LLMStreamEvent>, opts?: StreamLLMOptions): Response;
94
+ //# sourceMappingURL=streamLLM.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamLLM.d.ts","sourceRoot":"","sources":["../../../src/http/streaming/streamLLM.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA8BxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/C;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnE;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,aAAa,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,SAAS,CACvB,CAAC,EAAE,OAAO,EACV,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,EACrC,IAAI,GAAE,gBAAqB,GAC1B,QAAQ,CAoDV"}