@headless-lms/server 0.2.0 → 0.4.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 (351) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +5 -0
  2. package/dist/app/community-mail.d.ts +24 -0
  3. package/dist/app/community-mail.js +92 -0
  4. package/dist/app/community-mail.js.map +1 -0
  5. package/dist/app/container.d.ts +40 -19
  6. package/dist/app/container.js +294 -45
  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/app/notification-channels.d.ts +47 -0
  12. package/dist/app/notification-channels.js +174 -0
  13. package/dist/app/notification-channels.js.map +1 -0
  14. package/dist/app/notification-reads.d.ts +23 -0
  15. package/dist/app/notification-reads.js +95 -0
  16. package/dist/app/notification-reads.js.map +1 -0
  17. package/dist/http/config.d.ts +2 -1
  18. package/dist/http/errors.d.ts +15 -0
  19. package/dist/http/errors.js +162 -0
  20. package/dist/http/errors.js.map +1 -0
  21. package/dist/http/mcp/catalogue.d.ts +37 -0
  22. package/dist/http/mcp/catalogue.js +69 -0
  23. package/dist/http/mcp/catalogue.js.map +1 -0
  24. package/dist/http/mcp/challenge.d.ts +7 -0
  25. package/dist/http/mcp/challenge.js +35 -0
  26. package/dist/http/mcp/challenge.js.map +1 -0
  27. package/dist/http/mcp/input-schema.d.ts +7 -0
  28. package/dist/http/mcp/input-schema.js +28 -0
  29. package/dist/http/mcp/input-schema.js.map +1 -0
  30. package/dist/http/mcp/route.d.ts +8 -0
  31. package/dist/http/mcp/route.js +75 -0
  32. package/dist/http/mcp/route.js.map +1 -0
  33. package/dist/http/mcp/server.d.ts +8 -0
  34. package/dist/http/mcp/server.js +31 -0
  35. package/dist/http/mcp/server.js.map +1 -0
  36. package/dist/http/mcp/test-support.d.ts +55 -0
  37. package/dist/http/mcp/test-support.js +151 -0
  38. package/dist/http/mcp/test-support.js.map +1 -0
  39. package/dist/http/mcp/tool.d.ts +48 -0
  40. package/dist/http/mcp/tool.js +58 -0
  41. package/dist/http/mcp/tool.js.map +1 -0
  42. package/dist/http/mcp/tools/automations.d.ts +6 -0
  43. package/dist/http/mcp/tools/automations.js +120 -0
  44. package/dist/http/mcp/tools/automations.js.map +1 -0
  45. package/dist/http/mcp/tools/catalog.d.ts +6 -0
  46. package/dist/http/mcp/tools/catalog.js +200 -0
  47. package/dist/http/mcp/tools/catalog.js.map +1 -0
  48. package/dist/http/mcp/tools/comments.d.ts +6 -0
  49. package/dist/http/mcp/tools/comments.js +70 -0
  50. package/dist/http/mcp/tools/comments.js.map +1 -0
  51. package/dist/http/mcp/tools/communities.d.ts +6 -0
  52. package/dist/http/mcp/tools/communities.js +175 -0
  53. package/dist/http/mcp/tools/communities.js.map +1 -0
  54. package/dist/http/mcp/tools/community-members.d.ts +6 -0
  55. package/dist/http/mcp/tools/community-members.js +89 -0
  56. package/dist/http/mcp/tools/community-members.js.map +1 -0
  57. package/dist/http/mcp/tools/community-moderation.d.ts +6 -0
  58. package/dist/http/mcp/tools/community-moderation.js +144 -0
  59. package/dist/http/mcp/tools/community-moderation.js.map +1 -0
  60. package/dist/http/mcp/tools/courses.d.ts +6 -0
  61. package/dist/http/mcp/tools/courses.js +121 -0
  62. package/dist/http/mcp/tools/courses.js.map +1 -0
  63. package/dist/http/mcp/tools/index.d.ts +6 -0
  64. package/dist/http/mcp/tools/index.js +23 -0
  65. package/dist/http/mcp/tools/index.js.map +1 -0
  66. package/dist/http/mcp/tools/people.d.ts +6 -0
  67. package/dist/http/mcp/tools/people.js +145 -0
  68. package/dist/http/mcp/tools/people.js.map +1 -0
  69. package/dist/http/plugins/auth.js +13 -5
  70. package/dist/http/plugins/auth.js.map +1 -1
  71. package/dist/http/plugins/error-handler.d.ts +2 -1
  72. package/dist/http/plugins/error-handler.js +51 -65
  73. package/dist/http/plugins/error-handler.js.map +1 -1
  74. package/dist/http/plugins/openapi.js +49 -2
  75. package/dist/http/plugins/openapi.js.map +1 -1
  76. package/dist/http/routes/access.d.ts +7 -0
  77. package/dist/http/routes/access.js +140 -0
  78. package/dist/http/routes/access.js.map +1 -0
  79. package/dist/http/routes/activities.js +68 -23
  80. package/dist/http/routes/activities.js.map +1 -1
  81. package/dist/http/routes/assets.js +60 -55
  82. package/dist/http/routes/assets.js.map +1 -1
  83. package/dist/http/routes/automations.js +44 -24
  84. package/dist/http/routes/automations.js.map +1 -1
  85. package/dist/http/routes/bundles.js +29 -18
  86. package/dist/http/routes/bundles.js.map +1 -1
  87. package/dist/http/routes/communities.d.ts +7 -0
  88. package/dist/http/routes/communities.js +522 -0
  89. package/dist/http/routes/communities.js.map +1 -0
  90. package/dist/http/routes/community-moderation.d.ts +7 -0
  91. package/dist/http/routes/community-moderation.js +425 -0
  92. package/dist/http/routes/community-moderation.js.map +1 -0
  93. package/dist/http/routes/course-analytics.js +9 -7
  94. package/dist/http/routes/course-analytics.js.map +1 -1
  95. package/dist/http/routes/courses.js +30 -15
  96. package/dist/http/routes/courses.js.map +1 -1
  97. package/dist/http/routes/dashboard.js +15 -6
  98. package/dist/http/routes/dashboard.js.map +1 -1
  99. package/dist/http/routes/discussion.js +34 -26
  100. package/dist/http/routes/discussion.js.map +1 -1
  101. package/dist/http/routes/downloads.js +48 -30
  102. package/dist/http/routes/downloads.js.map +1 -1
  103. package/dist/http/routes/entitlements.js +16 -7
  104. package/dist/http/routes/entitlements.js.map +1 -1
  105. package/dist/http/routes/integrations.js +38 -41
  106. package/dist/http/routes/integrations.js.map +1 -1
  107. package/dist/http/routes/member/actor.d.ts +14 -0
  108. package/dist/http/routes/member/actor.js +11 -0
  109. package/dist/http/routes/member/actor.js.map +1 -0
  110. package/dist/http/routes/member/assets.d.ts +7 -0
  111. package/dist/http/routes/member/assets.js +79 -0
  112. package/dist/http/routes/member/assets.js.map +1 -0
  113. package/dist/http/routes/member/chats.d.ts +7 -0
  114. package/dist/http/routes/member/chats.js +435 -0
  115. package/dist/http/routes/member/chats.js.map +1 -0
  116. package/dist/http/routes/member/comments.d.ts +7 -0
  117. package/dist/http/routes/member/comments.js +187 -0
  118. package/dist/http/routes/member/comments.js.map +1 -0
  119. package/dist/http/routes/member/community.d.ts +7 -0
  120. package/dist/http/routes/member/community.js +312 -0
  121. package/dist/http/routes/member/community.js.map +1 -0
  122. package/dist/http/routes/member/courses.d.ts +7 -0
  123. package/dist/http/routes/member/courses.js +101 -0
  124. package/dist/http/routes/member/courses.js.map +1 -0
  125. package/dist/http/routes/member/devices.d.ts +7 -0
  126. package/dist/http/routes/member/devices.js +98 -0
  127. package/dist/http/routes/member/devices.js.map +1 -0
  128. package/dist/http/routes/member/downloads.d.ts +7 -0
  129. package/dist/http/routes/member/downloads.js +56 -0
  130. package/dist/http/routes/member/downloads.js.map +1 -0
  131. package/dist/http/routes/member/files.d.ts +7 -0
  132. package/dist/http/routes/member/files.js +184 -0
  133. package/dist/http/routes/member/files.js.map +1 -0
  134. package/dist/http/routes/member/index.d.ts +7 -0
  135. package/dist/http/routes/member/index.js +35 -0
  136. package/dist/http/routes/member/index.js.map +1 -0
  137. package/dist/http/routes/member/notification-settings.d.ts +7 -0
  138. package/dist/http/routes/member/notification-settings.js +108 -0
  139. package/dist/http/routes/member/notification-settings.js.map +1 -0
  140. package/dist/http/routes/member/notifications.d.ts +7 -0
  141. package/dist/http/routes/member/notifications.js +125 -0
  142. package/dist/http/routes/member/notifications.js.map +1 -0
  143. package/dist/http/routes/member/org.d.ts +7 -0
  144. package/dist/http/routes/member/org.js +56 -0
  145. package/dist/http/routes/member/org.js.map +1 -0
  146. package/dist/http/routes/member/posts.d.ts +7 -0
  147. package/dist/http/routes/member/posts.js +612 -0
  148. package/dist/http/routes/member/posts.js.map +1 -0
  149. package/dist/http/routes/member/profile.d.ts +7 -0
  150. package/dist/http/routes/member/profile.js +48 -0
  151. package/dist/http/routes/member/profile.js.map +1 -0
  152. package/dist/http/routes/member/progress.d.ts +7 -0
  153. package/dist/http/routes/member/progress.js +60 -0
  154. package/dist/http/routes/member/progress.js.map +1 -0
  155. package/dist/http/routes/organizations.js +171 -25
  156. package/dist/http/routes/organizations.js.map +1 -1
  157. package/dist/http/routes/students.js +32 -47
  158. package/dist/http/routes/students.js.map +1 -1
  159. package/dist/http/routes/webhooks.js +26 -18
  160. package/dist/http/routes/webhooks.js.map +1 -1
  161. package/dist/http/routes.js +8 -2
  162. package/dist/http/routes.js.map +1 -1
  163. package/dist/http/schemas/access.d.ts +146 -0
  164. package/dist/http/schemas/access.js +36 -0
  165. package/dist/http/schemas/access.js.map +1 -0
  166. package/dist/http/schemas/activities.d.ts +3 -1
  167. package/dist/http/schemas/activities.js +4 -4
  168. package/dist/http/schemas/activities.js.map +1 -1
  169. package/dist/http/schemas/assets.d.ts +79 -80
  170. package/dist/http/schemas/assets.js +23 -13
  171. package/dist/http/schemas/assets.js.map +1 -1
  172. package/dist/http/schemas/automations.d.ts +6 -0
  173. package/dist/http/schemas/bundles.js +6 -6
  174. package/dist/http/schemas/bundles.js.map +1 -1
  175. package/dist/http/schemas/chats.d.ts +409 -0
  176. package/dist/http/schemas/chats.js +56 -0
  177. package/dist/http/schemas/chats.js.map +1 -0
  178. package/dist/http/schemas/community.d.ts +597 -0
  179. package/dist/http/schemas/community.js +132 -0
  180. package/dist/http/schemas/community.js.map +1 -0
  181. package/dist/http/schemas/content.d.ts +4 -2
  182. package/dist/http/schemas/content.js +11 -8
  183. package/dist/http/schemas/content.js.map +1 -1
  184. package/dist/http/schemas/discussion.d.ts +98 -14
  185. package/dist/http/schemas/discussion.js +25 -12
  186. package/dist/http/schemas/discussion.js.map +1 -1
  187. package/dist/http/schemas/downloads.d.ts +11 -5
  188. package/dist/http/schemas/downloads.js +14 -11
  189. package/dist/http/schemas/downloads.js.map +1 -1
  190. package/dist/http/schemas/entitlements.d.ts +6 -6
  191. package/dist/http/schemas/entitlements.js +6 -6
  192. package/dist/http/schemas/entitlements.js.map +1 -1
  193. package/dist/http/schemas/files.d.ts +45 -0
  194. package/dist/http/schemas/files.js +25 -0
  195. package/dist/http/schemas/files.js.map +1 -0
  196. package/dist/http/schemas/index.d.ts +15 -8
  197. package/dist/http/schemas/index.js +15 -8
  198. package/dist/http/schemas/integrations.d.ts +4 -4
  199. package/dist/http/schemas/invites.d.ts +4 -0
  200. package/dist/http/schemas/invites.js +1 -0
  201. package/dist/http/schemas/invites.js.map +1 -1
  202. package/dist/http/schemas/{learn.d.ts → member.d.ts} +31 -18
  203. package/dist/http/schemas/{learn.js → member.js} +17 -13
  204. package/dist/http/schemas/member.js.map +1 -0
  205. package/dist/http/schemas/members.d.ts +35 -2
  206. package/dist/http/schemas/members.js +17 -3
  207. package/dist/http/schemas/members.js.map +1 -1
  208. package/dist/http/schemas/notifications.d.ts +550 -0
  209. package/dist/http/schemas/notifications.js +164 -0
  210. package/dist/http/schemas/notifications.js.map +1 -0
  211. package/dist/http/schemas/posts.d.ts +350 -0
  212. package/dist/http/schemas/posts.js +47 -0
  213. package/dist/http/schemas/posts.js.map +1 -0
  214. package/dist/http/schemas/profile.d.ts +23 -0
  215. package/dist/http/schemas/profile.js +15 -0
  216. package/dist/http/schemas/profile.js.map +1 -0
  217. package/dist/http/schemas/shared.d.ts +32 -1
  218. package/dist/http/schemas/shared.js +20 -2
  219. package/dist/http/schemas/shared.js.map +1 -1
  220. package/dist/http/schemas/students.d.ts +1 -7
  221. package/dist/http/schemas/students.js +1 -7
  222. package/dist/http/schemas/students.js.map +1 -1
  223. package/dist/http/scope.d.ts +3 -1
  224. package/dist/http/scope.js +26 -4
  225. package/dist/http/scope.js.map +1 -1
  226. package/dist/http/server.js +6 -1
  227. package/dist/http/server.js.map +1 -1
  228. package/dist/http/web-bridge.d.ts +1 -1
  229. package/dist/http/web-bridge.js +2 -2
  230. package/dist/http/web-bridge.js.map +1 -1
  231. package/dist/http/well-known.d.ts +7 -0
  232. package/dist/http/well-known.js +22 -0
  233. package/dist/http/well-known.js.map +1 -0
  234. package/dist/index.d.ts +3 -1
  235. package/dist/index.js +4 -2
  236. package/dist/index.js.map +1 -1
  237. package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +78 -0
  238. package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js.map +1 -0
  239. package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js +1267 -0
  240. package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js.map +1 -0
  241. package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js +814 -0
  242. package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js.map +1 -0
  243. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js +43 -0
  244. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js.map +1 -0
  245. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js +527 -0
  246. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js.map +1 -0
  247. package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/utils.js +2 -0
  248. package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js +1737 -0
  249. package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js.map +1 -0
  250. package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js +137 -0
  251. package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js.map +1 -0
  252. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +118 -0
  253. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js.map +1 -0
  254. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js +1222 -0
  255. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js.map +1 -0
  256. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js +91 -0
  257. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js.map +1 -0
  258. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js +113 -0
  259. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js.map +1 -0
  260. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js +449 -0
  261. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js.map +1 -0
  262. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js +163 -0
  263. package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js.map +1 -0
  264. package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js +3187 -0
  265. package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js.map +1 -0
  266. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js +11 -0
  267. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js.map +1 -0
  268. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js +16 -0
  269. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js.map +1 -0
  270. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js +11 -0
  271. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js.map +1 -0
  272. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js +15 -0
  273. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js.map +1 -0
  274. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js +13 -0
  275. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js.map +1 -0
  276. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js +34 -0
  277. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js.map +1 -0
  278. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js +12 -0
  279. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js.map +1 -0
  280. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js +122 -0
  281. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js.map +1 -0
  282. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js +39 -0
  283. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js.map +1 -0
  284. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js +99 -0
  285. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js.map +1 -0
  286. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js +25 -0
  287. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js.map +1 -0
  288. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js +14 -0
  289. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js.map +1 -0
  290. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js +21 -0
  291. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js.map +1 -0
  292. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js +6 -0
  293. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js.map +1 -0
  294. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js +12 -0
  295. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js.map +1 -0
  296. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js +18 -0
  297. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js.map +1 -0
  298. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js +24 -0
  299. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js.map +1 -0
  300. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js +9 -0
  301. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js.map +1 -0
  302. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js +30 -0
  303. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js.map +1 -0
  304. package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +939 -0
  305. package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js.map +1 -0
  306. package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js +82 -0
  307. package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js.map +1 -0
  308. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +82 -0
  309. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js.map +1 -0
  310. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js +8 -0
  311. package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js.map +1 -0
  312. package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js +83 -0
  313. package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js.map +1 -0
  314. 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
  315. 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
  316. 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
  317. 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
  318. 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
  319. 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
  320. 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
  321. 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
  322. package/dist/packages/server/package.js +6 -0
  323. package/dist/packages/server/package.js.map +1 -0
  324. package/package.json +9 -7
  325. package/dist/app/notifications.d.ts +0 -7
  326. package/dist/app/notifications.js +0 -26
  327. package/dist/app/notifications.js.map +0 -1
  328. package/dist/http/routes/learn/assets.d.ts +0 -8
  329. package/dist/http/routes/learn/assets.js +0 -32
  330. package/dist/http/routes/learn/assets.js.map +0 -1
  331. package/dist/http/routes/learn/comments.d.ts +0 -7
  332. package/dist/http/routes/learn/comments.js +0 -175
  333. package/dist/http/routes/learn/comments.js.map +0 -1
  334. package/dist/http/routes/learn/courses.d.ts +0 -7
  335. package/dist/http/routes/learn/courses.js +0 -98
  336. package/dist/http/routes/learn/courses.js.map +0 -1
  337. package/dist/http/routes/learn/downloads.d.ts +0 -7
  338. package/dist/http/routes/learn/downloads.js +0 -76
  339. package/dist/http/routes/learn/downloads.js.map +0 -1
  340. package/dist/http/routes/learn/index.d.ts +0 -7
  341. package/dist/http/routes/learn/index.js +0 -19
  342. package/dist/http/routes/learn/index.js.map +0 -1
  343. package/dist/http/routes/learn/org.d.ts +0 -7
  344. package/dist/http/routes/learn/org.js +0 -50
  345. package/dist/http/routes/learn/org.js.map +0 -1
  346. package/dist/http/routes/learn/progress.d.ts +0 -7
  347. package/dist/http/routes/learn/progress.js +0 -63
  348. package/dist/http/routes/learn/progress.js.map +0 -1
  349. package/dist/http/schemas/learn.js.map +0 -1
  350. package/dist/package.js +0 -6
  351. package/dist/package.js.map +0 -1
@@ -1,8 +1,9 @@
1
- import { ErrorBody } from "../schemas/shared.js";
1
+ import { refusals } from "../schemas/shared.js";
2
+ import { resolveScope } from "../scope.js";
2
3
  import { ActionInvocationResult, AvailableIntegrationsList, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, InvokeActionRequest, ReconnectRequest } from "../schemas/integrations.js";
3
4
  import "../schemas/index.js";
4
- import { NotFoundError } from "@headless-lms/core/shared/errors";
5
5
  import { z } from "zod";
6
+ import { NotFoundError } from "@headless-lms/core/shared/errors";
6
7
  //#region src/http/routes/integrations.ts
7
8
  function toApi(connection) {
8
9
  const { credentialRef: _credentialRef, ...rest } = connection;
@@ -23,17 +24,21 @@ async function integrationsRoutes(app, container) {
23
24
  const r = app.withTypeProvider();
24
25
  const integrations = container.integrations;
25
26
  const tags = ["Integrations"];
27
+ const staff = async (req) => {
28
+ await resolveScope(container, req);
29
+ };
26
30
  r.route({
27
31
  method: "GET",
28
32
  url: "/api/integrations/available",
29
- preHandler: app.requireOrgSession,
33
+ preHandler: staff,
30
34
  schema: {
31
35
  operationId: "listAvailableIntegrations",
32
36
  tags,
33
- summary: "List the integrations this deployment supports, with their config schemas",
37
+ summary: "List the integrations this deployment supports (staff)",
38
+ description: "Staff only (owner, admin, instructor). Each with the JSON Schemas of its config, its secrets and its actions.",
34
39
  response: {
35
40
  200: AvailableIntegrationsList,
36
- 401: ErrorBody
41
+ ...refusals(403)
37
42
  }
38
43
  },
39
44
  handler: async () => integrations.available()
@@ -41,15 +46,15 @@ async function integrationsRoutes(app, container) {
41
46
  r.route({
42
47
  method: "GET",
43
48
  url: "/api/integrations",
44
- preHandler: app.requireOrgSession,
49
+ preHandler: staff,
45
50
  schema: {
46
51
  operationId: "listConnections",
47
52
  tags,
48
- summary: "List the organization's integration connections",
53
+ summary: "List the organization's integration connections (staff)",
54
+ description: "Staff only (owner, admin, instructor). Secrets are never returned.",
49
55
  response: {
50
56
  200: ConnectionsList,
51
- 400: ErrorBody,
52
- 401: ErrorBody
57
+ ...refusals(403)
53
58
  }
54
59
  },
55
60
  handler: async (req, reply) => {
@@ -61,17 +66,16 @@ async function integrationsRoutes(app, container) {
61
66
  r.route({
62
67
  method: "POST",
63
68
  url: "/api/integrations",
64
- preHandler: app.requireOrgSession,
69
+ preHandler: staff,
65
70
  schema: {
66
71
  operationId: "connectIntegration",
67
72
  tags,
68
- summary: "Connect an integration (stores its secrets encrypted)",
73
+ summary: "Connect an integration (staff)",
74
+ description: "Staff only (owner, admin, instructor). Stores the secrets encrypted; they are never returned. 400 when the integration is unknown or the config is invalid; 409 when the organization already has a connection to it.",
69
75
  body: ConnectRequest,
70
76
  response: {
71
77
  201: Connection,
72
- 400: ErrorBody,
73
- 401: ErrorBody,
74
- 409: ErrorBody
78
+ ...refusals(400, 403, 409)
75
79
  }
76
80
  },
77
81
  handler: async (req, reply) => {
@@ -84,17 +88,16 @@ async function integrationsRoutes(app, container) {
84
88
  r.route({
85
89
  method: "GET",
86
90
  url: "/api/integrations/:id",
87
- preHandler: app.requireOrgSession,
91
+ preHandler: staff,
88
92
  schema: {
89
93
  operationId: "getConnection",
90
94
  tags,
91
- summary: "Get a connection",
95
+ summary: "Get a connection (staff)",
96
+ description: "Staff only (owner, admin, instructor). Secrets are never returned.",
92
97
  params: ConnectionIdParam,
93
98
  response: {
94
99
  200: Connection,
95
- 400: ErrorBody,
96
- 401: ErrorBody,
97
- 404: ErrorBody
100
+ ...refusals(403, 404)
98
101
  }
99
102
  },
100
103
  handler: async (req, reply) => {
@@ -108,18 +111,17 @@ async function integrationsRoutes(app, container) {
108
111
  r.route({
109
112
  method: "PATCH",
110
113
  url: "/api/integrations/:id",
111
- preHandler: app.requireOrgSession,
114
+ preHandler: staff,
112
115
  schema: {
113
116
  operationId: "configureConnection",
114
117
  tags,
115
- summary: "Change a connection's configuration or active flag",
118
+ summary: "Change a connection's configuration or active flag (staff)",
119
+ description: "Staff only (owner, admin, instructor). 400 when the config is invalid for the integration.",
116
120
  params: ConnectionIdParam,
117
121
  body: ConfigureRequest,
118
122
  response: {
119
123
  200: Connection,
120
- 400: ErrorBody,
121
- 401: ErrorBody,
122
- 404: ErrorBody
124
+ ...refusals(400, 403, 404)
123
125
  }
124
126
  },
125
127
  handler: async (req, reply) => {
@@ -133,18 +135,17 @@ async function integrationsRoutes(app, container) {
133
135
  r.route({
134
136
  method: "POST",
135
137
  url: "/api/integrations/:id/reconnect",
136
- preHandler: app.requireOrgSession,
138
+ preHandler: staff,
137
139
  schema: {
138
140
  operationId: "reconnectIntegration",
139
141
  tags,
140
- summary: "Replace a connection's secrets (re-authenticate)",
142
+ summary: "Replace a connection's secrets (staff)",
143
+ description: "Staff only (owner, admin, instructor). The new secrets replace the stored ones.",
141
144
  params: ConnectionIdParam,
142
145
  body: ReconnectRequest,
143
146
  response: {
144
147
  200: Connection,
145
- 400: ErrorBody,
146
- 401: ErrorBody,
147
- 404: ErrorBody
148
+ ...refusals(403, 404)
148
149
  }
149
150
  },
150
151
  handler: async (req, reply) => {
@@ -158,20 +159,17 @@ async function integrationsRoutes(app, container) {
158
159
  r.route({
159
160
  method: "POST",
160
161
  url: "/api/integrations/:id/actions/:actionId",
161
- preHandler: app.requireOrgSession,
162
+ preHandler: staff,
162
163
  schema: {
163
164
  operationId: "invokeConnectionAction",
164
165
  tags,
165
- summary: "Invoke one of a connection's actions (e.g. a listing that feeds a picker)",
166
+ summary: "Invoke one of a connection's actions (staff)",
167
+ description: "Staff only (owner, admin, instructor). Runs the action, such as a listing that feeds a picker, with `input` checked against its input schema. 400 when the action fails or rejects the input; 404 when the connection or action does not exist; 409 when the connection is inactive.",
166
168
  params: ConnectionActionParams,
167
169
  body: InvokeActionRequest,
168
170
  response: {
169
171
  200: ActionInvocationResult,
170
- 400: ErrorBody,
171
- 401: ErrorBody,
172
- 404: ErrorBody,
173
- 409: ErrorBody,
174
- 502: ErrorBody
172
+ ...refusals(400, 403, 404, 409)
175
173
  }
176
174
  },
177
175
  handler: async (req, reply) => {
@@ -183,17 +181,16 @@ async function integrationsRoutes(app, container) {
183
181
  r.route({
184
182
  method: "DELETE",
185
183
  url: "/api/integrations/:id",
186
- preHandler: app.requireOrgSession,
184
+ preHandler: staff,
187
185
  schema: {
188
186
  operationId: "disconnectIntegration",
189
187
  tags,
190
- summary: "Disconnect an integration (destroys its stored secrets)",
188
+ summary: "Disconnect an integration (staff)",
189
+ description: "Staff only (owner, admin, instructor). Destroys its stored secrets.",
191
190
  params: ConnectionIdParam,
192
191
  response: {
193
192
  204: z.void(),
194
- 400: ErrorBody,
195
- 401: ErrorBody,
196
- 404: ErrorBody
193
+ ...refusals(403, 404)
197
194
  }
198
195
  },
199
196
  handler: async (req, reply) => {
@@ -1 +1 @@
1
- {"version":3,"file":"integrations.js","names":[],"sources":["../../../src/http/routes/integrations.ts"],"sourcesContent":["// HTTP routes for integrations (an org's connections to external services).\n// All require a session with an active organization. Credentials are\n// write-only: accepted on connect/reconnect, never present in a response —\n// `toApi` strips the credentialRef so not even the reference leaks.\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport {\n ActionInvocationResult,\n AvailableIntegrationsList,\n ConfigureRequest,\n ConnectRequest,\n Connection,\n ConnectionActionParams,\n ConnectionIdParam,\n ConnectionsList,\n ErrorBody,\n InvokeActionRequest,\n ReconnectRequest,\n} from '../schemas/index.js';\nimport type { Connection as DomainConnection } from '@headless-lms/core/integrations';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../app/container.js';\n\nfunction toApi(connection: DomainConnection): Connection {\n const { credentialRef: _credentialRef, ...rest } = connection;\n return rest;\n}\n\n/** Resolve the session's active org to the domain org id, or 400 and return null. */\nasync function resolveOrgId(req: FastifyRequest, reply: FastifyReply): Promise<string | null> {\n if (!req.orgId) {\n await reply.code(400).send({ error: 'no_active_org', message: 'No active organization' });\n return null;\n }\n return req.orgId;\n}\n\nexport async function integrationsRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const integrations = container.integrations;\n const tags = ['Integrations'];\n\n r.route({\n method: 'GET',\n url: '/api/integrations/available',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listAvailableIntegrations',\n tags,\n summary: 'List the integrations this deployment supports, with their config schemas',\n response: { 200: AvailableIntegrationsList, 401: ErrorBody },\n },\n handler: async () => integrations.available(),\n });\n\n r.route({\n method: 'GET',\n url: '/api/integrations',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listConnections',\n tags,\n summary: \"List the organization's integration connections\",\n response: { 200: ConnectionsList, 400: ErrorBody, 401: ErrorBody },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n return (await integrations.list(orgId)).map(toApi);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/integrations',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'connectIntegration',\n tags,\n summary: 'Connect an integration (stores its secrets encrypted)',\n body: ConnectRequest,\n response: { 201: Connection, 400: ErrorBody, 401: ErrorBody, 409: ErrorBody },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.connect(orgId, req.body);\n return reply.code(201).send(toApi(connection));\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/integrations/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getConnection',\n tags,\n summary: 'Get a connection',\n params: ConnectionIdParam,\n response: { 200: Connection, 400: ErrorBody, 401: ErrorBody, 404: ErrorBody },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.get(orgId, req.params.id);\n if (!connection) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return toApi(connection);\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/integrations/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'configureConnection',\n tags,\n summary: \"Change a connection's configuration or active flag\",\n params: ConnectionIdParam,\n body: ConfigureRequest,\n response: { 200: Connection, 400: ErrorBody, 401: ErrorBody, 404: ErrorBody },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.configure(orgId, req.params.id, req.body);\n if (!connection) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return toApi(connection);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/integrations/:id/reconnect',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'reconnectIntegration',\n tags,\n summary: \"Replace a connection's secrets (re-authenticate)\",\n params: ConnectionIdParam,\n body: ReconnectRequest,\n response: { 200: Connection, 400: ErrorBody, 401: ErrorBody, 404: ErrorBody },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.reconnect(orgId, req.params.id, req.body.secrets);\n if (!connection) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return toApi(connection);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/integrations/:id/actions/:actionId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'invokeConnectionAction',\n tags,\n summary: \"Invoke one of a connection's actions (e.g. a listing that feeds a picker)\",\n params: ConnectionActionParams,\n body: InvokeActionRequest,\n response: {\n 200: ActionInvocationResult,\n 400: ErrorBody,\n 401: ErrorBody,\n 404: ErrorBody,\n 409: ErrorBody,\n 502: ErrorBody,\n },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const output = await integrations.invoke(\n orgId,\n req.params.id,\n req.params.actionId,\n req.body.input ?? {},\n );\n return { output: output as Record<string, unknown> };\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/integrations/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'disconnectIntegration',\n tags,\n summary: 'Disconnect an integration (destroys its stored secrets)',\n params: ConnectionIdParam,\n response: { 204: z.void(), 400: ErrorBody, 401: ErrorBody, 404: ErrorBody },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const removed = await integrations.disconnect(orgId, req.params.id);\n if (!removed) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return reply.code(204).send();\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"integrations.js","names":[],"sources":["../../../src/http/routes/integrations.ts"],"sourcesContent":["// HTTP routes for integrations (an org's connections to external services).\n// All require a session with an active organization. Credentials are\n// write-only: accepted on connect/reconnect, never present in a response —\n// `toApi` strips the credentialRef so not even the reference leaks.\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport {\n ActionInvocationResult,\n AvailableIntegrationsList,\n ConfigureRequest,\n ConnectRequest,\n Connection,\n ConnectionActionParams,\n ConnectionIdParam,\n ConnectionsList,\n InvokeActionRequest,\n ReconnectRequest,\n refusals,\n} from '../schemas/index.js';\nimport type { Connection as DomainConnection } from '@headless-lms/core/integrations';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../app/container.js';\nimport { resolveScope } from '../scope.js';\n\nfunction toApi(connection: DomainConnection): Connection {\n const { credentialRef: _credentialRef, ...rest } = connection;\n return rest;\n}\n\n/** Resolve the session's active org to the domain org id, or 400 and return null. */\nasync function resolveOrgId(req: FastifyRequest, reply: FastifyReply): Promise<string | null> {\n if (!req.orgId) {\n await reply.code(400).send({ error: 'no_active_org', message: 'No active organization' });\n return null;\n }\n return req.orgId;\n}\n\nexport async function integrationsRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const integrations = container.integrations;\n const tags = ['Integrations'];\n const staff = async (req: FastifyRequest) => {\n await resolveScope(container, req);\n };\n\n r.route({\n method: 'GET',\n url: '/api/integrations/available',\n preHandler: staff,\n schema: {\n operationId: 'listAvailableIntegrations',\n tags,\n summary: 'List the integrations this deployment supports (staff)',\n description:\n 'Staff only (owner, admin, instructor). Each with the JSON Schemas of its config, its secrets and its actions.',\n response: { 200: AvailableIntegrationsList, ...refusals(403) },\n },\n handler: async () => integrations.available(),\n });\n\n r.route({\n method: 'GET',\n url: '/api/integrations',\n preHandler: staff,\n schema: {\n operationId: 'listConnections',\n tags,\n summary: \"List the organization's integration connections (staff)\",\n description: 'Staff only (owner, admin, instructor). Secrets are never returned.',\n response: { 200: ConnectionsList, ...refusals(403) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n return (await integrations.list(orgId)).map(toApi);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/integrations',\n preHandler: staff,\n schema: {\n operationId: 'connectIntegration',\n tags,\n summary: 'Connect an integration (staff)',\n description:\n 'Staff only (owner, admin, instructor). Stores the secrets encrypted; they are never returned. 400 when the integration is unknown or the config is invalid; 409 when the organization already has a connection to it.',\n body: ConnectRequest,\n response: { 201: Connection, ...refusals(400, 403, 409) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.connect(orgId, req.body);\n return reply.code(201).send(toApi(connection));\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/integrations/:id',\n preHandler: staff,\n schema: {\n operationId: 'getConnection',\n tags,\n summary: 'Get a connection (staff)',\n description: 'Staff only (owner, admin, instructor). Secrets are never returned.',\n params: ConnectionIdParam,\n response: { 200: Connection, ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.get(orgId, req.params.id);\n if (!connection) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return toApi(connection);\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/integrations/:id',\n preHandler: staff,\n schema: {\n operationId: 'configureConnection',\n tags,\n summary: \"Change a connection's configuration or active flag (staff)\",\n description:\n 'Staff only (owner, admin, instructor). 400 when the config is invalid for the integration.',\n params: ConnectionIdParam,\n body: ConfigureRequest,\n response: { 200: Connection, ...refusals(400, 403, 404) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.configure(orgId, req.params.id, req.body);\n if (!connection) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return toApi(connection);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/integrations/:id/reconnect',\n preHandler: staff,\n schema: {\n operationId: 'reconnectIntegration',\n tags,\n summary: \"Replace a connection's secrets (staff)\",\n description:\n 'Staff only (owner, admin, instructor). The new secrets replace the stored ones.',\n params: ConnectionIdParam,\n body: ReconnectRequest,\n response: { 200: Connection, ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const connection = await integrations.reconnect(orgId, req.params.id, req.body.secrets);\n if (!connection) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return toApi(connection);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/integrations/:id/actions/:actionId',\n preHandler: staff,\n schema: {\n operationId: 'invokeConnectionAction',\n tags,\n summary: \"Invoke one of a connection's actions (staff)\",\n description:\n 'Staff only (owner, admin, instructor). Runs the action, such as a listing that feeds a picker, with `input` checked against its input schema. 400 when the action fails or rejects the input; 404 when the connection or action does not exist; 409 when the connection is inactive.',\n params: ConnectionActionParams,\n body: InvokeActionRequest,\n response: { 200: ActionInvocationResult, ...refusals(400, 403, 404, 409) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const output = await integrations.invoke(\n orgId,\n req.params.id,\n req.params.actionId,\n req.body.input ?? {},\n );\n return { output: output as Record<string, unknown> };\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/integrations/:id',\n preHandler: staff,\n schema: {\n operationId: 'disconnectIntegration',\n tags,\n summary: 'Disconnect an integration (staff)',\n description: 'Staff only (owner, admin, instructor). Destroys its stored secrets.',\n params: ConnectionIdParam,\n response: { 204: z.void(), ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const orgId = await resolveOrgId(req, reply);\n if (!orgId) {\n return;\n }\n const removed = await integrations.disconnect(orgId, req.params.id);\n if (!removed) {\n throw new NotFoundError('Connection', req.params.id);\n }\n return reply.code(204).send();\n },\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Container } from "../../../app/container.js";
2
+ //#region src/http/routes/member/actor.d.ts
3
+ declare function actorOf(container: Container, orgId: string, userId: string): Promise<{
4
+ id: string;
5
+ orgId: string;
6
+ userId: string;
7
+ role: "owner" | "admin" | "instructor" | "moderator" | "student";
8
+ status: "active" | "invited";
9
+ createdAt: Date;
10
+ updatedAt: Date;
11
+ }>;
12
+ //#endregion
13
+ export { actorOf };
14
+ //# sourceMappingURL=actor.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { ForbiddenError } from "@headless-lms/core/shared/errors";
2
+ //#region src/http/routes/member/actor.ts
3
+ async function actorOf(container, orgId, userId) {
4
+ const orgUser = await container.organizations.getOrgUser(orgId, userId);
5
+ if (!orgUser) throw new ForbiddenError("You are not a member of this organization");
6
+ return orgUser;
7
+ }
8
+ //#endregion
9
+ export { actorOf };
10
+
11
+ //# sourceMappingURL=actor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actor.js","names":[],"sources":["../../../../src/http/routes/member/actor.ts"],"sourcesContent":["import { ForbiddenError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../../app/container.js';\n\nexport async function actorOf(container: Container, orgId: string, userId: string) {\n const orgUser = await container.organizations.getOrgUser(orgId, userId);\n if (!orgUser) {\n throw new ForbiddenError('You are not a member of this organization');\n }\n return orgUser;\n}\n"],"mappings":";;AAGA,eAAsB,QAAQ,WAAsB,OAAe,QAAgB;CACjF,MAAM,UAAU,MAAM,UAAU,cAAc,WAAW,OAAO,MAAM;CACtE,IAAI,CAAC,SACH,MAAM,IAAI,eAAe,2CAA2C;CAEtE,OAAO;AACT"}
@@ -0,0 +1,7 @@
1
+ import { Container } from "../../../app/container.js";
2
+ import { FastifyInstance } from "fastify";
3
+ //#region src/http/routes/member/assets.d.ts
4
+ declare function memberAssetsRoutes(app: FastifyInstance, container: Container): Promise<void>;
5
+ //#endregion
6
+ export { memberAssetsRoutes };
7
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1,79 @@
1
+ import { refusals } from "../../schemas/shared.js";
2
+ import { Asset, AssetIdParam, RequestMemberUpload, UploadTicket } from "../../schemas/assets.js";
3
+ import "../../schemas/index.js";
4
+ import { actorOf } from "./actor.js";
5
+ import { z } from "zod";
6
+ import { NotFoundError } from "@headless-lms/core/shared/errors";
7
+ //#region src/http/routes/member/assets.ts
8
+ const tags = ["Assets"];
9
+ async function memberAssetsRoutes(app, container) {
10
+ const r = app.withTypeProvider();
11
+ r.route({
12
+ method: "POST",
13
+ url: "/api/member/uploads",
14
+ preHandler: app.requireOrgSession,
15
+ schema: {
16
+ operationId: "requestMemberUpload",
17
+ tags,
18
+ summary: "Register an image you are about to upload and get a presigned upload URL",
19
+ description: "For a member of the organization. Member uploads are images only (409 otherwise). The asset is yours: only you can finalize it or attach it to your profile, a post or a message. You can delete it while nothing references it.",
20
+ body: RequestMemberUpload,
21
+ response: {
22
+ 201: UploadTicket,
23
+ ...refusals(403, 409)
24
+ }
25
+ },
26
+ handler: async (req, reply) => {
27
+ const actor = await actorOf(container, req.orgId, req.userId);
28
+ const ticket = await container.assets.requestMemberUpload(req.orgId, actor.id, req.body);
29
+ return reply.code(201).send(ticket);
30
+ }
31
+ });
32
+ r.route({
33
+ method: "POST",
34
+ url: "/api/member/uploads/:id/finalize",
35
+ preHandler: app.requireOrgSession,
36
+ schema: {
37
+ operationId: "finalizeMemberUpload",
38
+ tags,
39
+ summary: "Confirm an upload you started",
40
+ description: "Uploader only; anyone else gets 404. Reads the stored size and content type. A file that is not an image or is over the size limit is discarded and answered with 409. A finalized file moves where the upload URL no longer reaches; finalizing it again returns it unchanged.",
41
+ params: AssetIdParam,
42
+ response: {
43
+ 200: Asset,
44
+ ...refusals(403, 404, 409)
45
+ }
46
+ },
47
+ handler: async (req) => {
48
+ const actor = await actorOf(container, req.orgId, req.userId);
49
+ const asset = await container.assets.confirmOwn(req.orgId, req.params.id, actor.id);
50
+ if (!asset) throw new NotFoundError("Asset", req.params.id);
51
+ return asset;
52
+ }
53
+ });
54
+ r.route({
55
+ method: "DELETE",
56
+ url: "/api/member/uploads/:id",
57
+ preHandler: app.requireOrgSession,
58
+ schema: {
59
+ operationId: "deleteMemberUpload",
60
+ tags,
61
+ summary: "Delete an upload of yours that nothing references",
62
+ description: "Uploader only; anyone else gets 404. 409 while a profile, post or message still uses it.",
63
+ params: AssetIdParam,
64
+ response: {
65
+ 204: z.void(),
66
+ ...refusals(403, 404, 409)
67
+ }
68
+ },
69
+ handler: async (req, reply) => {
70
+ const actor = await actorOf(container, req.orgId, req.userId);
71
+ if (!await container.assets.removeOwn(req.orgId, req.params.id, actor.id)) throw new NotFoundError("Asset", req.params.id);
72
+ return reply.code(204).send();
73
+ }
74
+ });
75
+ }
76
+ //#endregion
77
+ export { memberAssetsRoutes };
78
+
79
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","names":[],"sources":["../../../../src/http/routes/member/assets.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport {\n Asset,\n AssetIdParam,\n RequestMemberUpload,\n UploadTicket,\n refusals,\n} from '../../schemas/index.js';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport { actorOf } from './actor.js';\nimport type { Container } from '../../../app/container.js';\n\nconst tags = ['Assets'];\n\nexport async function memberAssetsRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n\n r.route({\n method: 'POST',\n url: '/api/member/uploads',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'requestMemberUpload',\n tags,\n summary: 'Register an image you are about to upload and get a presigned upload URL',\n description:\n 'For a member of the organization. Member uploads are images only (409 otherwise). The asset is yours: only you can finalize it or attach it to your profile, a post or a message. You can delete it while nothing references it.',\n body: RequestMemberUpload,\n response: { 201: UploadTicket, ...refusals(403, 409) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const ticket = await container.assets.requestMemberUpload(req.orgId, actor.id, req.body);\n return reply.code(201).send(ticket);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/uploads/:id/finalize',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'finalizeMemberUpload',\n tags,\n summary: 'Confirm an upload you started',\n description:\n 'Uploader only; anyone else gets 404. Reads the stored size and content type. A file that is not an image or is over the size limit is discarded and answered with 409. A finalized file moves where the upload URL no longer reaches; finalizing it again returns it unchanged.',\n params: AssetIdParam,\n response: { 200: Asset, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const asset = await container.assets.confirmOwn(req.orgId, req.params.id, actor.id);\n if (!asset) {\n throw new NotFoundError('Asset', req.params.id);\n }\n return asset;\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/member/uploads/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'deleteMemberUpload',\n tags,\n summary: 'Delete an upload of yours that nothing references',\n description:\n 'Uploader only; anyone else gets 404. 409 while a profile, post or message still uses it.',\n params: AssetIdParam,\n response: { 204: z.void(), ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const removed = await container.assets.removeOwn(req.orgId, req.params.id, actor.id);\n if (!removed) {\n throw new NotFoundError('Asset', req.params.id);\n }\n return reply.code(204).send();\n },\n });\n}\n"],"mappings":";;;;;;;AAcA,MAAM,OAAO,CAAC,QAAQ;AAEtB,eAAsB,mBACpB,KACA,WACe;CACf,MAAM,IAAI,IAAI,iBAAkC;CAEhD,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,MAAM;GACN,UAAU;IAAE,KAAK;IAAc,GAAG,SAAS,KAAK,GAAG;GAAE;EACvD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,QAAQ,WAAW,IAAI,OAAO,IAAI,MAAM;GAC5D,MAAM,SAAS,MAAM,UAAU,OAAO,oBAAoB,IAAI,OAAO,MAAM,IAAI,IAAI,IAAI;GACvF,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,MAAM;EACpC;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK;IAAO,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EACrD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,QAAQ,WAAW,IAAI,OAAO,IAAI,MAAM;GAC5D,MAAM,QAAQ,MAAM,UAAU,OAAO,WAAW,IAAI,OAAO,IAAI,OAAO,IAAI,MAAM,EAAE;GAClF,IAAI,CAAC,OACH,MAAM,IAAI,cAAc,SAAS,IAAI,OAAO,EAAE;GAEhD,OAAO;EACT;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK,EAAE,KAAK;IAAG,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EACxD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,QAAQ,WAAW,IAAI,OAAO,IAAI,MAAM;GAE5D,IAAI,CAAC,MADiB,UAAU,OAAO,UAAU,IAAI,OAAO,IAAI,OAAO,IAAI,MAAM,EAAE,GAEjF,MAAM,IAAI,cAAc,SAAS,IAAI,OAAO,EAAE;GAEhD,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;EAC9B;CACF,CAAC;AACH"}
@@ -0,0 +1,7 @@
1
+ import { Container } from "../../../app/container.js";
2
+ import { FastifyInstance } from "fastify";
3
+ //#region src/http/routes/member/chats.d.ts
4
+ declare function memberChatRoutes(app: FastifyInstance, container: Container): Promise<void>;
5
+ //#endregion
6
+ export { memberChatRoutes };
7
+ //# sourceMappingURL=chats.d.ts.map