@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,15 @@
1
+ import { defineJob, jobRegistry, } from "../jobs/defineJob.js";
2
+ /** Default queue name for cron tasks. */
3
+ export const CRON_QUEUE = "cron";
4
+ export function defineCron(args, register = jobRegistry) {
5
+ return defineJob({
6
+ queue: args.queue ?? CRON_QUEUE,
7
+ name: args.name,
8
+ handler: args.handler,
9
+ options: {
10
+ schedule: { cron: args.schedule, tz: args.tz },
11
+ defaultJobOptions: args.defaultJobOptions,
12
+ },
13
+ }, register);
14
+ }
15
+ //# sourceMappingURL=defineCron.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineCron.js","sourceRoot":"","sources":["../../../../src/app/services/cron/defineCron.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAIT,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAwD9B,yCAAyC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC,MAAM,UAAU,UAAU,CACxB,IAAoB,EACpB,WAA0D,WAAW;IAErE,OAAO,SAAS,CACd;QACE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,UAAU;QAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE;YACP,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YAC9C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C;KACF,EACD,QAA+B,CAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { CRON_QUEUE, type DefineCronArgs, defineCron } from "./defineCron.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/app/services/cron/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { CRON_QUEUE, defineCron } from "./defineCron.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/app/services/cron/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Lifecycle hooks for `EntityService` / `DrizzleEntityService`.
3
+ *
4
+ * Foundation contract that lets v4.x ship audit-trail, change-data-capture,
5
+ * webhook-fan-out, and tenant-scoping modules without service-by-service surgery.
6
+ *
7
+ * Hooks run inside the same transaction as the operation when one is active.
8
+ * `before*` hooks return either `void` (continue) or a transformed value
9
+ * (mutate the operation). `after*` hooks are observation-only.
10
+ *
11
+ * Compose multiple hook sets via `composeHooks(...)`; subclasses can override
12
+ * `getHooks()` on a service to register service-specific hooks alongside
13
+ * globally-composed ones.
14
+ *
15
+ * The hook context is the canonical framework-wide `RequestContext` (single
16
+ * AsyncLocalStorage instance) — same shape as what the logger and
17
+ * `withTransaction` see. `userId` carries the actor; the full user object is
18
+ * not stored in the context (hooks fetch it from the DB if they need it).
19
+ */
20
+ import type { RequestContext } from "../../context/RequestContext.js";
21
+ /** Alias kept for ergonomic imports — same shape as `RequestContext`. */
22
+ export type LifecycleHookContext = RequestContext;
23
+ export interface QueryFilter {
24
+ [key: string]: unknown;
25
+ }
26
+ /**
27
+ * Hook signatures. Each hook is optional; missing hooks are skipped.
28
+ * Generic over the row/insert/update types so subclasses get type safety.
29
+ */
30
+ export interface LifecycleHooks<TRow = unknown, TInsert = unknown, TPatch = unknown> {
31
+ /** Before an INSERT. Return a transformed `values` to mutate; return void to continue. */
32
+ beforeCreate?(values: TInsert, ctx: LifecycleHookContext): Promise<TInsert | void> | TInsert | void;
33
+ /** After an INSERT. Observation-only. */
34
+ afterCreate?(row: TRow, ctx: LifecycleHookContext): Promise<void> | void;
35
+ /**
36
+ * Before an UPDATE. `prev` is loaded before the write so audit consumers can diff.
37
+ * Return a transformed `patch` to mutate; return void to continue.
38
+ */
39
+ beforeUpdate?(prev: TRow, patch: TPatch, ctx: LifecycleHookContext): Promise<TPatch | void> | TPatch | void;
40
+ /** After an UPDATE. Observation-only. Receives both prev and next for diffing. */
41
+ afterUpdate?(prev: TRow, next: TRow, ctx: LifecycleHookContext): Promise<void> | void;
42
+ /** Before a DELETE (or soft-delete). Throw to abort the operation. */
43
+ beforeDelete?(row: TRow, ctx: LifecycleHookContext): Promise<void> | void;
44
+ /** After a DELETE / soft-delete. Observation-only. */
45
+ afterDelete?(row: TRow, ctx: LifecycleHookContext): Promise<void> | void;
46
+ /**
47
+ * Before any read query. Return a transformed filter to mutate (e.g., inject
48
+ * `tenantId = currentTenantId` for multi-tenancy). Return void to continue.
49
+ */
50
+ beforeQuery?(filter: QueryFilter, ctx: LifecycleHookContext): Promise<QueryFilter | void> | QueryFilter | void;
51
+ }
52
+ /**
53
+ * Compose multiple hook sets into one. Hooks fire in registration order for
54
+ * `before*` (so each can transform the result of the previous) and in reverse
55
+ * order for `after*` (LIFO — useful for nested cross-cutting concerns).
56
+ *
57
+ * Returning `undefined` from a `before*` hook means "no change"; the next hook
58
+ * receives the unchanged value from the previous step.
59
+ */
60
+ export declare function composeHooks<TRow, TInsert, TPatch>(...sets: Array<LifecycleHooks<TRow, TInsert, TPatch>>): LifecycleHooks<TRow, TInsert, TPatch>;
61
+ //# sourceMappingURL=LifecycleHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LifecycleHooks.d.ts","sourceRoot":"","sources":["../../../../src/app/services/hooks/LifecycleHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,yEAAyE;AACzE,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAElD,MAAM,WAAW,WAAW;IAG1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,IAAI,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO;IACjF,0FAA0F;IAC1F,YAAY,CAAC,CACX,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;IAE5C,yCAAyC;IACzC,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEzE;;;OAGG;IACH,YAAY,CAAC,CACX,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;IAE1C,kFAAkF;IAClF,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEtF,sEAAsE;IACtE,YAAY,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE1E,sDAAsD;IACtD,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEzE;;;OAGG;IACH,WAAW,CAAC,CACV,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC;CACrD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAChD,GAAG,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,GACpD,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAwDvC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Lifecycle hooks for `EntityService` / `DrizzleEntityService`.
3
+ *
4
+ * Foundation contract that lets v4.x ship audit-trail, change-data-capture,
5
+ * webhook-fan-out, and tenant-scoping modules without service-by-service surgery.
6
+ *
7
+ * Hooks run inside the same transaction as the operation when one is active.
8
+ * `before*` hooks return either `void` (continue) or a transformed value
9
+ * (mutate the operation). `after*` hooks are observation-only.
10
+ *
11
+ * Compose multiple hook sets via `composeHooks(...)`; subclasses can override
12
+ * `getHooks()` on a service to register service-specific hooks alongside
13
+ * globally-composed ones.
14
+ *
15
+ * The hook context is the canonical framework-wide `RequestContext` (single
16
+ * AsyncLocalStorage instance) — same shape as what the logger and
17
+ * `withTransaction` see. `userId` carries the actor; the full user object is
18
+ * not stored in the context (hooks fetch it from the DB if they need it).
19
+ */
20
+ /**
21
+ * Compose multiple hook sets into one. Hooks fire in registration order for
22
+ * `before*` (so each can transform the result of the previous) and in reverse
23
+ * order for `after*` (LIFO — useful for nested cross-cutting concerns).
24
+ *
25
+ * Returning `undefined` from a `before*` hook means "no change"; the next hook
26
+ * receives the unchanged value from the previous step.
27
+ */
28
+ export function composeHooks(...sets) {
29
+ return {
30
+ async beforeCreate(values, ctx) {
31
+ let current = values;
32
+ for (const set of sets) {
33
+ if (!set.beforeCreate)
34
+ continue;
35
+ const r = await set.beforeCreate(current, ctx);
36
+ if (r !== undefined)
37
+ current = r;
38
+ }
39
+ return current;
40
+ },
41
+ async afterCreate(row, ctx) {
42
+ for (let i = sets.length - 1; i >= 0; i--) {
43
+ await sets[i].afterCreate?.(row, ctx);
44
+ }
45
+ },
46
+ async beforeUpdate(prev, patch, ctx) {
47
+ let current = patch;
48
+ for (const set of sets) {
49
+ if (!set.beforeUpdate)
50
+ continue;
51
+ const r = await set.beforeUpdate(prev, current, ctx);
52
+ if (r !== undefined)
53
+ current = r;
54
+ }
55
+ return current;
56
+ },
57
+ async afterUpdate(prev, next, ctx) {
58
+ for (let i = sets.length - 1; i >= 0; i--) {
59
+ await sets[i].afterUpdate?.(prev, next, ctx);
60
+ }
61
+ },
62
+ async beforeDelete(row, ctx) {
63
+ for (const set of sets) {
64
+ await set.beforeDelete?.(row, ctx);
65
+ }
66
+ },
67
+ async afterDelete(row, ctx) {
68
+ for (let i = sets.length - 1; i >= 0; i--) {
69
+ await sets[i].afterDelete?.(row, ctx);
70
+ }
71
+ },
72
+ async beforeQuery(filter, ctx) {
73
+ let current = filter;
74
+ for (const set of sets) {
75
+ if (!set.beforeQuery)
76
+ continue;
77
+ const r = await set.beforeQuery(current, ctx);
78
+ if (r !== undefined)
79
+ current = r;
80
+ }
81
+ return current;
82
+ },
83
+ };
84
+ }
85
+ //# sourceMappingURL=LifecycleHooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LifecycleHooks.js","sourceRoot":"","sources":["../../../../src/app/services/hooks/LifecycleHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAwDH;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAG,IAAkD;IAErD,OAAO;QACL,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG;YAC5B,IAAI,OAAO,GAAG,MAAM,CAAC;YACrB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY;oBAAE,SAAS;gBAChC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC/C,IAAI,CAAC,KAAK,SAAS;oBAAE,OAAO,GAAG,CAAY,CAAC;YAC9C,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG;YACxB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;YACjC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY;oBAAE,SAAS;gBAChC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;gBACrD,IAAI,CAAC,KAAK,SAAS;oBAAE,OAAO,GAAG,CAAW,CAAC;YAC7C,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG;YAC/B,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG;YACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG;YACxB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG;YAC3B,IAAI,OAAO,GAAG,MAAM,CAAC;YACrB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,WAAW;oBAAE,SAAS;gBAC/B,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC9C,IAAI,CAAC,KAAK,SAAS;oBAAE,OAAO,GAAG,CAAgB,CAAC;YAClD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { type ConnectionOptions, type JobsOptions, Queue } from "bullmq";
2
+ import { logger as defaultLogger } from "../../../observability/logger.js";
3
+ import { type JobRegistry } from "./defineJob.js";
4
+ /**
5
+ * `JobsManager` — wires BullMQ Queues + Workers to the framework's
6
+ * declarative job registry.
7
+ *
8
+ * Producer side (always-on): one `Queue` per unique queue name. The
9
+ * framework exposes `enqueue(queue, name, payload, opts?)` for application
10
+ * code to push work.
11
+ *
12
+ * Worker side (opt-in via `WORKER_MODE`): one `Worker` per unique queue
13
+ * name; the worker dispatches incoming jobs to the right handler by
14
+ * `job.name`. Each handler invocation is wrapped in a fresh
15
+ * `RequestContext` so logger / DrizzleEntityService lifecycle hooks see
16
+ * a coherent context (with `requestId` set to the BullMQ job ID).
17
+ *
18
+ * `WORKER_MODE` selects role:
19
+ * - `api` (default in template; no workers spin up — only the producer)
20
+ * - `worker` (workers only — no HTTP server)
21
+ * - `all` (workers + HTTP — local dev default)
22
+ *
23
+ * On `quit()`: closes all queues + workers. Idempotent. Called from the
24
+ * graceful-shutdown manager (which adds it to the SIGTERM hook chain).
25
+ */
26
+ export type WorkerMode = "api" | "worker" | "all";
27
+ export interface JobsManagerOptions {
28
+ /** ioredis-compatible connection options or a Redis URL. Required by BullMQ. */
29
+ connection: ConnectionOptions;
30
+ /** Mode for this process. Defaults to `process.env.WORKER_MODE` or "api". */
31
+ mode?: WorkerMode;
32
+ /** Override the framework-wide registry. */
33
+ registry?: JobRegistry;
34
+ /** Override the default logger. */
35
+ logger?: typeof defaultLogger;
36
+ }
37
+ export declare class JobsManager {
38
+ private connection;
39
+ private mode;
40
+ private registry;
41
+ private logger;
42
+ private queues;
43
+ private workers;
44
+ private quitting;
45
+ constructor(opts: JobsManagerOptions);
46
+ /** Lazily get / create the BullMQ Queue for a queue name. */
47
+ getQueue(queueName: string): Queue;
48
+ /** Push a job onto its queue. */
49
+ enqueue(queueName: string, jobName: string, payload: unknown, opts?: JobsOptions): Promise<void>;
50
+ /**
51
+ * Start workers for every distinct queue (when mode includes worker).
52
+ * Idempotent — calling twice is a no-op. Returns the count of workers
53
+ * started (0 in `api` mode).
54
+ */
55
+ startWorkers(): Promise<number>;
56
+ /** Graceful shutdown — drain workers, close queues. Idempotent. */
57
+ quit(): Promise<void>;
58
+ getMode(): WorkerMode;
59
+ /**
60
+ * The set of queue names this manager knows about — sourced from the
61
+ * registry (every distinct `queue:` field across `defineJob(...)`
62
+ * declarations). Used by tooling that needs to enumerate queues
63
+ * (Bull-Board admin UI, custom dashboards, debugging endpoints).
64
+ */
65
+ getQueueNames(): string[];
66
+ }
67
+ //# sourceMappingURL=JobsManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobsManager.d.ts","sourceRoot":"","sources":["../../../../src/app/services/jobs/JobsManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AACjF,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAG3E,OAAO,EAAkC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,UAAU,EAAE,iBAAiB,CAAC;IAC9B,6EAA6E;IAC7E,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,aAAa,CAAC;CAC/B;AASD,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,MAAM,CAAuB;IAErC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,EAAE,kBAAkB;IAOpC,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK;IASlC,iCAAiC;IAC3B,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAoErC,mEAAmE;IAC7D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,IAAI,UAAU;IAIrB;;;;;OAKG;IACH,aAAa,IAAI,MAAM,EAAE;CAG1B"}
@@ -0,0 +1,121 @@
1
+ import { Queue, Worker } from "bullmq";
2
+ import { logger as defaultLogger } from "../../../observability/logger.js";
3
+ import { withSpan } from "../../../observability/tracing.js";
4
+ import { runWithRequestContext } from "../../context/RequestContext.js";
5
+ import { jobRegistry as defaultRegistry } from "./defineJob.js";
6
+ function resolveMode(explicit) {
7
+ if (explicit)
8
+ return explicit;
9
+ const envMode = process.env.WORKER_MODE;
10
+ if (envMode === "worker" || envMode === "all" || envMode === "api")
11
+ return envMode;
12
+ return "api";
13
+ }
14
+ export class JobsManager {
15
+ connection;
16
+ mode;
17
+ registry;
18
+ logger;
19
+ queues = new Map();
20
+ workers = [];
21
+ quitting = false;
22
+ constructor(opts) {
23
+ this.connection = opts.connection;
24
+ this.mode = resolveMode(opts.mode);
25
+ this.registry = opts.registry ?? defaultRegistry;
26
+ this.logger = opts.logger ?? defaultLogger;
27
+ }
28
+ /** Lazily get / create the BullMQ Queue for a queue name. */
29
+ getQueue(queueName) {
30
+ let q = this.queues.get(queueName);
31
+ if (!q) {
32
+ q = new Queue(queueName, { connection: this.connection });
33
+ this.queues.set(queueName, q);
34
+ }
35
+ return q;
36
+ }
37
+ /** Push a job onto its queue. */
38
+ async enqueue(queueName, jobName, payload, opts) {
39
+ // Verify the job is registered — surface typos as boot-time errors
40
+ // rather than silent dead-letter behavior.
41
+ const def = this.registry.find(queueName, jobName);
42
+ if (!def) {
43
+ throw new Error(`enqueue(): no job "${jobName}" registered in queue "${queueName}"`);
44
+ }
45
+ const merged = { ...def.options?.defaultJobOptions, ...opts };
46
+ await this.getQueue(queueName).add(jobName, payload, merged);
47
+ }
48
+ /**
49
+ * Start workers for every distinct queue (when mode includes worker).
50
+ * Idempotent — calling twice is a no-op. Returns the count of workers
51
+ * started (0 in `api` mode).
52
+ */
53
+ async startWorkers() {
54
+ if (this.mode === "api")
55
+ return 0;
56
+ if (this.workers.length > 0)
57
+ return this.workers.length;
58
+ for (const queueName of this.registry.queues()) {
59
+ const handlers = this.registry.byQueue(queueName);
60
+ const concurrency = Math.max(...handlers.map((h) => h.options?.concurrency ?? 1));
61
+ const worker = new Worker(queueName, async (job) => {
62
+ const handler = this.registry.find(queueName, job.name);
63
+ if (!handler) {
64
+ this.logger.warn({ queue: queueName, jobName: job.name, jobId: job.id }, "jobs.unknown_job");
65
+ throw new Error(`No handler for job "${job.name}" in queue "${queueName}"`);
66
+ }
67
+ return withSpan(`job.${queueName}.${job.name}`, async () => {
68
+ return runWithRequestContext({ requestId: `job:${job.id ?? "unknown"}` }, async () => {
69
+ return handler.handler(job.data, {
70
+ job,
71
+ context: { requestId: `job:${job.id ?? "unknown"}` },
72
+ });
73
+ });
74
+ }, { "job.queue": queueName, "job.name": job.name, "job.id": job.id ?? "" });
75
+ }, { connection: this.connection, concurrency });
76
+ worker.on("failed", (job, err) => {
77
+ this.logger.error({
78
+ queue: queueName,
79
+ jobName: job?.name,
80
+ jobId: job?.id,
81
+ attemptsMade: job?.attemptsMade,
82
+ err,
83
+ }, "jobs.failed");
84
+ });
85
+ this.workers.push(worker);
86
+ }
87
+ // Register repeatable jobs
88
+ for (const def of this.registry.list()) {
89
+ if (def.options?.schedule) {
90
+ await this.getQueue(def.queue).add(def.name, undefined, {
91
+ repeat: { pattern: def.options.schedule.cron, tz: def.options.schedule.tz },
92
+ ...def.options.defaultJobOptions,
93
+ });
94
+ }
95
+ }
96
+ return this.workers.length;
97
+ }
98
+ /** Graceful shutdown — drain workers, close queues. Idempotent. */
99
+ async quit() {
100
+ if (this.quitting)
101
+ return;
102
+ this.quitting = true;
103
+ await Promise.all(this.workers.map((w) => w.close().catch(() => undefined)));
104
+ await Promise.all([...this.queues.values()].map((q) => q.close().catch(() => undefined)));
105
+ this.workers = [];
106
+ this.queues.clear();
107
+ }
108
+ getMode() {
109
+ return this.mode;
110
+ }
111
+ /**
112
+ * The set of queue names this manager knows about — sourced from the
113
+ * registry (every distinct `queue:` field across `defineJob(...)`
114
+ * declarations). Used by tooling that needs to enumerate queues
115
+ * (Bull-Board admin UI, custom dashboards, debugging endpoints).
116
+ */
117
+ getQueueNames() {
118
+ return this.registry.queues();
119
+ }
120
+ }
121
+ //# sourceMappingURL=JobsManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobsManager.js","sourceRoot":"","sources":["../../../../src/app/services/jobs/JobsManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Bull-Board admin UI integration — wraps `@bull-board/hono` with API-key
3
+ * auth and auto-discovers queues from the framework's `JobsManager`.
4
+ *
5
+ * **Optional integration.** The `@bull-board/hono` and `@bull-board/api`
6
+ * packages are NOT in the framework's `dependencies` — consumers who
7
+ * want the dashboard install them in their own app. Importing this
8
+ * module without those packages installed throws `MODULE_NOT_FOUND` at
9
+ * import time, which is intentional: the framework doesn't pay for an
10
+ * EJS-based admin UI it doesn't always need.
11
+ *
12
+ * Why API-key auth instead of `requireAuth`:
13
+ * - Bull-Board is a *static* UI bundle plus a single API surface; the
14
+ * framework's per-route auth chain isn't a clean fit (Bull-Board
15
+ * registers its own routes inside `serverAdapter.registerPlugin()`).
16
+ * - Operators typically guard the dashboard at the network edge
17
+ * (private subnet, VPN, ingress allowlist) AND at the application
18
+ * layer (this API key) — defense in depth. Don't expose this on a
19
+ * public hostname even with the key set.
20
+ * - The `x-admin-api-key` header is constant-time-compared against
21
+ * the configured secret to avoid timing oracles.
22
+ *
23
+ * Usage:
24
+ * ```ts
25
+ * import { createBullBoardApp } from "@sixthsummit/ship-api/app/services/jobs/bullBoard";
26
+ *
27
+ * const bb = createBullBoardApp({
28
+ * jobsManager,
29
+ * apiKey: env.ADMIN_API_KEY, // required, ≥32 chars recommended
30
+ * basePath: "/admin/jobs", // optional, default "/admin/jobs"
31
+ * });
32
+ * app.route(bb.basePath, bb.app);
33
+ * ```
34
+ *
35
+ * The dashboard auto-refreshes its queue list — but it's a *snapshot*
36
+ * at adapter-construction time. If `defineJob(...)` declarations change
37
+ * after the dashboard is mounted (e.g. dynamic module loading), call
38
+ * `bb.refresh()` to re-derive the queue list.
39
+ */
40
+ import type { Hono } from "hono";
41
+ import type { JobsManager } from "./JobsManager.js";
42
+ export interface BullBoardOptions {
43
+ jobsManager: JobsManager;
44
+ /**
45
+ * API key required on the `x-admin-api-key` header. The framework
46
+ * enforces this is non-empty; production deployments should source it
47
+ * from a secret manager and rotate it independently of JWT keys.
48
+ */
49
+ apiKey: string;
50
+ /**
51
+ * Mount path. Defaults to `/admin/jobs`. The consumer must mount the
52
+ * returned `app` at the same path on the parent Hono — the value
53
+ * passed here is forwarded to Bull-Board's `setBasePath` so the
54
+ * dashboard's static-asset URLs resolve correctly.
55
+ */
56
+ basePath?: string;
57
+ }
58
+ export interface BullBoardHandle {
59
+ /** The Hono sub-app to `parent.route(basePath, ...)` onto your app. */
60
+ app: Hono;
61
+ /** The configured (or default) base path. */
62
+ basePath: string;
63
+ /** Re-derive the queue list from the JobsManager registry. */
64
+ refresh: () => void;
65
+ }
66
+ /**
67
+ * Build the Bull-Board sub-app. Throws if `apiKey` is empty. Throws
68
+ * `MODULE_NOT_FOUND` if `@bull-board/hono` / `@bull-board/api` are not
69
+ * installed (framework treats them as optional integrations).
70
+ */
71
+ export declare function createBullBoardApp(opts: BullBoardOptions): Promise<BullBoardHandle>;
72
+ //# sourceMappingURL=bullBoard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bullBoard.d.ts","sourceRoot":"","sources":["../../../../src/app/services/jobs/bullBoard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAQH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,GAAG,EAAE,IAAI,CAAC;IACV,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAkEzF"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Bull-Board admin UI integration — wraps `@bull-board/hono` with API-key
3
+ * auth and auto-discovers queues from the framework's `JobsManager`.
4
+ *
5
+ * **Optional integration.** The `@bull-board/hono` and `@bull-board/api`
6
+ * packages are NOT in the framework's `dependencies` — consumers who
7
+ * want the dashboard install them in their own app. Importing this
8
+ * module without those packages installed throws `MODULE_NOT_FOUND` at
9
+ * import time, which is intentional: the framework doesn't pay for an
10
+ * EJS-based admin UI it doesn't always need.
11
+ *
12
+ * Why API-key auth instead of `requireAuth`:
13
+ * - Bull-Board is a *static* UI bundle plus a single API surface; the
14
+ * framework's per-route auth chain isn't a clean fit (Bull-Board
15
+ * registers its own routes inside `serverAdapter.registerPlugin()`).
16
+ * - Operators typically guard the dashboard at the network edge
17
+ * (private subnet, VPN, ingress allowlist) AND at the application
18
+ * layer (this API key) — defense in depth. Don't expose this on a
19
+ * public hostname even with the key set.
20
+ * - The `x-admin-api-key` header is constant-time-compared against
21
+ * the configured secret to avoid timing oracles.
22
+ *
23
+ * Usage:
24
+ * ```ts
25
+ * import { createBullBoardApp } from "@sixthsummit/ship-api/app/services/jobs/bullBoard";
26
+ *
27
+ * const bb = createBullBoardApp({
28
+ * jobsManager,
29
+ * apiKey: env.ADMIN_API_KEY, // required, ≥32 chars recommended
30
+ * basePath: "/admin/jobs", // optional, default "/admin/jobs"
31
+ * });
32
+ * app.route(bb.basePath, bb.app);
33
+ * ```
34
+ *
35
+ * The dashboard auto-refreshes its queue list — but it's a *snapshot*
36
+ * at adapter-construction time. If `defineJob(...)` declarations change
37
+ * after the dashboard is mounted (e.g. dynamic module loading), call
38
+ * `bb.refresh()` to re-derive the queue list.
39
+ */
40
+ import { timingSafeEqual } from "node:crypto";
41
+ /**
42
+ * Build the Bull-Board sub-app. Throws if `apiKey` is empty. Throws
43
+ * `MODULE_NOT_FOUND` if `@bull-board/hono` / `@bull-board/api` are not
44
+ * installed (framework treats them as optional integrations).
45
+ */
46
+ export async function createBullBoardApp(opts) {
47
+ if (!opts.apiKey || opts.apiKey.length === 0) {
48
+ throw new Error("createBullBoardApp: apiKey is required (set ADMIN_API_KEY in env)");
49
+ }
50
+ const basePath = opts.basePath ?? "/admin/jobs";
51
+ // Dynamic imports — keep these out of the framework's dep tree so the
52
+ // ~30 KB EJS + UI bundle doesn't ship with every consumer.
53
+ const [{ HonoAdapter }, { createBullBoard }, { BullMQAdapter }, { serveStatic }, { Hono: HonoCtor },] = await Promise.all([
54
+ import("@bull-board/hono"),
55
+ import("@bull-board/api"),
56
+ import("@bull-board/api/bullMQAdapter"),
57
+ import("@hono/node-server/serve-static"),
58
+ import("hono"),
59
+ ]);
60
+ const serverAdapter = new HonoAdapter(serveStatic);
61
+ serverAdapter.setBasePath(basePath);
62
+ const buildAdapters = () => opts.jobsManager
63
+ .getQueueNames()
64
+ .map((name) => new BullMQAdapter(opts.jobsManager.getQueue(name)));
65
+ const board = createBullBoard({
66
+ queues: buildAdapters(),
67
+ serverAdapter,
68
+ });
69
+ const apiKeyBytes = Buffer.from(opts.apiKey);
70
+ const app = new HonoCtor();
71
+ app.use("*", async (c, next) => {
72
+ const supplied = c.req.header("x-admin-api-key");
73
+ if (!supplied) {
74
+ return c.json({ error: "Unauthorized" }, 401);
75
+ }
76
+ const suppliedBytes = Buffer.from(supplied);
77
+ // Constant-time compare. Length check first because `timingSafeEqual`
78
+ // throws on mismatched buffer lengths — but the early-return on a
79
+ // length mismatch is itself a small timing channel. The keyspace is
80
+ // operator-controlled, so this is acceptable.
81
+ if (suppliedBytes.length !== apiKeyBytes.length ||
82
+ !timingSafeEqual(suppliedBytes, apiKeyBytes)) {
83
+ return c.json({ error: "Unauthorized" }, 401);
84
+ }
85
+ return next();
86
+ });
87
+ app.route("/", serverAdapter.registerPlugin());
88
+ return {
89
+ app,
90
+ basePath,
91
+ refresh: () => {
92
+ board.replaceQueues(buildAdapters());
93
+ },
94
+ };
95
+ }
96
+ //# sourceMappingURL=bullBoard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bullBoard.js","sourceRoot":"","sources":["../../../../src/app/services/jobs/bullBoard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAmC9C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAsB;IAC7D,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,aAAa,CAAC;IAEhD,sEAAsE;IACtE,2DAA2D;IAC3D,MAAM,CACJ,EAAE,WAAW,EAAE,EACf,EAAE,eAAe,EAAE,EACnB,EAAE,aAAa,EAAE,EACjB,EAAE,WAAW,EAAE,EACf,EAAE,IAAI,EAAE,QAAQ,EAAE,EACnB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACpB,MAAM,CAAC,kBAAkB,CAAC;QAC1B,MAAM,CAAC,iBAAiB,CAAC;QACzB,MAAM,CAAC,+BAA+B,CAAC;QACvC,MAAM,CAAC,gCAAgC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC;KACf,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,CAAC;IACnD,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,aAAa,GAAG,GAAG,EAAE,CACzB,IAAI,CAAC,WAAW;SACb,aAAa,EAAE;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEvE,MAAM,KAAK,GAAG,eAAe,CAAC;QAC5B,MAAM,EAAE,aAAa,EAAE;QACvB,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE7C,MAAM,GAAG,GAAG,IAAI,QAAQ,EAAU,CAAC;IACnC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QAC7B,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,sEAAsE;QACtE,kEAAkE;QAClE,oEAAoE;QACpE,8CAA8C;QAC9C,IACE,aAAa,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM;YAC3C,CAAC,eAAe,CAAC,aAAa,EAAE,WAAW,CAAC,EAC5C,CAAC;YACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,cAAc,EAAE,CAAC,CAAC;IAE/C,OAAO;QACL,GAAG;QACH,QAAQ;QACR,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC"}