@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,94 @@
1
+ import type { TenantContext } from "../types/MultiTenancy.js";
2
+
3
+ /**
4
+ * Utility class for managing tenant context in multi-tenant operations
5
+ */
6
+ export default class TenantContextManager {
7
+ private static currentContext: TenantContext | null = null;
8
+
9
+ /**
10
+ * Set the current tenant context
11
+ */
12
+ static setContext(tenant: string, activityStatus?: "HOT" | "COLD" | "FROZEN"): void {
13
+ TenantContextManager.currentContext = {
14
+ tenant,
15
+ activityStatus: activityStatus || "HOT",
16
+ };
17
+ }
18
+
19
+ /**
20
+ * Get the current tenant context
21
+ */
22
+ static getContext(): TenantContext | null {
23
+ return TenantContextManager.currentContext;
24
+ }
25
+
26
+ /**
27
+ * Clear the current tenant context
28
+ */
29
+ static clearContext(): void {
30
+ TenantContextManager.currentContext = null;
31
+ }
32
+
33
+ /**
34
+ * Check if a tenant context is set
35
+ */
36
+ static hasContext(): boolean {
37
+ return TenantContextManager.currentContext !== null;
38
+ }
39
+
40
+ /**
41
+ * Get the current tenant name
42
+ */
43
+ static getCurrentTenant(): string | null {
44
+ return TenantContextManager.currentContext?.tenant || null;
45
+ }
46
+
47
+ /**
48
+ * Execute a function with a specific tenant context
49
+ */
50
+ static async withContext<T>(
51
+ tenant: string,
52
+ activityStatus: "HOT" | "COLD" | "FROZEN" | undefined,
53
+ fn: () => Promise<T>,
54
+ ): Promise<T> {
55
+ const previousContext = TenantContextManager.currentContext;
56
+
57
+ try {
58
+ TenantContextManager.setContext(tenant, activityStatus);
59
+ return await fn();
60
+ } finally {
61
+ TenantContextManager.currentContext = previousContext;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Create a tenant context object
67
+ */
68
+ static createContext(tenant: string, activityStatus?: "HOT" | "COLD" | "FROZEN"): TenantContext {
69
+ return {
70
+ tenant,
71
+ activityStatus: activityStatus || "HOT",
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Validate tenant name format
77
+ */
78
+ static validateTenantName(tenant: string): boolean {
79
+ // Weaviate tenant names must be lowercase and contain only alphanumeric characters and hyphens
80
+ return /^[a-z0-9-]+$/.test(tenant) && tenant.length > 0 && tenant.length <= 63;
81
+ }
82
+
83
+ /**
84
+ * Sanitize tenant name to meet Weaviate requirements
85
+ */
86
+ static sanitizeTenantName(tenant: string): string {
87
+ return tenant
88
+ .toLowerCase()
89
+ .replace(/[^a-z0-9-]/g, "-")
90
+ .replace(/-+/g, "-")
91
+ .replace(/^-|-$/g, "")
92
+ .substring(0, 63);
93
+ }
94
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Accounts module — public barrel.
3
+ *
4
+ * Default account / role / permission CRUD over the module's own identity
5
+ * tables. Consumers wire it via `defineAccountsRoutes(app, { service, provider })`.
6
+ */
7
+
8
+ export {
9
+ ACCOUNTS_PERMISSION_DEFINITIONS,
10
+ ACCOUNTS_PERMISSIONS,
11
+ type AccountsPermission,
12
+ } from "./permissions.js";
13
+ export { type AccountsRoutesDeps, buildAccountsApp, defineAccountsRoutes } from "./routes.js";
14
+ export {
15
+ type Account,
16
+ accounts,
17
+ accountsRelations,
18
+ accountsSchema,
19
+ type NewAccount,
20
+ type NewPermission,
21
+ type NewRole,
22
+ type NewRolePermission,
23
+ type NewTenant,
24
+ type Permission,
25
+ permissions,
26
+ permissionsRelations,
27
+ type Role,
28
+ type RolePermission,
29
+ rolePermissions,
30
+ rolePermissionsRelations,
31
+ roles,
32
+ rolesRelations,
33
+ type Tenant,
34
+ tenants,
35
+ tenantsSchema,
36
+ } from "./schema.js";
37
+ export { AccountService } from "./services/AccountService.js";
38
+ export {
39
+ type AccountIdParam,
40
+ accountIdParamSchema,
41
+ type CreateAccountInput,
42
+ createAccountSchema,
43
+ type ListAccountsQuery,
44
+ listAccountsQuerySchema,
45
+ type UpdateAccountInput,
46
+ updateAccountSchema,
47
+ } from "./validation/schemas.js";
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "accounts",
3
+ "description": "Identity + RBAC on the v4 substrate — owns the `accounts`/`roles`/`permissions`/`refresh_tokens` schema (relocated out of core), DrizzleEntityService, Hono routes, pluggable AuthProvider. Compose its `accountsSchema` fragment into `createApp({ schema })` and customize as needed.",
4
+ "version": "2.0.0-alpha.1",
5
+ "dependencies": [],
6
+ "npmDependencies": {},
7
+ "requiredEnvVars": [],
8
+ "optionalEnvVars": [],
9
+ "postInstall": [
10
+ "Add the schema to your composed schema: `createApp({ schema: { ...accountsSchema } })`",
11
+ "Wire the routes in src/index.ts, capturing the chained return so hc() types survive: `const app = defineAccountsRoutes(createApp({ schema }), { service, provider })`",
12
+ "Provide a service constructed against your composed schema: `new AccountService(app.db)`",
13
+ "Provide an AuthProvider (Firebase by default; Better-Auth/Clerk/WorkOS in v4.x)"
14
+ ]
15
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Permission slugs for the accounts module.
3
+ *
4
+ * v3 exported `Permission` entity instances; v4 exports plain string
5
+ * constants because authorization is enforced by `requirePermission(slug)`
6
+ * middleware at the route, not by `@HasPermission` decorators on a
7
+ * controller method. The Permission DB rows themselves are seeded by
8
+ * the consuming app (typically in a custom bootstrapper) — the module
9
+ * declares the *names* it expects to exist.
10
+ */
11
+
12
+ import type { PermissionDefinition } from "@sixthsummit/ship-api";
13
+
14
+ export const ACCOUNTS_PERMISSIONS = {
15
+ read: "accounts:read",
16
+ create: "accounts:create",
17
+ update: "accounts:update",
18
+ delete: "accounts:delete",
19
+ } as const;
20
+
21
+ export type AccountsPermission = (typeof ACCOUNTS_PERMISSIONS)[keyof typeof ACCOUNTS_PERMISSIONS];
22
+
23
+ /**
24
+ * The list form is what a seed script feeds to the Permission table.
25
+ * Each entry pairs the slug with a human-readable label that surfaces
26
+ * in admin UIs when assigning permissions to roles.
27
+ */
28
+ export const ACCOUNTS_PERMISSION_DEFINITIONS = [
29
+ { slug: ACCOUNTS_PERMISSIONS.read, label: "View Accounts" },
30
+ { slug: ACCOUNTS_PERMISSIONS.create, label: "Create Accounts" },
31
+ { slug: ACCOUNTS_PERMISSIONS.update, label: "Update Accounts" },
32
+ { slug: ACCOUNTS_PERMISSIONS.delete, label: "Delete Accounts" },
33
+ ] as const satisfies readonly PermissionDefinition[];
@@ -0,0 +1,200 @@
1
+ import type {
2
+ AuthenticatedAccount,
3
+ AuthProvider,
4
+ } from "@sixthsummit/ship-api/app/auth/AuthProvider";
5
+ import type { AppEnv } from "@sixthsummit/ship-api/http/app/createApp";
6
+ import { createModuleApp } from "@sixthsummit/ship-api/http/app/createApp";
7
+ import { NotFoundError } from "@sixthsummit/ship-api/http/errors/NotFoundError";
8
+ import { requireAuth } from "@sixthsummit/ship-api/http/middleware/requireAuth";
9
+ import { requirePermission } from "@sixthsummit/ship-api/http/middleware/requirePermission";
10
+ import { validate } from "@sixthsummit/ship-api/http/utils/validate";
11
+ import type { Hono, Schema } from "hono";
12
+ import type { BlankSchema } from "hono/types";
13
+
14
+ import { ACCOUNTS_PERMISSIONS } from "./permissions.js";
15
+ import type { AccountService } from "./services/AccountService.js";
16
+ import {
17
+ accountIdParamSchema,
18
+ createAccountSchema,
19
+ listAccountsQuerySchema,
20
+ updateAccountSchema,
21
+ } from "./validation/schemas.js";
22
+
23
+ /**
24
+ * v4 routes — `defineAccountsRoutes(app, deps)`.
25
+ *
26
+ * Replaces v3's `Router`-based `routes.ts` + `initializeRoutes(em)`
27
+ * pattern. Differences:
28
+ * - Returns the chained Hono app so consumer composition keeps RPC
29
+ * types end-to-end (`hc<typeof app>()` sees every account route).
30
+ * - Authorization runs at the route via `requirePermission(slug)`
31
+ * middleware, not the v3 `@HasPermission` decorator on a controller
32
+ * method.
33
+ * - Validation runs via `validate('json' | 'query' | 'param', schema)`
34
+ * wrapping `zValidator`; handlers read parsed input via
35
+ * `c.req.valid('json' | ...)`.
36
+ * - 404s throw `NotFoundError` so `app.onError` (registered via
37
+ * `registerErrorHandlers`) produces the consistent JSON error
38
+ * shape — handlers don't shape error responses themselves.
39
+ * - The service is injected (not constructed inside the route file
40
+ * from an EntityManager) so consumers swap it for tests / custom
41
+ * subclasses.
42
+ */
43
+
44
+ export interface AccountsRoutesDeps<TAccount extends AuthenticatedAccount = AuthenticatedAccount> {
45
+ service: AccountService;
46
+ provider: AuthProvider<TAccount>;
47
+ }
48
+
49
+ /**
50
+ * ⚠️ FOOT-GUN: do NOT thread one shared `app` through several modules'
51
+ * `defineXxxRoutes` calls. Chaining every module's routes onto a single app
52
+ * accumulates one giant Hono route-type and detonates `tsc` (TS2589 /
53
+ * "instantiation excessively deep") once you have enough modules. Prefer
54
+ * {@link buildAccountsApp} and mount it on the root with
55
+ * `root.route("/", buildAccountsApp(deps))` — each module then gets its own
56
+ * bounded sub-app. This raw `(app, deps)` form is kept for advanced
57
+ * composition (deliberately registering accounts routes onto an existing
58
+ * already-typed app).
59
+ */
60
+ // Generic over Hono's schema param `S`: `.get()`/`.post()` resolve on the
61
+ // parameter's declared type, so taking `Hono<AppEnv>` (or `<T extends
62
+ // Hono<AppEnv>>`) widens an already-chained app and erases every previously
63
+ // registered route from the RPC type. `Hono<AppEnv, S>` accumulates instead —
64
+ // the return type is `Hono<AppEnv, S & <these routes>>`.
65
+ export function defineAccountsRoutes<
66
+ TAccount extends AuthenticatedAccount = AuthenticatedAccount,
67
+ S extends Schema = BlankSchema,
68
+ >(app: Hono<AppEnv, S>, deps: AccountsRoutesDeps<TAccount>) {
69
+ const auth = requireAuth({ provider: deps.provider });
70
+
71
+ return app
72
+ .post(
73
+ "/accounts",
74
+ auth,
75
+ requirePermission(ACCOUNTS_PERMISSIONS.create),
76
+ validate("json", createAccountSchema),
77
+ async (c) => {
78
+ const body = c.req.valid("json");
79
+ const account = await deps.service.create(body);
80
+ return c.json(account, 201);
81
+ },
82
+ )
83
+ .get(
84
+ "/accounts",
85
+ auth,
86
+ requirePermission(ACCOUNTS_PERMISSIONS.read),
87
+ validate("query", listAccountsQuerySchema),
88
+ async (c) => {
89
+ const q = c.req.valid("query");
90
+ const rows = await deps.service.getAll({
91
+ search: q.search,
92
+ where: filterFromQuery(q),
93
+ });
94
+ return c.json(rows, 200);
95
+ },
96
+ )
97
+ .get(
98
+ "/accounts/list",
99
+ auth,
100
+ requirePermission(ACCOUNTS_PERMISSIONS.read),
101
+ validate("query", listAccountsQuerySchema),
102
+ async (c) => {
103
+ const q = c.req.valid("query");
104
+ const offset = (q.page - 1) * q.perPage;
105
+ const result = await deps.service.list({
106
+ search: q.search,
107
+ where: filterFromQuery(q),
108
+ limit: q.perPage,
109
+ offset,
110
+ });
111
+ return c.json({ ...result, page: q.page, perPage: q.perPage }, 200);
112
+ },
113
+ )
114
+ .get(
115
+ "/accounts/count",
116
+ auth,
117
+ requirePermission(ACCOUNTS_PERMISSIONS.read),
118
+ validate("query", listAccountsQuerySchema),
119
+ async (c) => {
120
+ const q = c.req.valid("query");
121
+ const count = await deps.service.count({
122
+ search: q.search,
123
+ where: filterFromQuery(q),
124
+ });
125
+ return c.json({ count }, 200);
126
+ },
127
+ )
128
+ .get(
129
+ "/accounts/:id",
130
+ auth,
131
+ requirePermission(ACCOUNTS_PERMISSIONS.read),
132
+ validate("param", accountIdParamSchema),
133
+ async (c) => {
134
+ const { id } = c.req.valid("param");
135
+ const account = await deps.service.get(id);
136
+ if (account === null) throw new NotFoundError("Account not found");
137
+ return c.json(account, 200);
138
+ },
139
+ )
140
+ .put(
141
+ "/accounts/:id",
142
+ auth,
143
+ requirePermission(ACCOUNTS_PERMISSIONS.update),
144
+ validate("param", accountIdParamSchema),
145
+ validate("json", updateAccountSchema),
146
+ async (c) => {
147
+ const { id } = c.req.valid("param");
148
+ const body = c.req.valid("json");
149
+ const account = await deps.service.update(id, body);
150
+ if (account === null) throw new NotFoundError("Account not found");
151
+ return c.json(account, 200);
152
+ },
153
+ )
154
+ .delete(
155
+ "/accounts/:id",
156
+ auth,
157
+ requirePermission(ACCOUNTS_PERMISSIONS.delete),
158
+ validate("param", accountIdParamSchema),
159
+ async (c) => {
160
+ const { id } = c.req.valid("param");
161
+ const existing = await deps.service.get(id);
162
+ if (existing === null) throw new NotFoundError("Account not found");
163
+ await deps.service.delete(id);
164
+ return c.body(null, 204);
165
+ },
166
+ );
167
+ }
168
+
169
+ /**
170
+ * Build the accounts module as its own sub-app, ready to mount on the root:
171
+ *
172
+ * ```ts
173
+ * const app = createApp({ cors }).route("/", buildAccountsApp({ service, provider }));
174
+ * ```
175
+ *
176
+ * This is the canonical wiring — each module is an independent, bounded
177
+ * sub-app, so the composed `hc()` client type scales without `tsc` overflow.
178
+ * The module owns its registry tag (`createModuleApp("accounts")`), so its
179
+ * routes show up under the `accounts` module in `/dev/routes` and `list_routes`.
180
+ */
181
+ export function buildAccountsApp<TAccount extends AuthenticatedAccount = AuthenticatedAccount>(
182
+ deps: AccountsRoutesDeps<TAccount>,
183
+ ) {
184
+ return defineAccountsRoutes(createModuleApp("accounts"), deps);
185
+ }
186
+
187
+ /**
188
+ * Translates the strict-typed query options into the
189
+ * `DrizzleEntityService.QueryOptions['where']` shape — booleans coerced
190
+ * from "true" / "false", optional fields stripped when absent.
191
+ */
192
+ function filterFromQuery(q: {
193
+ isActive?: "true" | "false";
194
+ roleId?: string;
195
+ }): Record<string, unknown> | undefined {
196
+ const where: Record<string, unknown> = {};
197
+ if (q.isActive !== undefined) where.isActive = q.isActive === "true";
198
+ if (q.roleId !== undefined) where.roleId = q.roleId;
199
+ return Object.keys(where).length > 0 ? where : undefined;
200
+ }
@@ -0,0 +1,219 @@
1
+ import { baseFields } from "@sixthsummit/ship-api/app/db/baseFields";
2
+ import { relations } from "drizzle-orm";
3
+ import {
4
+ boolean,
5
+ index,
6
+ pgTable,
7
+ timestamp,
8
+ uniqueIndex,
9
+ uuid,
10
+ varchar,
11
+ } from "drizzle-orm/pg-core";
12
+
13
+ /**
14
+ * Identity + RBAC schema for the accounts module.
15
+ *
16
+ * Relocated out of framework core (`@sixthsummit/ship-api/app/schema/*`) so the
17
+ * framework stays incrementally adoptable and each product owns / tailors its
18
+ * identity model (multi-tenant or not). Core ships the primitives — `baseFields`,
19
+ * the `AuthProvider` interface, `DrizzleEntityService`; this module owns the
20
+ * concrete tables.
21
+ *
22
+ * Spread `accountsSchema` into `createApp({ schema })` (and the test-DB harness)
23
+ * the way the old core `defaultSchema` was.
24
+ */
25
+
26
+ /**
27
+ * `tenants` — opt-in multi-tenancy root table (A2-1).
28
+ *
29
+ * Tenancy is a per-product choice. This table + the `tenantsSchema` fragment
30
+ * ship with the accounts module but are NOT part of the default `accountsSchema`
31
+ * — a single-tenant product never composes them and never sees a `tenants`
32
+ * table. A multi-tenant product:
33
+ * 1. composes `tenantsSchema` into `createApp({ schema })`,
34
+ * 2. applies `...tenantScoped(tenants)` to the domain tables it wants scoped
35
+ * (and, for the one-tenant-per-account default, to `accounts` — see the
36
+ * commented field below),
37
+ * 3. wires `resolveTenant()` after `requireAuth`.
38
+ *
39
+ * Domain tables FK `tenants`, not `accounts`, so a future move to a membership
40
+ * model (Model A → B) is an identity-tables-only migration. See
41
+ * `docs/v4/concepts/tenancy.md`.
42
+ */
43
+ export const tenants = pgTable("tenants", {
44
+ id: uuid("id").primaryKey().defaultRandom(),
45
+ slug: varchar("slug", { length: 100 }).notNull().unique(),
46
+ name: varchar("name", { length: 200 }).notNull(),
47
+ ...baseFields,
48
+ });
49
+
50
+ export type Tenant = typeof tenants.$inferSelect;
51
+ export type NewTenant = typeof tenants.$inferInsert;
52
+
53
+ /**
54
+ * Opt-in tenancy schema fragment — compose alongside `accountsSchema` when a
55
+ * product enables multi-tenancy:
56
+ * `createApp({ schema: { ...accountsSchema, ...tenantsSchema, ...domainTables } })`.
57
+ * Kept separate from `accountsSchema` so single-tenant products never get a
58
+ * `tenants` table.
59
+ */
60
+ export const tenantsSchema = {
61
+ tenants,
62
+ } as const;
63
+
64
+ export const roles = pgTable("roles", {
65
+ id: uuid("id").primaryKey().defaultRandom(),
66
+ slug: varchar("slug", { length: 100 }).notNull().unique(),
67
+ name: varchar("name", { length: 100 }).notNull(),
68
+ description: varchar("description", { length: 500 }),
69
+ ...baseFields,
70
+ });
71
+
72
+ export const permissions = pgTable("permissions", {
73
+ id: uuid("id").primaryKey().defaultRandom(),
74
+ slug: varchar("slug", { length: 200 }).notNull().unique(),
75
+ name: varchar("name", { length: 200 }).notNull(),
76
+ ...baseFields,
77
+ });
78
+
79
+ export const rolePermissions = pgTable("role_permissions", {
80
+ id: uuid("id").primaryKey().defaultRandom(),
81
+ roleId: uuid("role_id")
82
+ .notNull()
83
+ .references(() => roles.id, { onDelete: "cascade" }),
84
+ permissionId: uuid("permission_id")
85
+ .notNull()
86
+ .references(() => permissions.id, { onDelete: "cascade" }),
87
+ ...baseFields,
88
+ });
89
+
90
+ export const accounts = pgTable(
91
+ "accounts",
92
+ {
93
+ id: uuid("id").primaryKey().defaultRandom(),
94
+
95
+ /**
96
+ * Stable subject identifier from the auth provider (Firebase UID by default;
97
+ * `sub` claim under any other `AuthProvider` adapter).
98
+ */
99
+ firebaseUid: varchar("firebase_uid", { length: 128 }),
100
+
101
+ email: varchar("email", { length: 320 }).notNull(),
102
+ emailVerified: boolean("email_verified").notNull().default(false),
103
+
104
+ displayName: varchar("display_name", { length: 200 }),
105
+
106
+ /** Soft-disable without deleting (distinct from `deletedAt`). */
107
+ isActive: boolean("is_active").notNull().default(true),
108
+
109
+ /** Optional FK to a single primary role. Multi-role assignments are
110
+ * modeled in a join table by consumers who need them. */
111
+ roleId: uuid("role_id").references(() => roles.id, { onDelete: "set null" }),
112
+
113
+ // ─── Multi-tenancy (opt-in, A2-1) ────────────────────────────────
114
+ // Uncomment for the one-tenant-per-account model: adds a non-null
115
+ // `tenant_id` uuid FK → tenants.id. Then compose `tenantsSchema` into your
116
+ // app schema and wire `resolveTenant()` after `requireAuth`. Import the
117
+ // mixin from the barrel: `import { tenantScoped } from "@sixthsummit/ship-api"`.
118
+ // ...tenantScoped(tenants),
119
+
120
+ ...baseFields,
121
+ },
122
+ (table) => [
123
+ uniqueIndex("accounts_email_unique").on(table.email),
124
+ uniqueIndex("accounts_firebase_uid_unique").on(table.firebaseUid),
125
+ ],
126
+ );
127
+
128
+ export const rolesRelations = relations(roles, ({ many }) => ({
129
+ rolePermissions: many(rolePermissions),
130
+ }));
131
+
132
+ export const permissionsRelations = relations(permissions, ({ many }) => ({
133
+ rolePermissions: many(rolePermissions),
134
+ }));
135
+
136
+ export const rolePermissionsRelations = relations(rolePermissions, ({ one }) => ({
137
+ role: one(roles, {
138
+ fields: [rolePermissions.roleId],
139
+ references: [roles.id],
140
+ }),
141
+ permission: one(permissions, {
142
+ fields: [rolePermissions.permissionId],
143
+ references: [permissions.id],
144
+ }),
145
+ }));
146
+
147
+ export const accountsRelations = relations(accounts, ({ one }) => ({
148
+ role: one(roles, {
149
+ fields: [accounts.roleId],
150
+ references: [roles.id],
151
+ }),
152
+ }));
153
+
154
+ export type Account = typeof accounts.$inferSelect;
155
+ export type NewAccount = typeof accounts.$inferInsert;
156
+ export type Role = typeof roles.$inferSelect;
157
+ export type NewRole = typeof roles.$inferInsert;
158
+ export type Permission = typeof permissions.$inferSelect;
159
+ export type NewPermission = typeof permissions.$inferInsert;
160
+ export type RolePermission = typeof rolePermissions.$inferSelect;
161
+ export type NewRolePermission = typeof rolePermissions.$inferInsert;
162
+
163
+ /**
164
+ * `refresh_tokens` — server-side store for the JWT-cookie auth refresh-token
165
+ * rotation flow. `tokenHash` is a SHA-256 of the token (never the raw value);
166
+ * `revokedAt` supports immediate server-side revocation; `replacedById` tracks
167
+ * rotation history so refresh-token reuse (a theft signal) can revoke the whole
168
+ * chain. Consumed by the framework's generic `DrizzleRefreshTokenStore`, which
169
+ * takes this table via its constructor.
170
+ */
171
+ export const refreshTokens = pgTable(
172
+ "refresh_tokens",
173
+ {
174
+ id: uuid("id").primaryKey().defaultRandom(),
175
+ accountId: uuid("account_id")
176
+ .notNull()
177
+ .references(() => accounts.id, { onDelete: "cascade" }),
178
+ tokenHash: varchar("token_hash", { length: 128 }).notNull().unique(),
179
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
180
+ revokedAt: timestamp("revoked_at", { withTimezone: true }),
181
+ replacedById: uuid("replaced_by_id"),
182
+ /** User-agent / IP on issue, for audit + risk signals. */
183
+ userAgent: varchar("user_agent", { length: 500 }),
184
+ issuedFromIp: varchar("issued_from_ip", { length: 64 }),
185
+ ...baseFields,
186
+ },
187
+ (table) => [
188
+ index("refresh_tokens_account_id_idx").on(table.accountId),
189
+ index("refresh_tokens_expires_at_idx").on(table.expiresAt),
190
+ ],
191
+ );
192
+
193
+ export const refreshTokensRelations = relations(refreshTokens, ({ one }) => ({
194
+ account: one(accounts, {
195
+ fields: [refreshTokens.accountId],
196
+ references: [accounts.id],
197
+ }),
198
+ }));
199
+
200
+ export type RefreshToken = typeof refreshTokens.$inferSelect;
201
+ export type NewRefreshToken = typeof refreshTokens.$inferInsert;
202
+
203
+ /**
204
+ * Composable schema fragment — spread into `createApp({ schema })` and the
205
+ * integration-test DB harness. Replaces this module's slice of the old core
206
+ * `defaultSchema`.
207
+ */
208
+ export const accountsSchema = {
209
+ accounts,
210
+ accountsRelations,
211
+ roles,
212
+ rolesRelations,
213
+ permissions,
214
+ permissionsRelations,
215
+ rolePermissions,
216
+ rolePermissionsRelations,
217
+ refreshTokens,
218
+ refreshTokensRelations,
219
+ } as const;
@@ -0,0 +1,44 @@
1
+ import { DrizzleEntityService } from "@sixthsummit/ship-api/app/services/DrizzleEntityService";
2
+ import { accounts } from "../schema.js";
3
+
4
+ /**
5
+ * v4 `AccountService` — thin extension of `DrizzleEntityService` against
6
+ * the framework's default `accounts` table.
7
+ *
8
+ * Replaces v3's `EntityService<Account>` subclass. Same surface
9
+ * (`get`/`getAll`/`list`/`count`/`create`/`update`/`delete`) inherited
10
+ * from the base; only the entity-specific overrides live here:
11
+ *
12
+ * - `getTable()` returns the framework's default `accounts` pgTable
13
+ * - `getDefaultSearchFields()` lists the columns the free-text
14
+ * `?search=` filter scans (email + displayName, the human-readable
15
+ * identifiers operators reach for in admin UIs)
16
+ * - `getDefaultRelations()` declares `role` so `?relations=role`
17
+ * loads a populated role
18
+ *
19
+ * Soft-delete + audit-column auto-stamping (createdAt / createdBy on
20
+ * insert; updatedAt / updatedBy on update) are inherited from the
21
+ * base — no per-service wiring required.
22
+ *
23
+ * Schema customization: consumers who extend the `accounts` table via
24
+ * `createApp({ schema })` should subclass this service (or replace it
25
+ * entirely) so `getDefaultSearchFields()` reflects any new searchable
26
+ * columns. The `TSchema` generic carries the full composed schema so
27
+ * Drizzle relational queries stay typed end-to-end.
28
+ */
29
+ export class AccountService extends DrizzleEntityService<
30
+ typeof accounts,
31
+ { accounts: typeof accounts }
32
+ > {
33
+ protected getTable() {
34
+ return accounts;
35
+ }
36
+
37
+ protected override getDefaultSearchFields(): readonly string[] {
38
+ return ["email", "displayName"];
39
+ }
40
+
41
+ protected override getDefaultRelations(): readonly string[] {
42
+ return ["role"];
43
+ }
44
+ }