@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,250 @@
1
+ import chalk from "chalk";
2
+ import { execSync } from "child_process";
3
+ import fs from "fs/promises";
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ /**
11
+ * Project-name validator (F17). Mirrors npm's package-name rules
12
+ * (the loose subset that travels safely in directory paths). Reject
13
+ * names that:
14
+ * - contain path separators (`/`, `\`)
15
+ * - contain `..` (parent-dir traversal, even if `path.resolve` would
16
+ * later catch it)
17
+ * - contain null bytes (filesystem string-termination footgun)
18
+ * - start with `.` (hidden / dotfile collision)
19
+ * - start with a digit (npm forbids; npm-compatible names start with
20
+ * a letter)
21
+ * - contain anything outside `[a-zA-Z0-9_-]`
22
+ *
23
+ * Rejecting up front avoids filesystem clobbering of user-owned paths
24
+ * via `ship-api create ../../../etc/foo` (the `path.resolve` call
25
+ * downstream resolves out of `cwd` without these checks).
26
+ */
27
+ const PROJECT_NAME_RE = /^[a-z][a-z0-9_-]*$/i;
28
+ const FORBIDDEN_CHARS = ["/", "\\", "\0", ".."];
29
+
30
+ export function validateProjectName(name) {
31
+ if (typeof name !== "string" || name.length === 0) {
32
+ return "must be a non-empty string";
33
+ }
34
+ for (const forbidden of FORBIDDEN_CHARS) {
35
+ if (name.includes(forbidden)) {
36
+ return `must not contain ${JSON.stringify(forbidden)}`;
37
+ }
38
+ }
39
+ if (!PROJECT_NAME_RE.test(name)) {
40
+ return "must match /^[a-z][a-z0-9_-]*$/i (npm-package-name rules: start with a letter, then letters / digits / `-` / `_`)";
41
+ }
42
+ return null;
43
+ }
44
+
45
+ export async function createProject(projectName, _options) {
46
+ const isCurrentDirectory = _options.currentDir;
47
+
48
+ // F17: name validation. Skipped when `--current-dir` because that
49
+ // path uses cwd, not the name, and is purely a display string then.
50
+ if (!isCurrentDirectory) {
51
+ const reason = validateProjectName(projectName);
52
+ if (reason) {
53
+ console.error(chalk.red(`✗ Invalid project name "${projectName}": ${reason}`));
54
+ process.exit(1);
55
+ }
56
+ }
57
+
58
+ const projectPath = isCurrentDirectory ? process.cwd() : path.resolve(process.cwd(), projectName);
59
+ const displayName = isCurrentDirectory ? "current directory" : projectName;
60
+
61
+ console.log(chalk.blue(`🚀 Creating ShipAPI project: ${projectName}`));
62
+ if (isCurrentDirectory) {
63
+ console.log(chalk.blue(`📁 Installing in current directory`));
64
+ }
65
+
66
+ // Check if directory already exists (only for new directories)
67
+ if (!isCurrentDirectory) {
68
+ try {
69
+ await fs.access(projectPath);
70
+ throw new Error(`Directory ${projectName} already exists`);
71
+ } catch (_error) {
72
+ if (_error.code !== "ENOENT") {
73
+ throw _error;
74
+ }
75
+ }
76
+
77
+ // Create project directory
78
+ await fs.mkdir(projectPath, { recursive: true });
79
+ }
80
+
81
+ // Copy template files
82
+ await copyTemplate(projectPath, _options.template);
83
+
84
+ // Process template placeholders
85
+ await processTemplateFiles(projectPath, projectName);
86
+
87
+ // Install dependencies
88
+ if (!_options.skipInstall) {
89
+ console.log(chalk.yellow("📦 Installing dependencies..."));
90
+ process.chdir(projectPath);
91
+ execSync("npm install", { stdio: "inherit" });
92
+ }
93
+
94
+ // Initialize git
95
+ if (!_options.skipGit) {
96
+ console.log(chalk.yellow("🔧 Initializing git repository..."));
97
+ try {
98
+ execSync("git init", { stdio: "inherit" });
99
+ execSync("git add .", { stdio: "inherit" });
100
+ execSync('git commit -m "Initial commit: ShipAPI project setup"', { stdio: "inherit" });
101
+ } catch (_error) {
102
+ console.log(chalk.yellow("⚠️ Git initialization failed, continuing..."));
103
+ }
104
+ }
105
+
106
+ console.log(chalk.green(`✅ Project "${projectName}" created successfully in ${displayName}!`));
107
+ console.log(chalk.cyan(`\nNext steps:`));
108
+ if (!isCurrentDirectory) {
109
+ console.log(chalk.cyan(` cd ${projectName}`));
110
+ }
111
+ console.log(chalk.cyan(` npx ship-api add accounts # Add authentication module`));
112
+ console.log(chalk.cyan(` npm run local`));
113
+ console.log(chalk.cyan(`\nDocumentation: https://github.com/SixthSummit/Ship`));
114
+ }
115
+
116
+ async function copyTemplate(projectPath, template) {
117
+ const templatePath = path.join(__dirname, "..", "..", "templates", template);
118
+
119
+ try {
120
+ await fs.access(templatePath);
121
+ } catch (_error) {
122
+ throw new Error(`Template '${template}' not found`);
123
+ }
124
+
125
+ await copyDirectory(templatePath, projectPath);
126
+ }
127
+
128
+ async function copyDirectory(src, dest) {
129
+ const entries = await fs.readdir(src, { withFileTypes: true });
130
+
131
+ for (const entry of entries) {
132
+ const srcPath = path.join(src, entry.name);
133
+ // npm strips .gitignore (and other dot-leading ignore files) during
134
+ // package publish — templates work around it by shipping
135
+ // `_gitignore` and renaming on scaffold. Same trick as
136
+ // `create-next-app` and friends. Generalized to `_<name>` → `.<name>`
137
+ // so future ignore-style files (`.npmignore`, `.dockerignore`, etc.)
138
+ // can use the same convention.
139
+ const destName = entry.name.startsWith("_") ? "." + entry.name.slice(1) : entry.name;
140
+ const destPath = path.join(dest, destName);
141
+
142
+ if (entry.isDirectory()) {
143
+ await fs.mkdir(destPath, { recursive: true });
144
+ await copyDirectory(srcPath, destPath);
145
+ } else {
146
+ await fs.copyFile(srcPath, destPath);
147
+ }
148
+ }
149
+ }
150
+
151
+ async function processTemplateFiles(projectPath, projectName) {
152
+ // Determine ship-api version to use
153
+ const shipApiVersion = await getShipApiVersion();
154
+ const observabilityVersion = await getBundledDependencyVersion(
155
+ "@sixthsummit/ship-observability-otel",
156
+ "observability-otel",
157
+ );
158
+ console.log(chalk.blue(`📦 Using @sixthsummit/ship-api version: ${shipApiVersion}`));
159
+
160
+ // Process package.json - parse as JSON and update fields
161
+ const packageJsonPath = path.join(projectPath, "package.json");
162
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8"));
163
+
164
+ packageJson.name = projectName;
165
+
166
+ // Insert @sixthsummit/ship-api at the beginning of dependencies, with
167
+ // the version resolved by getShipApiVersion(). Templates SHOULD NOT
168
+ // declare @sixthsummit/ship-api themselves — but defensively strip it
169
+ // from existingDeps before the spread so the explicit version wins
170
+ // (otherwise the template's stale literal overrides via property-key
171
+ // collision).
172
+ const {
173
+ "@sixthsummit/ship-api": _existingShipApi,
174
+ "@sixthsummit/ship-observability-otel": _existingObservability,
175
+ ...existingDeps
176
+ } = packageJson.dependencies ?? {};
177
+ packageJson.dependencies = {
178
+ "@sixthsummit/ship-api": shipApiVersion,
179
+ "@sixthsummit/ship-observability-otel": observabilityVersion,
180
+ ...existingDeps,
181
+ };
182
+
183
+ await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
184
+
185
+ // Process .env.example - update PROJECT_ROOT
186
+ const envExamplePath = path.join(projectPath, ".env.example");
187
+ try {
188
+ let envExample = await fs.readFile(envExamplePath, "utf8");
189
+ envExample = envExample.replace(/PROJECT_ROOT=.*/, `PROJECT_ROOT=${projectPath}`);
190
+ envExample = envExample.replace(
191
+ /DATABASE_URL=postgresql:\/\/username:password@localhost:5432\/.*/,
192
+ `DATABASE_URL=postgresql://username:password@localhost:5432/${projectName}`,
193
+ );
194
+ await fs.writeFile(envExamplePath, envExample);
195
+ } catch (_error) {
196
+ // .env.example might not exist, that's okay
197
+ }
198
+ }
199
+
200
+ async function getShipApiVersion() {
201
+ // Read ship-api's package.json to get current version
202
+ const shipApiPackageJsonPath = path.join(__dirname, "..", "..", "package.json");
203
+ const shipApiPackageJson = JSON.parse(await fs.readFile(shipApiPackageJsonPath, "utf8"));
204
+ const currentVersion = shipApiPackageJson.version;
205
+ const isPrerelease = currentVersion.includes("-"); // e.g., 3.0.0-beta.1
206
+
207
+ if (isPrerelease) {
208
+ // For prereleases (beta, rc), use caret range to allow updates to newer betas and stable
209
+ // ^3.0.0-beta.1 will match 3.0.0-beta.2, 3.0.0, 3.0.1, etc.
210
+ return `^${currentVersion}`;
211
+ }
212
+
213
+ // For stable releases, try to get the latest stable version from npm
214
+ try {
215
+ const latestVersion = execSync("npm view @sixthsummit/ship-api version", {
216
+ encoding: "utf8",
217
+ }).trim();
218
+ return `^${latestVersion}`;
219
+ } catch (_error) {
220
+ // If npm view fails, use current version
221
+ return `^${currentVersion}`;
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Resolve a package split out of the monolith to the version declared by the
227
+ * installed CLI. Published package manifests contain a normal semver range;
228
+ * the workspace fallback keeps local scaffold tests deterministic.
229
+ */
230
+ export async function getBundledDependencyVersion(packageName, workspaceDirectory) {
231
+ const shipApiPackageJsonPath = path.join(__dirname, "..", "..", "package.json");
232
+ const shipApiPackageJson = JSON.parse(await fs.readFile(shipApiPackageJsonPath, "utf8"));
233
+ const declared = shipApiPackageJson.dependencies?.[packageName];
234
+
235
+ if (typeof declared !== "string") {
236
+ throw new Error(`${packageName} is not declared by @sixthsummit/ship-api`);
237
+ }
238
+ if (!declared.startsWith("workspace:")) return declared;
239
+
240
+ const workspacePackageJsonPath = path.join(
241
+ __dirname,
242
+ "..",
243
+ "..",
244
+ "..",
245
+ workspaceDirectory,
246
+ "package.json",
247
+ );
248
+ const workspacePackageJson = JSON.parse(await fs.readFile(workspacePackageJsonPath, "utf8"));
249
+ return `^${workspacePackageJson.version}`;
250
+ }
@@ -0,0 +1,227 @@
1
+ import chalk from "chalk";
2
+ import { spawn } from "child_process";
3
+ import fs from "fs/promises";
4
+ import path from "path";
5
+
6
+ /**
7
+ * `ship-api dev` — local-stack orchestrator.
8
+ *
9
+ * Brings up the dependency containers (Postgres, Redis, optional OTel
10
+ * collector) via Docker Compose, then runs the project's dev script with
11
+ * hot reload, then polls a health endpoint until it goes green and prints
12
+ * the URL — the "new project just works" experience.
13
+ *
14
+ * --bare Skip Docker. Use this when Postgres/Redis are already running
15
+ * on the host (or you're shelling into a remote stack).
16
+ * --reset `docker compose down -v` before starting — drops volumes for
17
+ * a clean slate (and forces fresh migrations on next boot).
18
+ * --port Override the polled port (defaults to 3000 / $PORT).
19
+ *
20
+ * Implementation notes:
21
+ *
22
+ * • Compose file discovery: looks for `compose.yml`, `compose.yaml`,
23
+ * `docker-compose.yml`, `docker-compose.yaml` in cwd. If none, behaves
24
+ * as `--bare`.
25
+ * • Service selection: spins up *only* dependency services (`postgres`,
26
+ * `redis`, `jaeger`, `otel-collector`) — never the `api` service,
27
+ * since the point of `dev` is to run the app via `tsx watch` for
28
+ * hot reload. (`jaeger` is the v4 template's trace viewer; the
29
+ * legacy `otel-collector` name is kept for v3 / older v4 templates
30
+ * that haven't been updated.)
31
+ * • Health probe: tries `/livez`, then `/healthz`, then `/health-check`,
32
+ * then `/`. First non-5xx response wins. Polls every 500ms with a 60s
33
+ * timeout.
34
+ * • Signal handling: forwards SIGINT/SIGTERM to the npm child. Compose
35
+ * stays running so the next `dev` invocation reuses warm containers
36
+ * (use `--reset` to tear down explicitly).
37
+ */
38
+
39
+ const DEPENDENCY_SERVICES = ["postgres", "redis", "jaeger", "otel-collector"];
40
+ const HEALTH_PATHS = ["/livez", "/healthz", "/health-check", "/"];
41
+ const HEALTH_TIMEOUT_MS = 60_000;
42
+ const HEALTH_INTERVAL_MS = 500;
43
+
44
+ export async function devCommand(options = {}) {
45
+ const cwd = process.cwd();
46
+ const port = Number(options.port ?? process.env.PORT ?? 3000);
47
+ const useDocker = !options.bare;
48
+ const reset = Boolean(options.reset);
49
+
50
+ console.log(chalk.blue("🚀 ship-api dev"));
51
+
52
+ let composeFile = null;
53
+ if (useDocker) {
54
+ composeFile = await findComposeFile(cwd);
55
+ if (!composeFile) {
56
+ console.log(
57
+ chalk.yellow(
58
+ "⚠ no docker-compose.yml found — running in --bare mode (assumes Postgres/Redis are already up)",
59
+ ),
60
+ );
61
+ }
62
+ }
63
+
64
+ if (composeFile && reset) {
65
+ console.log(chalk.gray(`↻ docker compose down -v (${composeFile})`));
66
+ await runToCompletion("docker", ["compose", "-f", composeFile, "down", "-v"], { cwd });
67
+ }
68
+
69
+ if (composeFile) {
70
+ const services = await selectExistingServices(composeFile, cwd, DEPENDENCY_SERVICES);
71
+ if (services.length === 0) {
72
+ console.log(
73
+ chalk.yellow(
74
+ `⚠ ${composeFile} has no services matching ${DEPENDENCY_SERVICES.join(", ")} — skipping compose up`,
75
+ ),
76
+ );
77
+ } else {
78
+ console.log(chalk.gray(`↑ docker compose up -d ${services.join(" ")}`));
79
+ const composeUp = await runToCompletion(
80
+ "docker",
81
+ ["compose", "-f", composeFile, "up", "-d", ...services],
82
+ { cwd },
83
+ );
84
+ if (composeUp.code !== 0) {
85
+ throw new Error(`docker compose up failed (exit ${composeUp.code})`);
86
+ }
87
+ }
88
+ }
89
+
90
+ // Pick the dev script. Templates expose `local` (v3) or `dev` (v4).
91
+ const devScript = await pickDevScript(cwd);
92
+ console.log(chalk.gray(`▶ npm run ${devScript}`));
93
+
94
+ const npmChild = spawn("npm", ["run", devScript], {
95
+ cwd,
96
+ stdio: "inherit",
97
+ env: process.env,
98
+ });
99
+
100
+ let cleanedUp = false;
101
+ const cleanup = (signal) => {
102
+ if (cleanedUp) return;
103
+ cleanedUp = true;
104
+ if (!npmChild.killed) npmChild.kill(signal);
105
+ };
106
+ process.on("SIGINT", () => cleanup("SIGINT"));
107
+ process.on("SIGTERM", () => cleanup("SIGTERM"));
108
+
109
+ const childExit = new Promise((resolve) => {
110
+ npmChild.once("exit", (code, signal) => resolve({ code, signal }));
111
+ });
112
+
113
+ // Race the health probe vs. an early child exit.
114
+ const healthResult = await Promise.race([
115
+ pollHealth(`http://localhost:${port}`),
116
+ childExit.then((r) => ({ kind: "child-exited", ...r })),
117
+ ]);
118
+
119
+ if (healthResult.kind === "child-exited") {
120
+ throw new Error(
121
+ `dev process exited before becoming healthy (code=${healthResult.code} signal=${healthResult.signal})`,
122
+ );
123
+ }
124
+ if (!healthResult.ok) {
125
+ console.log(
126
+ chalk.yellow(
127
+ `⚠ ${healthResult.reason}. The server may still be starting — try opening http://localhost:${port} in a moment.`,
128
+ ),
129
+ );
130
+ } else {
131
+ console.log(
132
+ chalk.green(
133
+ `✓ healthy at http://localhost:${port}${healthResult.path} — opening in your browser`,
134
+ ),
135
+ );
136
+ }
137
+
138
+ // Stay attached to the npm child so logs flow until Ctrl+C.
139
+ const { code } = await childExit;
140
+ if (code !== 0 && code !== null) {
141
+ process.exitCode = code;
142
+ }
143
+ }
144
+
145
+ // Exported for tests. Internal helpers used by `devCommand`.
146
+ export const __test = {
147
+ findComposeFile: (...args) => findComposeFile(...args),
148
+ selectExistingServices: (...args) => selectExistingServices(...args),
149
+ pickDevScript: (...args) => pickDevScript(...args),
150
+ };
151
+
152
+ async function findComposeFile(cwd) {
153
+ const candidates = ["compose.yml", "compose.yaml", "docker-compose.yml", "docker-compose.yaml"];
154
+ for (const name of candidates) {
155
+ const full = path.join(cwd, name);
156
+ try {
157
+ await fs.access(full);
158
+ return name;
159
+ } catch {
160
+ // try next
161
+ }
162
+ }
163
+ return null;
164
+ }
165
+
166
+ async function selectExistingServices(composeFile, cwd, candidates) {
167
+ // Cheap parse — read the file and look for top-level service keys via
168
+ // the indent-aware regex `\n <name>:`. Avoids a YAML dep for a CLI tool.
169
+ const text = await fs.readFile(path.join(cwd, composeFile), "utf8");
170
+ const out = [];
171
+ for (const name of candidates) {
172
+ const re = new RegExp(`(?:^|\\n) ${escapeRegex(name)}:`, "m");
173
+ if (re.test(text)) out.push(name);
174
+ }
175
+ return out;
176
+ }
177
+
178
+ async function pickDevScript(cwd) {
179
+ const pkgPath = path.join(cwd, "package.json");
180
+ try {
181
+ const pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"));
182
+ const scripts = pkg.scripts ?? {};
183
+ if (scripts.dev) return "dev";
184
+ if (scripts.local) return "local";
185
+ if (scripts.start) return "start";
186
+ } catch {
187
+ // fall through
188
+ }
189
+ return "local";
190
+ }
191
+
192
+ async function pollHealth(baseUrl) {
193
+ const deadline = Date.now() + HEALTH_TIMEOUT_MS;
194
+ while (Date.now() < deadline) {
195
+ for (const p of HEALTH_PATHS) {
196
+ try {
197
+ const res = await fetch(`${baseUrl}${p}`, {
198
+ // Treat any 2xx/3xx/4xx as "the server is reachable enough".
199
+ // 5xx (or no response) keeps polling.
200
+ });
201
+ if (res.status < 500) {
202
+ return { kind: "healthy", ok: true, path: p, status: res.status };
203
+ }
204
+ } catch {
205
+ // connection refused / DNS / network — still booting
206
+ }
207
+ }
208
+ await new Promise((r) => setTimeout(r, HEALTH_INTERVAL_MS));
209
+ }
210
+ return {
211
+ kind: "healthy",
212
+ ok: false,
213
+ reason: `no health endpoint became reachable within ${HEALTH_TIMEOUT_MS / 1000}s`,
214
+ };
215
+ }
216
+
217
+ function runToCompletion(command, args, opts) {
218
+ return new Promise((resolve, reject) => {
219
+ const child = spawn(command, args, { ...opts, stdio: "inherit" });
220
+ child.once("error", reject);
221
+ child.once("exit", (code, signal) => resolve({ code, signal }));
222
+ });
223
+ }
224
+
225
+ function escapeRegex(s) {
226
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
227
+ }