@headless-lms/server 0.2.0 → 0.3.0

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 (339) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +5 -0
  2. package/dist/app/community-mail.d.ts +26 -0
  3. package/dist/app/community-mail.js +96 -0
  4. package/dist/app/community-mail.js.map +1 -0
  5. package/dist/app/container.d.ts +18 -14
  6. package/dist/app/container.js +136 -43
  7. package/dist/app/container.js.map +1 -1
  8. package/dist/app/mcp-endpoints.d.ts +13 -0
  9. package/dist/app/mcp-endpoints.js +25 -0
  10. package/dist/app/mcp-endpoints.js.map +1 -0
  11. package/dist/http/config.d.ts +2 -1
  12. package/dist/http/errors.d.ts +14 -0
  13. package/dist/http/errors.js +147 -0
  14. package/dist/http/errors.js.map +1 -0
  15. package/dist/http/mcp/catalogue.d.ts +37 -0
  16. package/dist/http/mcp/catalogue.js +69 -0
  17. package/dist/http/mcp/catalogue.js.map +1 -0
  18. package/dist/http/mcp/challenge.d.ts +7 -0
  19. package/dist/http/mcp/challenge.js +35 -0
  20. package/dist/http/mcp/challenge.js.map +1 -0
  21. package/dist/http/mcp/input-schema.d.ts +7 -0
  22. package/dist/http/mcp/input-schema.js +28 -0
  23. package/dist/http/mcp/input-schema.js.map +1 -0
  24. package/dist/http/mcp/route.d.ts +8 -0
  25. package/dist/http/mcp/route.js +75 -0
  26. package/dist/http/mcp/route.js.map +1 -0
  27. package/dist/http/mcp/server.d.ts +8 -0
  28. package/dist/http/mcp/server.js +31 -0
  29. package/dist/http/mcp/server.js.map +1 -0
  30. package/dist/http/mcp/test-support.d.ts +55 -0
  31. package/dist/http/mcp/test-support.js +151 -0
  32. package/dist/http/mcp/test-support.js.map +1 -0
  33. package/dist/http/mcp/tool.d.ts +48 -0
  34. package/dist/http/mcp/tool.js +58 -0
  35. package/dist/http/mcp/tool.js.map +1 -0
  36. package/dist/http/mcp/tools/automations.d.ts +6 -0
  37. package/dist/http/mcp/tools/automations.js +120 -0
  38. package/dist/http/mcp/tools/automations.js.map +1 -0
  39. package/dist/http/mcp/tools/catalog.d.ts +6 -0
  40. package/dist/http/mcp/tools/catalog.js +200 -0
  41. package/dist/http/mcp/tools/catalog.js.map +1 -0
  42. package/dist/http/mcp/tools/comments.d.ts +6 -0
  43. package/dist/http/mcp/tools/comments.js +70 -0
  44. package/dist/http/mcp/tools/comments.js.map +1 -0
  45. package/dist/http/mcp/tools/communities.d.ts +6 -0
  46. package/dist/http/mcp/tools/communities.js +175 -0
  47. package/dist/http/mcp/tools/communities.js.map +1 -0
  48. package/dist/http/mcp/tools/community-members.d.ts +6 -0
  49. package/dist/http/mcp/tools/community-members.js +89 -0
  50. package/dist/http/mcp/tools/community-members.js.map +1 -0
  51. package/dist/http/mcp/tools/community-moderation.d.ts +6 -0
  52. package/dist/http/mcp/tools/community-moderation.js +144 -0
  53. package/dist/http/mcp/tools/community-moderation.js.map +1 -0
  54. package/dist/http/mcp/tools/courses.d.ts +6 -0
  55. package/dist/http/mcp/tools/courses.js +121 -0
  56. package/dist/http/mcp/tools/courses.js.map +1 -0
  57. package/dist/http/mcp/tools/index.d.ts +6 -0
  58. package/dist/http/mcp/tools/index.js +23 -0
  59. package/dist/http/mcp/tools/index.js.map +1 -0
  60. package/dist/http/mcp/tools/people.d.ts +6 -0
  61. package/dist/http/mcp/tools/people.js +145 -0
  62. package/dist/http/mcp/tools/people.js.map +1 -0
  63. package/dist/http/plugins/auth.js +13 -5
  64. package/dist/http/plugins/auth.js.map +1 -1
  65. package/dist/http/plugins/error-handler.d.ts +2 -1
  66. package/dist/http/plugins/error-handler.js +49 -65
  67. package/dist/http/plugins/error-handler.js.map +1 -1
  68. package/dist/http/plugins/openapi.js +49 -2
  69. package/dist/http/plugins/openapi.js.map +1 -1
  70. package/dist/http/routes/access.d.ts +7 -0
  71. package/dist/http/routes/access.js +140 -0
  72. package/dist/http/routes/access.js.map +1 -0
  73. package/dist/http/routes/activities.js +68 -23
  74. package/dist/http/routes/activities.js.map +1 -1
  75. package/dist/http/routes/assets.js +60 -55
  76. package/dist/http/routes/assets.js.map +1 -1
  77. package/dist/http/routes/automations.js +44 -24
  78. package/dist/http/routes/automations.js.map +1 -1
  79. package/dist/http/routes/bundles.js +29 -18
  80. package/dist/http/routes/bundles.js.map +1 -1
  81. package/dist/http/routes/communities.d.ts +7 -0
  82. package/dist/http/routes/communities.js +462 -0
  83. package/dist/http/routes/communities.js.map +1 -0
  84. package/dist/http/routes/community-moderation.d.ts +7 -0
  85. package/dist/http/routes/community-moderation.js +425 -0
  86. package/dist/http/routes/community-moderation.js.map +1 -0
  87. package/dist/http/routes/course-analytics.js +9 -7
  88. package/dist/http/routes/course-analytics.js.map +1 -1
  89. package/dist/http/routes/courses.js +30 -15
  90. package/dist/http/routes/courses.js.map +1 -1
  91. package/dist/http/routes/dashboard.js +15 -6
  92. package/dist/http/routes/dashboard.js.map +1 -1
  93. package/dist/http/routes/discussion.js +34 -26
  94. package/dist/http/routes/discussion.js.map +1 -1
  95. package/dist/http/routes/downloads.js +48 -30
  96. package/dist/http/routes/downloads.js.map +1 -1
  97. package/dist/http/routes/entitlements.js +16 -7
  98. package/dist/http/routes/entitlements.js.map +1 -1
  99. package/dist/http/routes/integrations.js +38 -41
  100. package/dist/http/routes/integrations.js.map +1 -1
  101. package/dist/http/routes/member/actor.d.ts +14 -0
  102. package/dist/http/routes/member/actor.js +11 -0
  103. package/dist/http/routes/member/actor.js.map +1 -0
  104. package/dist/http/routes/member/assets.d.ts +7 -0
  105. package/dist/http/routes/member/assets.js +79 -0
  106. package/dist/http/routes/member/assets.js.map +1 -0
  107. package/dist/http/routes/member/chats.d.ts +7 -0
  108. package/dist/http/routes/member/chats.js +456 -0
  109. package/dist/http/routes/member/chats.js.map +1 -0
  110. package/dist/http/routes/member/comments.d.ts +7 -0
  111. package/dist/http/routes/member/comments.js +187 -0
  112. package/dist/http/routes/member/comments.js.map +1 -0
  113. package/dist/http/routes/member/community.d.ts +7 -0
  114. package/dist/http/routes/member/community.js +288 -0
  115. package/dist/http/routes/member/community.js.map +1 -0
  116. package/dist/http/routes/member/courses.d.ts +7 -0
  117. package/dist/http/routes/member/courses.js +101 -0
  118. package/dist/http/routes/member/courses.js.map +1 -0
  119. package/dist/http/routes/member/downloads.d.ts +7 -0
  120. package/dist/http/routes/member/downloads.js +56 -0
  121. package/dist/http/routes/member/downloads.js.map +1 -0
  122. package/dist/http/routes/member/files.d.ts +7 -0
  123. package/dist/http/routes/member/files.js +184 -0
  124. package/dist/http/routes/member/files.js.map +1 -0
  125. package/dist/http/routes/member/index.d.ts +7 -0
  126. package/dist/http/routes/member/index.js +31 -0
  127. package/dist/http/routes/member/index.js.map +1 -0
  128. package/dist/http/routes/member/notifications.d.ts +7 -0
  129. package/dist/http/routes/member/notifications.js +101 -0
  130. package/dist/http/routes/member/notifications.js.map +1 -0
  131. package/dist/http/routes/member/org.d.ts +7 -0
  132. package/dist/http/routes/member/org.js +56 -0
  133. package/dist/http/routes/member/org.js.map +1 -0
  134. package/dist/http/routes/member/posts.d.ts +7 -0
  135. package/dist/http/routes/member/posts.js +612 -0
  136. package/dist/http/routes/member/posts.js.map +1 -0
  137. package/dist/http/routes/member/profile.d.ts +7 -0
  138. package/dist/http/routes/member/profile.js +48 -0
  139. package/dist/http/routes/member/profile.js.map +1 -0
  140. package/dist/http/routes/member/progress.d.ts +7 -0
  141. package/dist/http/routes/member/progress.js +60 -0
  142. package/dist/http/routes/member/progress.js.map +1 -0
  143. package/dist/http/routes/organizations.js +49 -24
  144. package/dist/http/routes/organizations.js.map +1 -1
  145. package/dist/http/routes/students.js +32 -47
  146. package/dist/http/routes/students.js.map +1 -1
  147. package/dist/http/routes/webhooks.js +26 -18
  148. package/dist/http/routes/webhooks.js.map +1 -1
  149. package/dist/http/routes.js +8 -2
  150. package/dist/http/routes.js.map +1 -1
  151. package/dist/http/schemas/access.d.ts +146 -0
  152. package/dist/http/schemas/access.js +36 -0
  153. package/dist/http/schemas/access.js.map +1 -0
  154. package/dist/http/schemas/activities.d.ts +3 -1
  155. package/dist/http/schemas/activities.js +4 -4
  156. package/dist/http/schemas/activities.js.map +1 -1
  157. package/dist/http/schemas/assets.d.ts +73 -74
  158. package/dist/http/schemas/assets.js +23 -13
  159. package/dist/http/schemas/assets.js.map +1 -1
  160. package/dist/http/schemas/automations.d.ts +10 -0
  161. package/dist/http/schemas/bundles.js +6 -6
  162. package/dist/http/schemas/bundles.js.map +1 -1
  163. package/dist/http/schemas/chats.d.ts +386 -0
  164. package/dist/http/schemas/chats.js +58 -0
  165. package/dist/http/schemas/chats.js.map +1 -0
  166. package/dist/http/schemas/community.d.ts +537 -0
  167. package/dist/http/schemas/community.js +129 -0
  168. package/dist/http/schemas/community.js.map +1 -0
  169. package/dist/http/schemas/content.d.ts +4 -2
  170. package/dist/http/schemas/content.js +11 -8
  171. package/dist/http/schemas/content.js.map +1 -1
  172. package/dist/http/schemas/discussion.d.ts +76 -14
  173. package/dist/http/schemas/discussion.js +12 -11
  174. package/dist/http/schemas/discussion.js.map +1 -1
  175. package/dist/http/schemas/downloads.d.ts +11 -5
  176. package/dist/http/schemas/downloads.js +14 -11
  177. package/dist/http/schemas/downloads.js.map +1 -1
  178. package/dist/http/schemas/entitlements.d.ts +6 -6
  179. package/dist/http/schemas/entitlements.js +6 -6
  180. package/dist/http/schemas/entitlements.js.map +1 -1
  181. package/dist/http/schemas/files.d.ts +45 -0
  182. package/dist/http/schemas/files.js +25 -0
  183. package/dist/http/schemas/files.js.map +1 -0
  184. package/dist/http/schemas/index.d.ts +15 -8
  185. package/dist/http/schemas/index.js +15 -8
  186. package/dist/http/schemas/integrations.d.ts +2 -2
  187. package/dist/http/schemas/invites.d.ts +4 -0
  188. package/dist/http/schemas/invites.js +1 -0
  189. package/dist/http/schemas/invites.js.map +1 -1
  190. package/dist/http/schemas/{learn.d.ts → member.d.ts} +31 -18
  191. package/dist/http/schemas/{learn.js → member.js} +17 -13
  192. package/dist/http/schemas/member.js.map +1 -0
  193. package/dist/http/schemas/members.d.ts +39 -6
  194. package/dist/http/schemas/members.js +17 -3
  195. package/dist/http/schemas/members.js.map +1 -1
  196. package/dist/http/schemas/notifications.d.ts +227 -0
  197. package/dist/http/schemas/notifications.js +44 -0
  198. package/dist/http/schemas/notifications.js.map +1 -0
  199. package/dist/http/schemas/posts.d.ts +316 -0
  200. package/dist/http/schemas/posts.js +47 -0
  201. package/dist/http/schemas/posts.js.map +1 -0
  202. package/dist/http/schemas/profile.d.ts +23 -0
  203. package/dist/http/schemas/profile.js +15 -0
  204. package/dist/http/schemas/profile.js.map +1 -0
  205. package/dist/http/schemas/shared.d.ts +25 -1
  206. package/dist/http/schemas/shared.js +19 -2
  207. package/dist/http/schemas/shared.js.map +1 -1
  208. package/dist/http/schemas/students.d.ts +4 -10
  209. package/dist/http/schemas/students.js +1 -7
  210. package/dist/http/schemas/students.js.map +1 -1
  211. package/dist/http/scope.d.ts +2 -1
  212. package/dist/http/scope.js +20 -4
  213. package/dist/http/scope.js.map +1 -1
  214. package/dist/http/server.js +6 -1
  215. package/dist/http/server.js.map +1 -1
  216. package/dist/http/web-bridge.d.ts +1 -1
  217. package/dist/http/web-bridge.js +2 -2
  218. package/dist/http/web-bridge.js.map +1 -1
  219. package/dist/http/well-known.d.ts +7 -0
  220. package/dist/http/well-known.js +22 -0
  221. package/dist/http/well-known.js.map +1 -0
  222. package/dist/index.d.ts +2 -1
  223. package/dist/index.js +4 -2
  224. package/dist/index.js.map +1 -1
  225. package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +78 -0
  226. package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js.map +1 -0
  227. package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js +1267 -0
  228. package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js.map +1 -0
  229. package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js +814 -0
  230. package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js.map +1 -0
  231. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js +43 -0
  232. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js.map +1 -0
  233. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js +527 -0
  234. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js.map +1 -0
  235. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/utils.js +2 -0
  236. package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js +1737 -0
  237. package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js.map +1 -0
  238. package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js +137 -0
  239. package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js.map +1 -0
  240. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +118 -0
  241. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js.map +1 -0
  242. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js +1222 -0
  243. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js.map +1 -0
  244. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js +91 -0
  245. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js.map +1 -0
  246. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js +113 -0
  247. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js.map +1 -0
  248. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js +449 -0
  249. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js.map +1 -0
  250. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js +163 -0
  251. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js.map +1 -0
  252. package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js +3187 -0
  253. package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js.map +1 -0
  254. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js +11 -0
  255. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js.map +1 -0
  256. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js +16 -0
  257. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js.map +1 -0
  258. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js +11 -0
  259. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js.map +1 -0
  260. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js +15 -0
  261. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js.map +1 -0
  262. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js +13 -0
  263. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js.map +1 -0
  264. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js +34 -0
  265. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js.map +1 -0
  266. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js +12 -0
  267. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js.map +1 -0
  268. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js +122 -0
  269. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js.map +1 -0
  270. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js +39 -0
  271. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js.map +1 -0
  272. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js +99 -0
  273. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js.map +1 -0
  274. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js +25 -0
  275. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js.map +1 -0
  276. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js +14 -0
  277. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js.map +1 -0
  278. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js +21 -0
  279. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js.map +1 -0
  280. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js +6 -0
  281. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js.map +1 -0
  282. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js +12 -0
  283. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js.map +1 -0
  284. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js +18 -0
  285. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js.map +1 -0
  286. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js +24 -0
  287. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js.map +1 -0
  288. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js +9 -0
  289. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js.map +1 -0
  290. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js +30 -0
  291. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js.map +1 -0
  292. package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +939 -0
  293. package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js.map +1 -0
  294. package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js +82 -0
  295. package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js.map +1 -0
  296. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +82 -0
  297. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js.map +1 -0
  298. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js +8 -0
  299. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js.map +1 -0
  300. package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js +83 -0
  301. package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js.map +1 -0
  302. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js +9 -0
  303. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js.map +1 -0
  304. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/date.W2xKR2qe.js +51 -0
  305. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/date.W2xKR2qe.js.map +1 -0
  306. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/utils.C8RiOc4B.js +48 -0
  307. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/utils.C8RiOc4B.js.map +1 -0
  308. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/vi.DgezovHB.js +2426 -0
  309. package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/vi.DgezovHB.js.map +1 -0
  310. package/dist/packages/server/package.js +6 -0
  311. package/dist/packages/server/package.js.map +1 -0
  312. package/package.json +9 -7
  313. package/dist/app/notifications.d.ts +0 -7
  314. package/dist/app/notifications.js +0 -26
  315. package/dist/app/notifications.js.map +0 -1
  316. package/dist/http/routes/learn/assets.d.ts +0 -8
  317. package/dist/http/routes/learn/assets.js +0 -32
  318. package/dist/http/routes/learn/assets.js.map +0 -1
  319. package/dist/http/routes/learn/comments.d.ts +0 -7
  320. package/dist/http/routes/learn/comments.js +0 -175
  321. package/dist/http/routes/learn/comments.js.map +0 -1
  322. package/dist/http/routes/learn/courses.d.ts +0 -7
  323. package/dist/http/routes/learn/courses.js +0 -98
  324. package/dist/http/routes/learn/courses.js.map +0 -1
  325. package/dist/http/routes/learn/downloads.d.ts +0 -7
  326. package/dist/http/routes/learn/downloads.js +0 -76
  327. package/dist/http/routes/learn/downloads.js.map +0 -1
  328. package/dist/http/routes/learn/index.d.ts +0 -7
  329. package/dist/http/routes/learn/index.js +0 -19
  330. package/dist/http/routes/learn/index.js.map +0 -1
  331. package/dist/http/routes/learn/org.d.ts +0 -7
  332. package/dist/http/routes/learn/org.js +0 -50
  333. package/dist/http/routes/learn/org.js.map +0 -1
  334. package/dist/http/routes/learn/progress.d.ts +0 -7
  335. package/dist/http/routes/learn/progress.js +0 -63
  336. package/dist/http/routes/learn/progress.js.map +0 -1
  337. package/dist/http/schemas/learn.js.map +0 -1
  338. package/dist/package.js +0 -6
  339. package/dist/package.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
4
+ //#endregion
5
+ export { __require };
@@ -0,0 +1,26 @@
1
+ import { ContentService } from "@headless-lms/core/content";
2
+ import { EntitlementsService } from "@headless-lms/core/entitlements";
3
+ import { ChatService, DiscussionService, PostService } from "@headless-lms/core/discussion";
4
+ import { IdentityService } from "@headless-lms/core/identity";
5
+ import { OrganizationService } from "@headless-lms/core/organizations";
6
+ import { AssetsService } from "@headless-lms/core/assets";
7
+ import { CommunityMailReads, GrantWriter, ScheduledWork } from "@headless-lms/core/automations";
8
+ //#region src/app/community-mail.d.ts
9
+ type CommunityMailDeps = {
10
+ content: Pick<ContentService, 'getCommunity' | 'getSpace' | 'listCommunitiesById'>;
11
+ entitlements: Pick<EntitlementsService, 'openSpacesFor' | 'communitiesOpenedBy' | 'communityMembersAmong' | 'spaceOpenersAmong' | 'spaceOpeners' | 'communityModeratorIds' | 'countActiveSpaceMembers' | 'communityIdsOpenedFor' | 'ensureGrant' | 'expireDue' | 'hasDueNotices'>;
12
+ organizations: Pick<OrganizationService, 'getOrgUserById' | 'staffOrgUserIds'>;
13
+ identity: Pick<IdentityService, 'displayName'>;
14
+ posts: Pick<PostService, 'followerIds' | 'find' | 'publishDue' | 'hasDue'>;
15
+ discussion: Pick<DiscussionService, 'getComment' | 'sendDigest'>;
16
+ chats: Pick<ChatService, 'chatSummary' | 'latestMessageBody' | 'isBlocked'>;
17
+ assets: Pick<AssetsService, 'removeUnattached' | 'hasUnattached'>;
18
+ };
19
+ declare function communityMail(deps: CommunityMailDeps): {
20
+ mail: Omit<CommunityMailReads, 'recentMessageRecipients'>;
21
+ grants: GrantWriter;
22
+ scheduledWork: ScheduledWork;
23
+ };
24
+ //#endregion
25
+ export { CommunityMailDeps, communityMail };
26
+ //# sourceMappingURL=community-mail.d.ts.map
@@ -0,0 +1,96 @@
1
+ //#region src/app/community-mail.ts
2
+ function communityMail(deps) {
3
+ return {
4
+ mail: {
5
+ async communityTitle(orgId, communityId) {
6
+ return (await deps.content.getCommunity(orgId, communityId))?.title ?? null;
7
+ },
8
+ async space(orgId, spaceId) {
9
+ const space = await deps.content.getSpace(orgId, spaceId);
10
+ return space ? {
11
+ name: space.name,
12
+ communityId: space.communityId,
13
+ capacity: space.capacity
14
+ } : null;
15
+ },
16
+ async openSpaceNames(orgId, orgUserId, communityId) {
17
+ const orgUser = await deps.organizations.getOrgUserById(orgId, orgUserId);
18
+ if (!orgUser) return [];
19
+ return (await deps.entitlements.openSpacesFor(orgId, {
20
+ id: orgUser.id,
21
+ role: orgUser.role
22
+ }, communityId)).map((space) => space.name);
23
+ },
24
+ communitiesOpenedBy: (orgId, grant) => deps.entitlements.communitiesOpenedBy(orgId, grant),
25
+ communityMembersAmong: (orgId, communityId, ids) => deps.entitlements.communityMembersAmong(orgId, communityId, ids),
26
+ spaceOpenersAmong: (orgId, spaceId, ids) => deps.entitlements.spaceOpenersAmong(orgId, spaceId, ids),
27
+ spaceOpeners: (orgId, spaceId) => deps.entitlements.spaceOpeners(orgId, spaceId),
28
+ moderationAudience: (orgId, communityId) => deps.entitlements.communityModeratorIds(orgId, communityId),
29
+ staffIds: (orgId) => deps.organizations.staffOrgUserIds(orgId),
30
+ async displayName(orgId, orgUserId) {
31
+ const orgUser = await deps.organizations.getOrgUserById(orgId, orgUserId);
32
+ return deps.identity.displayName(orgUser?.userId ?? null);
33
+ },
34
+ followerIds: (orgId, postId) => deps.posts.followerIds(orgId, postId),
35
+ async comment(orgId, commentId) {
36
+ const comment = await deps.discussion.getComment(orgId, commentId);
37
+ return comment ? {
38
+ orgUserId: comment.orgUserId,
39
+ postId: comment.postId,
40
+ body: comment.body
41
+ } : null;
42
+ },
43
+ async post(orgId, postId) {
44
+ const post = await deps.posts.find(orgId, postId);
45
+ return post ? {
46
+ title: post.title,
47
+ body: post.body,
48
+ spaceId: post.spaceId,
49
+ orgUserId: post.orgUserId,
50
+ communityId: post.communityId
51
+ } : null;
52
+ },
53
+ async chat(orgId, chatId) {
54
+ const summary = await deps.chats.chatSummary(orgId, chatId);
55
+ return summary ? {
56
+ communityId: summary.chat.communityId,
57
+ kind: summary.chat.kind,
58
+ status: summary.chat.status,
59
+ createdBy: summary.chat.createdBy,
60
+ participants: summary.participants.map((participant) => ({
61
+ orgUserId: participant.orgUserId,
62
+ muted: participant.muted,
63
+ mutedUntil: participant.mutedUntil,
64
+ leftAt: participant.leftAt
65
+ }))
66
+ } : null;
67
+ },
68
+ latestMessageBody: (orgId, chatId) => deps.chats.latestMessageBody(orgId, chatId),
69
+ pairBlocked: (orgId, communityId, a, b) => deps.chats.isBlocked(orgId, communityId, a, b),
70
+ activeMemberCount: (orgId, spaceId) => deps.entitlements.countActiveSpaceMembers(orgId, spaceId),
71
+ async memberCommunityTitles(orgId, orgUserId) {
72
+ const ids = await deps.entitlements.communityIdsOpenedFor(orgId, orgUserId);
73
+ return (await deps.content.listCommunitiesById(orgId, ids)).map((community) => ({
74
+ id: community.id,
75
+ title: community.title
76
+ }));
77
+ }
78
+ },
79
+ grants: { grant: (orgId, input) => deps.entitlements.ensureGrant(orgId, input) },
80
+ scheduledWork: {
81
+ publishDuePosts: (orgId, now) => deps.posts.publishDue(orgId, now),
82
+ hasDuePosts: (orgId, now) => deps.posts.hasDue(orgId, now),
83
+ expireDueGrants: (orgId, now) => deps.entitlements.expireDue(orgId, now),
84
+ hasDueGrants: (orgId, now) => deps.entitlements.hasDueNotices(orgId, now),
85
+ sendDigest: (orgId, now) => deps.discussion.sendDigest(orgId, now),
86
+ removeUnattachedUploads: async (orgId, now) => {
87
+ await deps.assets.removeUnattached(orgId, now);
88
+ },
89
+ hasUnattachedUploads: (orgId, now) => deps.assets.hasUnattached(orgId, now)
90
+ }
91
+ };
92
+ }
93
+ //#endregion
94
+ export { communityMail };
95
+
96
+ //# sourceMappingURL=community-mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"community-mail.js","names":[],"sources":["../../src/app/community-mail.ts"],"sourcesContent":["import type { AssetsService } from '@headless-lms/core/assets';\nimport type {\n CommunityMailReads,\n GrantWriter,\n ScheduledWork,\n} from '@headless-lms/core/automations';\nimport type { ContentService } from '@headless-lms/core/content';\nimport type { ChatService, DiscussionService, PostService } from '@headless-lms/core/discussion';\nimport type { EntitlementsService } from '@headless-lms/core/entitlements';\nimport type { IdentityService } from '@headless-lms/core/identity';\nimport type { OrganizationService } from '@headless-lms/core/organizations';\n\nexport type CommunityMailDeps = {\n content: Pick<ContentService, 'getCommunity' | 'getSpace' | 'listCommunitiesById'>;\n entitlements: Pick<\n EntitlementsService,\n | 'openSpacesFor'\n | 'communitiesOpenedBy'\n | 'communityMembersAmong'\n | 'spaceOpenersAmong'\n | 'spaceOpeners'\n | 'communityModeratorIds'\n | 'countActiveSpaceMembers'\n | 'communityIdsOpenedFor'\n | 'ensureGrant'\n | 'expireDue'\n | 'hasDueNotices'\n >;\n organizations: Pick<OrganizationService, 'getOrgUserById' | 'staffOrgUserIds'>;\n identity: Pick<IdentityService, 'displayName'>;\n posts: Pick<PostService, 'followerIds' | 'find' | 'publishDue' | 'hasDue'>;\n discussion: Pick<DiscussionService, 'getComment' | 'sendDigest'>;\n chats: Pick<ChatService, 'chatSummary' | 'latestMessageBody' | 'isBlocked'>;\n assets: Pick<AssetsService, 'removeUnattached' | 'hasUnattached'>;\n};\n\nexport function communityMail(deps: CommunityMailDeps): {\n mail: Omit<CommunityMailReads, 'recentMessageRecipients'>;\n grants: GrantWriter;\n scheduledWork: ScheduledWork;\n} {\n const mail: Omit<CommunityMailReads, 'recentMessageRecipients'> = {\n async communityTitle(orgId, communityId) {\n return (await deps.content.getCommunity(orgId, communityId))?.title ?? null;\n },\n async space(orgId, spaceId) {\n const space = await deps.content.getSpace(orgId, spaceId);\n return space\n ? { name: space.name, communityId: space.communityId, capacity: space.capacity }\n : null;\n },\n async openSpaceNames(orgId, orgUserId, communityId) {\n const orgUser = await deps.organizations.getOrgUserById(orgId, orgUserId);\n if (!orgUser) {\n return [];\n }\n const spaces = await deps.entitlements.openSpacesFor(\n orgId,\n { id: orgUser.id, role: orgUser.role },\n communityId,\n );\n return spaces.map((space) => space.name);\n },\n communitiesOpenedBy: (orgId, grant) => deps.entitlements.communitiesOpenedBy(orgId, grant),\n communityMembersAmong: (orgId, communityId, ids) =>\n deps.entitlements.communityMembersAmong(orgId, communityId, ids),\n spaceOpenersAmong: (orgId, spaceId, ids) =>\n deps.entitlements.spaceOpenersAmong(orgId, spaceId, ids),\n spaceOpeners: (orgId, spaceId) => deps.entitlements.spaceOpeners(orgId, spaceId),\n moderationAudience: (orgId, communityId) =>\n deps.entitlements.communityModeratorIds(orgId, communityId),\n staffIds: (orgId) => deps.organizations.staffOrgUserIds(orgId),\n async displayName(orgId, orgUserId) {\n const orgUser = await deps.organizations.getOrgUserById(orgId, orgUserId);\n return deps.identity.displayName(orgUser?.userId ?? null);\n },\n followerIds: (orgId, postId) => deps.posts.followerIds(orgId, postId),\n async comment(orgId, commentId) {\n const comment = await deps.discussion.getComment(orgId, commentId);\n return comment\n ? { orgUserId: comment.orgUserId, postId: comment.postId, body: comment.body }\n : null;\n },\n async post(orgId, postId) {\n const post = await deps.posts.find(orgId, postId);\n return post\n ? {\n title: post.title,\n body: post.body,\n spaceId: post.spaceId,\n orgUserId: post.orgUserId,\n communityId: post.communityId,\n }\n : null;\n },\n async chat(orgId, chatId) {\n const summary = await deps.chats.chatSummary(orgId, chatId);\n return summary\n ? {\n communityId: summary.chat.communityId,\n kind: summary.chat.kind,\n status: summary.chat.status,\n createdBy: summary.chat.createdBy,\n participants: summary.participants.map((participant) => ({\n orgUserId: participant.orgUserId,\n muted: participant.muted,\n mutedUntil: participant.mutedUntil,\n leftAt: participant.leftAt,\n })),\n }\n : null;\n },\n latestMessageBody: (orgId, chatId) => deps.chats.latestMessageBody(orgId, chatId),\n pairBlocked: (orgId, communityId, a, b) => deps.chats.isBlocked(orgId, communityId, a, b),\n activeMemberCount: (orgId, spaceId) =>\n deps.entitlements.countActiveSpaceMembers(orgId, spaceId),\n async memberCommunityTitles(orgId, orgUserId) {\n const ids = await deps.entitlements.communityIdsOpenedFor(orgId, orgUserId);\n const communities = await deps.content.listCommunitiesById(orgId, ids);\n return communities.map((community) => ({ id: community.id, title: community.title }));\n },\n };\n return {\n mail,\n grants: {\n grant: (orgId, input) => deps.entitlements.ensureGrant(orgId, input),\n },\n scheduledWork: {\n publishDuePosts: (orgId, now) => deps.posts.publishDue(orgId, now),\n hasDuePosts: (orgId, now) => deps.posts.hasDue(orgId, now),\n expireDueGrants: (orgId, now) => deps.entitlements.expireDue(orgId, now),\n hasDueGrants: (orgId, now) => deps.entitlements.hasDueNotices(orgId, now),\n sendDigest: (orgId, now) => deps.discussion.sendDigest(orgId, now),\n removeUnattachedUploads: async (orgId, now) => {\n await deps.assets.removeUnattached(orgId, now);\n },\n hasUnattachedUploads: (orgId, now) => deps.assets.hasUnattached(orgId, now),\n },\n };\n}\n"],"mappings":"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"}
@@ -1,19 +1,18 @@
1
+ import { McpEndpoints } from "./mcp-endpoints.js";
1
2
  import { PollingOutboxRelayConfig } from "@headless-lms/adapter-defaults/events/outbox-relay";
2
3
  import { LogLevel, PinoInstance, RequestLogContext } from "@headless-lms/adapter-defaults/logging";
3
4
  import { BetterAuth } from "@headless-lms/adapter-auth";
4
5
  import { ContentService } from "@headless-lms/core/content";
5
6
  import { EntitlementsServiceImpl } from "@headless-lms/core/entitlements";
6
7
  import { ProgressServiceImpl } from "@headless-lms/core/progress";
7
- import { DiscussionServiceImpl } from "@headless-lms/core/discussion";
8
- import { IdentityServiceImpl, SessionAdmin } from "@headless-lms/core/identity";
8
+ import { ChatServiceImpl, DiscussionServiceImpl, PostServiceImpl } from "@headless-lms/core/discussion";
9
+ import { IdentityServiceImpl, NotificationServiceImpl, SessionAdmin } from "@headless-lms/core/identity";
9
10
  import { OrgAdmin, OrganizationServiceImpl } from "@headless-lms/core/organizations";
10
11
  import { AssetsServiceImpl } from "@headless-lms/core/assets";
11
12
  import { IntegrationsServiceImpl } from "@headless-lms/core/integrations";
12
13
  import { AutomationsServiceImpl } from "@headless-lms/core/automations";
13
- import { StudentsReportServiceImpl } from "@headless-lms/core/reporting/students";
14
- import { DashboardReportServiceImpl } from "@headless-lms/core/reporting/dashboard";
15
- import { CoursesReportServiceImpl } from "@headless-lms/core/reporting/courses";
16
- import { LearnReportServiceImpl } from "@headless-lms/core/reporting/learn";
14
+ import { AdminReportServiceImpl } from "@headless-lms/core/reporting/admin";
15
+ import { MemberReportServiceImpl } from "@headless-lms/core/reporting/member";
17
16
  import { Mailer } from "@headless-lms/core/shared/mailer";
18
17
  import { SettingsService } from "@headless-lms/core/shared/settings";
19
18
  import { AutomationEngine, WebhookSender } from "@headless-lms/core/types";
@@ -25,9 +24,9 @@ interface AdapterOverrides {
25
24
  storage?: ObjectStorage;
26
25
  /** Resolves email templates to rendered content. Absent → fail-loudly stub. */
27
26
  templates?: TemplateRenderer;
28
- /** Durable automation engine. Absent → InlineAutomationEngine (in-process, one attempt per action). */
29
- workflows?: AutomationEngine;
30
- /** Outbound HTTP for webhook deliveries. Absent → FetchWebhookSender (fetch, 10s timeout). */
27
+ /** Durable automation engine, or a factory given the automations logger. Absent → InlineAutomationEngine (in-process, one attempt per action). */
28
+ workflows?: AutomationEngine | ((logger: Logger) => AutomationEngine);
29
+ /** Outbound HTTP for webhook deliveries. Absent → FetchWebhookSender (public addresses only, 10s timeout). */
31
30
  webhooks?: WebhookSender;
32
31
  }
33
32
  interface BuildContainerOptions {
@@ -57,9 +56,12 @@ interface Config {
57
56
  outbox?: OutboxConfig;
58
57
  /** Log level for the process-wide logger (HTTP + domain + relay). Default "info". */
59
58
  logging?: LoggingConfig;
60
- /** Presigned URL lifetime for entitled download delivery, seconds. Mirrors
59
+ /** Lifetime of every signed file URL a response carries, seconds. Mirrors
61
60
  * ServerConfig.deliveryExpirySeconds — createContainer threads it through. */
62
61
  deliveryExpirySeconds: number;
62
+ memberImageMaxBytes: number;
63
+ /** Let the default webhook sender reach loopback and private network addresses. Local development only. */
64
+ webhookAllowPrivateNetwork?: boolean;
63
65
  }
64
66
  /** Tuning for the transactional-outbox relay. Every field is optional; the
65
67
  * container resolves against OUTBOX_DEFAULTS. */
@@ -82,13 +84,17 @@ declare const LOGGING_DEFAULTS: Required<LoggingConfig>;
82
84
  declare function resolveLoggingConfig(config?: LoggingConfig): Required<LoggingConfig>;
83
85
  interface Container {
84
86
  auth: BetterAuth;
87
+ mcp: McpEndpoints;
85
88
  orgProvider: OrgAdmin;
86
89
  identity: IdentityServiceImpl;
90
+ notifications: NotificationServiceImpl;
87
91
  organizations: OrganizationServiceImpl;
88
92
  content: ContentService;
89
93
  entitlements: EntitlementsServiceImpl;
90
94
  progress: ProgressServiceImpl;
91
95
  discussion: DiscussionServiceImpl;
96
+ posts: PostServiceImpl;
97
+ chats: ChatServiceImpl;
92
98
  assets: AssetsServiceImpl;
93
99
  integrations: IntegrationsServiceImpl;
94
100
  automations: AutomationsServiceImpl;
@@ -96,10 +102,8 @@ interface Container {
96
102
  * inject `settings.for('<namespace>')` into a service, never the service itself. */
97
103
  settings: SettingsService;
98
104
  reporting: {
99
- students: StudentsReportServiceImpl;
100
- dashboard: DashboardReportServiceImpl;
101
- courses: CoursesReportServiceImpl;
102
- learn: LearnReportServiceImpl;
105
+ admin: AdminReportServiceImpl;
106
+ member: MemberReportServiceImpl;
103
107
  };
104
108
  storage: ObjectStorage;
105
109
  mailer: Mailer;
@@ -1,6 +1,7 @@
1
1
  import { loadIntegrations } from "./integrations.js";
2
- import { registerNotificationSubscribers } from "./notifications.js";
3
- import { DrizzleAssetsRepository, DrizzleAutomationRunsRepository, DrizzleAutomationsRepository, DrizzleConnectionsRepository, DrizzleContentRepository, DrizzleCourseAnalyticsRepository, DrizzleCredentialStore, DrizzleDashboardRepository, DrizzleDiscussionRepository, DrizzleEntitlementsRepository, DrizzleIdentityRepository, DrizzleLearnRepository, DrizzleMembersRepository, DrizzleOrganizationsRepository, DrizzleOutboxAppender, DrizzleOutboxStore, DrizzleProgressRepository, DrizzleSettingsRepository, DrizzleStudentsRepository, DrizzleUnitOfWork, createDb } from "@headless-lms/adapter-db";
2
+ import { mcpEndpoints } from "./mcp-endpoints.js";
3
+ import { communityMail } from "./community-mail.js";
4
+ import { DrizzleAdminRepository, DrizzleAssetsRepository, DrizzleAutomationRunsRepository, DrizzleAutomationsRepository, DrizzleChatRepository, DrizzleConnectionsRepository, DrizzleContentRepository, DrizzleCredentialStore, DrizzleDiscussionRepository, DrizzleEntitlementsRepository, DrizzleIdentityRepository, DrizzleMemberRepository, DrizzleMembersRepository, DrizzleNotificationsRepository, DrizzleOrganizationsRepository, DrizzleOutboxAppender, DrizzleOutboxStore, DrizzlePostRepository, DrizzleProgressRepository, DrizzleSettingsRepository, DrizzleUnitOfWork, createDb } from "@headless-lms/adapter-db";
4
5
  import { InMemoryEventBus } from "@headless-lms/adapter-defaults/events";
5
6
  import { PollingOutboxRelay } from "@headless-lms/adapter-defaults/events/outbox-relay";
6
7
  import { InlineAutomationEngine } from "@headless-lms/adapter-defaults/workflows";
@@ -12,16 +13,14 @@ import { BetterAuth } from "@headless-lms/adapter-auth";
12
13
  import { ContentService } from "@headless-lms/core/content";
13
14
  import { EntitlementsServiceImpl } from "@headless-lms/core/entitlements";
14
15
  import { ProgressServiceImpl } from "@headless-lms/core/progress";
15
- import { DiscussionServiceImpl } from "@headless-lms/core/discussion";
16
- import { IdentityServiceImpl } from "@headless-lms/core/identity";
16
+ import { ChatServiceImpl, DiscussionServiceImpl, PostServiceImpl } from "@headless-lms/core/discussion";
17
+ import { IdentityServiceImpl, NotificationServiceImpl } from "@headless-lms/core/identity";
17
18
  import { OrganizationServiceImpl, parseRole } from "@headless-lms/core/organizations";
18
- import { AssetsServiceImpl } from "@headless-lms/core/assets";
19
+ import { AssetsServiceImpl, createFileUrls } from "@headless-lms/core/assets";
19
20
  import { IntegrationsServiceImpl } from "@headless-lms/core/integrations";
20
21
  import { AutomationsServiceImpl } from "@headless-lms/core/automations";
21
- import { StudentsReportServiceImpl } from "@headless-lms/core/reporting/students";
22
- import { DashboardReportServiceImpl } from "@headless-lms/core/reporting/dashboard";
23
- import { CoursesReportServiceImpl } from "@headless-lms/core/reporting/courses";
24
- import { LearnReportServiceImpl } from "@headless-lms/core/reporting/learn";
22
+ import { AdminReportServiceImpl } from "@headless-lms/core/reporting/admin";
23
+ import { MemberReportServiceImpl } from "@headless-lms/core/reporting/member";
25
24
  import { Mailer } from "@headless-lms/core/shared/mailer";
26
25
  import { SettingsService } from "@headless-lms/core/shared/settings";
27
26
  //#region src/app/container.ts
@@ -56,7 +55,8 @@ async function buildContainer(config, options) {
56
55
  const email = options?.adapters?.email ?? new EmailAdapter(logger.child({ name: "email" }));
57
56
  const storage = options?.adapters?.storage ?? new StorageAdapter(logger.child({ name: "storage" }));
58
57
  const templates = options?.adapters?.templates ?? new StubTemplateRenderer(logger.child({ name: "email" }));
59
- const automationEngine = options?.adapters?.workflows ?? new InlineAutomationEngine();
58
+ const workflows = options?.adapters?.workflows;
59
+ const automationEngine = typeof workflows === "function" ? workflows(automationsLogger) : workflows ?? new InlineAutomationEngine(automationsLogger);
60
60
  const mailer = new Mailer(templates, email, {
61
61
  ...config.emailBranding ?? {
62
62
  brandName: "Headless LMS",
@@ -64,6 +64,19 @@ async function buildContainer(config, options) {
64
64
  },
65
65
  studentPortalUrl: config.studentPortalUrl
66
66
  });
67
+ const fileUrls = createFileUrls(config.authBaseURL);
68
+ const assets = new AssetsServiceImpl({
69
+ storage,
70
+ repo: new DrizzleAssetsRepository(db, assetsLogger),
71
+ uow: new DrizzleUnitOfWork(db, (tx) => ({
72
+ assets: new DrizzleAssetsRepository(tx, assetsLogger),
73
+ outbox: new DrizzleOutboxAppender(tx, outboxLogger)
74
+ })),
75
+ memberImageMaxBytes: config.memberImageMaxBytes,
76
+ downloadLinkExpirySeconds: config.deliveryExpirySeconds,
77
+ fileUrls,
78
+ logger: assetsLogger
79
+ });
67
80
  const identityUoW = new DrizzleUnitOfWork(db, (tx) => ({
68
81
  identity: new DrizzleIdentityRepository(tx, logger.child({ name: "identity" })),
69
82
  outbox: new DrizzleOutboxAppender(tx, logger.child({ name: "identity" }))
@@ -72,15 +85,22 @@ async function buildContainer(config, options) {
72
85
  repo: new DrizzleIdentityRepository(db, logger.child({ name: "identity_repo" })),
73
86
  logger: logger.child({ name: "identity" }),
74
87
  uow: identityUoW,
75
- mailer
88
+ mailer,
89
+ images: assets,
90
+ fileUrls
91
+ });
92
+ const notifications = new NotificationServiceImpl({
93
+ repo: new DrizzleNotificationsRepository(db),
94
+ logger: logger.child({ name: "notifications" })
76
95
  });
96
+ const organizationsRepo = new DrizzleOrganizationsRepository(db, logger.child({ name: "org" }));
77
97
  const organizationsUow = new DrizzleUnitOfWork(db, (tx) => ({
78
98
  organizations: new DrizzleOrganizationsRepository(tx, logger.child({ name: "org" })),
79
99
  outbox: new DrizzleOutboxAppender(tx, logger.child({ name: "org" }))
80
100
  }));
81
101
  const orgAdminRef = { current: void 0 };
82
102
  const organizations = new OrganizationServiceImpl({
83
- repo: new DrizzleOrganizationsRepository(db, logger.child({ name: "org" })),
103
+ repo: organizationsRepo,
84
104
  membersRepo: new DrizzleMembersRepository(db, logger.child({ name: "org" })),
85
105
  people: identity,
86
106
  uow: organizationsUow,
@@ -103,14 +123,28 @@ async function buildContainer(config, options) {
103
123
  const content = new ContentService({
104
124
  repo: new DrizzleContentRepository(db, contentLogger),
105
125
  uow: contentUow,
126
+ libraryAssets: assets,
127
+ files: assets,
128
+ fileUrls,
106
129
  logger: contentLogger
107
130
  });
108
131
  const entitlementsUow = new DrizzleUnitOfWork(db, (tx) => ({
109
132
  entitlements: new DrizzleEntitlementsRepository(tx, entitlementsLogger),
133
+ spaces: new DrizzleContentRepository(tx, contentLogger),
110
134
  outbox: new DrizzleOutboxAppender(tx, outboxLogger)
111
135
  }));
136
+ const authors = {
137
+ roleOf: async (orgId, orgUserId) => {
138
+ return (await organizationsRepo.findOrgUserById(orgId, orgUserId))?.role ?? null;
139
+ },
140
+ rolesOf: async (orgId, orgUserIds) => {
141
+ const rows = await organizationsRepo.findOrgUsersByIds(orgId, orgUserIds);
142
+ return Object.fromEntries(rows.map((row) => [row.id, row.role]));
143
+ }
144
+ };
112
145
  const entitlements = new EntitlementsServiceImpl({
113
146
  repo: new DrizzleEntitlementsRepository(db, entitlementsLogger),
147
+ content,
114
148
  uow: entitlementsUow,
115
149
  logger: entitlementsLogger
116
150
  });
@@ -121,49 +155,68 @@ async function buildContainer(config, options) {
121
155
  const progress = new ProgressServiceImpl({
122
156
  repo: new DrizzleProgressRepository(db, progressLogger),
123
157
  content,
158
+ access: entitlements,
124
159
  uow: progressUow,
125
160
  logger: progressLogger
126
161
  });
127
- const discussion = new DiscussionServiceImpl({
128
- repo: new DrizzleDiscussionRepository(db, discussionLogger),
162
+ const postReads = new DrizzlePostRepository(db, discussionLogger);
163
+ const discussionReads = new DrizzleDiscussionRepository(db, discussionLogger);
164
+ const chatReads = new DrizzleChatRepository(db, discussionLogger);
165
+ const posts = new PostServiceImpl({
166
+ repo: postReads,
129
167
  access: entitlements,
130
168
  content,
169
+ authors,
170
+ profiles: discussionReads,
171
+ comments: discussionReads,
172
+ images: assets,
173
+ fileUrls,
131
174
  uow: new DrizzleUnitOfWork(db, (tx) => ({
132
- discussion: new DrizzleDiscussionRepository(tx, discussionLogger),
175
+ posts: new DrizzlePostRepository(tx, discussionLogger),
133
176
  outbox: new DrizzleOutboxAppender(tx, outboxLogger)
134
177
  })),
135
- settings,
136
178
  logger: discussionLogger
137
179
  });
138
- const assets = new AssetsServiceImpl({
139
- storage,
140
- repo: new DrizzleAssetsRepository(db, assetsLogger),
180
+ const chats = new ChatServiceImpl({
181
+ repo: chatReads,
182
+ access: entitlements,
183
+ content,
184
+ authors,
185
+ profiles: discussionReads,
186
+ images: assets,
187
+ fileUrls,
141
188
  uow: new DrizzleUnitOfWork(db, (tx) => ({
142
- assets: new DrizzleAssetsRepository(tx, assetsLogger),
189
+ chats: new DrizzleChatRepository(tx, discussionLogger),
143
190
  outbox: new DrizzleOutboxAppender(tx, outboxLogger)
144
191
  })),
145
- logger: assetsLogger
192
+ logger: discussionLogger
193
+ });
194
+ const discussion = new DiscussionServiceImpl({
195
+ repo: discussionReads,
196
+ access: entitlements,
197
+ content,
198
+ posts,
199
+ communities: { listIds: (orgId) => content.listPublishedCommunityIds(orgId) },
200
+ fileUrls,
201
+ uow: new DrizzleUnitOfWork(db, (tx) => ({
202
+ discussion: new DrizzleDiscussionRepository(tx, discussionLogger),
203
+ outbox: new DrizzleOutboxAppender(tx, outboxLogger)
204
+ })),
205
+ settings,
206
+ logger: discussionLogger
146
207
  });
147
208
  const reporting = {
148
- students: new StudentsReportServiceImpl({
149
- repo: new DrizzleStudentsRepository(db, reportingLogger),
150
- logger: reportingLogger
151
- }),
152
- dashboard: new DashboardReportServiceImpl({
153
- repo: new DrizzleDashboardRepository(db, reportingLogger),
154
- logger: reportingLogger
155
- }),
156
- courses: new CoursesReportServiceImpl({
157
- repo: new DrizzleCourseAnalyticsRepository(db, reportingLogger),
158
- logger: reportingLogger
159
- }),
160
- learn: new LearnReportServiceImpl({
161
- reader: new DrizzleLearnRepository(db, reportingLogger),
209
+ admin: new AdminReportServiceImpl({ repo: new DrizzleAdminRepository(db, reportingLogger) }),
210
+ member: new MemberReportServiceImpl({
211
+ repo: new DrizzleMemberRepository(db, reportingLogger),
162
212
  content,
163
213
  progress,
164
- assets,
165
- deliveryExpirySeconds: config.deliveryExpirySeconds,
166
- logger: reportingLogger
214
+ files: assets,
215
+ fileUrls,
216
+ access: entitlements,
217
+ notifications,
218
+ posts,
219
+ chats
167
220
  })
168
221
  };
169
222
  const credentialStore = new DrizzleCredentialStore(db, config.credentialStoreKey, integrationsLogger);
@@ -187,7 +240,14 @@ async function buildContainer(config, options) {
187
240
  outbox: new DrizzleOutboxAppender(tx, automationsLogger)
188
241
  }));
189
242
  const mailerLookups = {
190
- orgUserEmail: async (orgId, orgUserId) => (await reporting.students.get(orgId, orgUserId))?.email ?? null,
243
+ orgUserPerson: async (orgId, orgUserId) => {
244
+ const orgUser = await organizationsRepo.findOrgUserById(orgId, orgUserId);
245
+ const user = orgUser ? await identity.getUserById(orgUser.userId) : null;
246
+ return user ? {
247
+ userId: user.id,
248
+ email: user.email
249
+ } : null;
250
+ },
191
251
  contentInfo: async (orgId, contentId) => {
192
252
  const course = await content.getCourse(orgId, contentId);
193
253
  if (course) return {
@@ -196,28 +256,48 @@ async function buildContainer(config, options) {
196
256
  type: course.type
197
257
  };
198
258
  const download = await content.getDownload(orgId, contentId);
199
- return download ? {
259
+ if (download) return {
200
260
  id: download.id,
201
261
  title: download.title,
202
262
  type: download.type
263
+ };
264
+ const community = await content.getCommunity(orgId, contentId);
265
+ return community ? {
266
+ id: community.id,
267
+ title: community.title,
268
+ type: community.type
203
269
  } : null;
204
270
  }
205
271
  };
272
+ const runsRepo = new DrizzleAutomationRunsRepository(db, automationsLogger);
273
+ const wired = communityMail({
274
+ content,
275
+ entitlements,
276
+ organizations,
277
+ identity,
278
+ posts,
279
+ discussion,
280
+ chats,
281
+ assets
282
+ });
206
283
  const automations = new AutomationsServiceImpl({
207
284
  repo: new DrizzleAutomationsRepository(db, automationsLogger),
208
- runsRepo: new DrizzleAutomationRunsRepository(db, automationsLogger),
285
+ runsRepo,
209
286
  uow: automationsUow,
210
287
  engine: automationEngine,
211
288
  mailer,
212
289
  lookups: mailerLookups,
213
290
  integrations,
214
291
  credentials: credentialStore,
215
- webhooks: options?.adapters?.webhooks ?? new FetchWebhookSender(),
292
+ webhooks: options?.adapters?.webhooks ?? new FetchWebhookSender({ allowPrivateNetwork: config.webhookAllowPrivateNetwork }),
293
+ mail: wired.mail,
294
+ grants: wired.grants,
295
+ desk: notifications,
296
+ scheduledWork: wired.scheduledWork,
216
297
  logger: automationsLogger
217
298
  });
218
299
  automationEngine.register(automations);
219
300
  const eventBus = new InMemoryEventBus();
220
- registerNotificationSubscribers(eventBus, mailer, mailerLookups);
221
301
  eventBus.subscribeAll((event) => automations.handle(event));
222
302
  const outboxConfig = resolveOutboxConfig(config.outbox);
223
303
  const outboxRelay = new PollingOutboxRelay(new DrizzleOutboxStore(db, outboxLogger), eventBus, outboxConfig, outboxLogger);
@@ -230,9 +310,18 @@ async function buildContainer(config, options) {
230
310
  throw err;
231
311
  }
232
312
  };
313
+ const mcp = mcpEndpoints(config);
314
+ if (!mcp.oauthEnabled) authLogger.warn("MCP OAuth is off: BETTER_AUTH_URL must be https or a loopback host; /mcp accepts API keys only", { authBaseURL: config.authBaseURL });
233
315
  const auth = new BetterAuth({
234
316
  db,
235
317
  baseUrl: config.authBaseURL,
318
+ mcp: {
319
+ oauthEnabled: mcp.oauthEnabled,
320
+ resource: mcp.resource,
321
+ loginPage: mcp.loginPage,
322
+ consentPage: mcp.consentPage,
323
+ orgPickerPage: mcp.orgPickerPage
324
+ },
236
325
  secret: config.authSecret,
237
326
  trustedOrigins: config.trustedOrigins,
238
327
  hooks: {
@@ -314,13 +403,17 @@ async function buildContainer(config, options) {
314
403
  orgAdminRef.current = auth;
315
404
  return {
316
405
  auth,
406
+ mcp,
317
407
  identity,
408
+ notifications,
318
409
  organizations,
319
410
  orgProvider: auth,
320
411
  content,
321
412
  entitlements,
322
413
  progress,
323
414
  discussion,
415
+ posts,
416
+ chats,
324
417
  assets,
325
418
  integrations,
326
419
  automations,