@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,591 @@
1
+ import { Resend } from "resend";
2
+ import TemplateRegistry from "./TemplateRegistry.js";
3
+ import TemplateRenderer from "./TemplateRenderer.js";
4
+ import type {
5
+ EmailAddress,
6
+ EmailTemplate,
7
+ RenderedTemplate,
8
+ RenderTemplateOptions,
9
+ SendBatchEmailsOptions,
10
+ SendBatchEmailsResult,
11
+ SendEmailOptions,
12
+ SendEmailResult,
13
+ } from "./types/index.js";
14
+
15
+ /**
16
+ * EmailService - Service for sending emails using Resend
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const emailService = new EmailService(env.RESEND_API_KEY, env.RESEND_DEFAULT_FROM);
21
+ *
22
+ * // Send a simple email
23
+ * await emailService.sendEmail({
24
+ * from: 'noreply@example.com',
25
+ * to: 'user@example.com',
26
+ * subject: 'Welcome!',
27
+ * text: 'Welcome to our platform',
28
+ * });
29
+ *
30
+ * // Send an HTML email
31
+ * await emailService.sendEmail({
32
+ * from: 'noreply@example.com',
33
+ * to: ['user1@example.com', 'user2@example.com'],
34
+ * subject: 'Welcome!',
35
+ * html: '<h1>Welcome to our platform</h1>',
36
+ * });
37
+ *
38
+ * // Send batch emails
39
+ * await emailService.sendBatchEmails({
40
+ * emails: [
41
+ * {
42
+ * from: 'noreply@example.com',
43
+ * to: 'user1@example.com',
44
+ * subject: 'Welcome User 1',
45
+ * text: 'Welcome!',
46
+ * },
47
+ * {
48
+ * from: 'noreply@example.com',
49
+ * to: 'user2@example.com',
50
+ * subject: 'Welcome User 2',
51
+ * text: 'Welcome!',
52
+ * },
53
+ * ],
54
+ * });
55
+ *
56
+ * // Send email using a template
57
+ * await emailService.sendEmailWithTemplate({
58
+ * templateId: 'welcome',
59
+ * to: 'user@example.com',
60
+ * variables: {
61
+ * firstName: 'John',
62
+ * lastName: 'Doe',
63
+ * email: 'user@example.com',
64
+ * },
65
+ * });
66
+ *
67
+ * // Register a custom template
68
+ * emailService.registerTemplate({
69
+ * id: 'custom-welcome',
70
+ * name: 'Custom Welcome',
71
+ * subject: 'Welcome {{firstName}}!',
72
+ * html: '<h1>Hello {{firstName}} {{lastName}}!</h1>',
73
+ * });
74
+ * ```
75
+ */
76
+ export default class EmailService {
77
+ private resend: Resend;
78
+ private defaultFrom: string;
79
+ private templateRegistry: TemplateRegistry;
80
+ private templateRenderer: TemplateRenderer;
81
+
82
+ /**
83
+ * Initialize Email Service
84
+ * @param apiKey - Resend API key. Required at runtime — pass it from your app's validated env (no implicit env fallback).
85
+ * @param defaultFrom - Default "from" email address. Required at runtime.
86
+ */
87
+ constructor(apiKey?: string, defaultFrom?: string) {
88
+ const key = apiKey;
89
+
90
+ if (!key || key.trim() === "") {
91
+ throw new Error(
92
+ "Resend API key is required — pass it to the EmailService constructor (e.g. from your app's validated env).",
93
+ );
94
+ }
95
+
96
+ const from = defaultFrom;
97
+
98
+ if (!from || from.trim() === "") {
99
+ throw new Error(
100
+ "Default from address is required — pass it to the EmailService constructor (e.g. from your app's validated env).",
101
+ );
102
+ }
103
+
104
+ this.resend = new Resend(key);
105
+ this.defaultFrom = from;
106
+ this.templateRegistry = new TemplateRegistry();
107
+ this.templateRenderer = new TemplateRenderer();
108
+ }
109
+
110
+ /**
111
+ * Send a single email
112
+ * @param options - Email options
113
+ * @returns Object containing email ID and any errors
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const result = await emailService.sendEmail({
118
+ * from: 'noreply@example.com',
119
+ * to: 'user@example.com',
120
+ * subject: 'Welcome!',
121
+ * text: 'Welcome to our platform',
122
+ * });
123
+ *
124
+ * if (result.error) {
125
+ * console.error('Failed to send email:', result.error);
126
+ * } else {
127
+ * console.log('Email sent:', result.id);
128
+ * }
129
+ * ```
130
+ */
131
+ async sendEmail(options: SendEmailOptions): Promise<SendEmailResult> {
132
+ try {
133
+ // Use default from if not provided and normalize if it's an object
134
+ let from: string;
135
+ const fromOption = options.from;
136
+
137
+ if (fromOption) {
138
+ // Normalize from address if it's an object
139
+ if (typeof fromOption === "string") {
140
+ from = fromOption;
141
+ } else {
142
+ const fromObject = fromOption as { name: string; email: string };
143
+ from = `${fromObject.name} <${fromObject.email}>`;
144
+ }
145
+ } else {
146
+ from = this.defaultFrom;
147
+ }
148
+
149
+ if (!from) {
150
+ return {
151
+ error: new Error("From address is required. Provide it in options or set a default."),
152
+ };
153
+ }
154
+
155
+ // Validate that at least text or html is provided
156
+ if (!options.text && !options.html) {
157
+ return {
158
+ error: new Error("Email must have either text or html content"),
159
+ };
160
+ }
161
+
162
+ // Normalize email addresses
163
+ const to = this.normalizeEmailAddresses(options.to);
164
+ const cc = options.cc ? this.normalizeEmailAddresses(options.cc) : undefined;
165
+ const bcc = options.bcc ? this.normalizeEmailAddresses(options.bcc) : undefined;
166
+ const replyTo = options.replyTo ? this.normalizeEmailAddresses(options.replyTo) : undefined;
167
+
168
+ // Prepare email payload
169
+ const emailPayload: any = {
170
+ from,
171
+ to,
172
+ subject: options.subject,
173
+ cc,
174
+ bcc,
175
+ replyTo,
176
+ attachments: options.attachments,
177
+ tags: options.tags,
178
+ headers: options.headers,
179
+ scheduledAt: options.scheduledAt,
180
+ };
181
+
182
+ // Add text or html (at least one must be present)
183
+ if (options.html) {
184
+ emailPayload.html = options.html;
185
+ if (options.text) {
186
+ emailPayload.text = options.text;
187
+ }
188
+ } else if (options.text) {
189
+ emailPayload.text = options.text;
190
+ }
191
+
192
+ // Send email using Resend
193
+ const response = await this.resend.emails.send(emailPayload);
194
+
195
+ // Handle Resend response
196
+ if (response.error) {
197
+ return {
198
+ error: new Error(response.error.message),
199
+ };
200
+ }
201
+
202
+ return {
203
+ id: response.data?.id,
204
+ };
205
+ } catch (error) {
206
+ return {
207
+ error: error instanceof Error ? error : new Error(String(error)),
208
+ };
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Send multiple emails in a batch (up to 100 emails per batch)
214
+ * @param options - Batch email options
215
+ * @returns Array of results for each email
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * const results = await emailService.sendBatchEmails({
220
+ * emails: [
221
+ * {
222
+ * from: 'noreply@example.com',
223
+ * to: 'user1@example.com',
224
+ * subject: 'Welcome User 1',
225
+ * text: 'Welcome!',
226
+ * },
227
+ * {
228
+ * from: 'noreply@example.com',
229
+ * to: 'user2@example.com',
230
+ * subject: 'Welcome User 2',
231
+ * text: 'Welcome!',
232
+ * },
233
+ * ],
234
+ * });
235
+ *
236
+ * results.forEach((result, index) => {
237
+ * if (result.error) {
238
+ * console.error(`Email ${index} failed:`, result.error);
239
+ * } else {
240
+ * console.log(`Email ${index} sent:`, result.id);
241
+ * }
242
+ * });
243
+ * ```
244
+ */
245
+ async sendBatchEmails(options: SendBatchEmailsOptions): Promise<SendBatchEmailsResult> {
246
+ try {
247
+ // Validate batch size
248
+ if (options.emails.length > 100) {
249
+ throw new Error("Batch size cannot exceed 100 emails");
250
+ }
251
+
252
+ if (options.emails.length === 0) {
253
+ return { data: [] };
254
+ }
255
+
256
+ // Prepare emails for batch send
257
+ const emails = options.emails.map((email) => {
258
+ const from = email.from || this.defaultFrom;
259
+
260
+ if (!from) {
261
+ throw new Error(
262
+ "From address is required for all emails. Provide it in options or set a default.",
263
+ );
264
+ }
265
+
266
+ // Validate that at least text or html is provided
267
+ if (!email.text && !email.html) {
268
+ throw new Error("Each email must have either text or html content");
269
+ }
270
+
271
+ const emailPayload: any = {
272
+ from,
273
+ to: this.normalizeEmailAddresses(email.to),
274
+ subject: email.subject,
275
+ };
276
+
277
+ // Add text or html (at least one must be present)
278
+ if (email.html) {
279
+ emailPayload.html = email.html;
280
+ if (email.text) {
281
+ emailPayload.text = email.text;
282
+ }
283
+ } else if (email.text) {
284
+ emailPayload.text = email.text;
285
+ }
286
+
287
+ // Add optional fields only if they exist
288
+ if (email.cc) {
289
+ emailPayload.cc = this.normalizeEmailAddresses(email.cc);
290
+ }
291
+ if (email.bcc) {
292
+ emailPayload.bcc = this.normalizeEmailAddresses(email.bcc);
293
+ }
294
+ if (email.replyTo) {
295
+ emailPayload.replyTo = this.normalizeEmailAddresses(email.replyTo);
296
+ }
297
+ if (email.attachments) {
298
+ emailPayload.attachments = email.attachments;
299
+ }
300
+ if (email.tags) {
301
+ emailPayload.tags = email.tags;
302
+ }
303
+ if (email.headers) {
304
+ emailPayload.headers = email.headers;
305
+ }
306
+ if (email.scheduledAt) {
307
+ emailPayload.scheduledAt = email.scheduledAt;
308
+ }
309
+
310
+ return emailPayload;
311
+ });
312
+
313
+ // Send batch using Resend
314
+ const response = await this.resend.batch.send(emails);
315
+
316
+ // Handle Resend response
317
+ if (response.error) {
318
+ return {
319
+ error: new Error(response.error.message),
320
+ };
321
+ }
322
+
323
+ return {
324
+ data: response.data?.data || [],
325
+ };
326
+ } catch (error) {
327
+ return {
328
+ error: error instanceof Error ? error : new Error(String(error)),
329
+ };
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Normalize email addresses to string array
335
+ * @param addresses - Email address(es) in various formats
336
+ * @returns Array of email address strings
337
+ */
338
+ private normalizeEmailAddresses(addresses: EmailAddress | EmailAddress[]): string[] {
339
+ const addressArray = Array.isArray(addresses) ? addresses : [addresses];
340
+
341
+ return addressArray.map((addr) => {
342
+ if (typeof addr === "string") {
343
+ return addr;
344
+ }
345
+ // Format: "Name <email@example.com>"
346
+ return `${addr.name} <${addr.email}>`;
347
+ });
348
+ }
349
+
350
+ /**
351
+ * Get the default from address
352
+ * @returns Default from email address
353
+ */
354
+ getDefaultFrom(): string {
355
+ return this.defaultFrom;
356
+ }
357
+
358
+ /**
359
+ * Set the default from address
360
+ * @param defaultFrom - New default from email address
361
+ */
362
+ setDefaultFrom(defaultFrom: string): void {
363
+ this.defaultFrom = defaultFrom;
364
+ }
365
+
366
+ /**
367
+ * Register an email template
368
+ * @param template - Template to register
369
+ */
370
+ registerTemplate<T extends Record<string, any> = Record<string, any>>(
371
+ template: EmailTemplate<T>,
372
+ ): void {
373
+ this.templateRegistry.register(template);
374
+ }
375
+
376
+ /**
377
+ * Register multiple email templates
378
+ * @param templates - Array of templates to register
379
+ */
380
+ registerTemplates(templates: EmailTemplate[]): void {
381
+ this.templateRegistry.registerMany(templates);
382
+ }
383
+
384
+ /**
385
+ * Get a registered template by ID
386
+ * @param id - Template ID
387
+ * @returns Template or undefined if not found
388
+ */
389
+ getTemplate(id: string): EmailTemplate | undefined {
390
+ return this.templateRegistry.get(id);
391
+ }
392
+
393
+ /**
394
+ * List all registered templates
395
+ * @returns Array of all templates
396
+ */
397
+ listTemplates(): EmailTemplate[] {
398
+ return this.templateRegistry.list();
399
+ }
400
+
401
+ /**
402
+ * Check if a template exists
403
+ * @param id - Template ID
404
+ * @returns True if template exists
405
+ */
406
+ hasTemplate(id: string): boolean {
407
+ return this.templateRegistry.has(id);
408
+ }
409
+
410
+ /**
411
+ * Render a template with variables
412
+ * @param options - Template rendering options
413
+ * @returns Rendered template
414
+ *
415
+ * @example
416
+ * ```typescript
417
+ * const rendered = emailService.renderTemplate({
418
+ * templateId: 'welcome',
419
+ * variables: {
420
+ * firstName: 'John',
421
+ * lastName: 'Doe',
422
+ * email: 'john@example.com',
423
+ * },
424
+ * });
425
+ * ```
426
+ */
427
+ renderTemplate<T extends Record<string, any> = Record<string, any>>(
428
+ options: RenderTemplateOptions<T>,
429
+ ): RenderedTemplate {
430
+ const template = this.templateRegistry.getOrThrow(options.templateId);
431
+ const rendered = this.templateRenderer.render(template, options.variables);
432
+
433
+ // Apply overrides from options
434
+ if (options.from) {
435
+ rendered.from = options.from;
436
+ }
437
+ if (options.replyTo) {
438
+ rendered.replyTo = options.replyTo;
439
+ }
440
+ if (options.tags) {
441
+ const additionalTags = options.tags.map((tag) => ({ name: tag, value: tag }));
442
+ rendered.tags = [...(rendered.tags || []), ...additionalTags];
443
+ }
444
+
445
+ return rendered;
446
+ }
447
+
448
+ /**
449
+ * Send an email using a template
450
+ * @param options - Template rendering and email sending options
451
+ * @returns Object containing email ID and any errors
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * const result = await emailService.sendEmailWithTemplate({
456
+ * templateId: 'welcome',
457
+ * to: 'user@example.com',
458
+ * variables: {
459
+ * firstName: 'John',
460
+ * lastName: 'Doe',
461
+ * email: 'user@example.com',
462
+ * },
463
+ * });
464
+ *
465
+ * if (result.error) {
466
+ * console.error('Failed to send email:', result.error);
467
+ * } else {
468
+ * console.log('Email sent:', result.id);
469
+ * }
470
+ * ```
471
+ */
472
+ async sendEmailWithTemplate<T extends Record<string, any> = Record<string, any>>(
473
+ options: RenderTemplateOptions<T> & {
474
+ to: EmailAddress | EmailAddress[];
475
+ cc?: EmailAddress | EmailAddress[];
476
+ bcc?: EmailAddress | EmailAddress[];
477
+ attachments?: any[];
478
+ headers?: Record<string, string>;
479
+ scheduledAt?: string;
480
+ },
481
+ ): Promise<SendEmailResult> {
482
+ try {
483
+ // Render the template
484
+ const rendered = this.renderTemplate({
485
+ templateId: options.templateId,
486
+ variables: options.variables,
487
+ from: options.from,
488
+ replyTo: options.replyTo,
489
+ tags: options.tags,
490
+ });
491
+
492
+ // Send the email
493
+ return await this.sendEmail({
494
+ from: rendered.from || this.defaultFrom,
495
+ to: options.to,
496
+ cc: options.cc,
497
+ bcc: options.bcc,
498
+ subject: rendered.subject,
499
+ html: rendered.html,
500
+ text: rendered.text,
501
+ replyTo: rendered.replyTo,
502
+ attachments: options.attachments,
503
+ tags: rendered.tags,
504
+ headers: options.headers,
505
+ scheduledAt: options.scheduledAt,
506
+ });
507
+ } catch (error) {
508
+ return {
509
+ error: error instanceof Error ? error : new Error(String(error)),
510
+ };
511
+ }
512
+ }
513
+
514
+ /**
515
+ * Send multiple emails using templates
516
+ * @param emails - Array of template-based email options
517
+ * @returns Array of results for each email
518
+ *
519
+ * @example
520
+ * ```typescript
521
+ * const results = await emailService.sendBatchEmailsWithTemplates([
522
+ * {
523
+ * templateId: 'welcome',
524
+ * to: 'user1@example.com',
525
+ * variables: { firstName: 'John', lastName: 'Doe', email: 'user1@example.com' },
526
+ * },
527
+ * {
528
+ * templateId: 'welcome',
529
+ * to: 'user2@example.com',
530
+ * variables: { firstName: 'Jane', lastName: 'Smith', email: 'user2@example.com' },
531
+ * },
532
+ * ]);
533
+ * ```
534
+ */
535
+ async sendBatchEmailsWithTemplates<T extends Record<string, any> = Record<string, any>>(
536
+ emails: Array<
537
+ RenderTemplateOptions<T> & {
538
+ to: EmailAddress | EmailAddress[];
539
+ cc?: EmailAddress | EmailAddress[];
540
+ bcc?: EmailAddress | EmailAddress[];
541
+ attachments?: any[];
542
+ headers?: Record<string, string>;
543
+ scheduledAt?: string;
544
+ }
545
+ >,
546
+ ): Promise<SendBatchEmailsResult> {
547
+ try {
548
+ // Validate batch size
549
+ if (emails.length > 100) {
550
+ throw new Error("Batch size cannot exceed 100 emails");
551
+ }
552
+
553
+ if (emails.length === 0) {
554
+ return { data: [] };
555
+ }
556
+
557
+ // Render all templates and prepare emails
558
+ const preparedEmails = emails.map((emailOptions) => {
559
+ const rendered = this.renderTemplate({
560
+ templateId: emailOptions.templateId,
561
+ variables: emailOptions.variables,
562
+ from: emailOptions.from,
563
+ replyTo: emailOptions.replyTo,
564
+ tags: emailOptions.tags,
565
+ });
566
+
567
+ return {
568
+ from: rendered.from || this.defaultFrom,
569
+ to: emailOptions.to,
570
+ cc: emailOptions.cc,
571
+ bcc: emailOptions.bcc,
572
+ subject: rendered.subject,
573
+ html: rendered.html,
574
+ text: rendered.text,
575
+ replyTo: rendered.replyTo,
576
+ attachments: emailOptions.attachments,
577
+ tags: rendered.tags,
578
+ headers: emailOptions.headers,
579
+ scheduledAt: emailOptions.scheduledAt,
580
+ };
581
+ });
582
+
583
+ // Send batch
584
+ return await this.sendBatchEmails({ emails: preparedEmails });
585
+ } catch (error) {
586
+ return {
587
+ error: error instanceof Error ? error : new Error(String(error)),
588
+ };
589
+ }
590
+ }
591
+ }