@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,389 @@
1
+ import { encoding_for_model, get_encoding, type Tiktoken } from "tiktoken";
2
+ import type { SemanticChunkingOptions, TextChunk } from "../types/index.js";
3
+ import type { ChunkingStrategy } from "./ChunkingStrategy.js";
4
+
5
+ /**
6
+ * Semantic chunking strategy that creates chunks based on document structure
7
+ *
8
+ * Industry Best Practices Implemented:
9
+ * - Content-aware chunking using document structure
10
+ * - Preserves semantic units (paragraphs, sections, lists)
11
+ * - Handles code blocks, headers, and lists specially
12
+ * - Merges small chunks to avoid fragmentation
13
+ * - Maintains context through structural boundaries
14
+ *
15
+ * This approach is superior for RAG and embedding applications as it:
16
+ * - Preserves meaning and context better than fixed-size chunking
17
+ * - Avoids splitting related content
18
+ * - Improves retrieval accuracy
19
+ * - Maintains document hierarchy
20
+ */
21
+ export class SemanticChunkingStrategy implements ChunkingStrategy {
22
+ private encoder: Tiktoken;
23
+ private maxTokens: number;
24
+ private minTokens: number;
25
+ private mergeSmallChunks: boolean;
26
+
27
+ // Document structure patterns
28
+ private static readonly HEADER_PATTERN = /^#{1,6}\s+.+$|^.+\n[=-]{3,}$/gm;
29
+ private static readonly PARAGRAPH_BREAK = /\n\s*\n/g;
30
+ private static readonly CODE_BLOCK = /```[\s\S]*?```/g;
31
+ private static readonly LIST_PATTERN =
32
+ /(?:^|\n)(?:[\s]*[-*+•]\s+.+(?:\n(?![\s]*[-*+•]\s+).+)*)+/gm;
33
+ private static readonly NUMBERED_LIST =
34
+ /(?:^|\n)(?:[\s]*\d+\.\s+.+(?:\n(?![\s]*\d+\.\s+).+)*)+/gm;
35
+
36
+ constructor(options: SemanticChunkingOptions) {
37
+ this.maxTokens = options.maxTokens;
38
+ this.minTokens = options.minTokens ?? 100;
39
+ this.mergeSmallChunks = options.mergeSmallChunks ?? true;
40
+
41
+ // Validate options
42
+ if (this.minTokens >= this.maxTokens) {
43
+ throw new Error("minTokens must be less than maxTokens");
44
+ }
45
+
46
+ // Initialize the tokenizer
47
+ const encodingName = options.encoding || "cl100k_base";
48
+ try {
49
+ this.encoder = get_encoding(encodingName as any);
50
+ } catch {
51
+ this.encoder = encoding_for_model("gpt-3.5-turbo");
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Chunks the text based on semantic/structural boundaries
57
+ * @param text - The text to chunk
58
+ * @returns An array of semantically coherent chunks
59
+ */
60
+ async chunk(text: string): Promise<TextChunk[]> {
61
+ // Parse the document into semantic units
62
+ const semanticUnits = this.parseSemanticUnits(text);
63
+
64
+ // Group semantic units into chunks
65
+ const chunks = this.groupIntoChunks(semanticUnits, text);
66
+
67
+ return chunks;
68
+ }
69
+
70
+ /**
71
+ * Parses the document into semantic units (paragraphs, headers, code blocks, lists)
72
+ * @param text - The text to parse
73
+ * @returns Array of semantic units with their positions
74
+ */
75
+ private parseSemanticUnits(
76
+ text: string,
77
+ ): Array<{ content: string; startIndex: number; endIndex: number; type: string }> {
78
+ const units: Array<{ content: string; startIndex: number; endIndex: number; type: string }> =
79
+ [];
80
+
81
+ // Track which parts of text have been processed
82
+ const processed = new Array(text.length).fill(false);
83
+
84
+ // Extract code blocks first (highest priority to avoid splitting)
85
+ const codeBlocks = Array.from(text.matchAll(SemanticChunkingStrategy.CODE_BLOCK));
86
+ for (const match of codeBlocks) {
87
+ const startIndex = match.index!;
88
+ const content = match[0];
89
+ const endIndex = startIndex + content.length;
90
+
91
+ units.push({
92
+ content,
93
+ startIndex,
94
+ endIndex,
95
+ type: "code",
96
+ });
97
+
98
+ // Mark as processed
99
+ for (let i = startIndex; i < endIndex; i++) {
100
+ processed[i] = true;
101
+ }
102
+ }
103
+
104
+ // Extract numbered lists
105
+ const numberedLists = Array.from(text.matchAll(SemanticChunkingStrategy.NUMBERED_LIST));
106
+ for (const match of numberedLists) {
107
+ const startIndex = match.index!;
108
+ const content = match[0];
109
+ const endIndex = startIndex + content.length;
110
+
111
+ // Check if already processed (e.g., in code block)
112
+ if (!processed[startIndex]) {
113
+ units.push({
114
+ content: content.trim(),
115
+ startIndex,
116
+ endIndex,
117
+ type: "numbered_list",
118
+ });
119
+
120
+ for (let i = startIndex; i < endIndex; i++) {
121
+ processed[i] = true;
122
+ }
123
+ }
124
+ }
125
+
126
+ // Extract bullet lists
127
+ const lists = Array.from(text.matchAll(SemanticChunkingStrategy.LIST_PATTERN));
128
+ for (const match of lists) {
129
+ const startIndex = match.index!;
130
+ const content = match[0];
131
+ const endIndex = startIndex + content.length;
132
+
133
+ if (!processed[startIndex]) {
134
+ units.push({
135
+ content: content.trim(),
136
+ startIndex,
137
+ endIndex,
138
+ type: "list",
139
+ });
140
+
141
+ for (let i = startIndex; i < endIndex; i++) {
142
+ processed[i] = true;
143
+ }
144
+ }
145
+ }
146
+
147
+ // Split remaining text by paragraphs
148
+ let currentIndex = 0;
149
+ const paragraphs = text.split(SemanticChunkingStrategy.PARAGRAPH_BREAK);
150
+
151
+ for (const paragraph of paragraphs) {
152
+ const startIndex = text.indexOf(paragraph, currentIndex);
153
+ if (startIndex === -1) continue;
154
+
155
+ const endIndex = startIndex + paragraph.length;
156
+
157
+ // Check if this paragraph is already processed
158
+ const alreadyProcessed = processed.slice(startIndex, endIndex).some((p) => p);
159
+
160
+ if (!alreadyProcessed && paragraph.trim().length > 0) {
161
+ // Check if it's a header
162
+ const isHeader = SemanticChunkingStrategy.HEADER_PATTERN.test(paragraph);
163
+
164
+ units.push({
165
+ content: paragraph.trim(),
166
+ startIndex,
167
+ endIndex,
168
+ type: isHeader ? "header" : "paragraph",
169
+ });
170
+
171
+ for (let i = startIndex; i < endIndex; i++) {
172
+ processed[i] = true;
173
+ }
174
+ }
175
+
176
+ currentIndex = endIndex;
177
+ }
178
+
179
+ // Sort by start index
180
+ return units.sort((a, b) => a.startIndex - b.startIndex);
181
+ }
182
+
183
+ /**
184
+ * Groups semantic units into chunks that respect token limits
185
+ * @param units - The semantic units to group
186
+ * @param fullText - The full document text
187
+ * @returns Array of text chunks
188
+ */
189
+ private groupIntoChunks(
190
+ units: Array<{ content: string; startIndex: number; endIndex: number; type: string }>,
191
+ fullText: string,
192
+ ): TextChunk[] {
193
+ const chunks: TextChunk[] = [];
194
+ let currentChunk: string[] = [];
195
+ let currentTokenCount = 0;
196
+ let chunkStartIndex = 0;
197
+ let chunkIndex = 0;
198
+
199
+ for (let i = 0; i < units.length; i++) {
200
+ const unit = units[i];
201
+ const unitTokens = this.encoder.encode(unit.content).length;
202
+
203
+ // If this unit alone exceeds maxTokens, split it
204
+ if (unitTokens > this.maxTokens) {
205
+ // Save current chunk if not empty
206
+ if (currentChunk.length > 0) {
207
+ const chunkContent = currentChunk.join("\n\n");
208
+ chunks.push({
209
+ content: chunkContent,
210
+ startIndex: chunkStartIndex,
211
+ endIndex: chunkStartIndex + chunkContent.length,
212
+ tokenCount: currentTokenCount,
213
+ chunkIndex: chunkIndex++,
214
+ });
215
+ currentChunk = [];
216
+ currentTokenCount = 0;
217
+ }
218
+
219
+ // Split the large unit
220
+ const subChunks = this.splitLargeUnit(unit, fullText);
221
+ subChunks.forEach((subChunk) => {
222
+ chunks.push({
223
+ ...subChunk,
224
+ chunkIndex: chunkIndex++,
225
+ });
226
+ });
227
+
228
+ chunkStartIndex = unit.endIndex;
229
+ continue;
230
+ }
231
+
232
+ // Check if adding this unit would exceed maxTokens
233
+ if (currentTokenCount + unitTokens > this.maxTokens && currentChunk.length > 0) {
234
+ // Save current chunk
235
+ const chunkContent = currentChunk.join("\n\n");
236
+ chunks.push({
237
+ content: chunkContent,
238
+ startIndex: chunkStartIndex,
239
+ endIndex: chunkStartIndex + chunkContent.length,
240
+ tokenCount: currentTokenCount,
241
+ chunkIndex: chunkIndex++,
242
+ });
243
+
244
+ // Start new chunk
245
+ currentChunk = [unit.content];
246
+ currentTokenCount = unitTokens;
247
+ chunkStartIndex = unit.startIndex;
248
+ } else {
249
+ // Add to current chunk
250
+ if (currentChunk.length === 0) {
251
+ chunkStartIndex = unit.startIndex;
252
+ }
253
+ currentChunk.push(unit.content);
254
+ currentTokenCount += unitTokens;
255
+ }
256
+ }
257
+
258
+ // Add final chunk
259
+ if (currentChunk.length > 0) {
260
+ const chunkContent = currentChunk.join("\n\n");
261
+ chunks.push({
262
+ content: chunkContent,
263
+ startIndex: chunkStartIndex,
264
+ endIndex: chunkStartIndex + chunkContent.length,
265
+ tokenCount: currentTokenCount,
266
+ chunkIndex: chunkIndex++,
267
+ });
268
+ }
269
+
270
+ // Merge small chunks if enabled
271
+ if (this.mergeSmallChunks) {
272
+ return this.mergeSmallChunksInternal(chunks);
273
+ }
274
+
275
+ return chunks;
276
+ }
277
+
278
+ /**
279
+ * Splits a large semantic unit into smaller chunks
280
+ * @param unit - The unit to split
281
+ * @param fullText - The full document text
282
+ * @returns Array of chunks
283
+ */
284
+ private splitLargeUnit(
285
+ unit: { content: string; startIndex: number; endIndex: number; type: string },
286
+ _fullText: string,
287
+ ): Omit<TextChunk, "chunkIndex">[] {
288
+ const chunks: Omit<TextChunk, "chunkIndex">[] = [];
289
+
290
+ // Split by sentences for large units
291
+ const sentences = unit.content.split(/(?<=[.!?])\s+/);
292
+ let currentChunk: string[] = [];
293
+ let currentTokenCount = 0;
294
+ let sentenceStartIndex = unit.startIndex;
295
+
296
+ for (const sentence of sentences) {
297
+ const sentenceTokens = this.encoder.encode(sentence).length;
298
+
299
+ if (currentTokenCount + sentenceTokens > this.maxTokens && currentChunk.length > 0) {
300
+ const chunkContent = currentChunk.join(" ");
301
+ chunks.push({
302
+ content: chunkContent,
303
+ startIndex: sentenceStartIndex,
304
+ endIndex: sentenceStartIndex + chunkContent.length,
305
+ tokenCount: currentTokenCount,
306
+ });
307
+
308
+ currentChunk = [sentence];
309
+ currentTokenCount = sentenceTokens;
310
+ sentenceStartIndex += chunkContent.length + 1;
311
+ } else {
312
+ currentChunk.push(sentence);
313
+ currentTokenCount += sentenceTokens;
314
+ }
315
+ }
316
+
317
+ if (currentChunk.length > 0) {
318
+ const chunkContent = currentChunk.join(" ");
319
+ chunks.push({
320
+ content: chunkContent,
321
+ startIndex: sentenceStartIndex,
322
+ endIndex: sentenceStartIndex + chunkContent.length,
323
+ tokenCount: currentTokenCount,
324
+ });
325
+ }
326
+
327
+ return chunks;
328
+ }
329
+
330
+ /**
331
+ * Merges small chunks with adjacent chunks to avoid fragmentation
332
+ * Industry Best Practice: Avoid chunks smaller than minTokens
333
+ *
334
+ * @param chunks - The chunks to merge
335
+ * @returns Merged chunks
336
+ */
337
+ private mergeSmallChunksInternal(chunks: TextChunk[]): TextChunk[] {
338
+ if (chunks.length <= 1) return chunks;
339
+
340
+ const merged: TextChunk[] = [];
341
+ let i = 0;
342
+
343
+ while (i < chunks.length) {
344
+ const chunk = chunks[i];
345
+
346
+ // If chunk is too small and not the last one, try to merge with next
347
+ if (chunk.tokenCount < this.minTokens && i < chunks.length - 1) {
348
+ const nextChunk = chunks[i + 1];
349
+ const combinedTokenCount = chunk.tokenCount + nextChunk.tokenCount;
350
+
351
+ // Merge if combined size is acceptable
352
+ if (combinedTokenCount <= this.maxTokens) {
353
+ const mergedContent = `${chunk.content}\n\n${nextChunk.content}`;
354
+ merged.push({
355
+ content: mergedContent,
356
+ startIndex: chunk.startIndex,
357
+ endIndex: nextChunk.endIndex,
358
+ tokenCount: combinedTokenCount,
359
+ chunkIndex: merged.length,
360
+ });
361
+ i += 2; // Skip both chunks
362
+ continue;
363
+ }
364
+ }
365
+
366
+ // Add chunk as is
367
+ merged.push({
368
+ ...chunk,
369
+ chunkIndex: merged.length,
370
+ });
371
+ i++;
372
+ }
373
+
374
+ return merged;
375
+ }
376
+
377
+ /**
378
+ * Cleanup method to free the encoder
379
+ */
380
+ dispose(): void {
381
+ try {
382
+ if (this.encoder) {
383
+ this.encoder.free();
384
+ }
385
+ } catch {
386
+ // Encoder may have already been freed
387
+ }
388
+ }
389
+ }
@@ -0,0 +1,258 @@
1
+ import { encoding_for_model, get_encoding, type Tiktoken } from "tiktoken";
2
+ import type { SlidingWindowChunkingOptions, TextChunk } from "../types/index.js";
3
+ import type { ChunkingStrategy } from "./ChunkingStrategy.js";
4
+
5
+ /**
6
+ * Sliding window chunking strategy that creates overlapping chunks and respects semantic boundaries
7
+ *
8
+ * Industry Best Practices:
9
+ * - Respects paragraph boundaries (primary)
10
+ * - Respects sentence boundaries (fallback)
11
+ * - Improved sentence detection handling abbreviations, URLs, numbers
12
+ * - Configurable minimum chunk size
13
+ * - Avoids splitting semantic units
14
+ */
15
+ export class SlidingWindowChunkingStrategy implements ChunkingStrategy {
16
+ private encoder: Tiktoken;
17
+
18
+ // Paragraph boundary patterns (double newline or more)
19
+ private static readonly PARAGRAPH_ENDINGS = /\n\s*\n/g;
20
+
21
+ // Improved sentence boundary patterns that handle edge cases
22
+ // Handles: abbreviations, numbers, URLs, quotes, ellipsis
23
+ private static readonly SENTENCE_ENDINGS =
24
+ /(?<=[.!?])\s+(?=[A-Z])|(?<=[.!?]["'])\s+(?=[A-Z])|(?<=[.!?])\s*$/gm;
25
+
26
+ // Patterns for content that should not be split
27
+ private static readonly CODE_BLOCK = /```[\s\S]*?```|`[^`]+`/g;
28
+
29
+ private minChunkRatio: number;
30
+ private preferParagraphBoundaries: boolean;
31
+
32
+ constructor(private options: SlidingWindowChunkingOptions) {
33
+ // Validate options
34
+ if (options.overlapTokens >= options.maxTokens) {
35
+ throw new Error("overlapTokens must be less than maxTokens");
36
+ }
37
+
38
+ // Set configurable options with defaults
39
+ this.minChunkRatio = options.minChunkRatio ?? 0.5;
40
+ this.preferParagraphBoundaries = options.preferParagraphBoundaries ?? true;
41
+
42
+ // Validate minChunkRatio
43
+ if (this.minChunkRatio < 0.1 || this.minChunkRatio > 0.9) {
44
+ throw new Error("minChunkRatio must be between 0.1 and 0.9");
45
+ }
46
+
47
+ // Initialize the tokenizer with the specified encoding
48
+ const encodingName = options.encoding || "cl100k_base";
49
+ try {
50
+ this.encoder = get_encoding(encodingName as any);
51
+ } catch {
52
+ // Fallback to GPT-3.5/4 encoding
53
+ this.encoder = encoding_for_model("gpt-3.5-turbo");
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Chunks the text with sliding window approach and sentence boundary respect
59
+ * @param text - The text to chunk
60
+ * @returns An array of text chunks
61
+ */
62
+ async chunk(text: string): Promise<TextChunk[]> {
63
+ const chunks: TextChunk[] = [];
64
+
65
+ // Tokenize the entire text
66
+ const tokens = this.encoder.encode(text);
67
+ const maxTokens = this.options.maxTokens;
68
+ const overlapTokens = this.options.overlapTokens;
69
+ const stepSize = maxTokens - overlapTokens;
70
+
71
+ let chunkIndex = 0;
72
+ let currentPosition = 0;
73
+
74
+ while (currentPosition < tokens.length) {
75
+ // Get the chunk tokens
76
+ const chunkEndPosition = Math.min(currentPosition + maxTokens, tokens.length);
77
+ let chunkTokens: Uint32Array = tokens.slice(currentPosition, chunkEndPosition);
78
+
79
+ // Decode to text
80
+ const decoded = this.encoder.decode(chunkTokens);
81
+ let chunkText = typeof decoded === "string" ? decoded : new TextDecoder().decode(decoded);
82
+
83
+ // If this is not the last chunk, adjust to end at sentence boundary
84
+ if (chunkEndPosition < tokens.length) {
85
+ const adjustedChunk = this.adjustToSentenceBoundary(
86
+ chunkText,
87
+ chunkTokens,
88
+ text,
89
+ currentPosition,
90
+ );
91
+
92
+ if (adjustedChunk) {
93
+ chunkText = adjustedChunk.text;
94
+ chunkTokens = adjustedChunk.tokens as Uint32Array;
95
+ }
96
+ }
97
+
98
+ // Calculate character indices
99
+ const startIndex = this.getCharacterIndex(text, tokens, currentPosition);
100
+ const endIndex = startIndex + chunkText.length;
101
+
102
+ chunks.push({
103
+ content: chunkText,
104
+ startIndex,
105
+ endIndex,
106
+ tokenCount: chunkTokens.length,
107
+ chunkIndex: chunkIndex++,
108
+ });
109
+
110
+ // Move to next position with overlap
111
+ if (chunkEndPosition >= tokens.length) {
112
+ break; // We've reached the end
113
+ }
114
+
115
+ currentPosition += stepSize;
116
+ }
117
+
118
+ return chunks;
119
+ }
120
+
121
+ /**
122
+ * Adjusts the chunk to end at a semantic boundary (paragraph or sentence)
123
+ * Industry Best Practice: Prefer paragraph > sentence > word boundaries
124
+ *
125
+ * @param chunkText - The current chunk text
126
+ * @param chunkTokens - The current chunk tokens
127
+ * @param fullText - The full document text
128
+ * @param tokenStartPosition - The starting token position
129
+ * @returns Adjusted chunk or null if no adjustment needed
130
+ */
131
+ private adjustToSentenceBoundary(
132
+ chunkText: string,
133
+ _chunkTokens: Uint32Array,
134
+ _fullText: string,
135
+ _tokenStartPosition: number,
136
+ ): { text: string; tokens: Uint32Array } | null {
137
+ let boundaryPosition: number | null = null;
138
+
139
+ // Try to find a paragraph boundary first (best practice for semantic coherence)
140
+ if (this.preferParagraphBoundaries) {
141
+ boundaryPosition = this.findLastParagraphBoundary(chunkText);
142
+ if (boundaryPosition !== null && this.isValidBoundaryPosition(chunkText, boundaryPosition)) {
143
+ const adjustedText = chunkText.substring(0, boundaryPosition).trim();
144
+ const adjustedTokens = this.encoder.encode(adjustedText);
145
+ return {
146
+ text: adjustedText,
147
+ tokens: adjustedTokens,
148
+ };
149
+ }
150
+ }
151
+
152
+ // Fall back to sentence boundary if no paragraph boundary found
153
+ boundaryPosition = this.findLastSentenceBoundary(chunkText);
154
+ if (boundaryPosition !== null && this.isValidBoundaryPosition(chunkText, boundaryPosition)) {
155
+ const adjustedText = chunkText.substring(0, boundaryPosition).trim();
156
+ const adjustedTokens = this.encoder.encode(adjustedText);
157
+ return {
158
+ text: adjustedText,
159
+ tokens: adjustedTokens,
160
+ };
161
+ }
162
+
163
+ // No suitable boundary found, return original
164
+ return null;
165
+ }
166
+
167
+ /**
168
+ * Finds the last paragraph boundary in the text
169
+ * @param text - The text to search
170
+ * @returns The position of the last paragraph boundary, or null if none found
171
+ */
172
+ private findLastParagraphBoundary(text: string): number | null {
173
+ const matches = Array.from(text.matchAll(SlidingWindowChunkingStrategy.PARAGRAPH_ENDINGS));
174
+ if (matches.length === 0) return null;
175
+
176
+ const lastMatch = matches[matches.length - 1];
177
+ return lastMatch.index! + lastMatch[0].length;
178
+ }
179
+
180
+ /**
181
+ * Finds the last sentence boundary in the text
182
+ * Uses improved regex that handles abbreviations, URLs, and other edge cases
183
+ *
184
+ * @param text - The text to search
185
+ * @returns The position of the last sentence boundary, or null if none found
186
+ */
187
+ private findLastSentenceBoundary(text: string): number | null {
188
+ // Check if we're in the middle of a code block (should not split)
189
+ const codeBlocks = Array.from(text.matchAll(SlidingWindowChunkingStrategy.CODE_BLOCK));
190
+ const inCodeBlock = codeBlocks.some((match) => {
191
+ const matchEnd = match.index! + match[0].length;
192
+ return matchEnd > text.length * 0.8; // Last 20% is in code block
193
+ });
194
+
195
+ if (inCodeBlock) return null;
196
+
197
+ // Find sentence boundaries
198
+ const matches = Array.from(text.matchAll(SlidingWindowChunkingStrategy.SENTENCE_ENDINGS));
199
+ if (matches.length === 0) return null;
200
+
201
+ // Get the last match
202
+ const lastMatch = matches[matches.length - 1];
203
+ return lastMatch.index! + lastMatch[0].length;
204
+ }
205
+
206
+ /**
207
+ * Validates if a boundary position results in a chunk of acceptable size
208
+ * Industry Best Practice: Chunks should be at least minChunkRatio of target size
209
+ *
210
+ * @param text - The full chunk text
211
+ * @param boundaryPosition - The proposed boundary position
212
+ * @returns True if the boundary position is valid
213
+ */
214
+ private isValidBoundaryPosition(text: string, boundaryPosition: number): boolean {
215
+ // Ensure the resulting chunk is not too small
216
+ if (boundaryPosition < text.length * this.minChunkRatio) {
217
+ return false;
218
+ }
219
+
220
+ // Ensure we're not cutting off a tiny amount (less than 10 characters)
221
+ if (text.length - boundaryPosition < 10) {
222
+ return true; // Close enough to the end
223
+ }
224
+
225
+ return true;
226
+ }
227
+
228
+ /**
229
+ * Helper method to get the character index from a token index
230
+ * @param text - The original text
231
+ * @param tokens - All tokens
232
+ * @param tokenIndex - The token index to convert
233
+ * @returns The character index
234
+ */
235
+ private getCharacterIndex(text: string, tokens: Uint32Array, tokenIndex: number): number {
236
+ if (tokenIndex === 0) return 0;
237
+
238
+ // Decode tokens up to the target index to find character position
239
+ const tokensUpToIndex = tokens.slice(0, tokenIndex);
240
+ const decoded = this.encoder.decode(tokensUpToIndex);
241
+ const decodedUpToIndex =
242
+ typeof decoded === "string" ? decoded : new TextDecoder().decode(decoded);
243
+ return decodedUpToIndex.length;
244
+ }
245
+
246
+ /**
247
+ * Cleanup method to free the encoder
248
+ */
249
+ dispose(): void {
250
+ try {
251
+ if (this.encoder) {
252
+ this.encoder.free();
253
+ }
254
+ } catch {
255
+ // Encoder may have already been freed
256
+ }
257
+ }
258
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Represents a chunk of text with metadata
3
+ */
4
+ export interface TextChunk {
5
+ /** The text content of the chunk */
6
+ content: string;
7
+ /** The starting character index in the original document */
8
+ startIndex: number;
9
+ /** The ending character index in the original document */
10
+ endIndex: number;
11
+ /** The token count of the chunk */
12
+ tokenCount: number;
13
+ /** The chunk number (0-indexed) */
14
+ chunkIndex: number;
15
+ }
16
+
17
+ /**
18
+ * Configuration options for fixed length chunking
19
+ */
20
+ export interface FixedLengthChunkingOptions {
21
+ /** The maximum number of tokens per chunk */
22
+ maxTokens: number;
23
+ /** The encoding to use for token counting (default: 'cl100k_base' for GPT-3.5/4) */
24
+ encoding?: string;
25
+ }
26
+
27
+ /**
28
+ * Configuration options for sliding window chunking
29
+ */
30
+ export interface SlidingWindowChunkingOptions {
31
+ /** The maximum number of tokens per chunk */
32
+ maxTokens: number;
33
+ /** The number of overlapping tokens between chunks */
34
+ overlapTokens: number;
35
+ /** The encoding to use for token counting (default: 'cl100k_base' for GPT-3.5/4) */
36
+ encoding?: string;
37
+ /** Minimum chunk size as a ratio of maxTokens (default: 0.5 = 50%) */
38
+ minChunkRatio?: number;
39
+ /** Prefer paragraph boundaries over sentence boundaries (default: true) */
40
+ preferParagraphBoundaries?: boolean;
41
+ }
42
+
43
+ /**
44
+ * Configuration options for semantic chunking
45
+ */
46
+ export interface SemanticChunkingOptions {
47
+ /** The maximum number of tokens per chunk */
48
+ maxTokens: number;
49
+ /** The minimum number of tokens per chunk (default: 100) */
50
+ minTokens?: number;
51
+ /** The encoding to use for token counting (default: 'cl100k_base') */
52
+ encoding?: string;
53
+ /** Whether to merge small chunks with adjacent chunks (default: true) */
54
+ mergeSmallChunks?: boolean;
55
+ }
56
+
57
+ /**
58
+ * Union type for all chunking options
59
+ */
60
+ export type ChunkingOptions =
61
+ | FixedLengthChunkingOptions
62
+ | SlidingWindowChunkingOptions
63
+ | SemanticChunkingOptions;