@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.
- package/dist/_virtual/_rolldown/runtime.js +5 -0
- package/dist/app/community-mail.d.ts +26 -0
- package/dist/app/community-mail.js +96 -0
- package/dist/app/community-mail.js.map +1 -0
- package/dist/app/container.d.ts +18 -14
- package/dist/app/container.js +136 -43
- package/dist/app/container.js.map +1 -1
- package/dist/app/mcp-endpoints.d.ts +13 -0
- package/dist/app/mcp-endpoints.js +25 -0
- package/dist/app/mcp-endpoints.js.map +1 -0
- package/dist/http/config.d.ts +2 -1
- package/dist/http/errors.d.ts +14 -0
- package/dist/http/errors.js +147 -0
- package/dist/http/errors.js.map +1 -0
- package/dist/http/mcp/catalogue.d.ts +37 -0
- package/dist/http/mcp/catalogue.js +69 -0
- package/dist/http/mcp/catalogue.js.map +1 -0
- package/dist/http/mcp/challenge.d.ts +7 -0
- package/dist/http/mcp/challenge.js +35 -0
- package/dist/http/mcp/challenge.js.map +1 -0
- package/dist/http/mcp/input-schema.d.ts +7 -0
- package/dist/http/mcp/input-schema.js +28 -0
- package/dist/http/mcp/input-schema.js.map +1 -0
- package/dist/http/mcp/route.d.ts +8 -0
- package/dist/http/mcp/route.js +75 -0
- package/dist/http/mcp/route.js.map +1 -0
- package/dist/http/mcp/server.d.ts +8 -0
- package/dist/http/mcp/server.js +31 -0
- package/dist/http/mcp/server.js.map +1 -0
- package/dist/http/mcp/test-support.d.ts +55 -0
- package/dist/http/mcp/test-support.js +151 -0
- package/dist/http/mcp/test-support.js.map +1 -0
- package/dist/http/mcp/tool.d.ts +48 -0
- package/dist/http/mcp/tool.js +58 -0
- package/dist/http/mcp/tool.js.map +1 -0
- package/dist/http/mcp/tools/automations.d.ts +6 -0
- package/dist/http/mcp/tools/automations.js +120 -0
- package/dist/http/mcp/tools/automations.js.map +1 -0
- package/dist/http/mcp/tools/catalog.d.ts +6 -0
- package/dist/http/mcp/tools/catalog.js +200 -0
- package/dist/http/mcp/tools/catalog.js.map +1 -0
- package/dist/http/mcp/tools/comments.d.ts +6 -0
- package/dist/http/mcp/tools/comments.js +70 -0
- package/dist/http/mcp/tools/comments.js.map +1 -0
- package/dist/http/mcp/tools/communities.d.ts +6 -0
- package/dist/http/mcp/tools/communities.js +175 -0
- package/dist/http/mcp/tools/communities.js.map +1 -0
- package/dist/http/mcp/tools/community-members.d.ts +6 -0
- package/dist/http/mcp/tools/community-members.js +89 -0
- package/dist/http/mcp/tools/community-members.js.map +1 -0
- package/dist/http/mcp/tools/community-moderation.d.ts +6 -0
- package/dist/http/mcp/tools/community-moderation.js +144 -0
- package/dist/http/mcp/tools/community-moderation.js.map +1 -0
- package/dist/http/mcp/tools/courses.d.ts +6 -0
- package/dist/http/mcp/tools/courses.js +121 -0
- package/dist/http/mcp/tools/courses.js.map +1 -0
- package/dist/http/mcp/tools/index.d.ts +6 -0
- package/dist/http/mcp/tools/index.js +23 -0
- package/dist/http/mcp/tools/index.js.map +1 -0
- package/dist/http/mcp/tools/people.d.ts +6 -0
- package/dist/http/mcp/tools/people.js +145 -0
- package/dist/http/mcp/tools/people.js.map +1 -0
- package/dist/http/plugins/auth.js +13 -5
- package/dist/http/plugins/auth.js.map +1 -1
- package/dist/http/plugins/error-handler.d.ts +2 -1
- package/dist/http/plugins/error-handler.js +49 -65
- package/dist/http/plugins/error-handler.js.map +1 -1
- package/dist/http/plugins/openapi.js +49 -2
- package/dist/http/plugins/openapi.js.map +1 -1
- package/dist/http/routes/access.d.ts +7 -0
- package/dist/http/routes/access.js +140 -0
- package/dist/http/routes/access.js.map +1 -0
- package/dist/http/routes/activities.js +68 -23
- package/dist/http/routes/activities.js.map +1 -1
- package/dist/http/routes/assets.js +60 -55
- package/dist/http/routes/assets.js.map +1 -1
- package/dist/http/routes/automations.js +44 -24
- package/dist/http/routes/automations.js.map +1 -1
- package/dist/http/routes/bundles.js +29 -18
- package/dist/http/routes/bundles.js.map +1 -1
- package/dist/http/routes/communities.d.ts +7 -0
- package/dist/http/routes/communities.js +462 -0
- package/dist/http/routes/communities.js.map +1 -0
- package/dist/http/routes/community-moderation.d.ts +7 -0
- package/dist/http/routes/community-moderation.js +425 -0
- package/dist/http/routes/community-moderation.js.map +1 -0
- package/dist/http/routes/course-analytics.js +9 -7
- package/dist/http/routes/course-analytics.js.map +1 -1
- package/dist/http/routes/courses.js +30 -15
- package/dist/http/routes/courses.js.map +1 -1
- package/dist/http/routes/dashboard.js +15 -6
- package/dist/http/routes/dashboard.js.map +1 -1
- package/dist/http/routes/discussion.js +34 -26
- package/dist/http/routes/discussion.js.map +1 -1
- package/dist/http/routes/downloads.js +48 -30
- package/dist/http/routes/downloads.js.map +1 -1
- package/dist/http/routes/entitlements.js +16 -7
- package/dist/http/routes/entitlements.js.map +1 -1
- package/dist/http/routes/integrations.js +38 -41
- package/dist/http/routes/integrations.js.map +1 -1
- package/dist/http/routes/member/actor.d.ts +14 -0
- package/dist/http/routes/member/actor.js +11 -0
- package/dist/http/routes/member/actor.js.map +1 -0
- package/dist/http/routes/member/assets.d.ts +7 -0
- package/dist/http/routes/member/assets.js +79 -0
- package/dist/http/routes/member/assets.js.map +1 -0
- package/dist/http/routes/member/chats.d.ts +7 -0
- package/dist/http/routes/member/chats.js +456 -0
- package/dist/http/routes/member/chats.js.map +1 -0
- package/dist/http/routes/member/comments.d.ts +7 -0
- package/dist/http/routes/member/comments.js +187 -0
- package/dist/http/routes/member/comments.js.map +1 -0
- package/dist/http/routes/member/community.d.ts +7 -0
- package/dist/http/routes/member/community.js +288 -0
- package/dist/http/routes/member/community.js.map +1 -0
- package/dist/http/routes/member/courses.d.ts +7 -0
- package/dist/http/routes/member/courses.js +101 -0
- package/dist/http/routes/member/courses.js.map +1 -0
- package/dist/http/routes/member/downloads.d.ts +7 -0
- package/dist/http/routes/member/downloads.js +56 -0
- package/dist/http/routes/member/downloads.js.map +1 -0
- package/dist/http/routes/member/files.d.ts +7 -0
- package/dist/http/routes/member/files.js +184 -0
- package/dist/http/routes/member/files.js.map +1 -0
- package/dist/http/routes/member/index.d.ts +7 -0
- package/dist/http/routes/member/index.js +31 -0
- package/dist/http/routes/member/index.js.map +1 -0
- package/dist/http/routes/member/notifications.d.ts +7 -0
- package/dist/http/routes/member/notifications.js +101 -0
- package/dist/http/routes/member/notifications.js.map +1 -0
- package/dist/http/routes/member/org.d.ts +7 -0
- package/dist/http/routes/member/org.js +56 -0
- package/dist/http/routes/member/org.js.map +1 -0
- package/dist/http/routes/member/posts.d.ts +7 -0
- package/dist/http/routes/member/posts.js +612 -0
- package/dist/http/routes/member/posts.js.map +1 -0
- package/dist/http/routes/member/profile.d.ts +7 -0
- package/dist/http/routes/member/profile.js +48 -0
- package/dist/http/routes/member/profile.js.map +1 -0
- package/dist/http/routes/member/progress.d.ts +7 -0
- package/dist/http/routes/member/progress.js +60 -0
- package/dist/http/routes/member/progress.js.map +1 -0
- package/dist/http/routes/organizations.js +49 -24
- package/dist/http/routes/organizations.js.map +1 -1
- package/dist/http/routes/students.js +32 -47
- package/dist/http/routes/students.js.map +1 -1
- package/dist/http/routes/webhooks.js +26 -18
- package/dist/http/routes/webhooks.js.map +1 -1
- package/dist/http/routes.js +8 -2
- package/dist/http/routes.js.map +1 -1
- package/dist/http/schemas/access.d.ts +146 -0
- package/dist/http/schemas/access.js +36 -0
- package/dist/http/schemas/access.js.map +1 -0
- package/dist/http/schemas/activities.d.ts +3 -1
- package/dist/http/schemas/activities.js +4 -4
- package/dist/http/schemas/activities.js.map +1 -1
- package/dist/http/schemas/assets.d.ts +73 -74
- package/dist/http/schemas/assets.js +23 -13
- package/dist/http/schemas/assets.js.map +1 -1
- package/dist/http/schemas/automations.d.ts +10 -0
- package/dist/http/schemas/bundles.js +6 -6
- package/dist/http/schemas/bundles.js.map +1 -1
- package/dist/http/schemas/chats.d.ts +386 -0
- package/dist/http/schemas/chats.js +58 -0
- package/dist/http/schemas/chats.js.map +1 -0
- package/dist/http/schemas/community.d.ts +537 -0
- package/dist/http/schemas/community.js +129 -0
- package/dist/http/schemas/community.js.map +1 -0
- package/dist/http/schemas/content.d.ts +4 -2
- package/dist/http/schemas/content.js +11 -8
- package/dist/http/schemas/content.js.map +1 -1
- package/dist/http/schemas/discussion.d.ts +76 -14
- package/dist/http/schemas/discussion.js +12 -11
- package/dist/http/schemas/discussion.js.map +1 -1
- package/dist/http/schemas/downloads.d.ts +11 -5
- package/dist/http/schemas/downloads.js +14 -11
- package/dist/http/schemas/downloads.js.map +1 -1
- package/dist/http/schemas/entitlements.d.ts +6 -6
- package/dist/http/schemas/entitlements.js +6 -6
- package/dist/http/schemas/entitlements.js.map +1 -1
- package/dist/http/schemas/files.d.ts +45 -0
- package/dist/http/schemas/files.js +25 -0
- package/dist/http/schemas/files.js.map +1 -0
- package/dist/http/schemas/index.d.ts +15 -8
- package/dist/http/schemas/index.js +15 -8
- package/dist/http/schemas/integrations.d.ts +2 -2
- package/dist/http/schemas/invites.d.ts +4 -0
- package/dist/http/schemas/invites.js +1 -0
- package/dist/http/schemas/invites.js.map +1 -1
- package/dist/http/schemas/{learn.d.ts → member.d.ts} +31 -18
- package/dist/http/schemas/{learn.js → member.js} +17 -13
- package/dist/http/schemas/member.js.map +1 -0
- package/dist/http/schemas/members.d.ts +39 -6
- package/dist/http/schemas/members.js +17 -3
- package/dist/http/schemas/members.js.map +1 -1
- package/dist/http/schemas/notifications.d.ts +227 -0
- package/dist/http/schemas/notifications.js +44 -0
- package/dist/http/schemas/notifications.js.map +1 -0
- package/dist/http/schemas/posts.d.ts +316 -0
- package/dist/http/schemas/posts.js +47 -0
- package/dist/http/schemas/posts.js.map +1 -0
- package/dist/http/schemas/profile.d.ts +23 -0
- package/dist/http/schemas/profile.js +15 -0
- package/dist/http/schemas/profile.js.map +1 -0
- package/dist/http/schemas/shared.d.ts +25 -1
- package/dist/http/schemas/shared.js +19 -2
- package/dist/http/schemas/shared.js.map +1 -1
- package/dist/http/schemas/students.d.ts +4 -10
- package/dist/http/schemas/students.js +1 -7
- package/dist/http/schemas/students.js.map +1 -1
- package/dist/http/scope.d.ts +2 -1
- package/dist/http/scope.js +20 -4
- package/dist/http/scope.js.map +1 -1
- package/dist/http/server.js +6 -1
- package/dist/http/server.js.map +1 -1
- package/dist/http/web-bridge.d.ts +1 -1
- package/dist/http/web-bridge.js +2 -2
- package/dist/http/web-bridge.js.map +1 -1
- package/dist/http/well-known.d.ts +7 -0
- package/dist/http/well-known.js +22 -0
- package/dist/http/well-known.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +78 -0
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js +1267 -0
- package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js +814 -0
- package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js +43 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js +527 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/utils.js +2 -0
- package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js +1737 -0
- package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js +137 -0
- package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +118 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js +1222 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js +91 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js +113 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js +449 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js +163 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js.map +1 -0
- package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js +3187 -0
- package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js +11 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js +16 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js +11 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js +15 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js +13 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js +34 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js +12 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js +122 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js +39 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js +99 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js +25 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js +14 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js +21 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js +6 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js +12 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js +18 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js +24 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js +9 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js +30 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js.map +1 -0
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +939 -0
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js.map +1 -0
- package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js +82 -0
- package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js.map +1 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +82 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js.map +1 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js +8 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js.map +1 -0
- package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js +83 -0
- package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js.map +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/dist/packages/server/package.js +6 -0
- package/dist/packages/server/package.js.map +1 -0
- package/package.json +9 -7
- package/dist/app/notifications.d.ts +0 -7
- package/dist/app/notifications.js +0 -26
- package/dist/app/notifications.js.map +0 -1
- package/dist/http/routes/learn/assets.d.ts +0 -8
- package/dist/http/routes/learn/assets.js +0 -32
- package/dist/http/routes/learn/assets.js.map +0 -1
- package/dist/http/routes/learn/comments.d.ts +0 -7
- package/dist/http/routes/learn/comments.js +0 -175
- package/dist/http/routes/learn/comments.js.map +0 -1
- package/dist/http/routes/learn/courses.d.ts +0 -7
- package/dist/http/routes/learn/courses.js +0 -98
- package/dist/http/routes/learn/courses.js.map +0 -1
- package/dist/http/routes/learn/downloads.d.ts +0 -7
- package/dist/http/routes/learn/downloads.js +0 -76
- package/dist/http/routes/learn/downloads.js.map +0 -1
- package/dist/http/routes/learn/index.d.ts +0 -7
- package/dist/http/routes/learn/index.js +0 -19
- package/dist/http/routes/learn/index.js.map +0 -1
- package/dist/http/routes/learn/org.d.ts +0 -7
- package/dist/http/routes/learn/org.js +0 -50
- package/dist/http/routes/learn/org.js.map +0 -1
- package/dist/http/routes/learn/progress.d.ts +0 -7
- package/dist/http/routes/learn/progress.js +0 -63
- package/dist/http/routes/learn/progress.js.map +0 -1
- package/dist/http/schemas/learn.js.map +0 -1
- package/dist/package.js +0 -6
- package/dist/package.js.map +0 -1
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { refusals } from "../../schemas/shared.js";
|
|
2
|
+
import { ActivityComments, CommentIdParam, CommentReport, CommentView, DiscussionActivityParam, EditComment, PostComment, Reactions, ReportComment, ResolveCommentFlags, SetReaction } from "../../schemas/discussion.js";
|
|
3
|
+
import "../../schemas/index.js";
|
|
4
|
+
import { actorOf } from "./actor.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
//#region src/http/routes/member/comments.ts
|
|
7
|
+
async function memberCommentsRoutes(app, container) {
|
|
8
|
+
const r = app.withTypeProvider();
|
|
9
|
+
const discussion = container.discussion;
|
|
10
|
+
const tags = ["Discussion"];
|
|
11
|
+
r.route({
|
|
12
|
+
method: "GET",
|
|
13
|
+
url: "/api/member/activities/:activityId/comments",
|
|
14
|
+
preHandler: app.requireOrgSession,
|
|
15
|
+
schema: {
|
|
16
|
+
operationId: "listActivityComments",
|
|
17
|
+
tags,
|
|
18
|
+
summary: "Read an activity's comments",
|
|
19
|
+
description: "For a student who can open the course, and staff. Returns the activity's resolved comment settings with the comments; removed comments keep their place without their body.",
|
|
20
|
+
params: DiscussionActivityParam,
|
|
21
|
+
response: {
|
|
22
|
+
200: ActivityComments,
|
|
23
|
+
...refusals(403, 404)
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
handler: async (req) => {
|
|
27
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
28
|
+
return discussion.activityComments(req.orgId, req.params.activityId, orgUser);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
r.route({
|
|
32
|
+
method: "POST",
|
|
33
|
+
url: "/api/member/activities/:activityId/comments",
|
|
34
|
+
preHandler: app.requireOrgSession,
|
|
35
|
+
schema: {
|
|
36
|
+
operationId: "postComment",
|
|
37
|
+
tags,
|
|
38
|
+
summary: "Post a comment or reply on an activity",
|
|
39
|
+
description: "For a student who can open the course, and staff, while discussion is on for the activity (403 otherwise). Lands pending when the course requires review and you are not staff. Replies nest one level and need threading on.",
|
|
40
|
+
params: DiscussionActivityParam,
|
|
41
|
+
body: PostComment,
|
|
42
|
+
response: {
|
|
43
|
+
201: CommentView,
|
|
44
|
+
...refusals(403, 404)
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
handler: async (req, reply) => {
|
|
48
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
49
|
+
const comment = await discussion.postComment(req.orgId, {
|
|
50
|
+
actor: orgUser,
|
|
51
|
+
activityId: req.params.activityId,
|
|
52
|
+
parentId: req.body.parentId,
|
|
53
|
+
body: req.body.body
|
|
54
|
+
});
|
|
55
|
+
return reply.code(201).send(comment);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
r.route({
|
|
59
|
+
method: "PATCH",
|
|
60
|
+
url: "/api/member/comments/:commentId",
|
|
61
|
+
preHandler: app.requireOrgSession,
|
|
62
|
+
schema: {
|
|
63
|
+
operationId: "editComment",
|
|
64
|
+
tags,
|
|
65
|
+
summary: "Revise your own comment",
|
|
66
|
+
description: "Author only; not even staff may revise it. Discussion must be open where the comment is, and a removed comment cannot be revised.",
|
|
67
|
+
params: CommentIdParam,
|
|
68
|
+
body: EditComment,
|
|
69
|
+
response: {
|
|
70
|
+
200: CommentView,
|
|
71
|
+
...refusals(403, 404)
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
handler: async (req) => {
|
|
75
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
76
|
+
return discussion.edit(req.orgId, req.params.commentId, orgUser, req.body.body);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
r.route({
|
|
80
|
+
method: "DELETE",
|
|
81
|
+
url: "/api/member/comments/:commentId",
|
|
82
|
+
preHandler: app.requireOrgSession,
|
|
83
|
+
schema: {
|
|
84
|
+
operationId: "deleteComment",
|
|
85
|
+
tags,
|
|
86
|
+
summary: "Delete your comment, or one you moderate",
|
|
87
|
+
description: "For the author, staff on an activity comment, or a moderator on a post comment. The comment is marked removed and keeps its place in the thread. Deleting a removed comment returns it unchanged.",
|
|
88
|
+
params: CommentIdParam,
|
|
89
|
+
response: {
|
|
90
|
+
200: CommentView,
|
|
91
|
+
...refusals(403, 404)
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
handler: async (req) => {
|
|
95
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
96
|
+
return discussion.remove(req.orgId, req.params.commentId, orgUser);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
r.route({
|
|
100
|
+
method: "PUT",
|
|
101
|
+
url: "/api/member/comments/:commentId/reaction",
|
|
102
|
+
preHandler: app.requireOrgSession,
|
|
103
|
+
schema: {
|
|
104
|
+
operationId: "setCommentReaction",
|
|
105
|
+
tags,
|
|
106
|
+
summary: "Set your reaction on a comment",
|
|
107
|
+
description: "For anyone who can read the comment, while reactions are on where it is (403 otherwise). Replaces any reaction you already had and returns the new counts.",
|
|
108
|
+
params: CommentIdParam,
|
|
109
|
+
body: SetReaction,
|
|
110
|
+
response: {
|
|
111
|
+
200: Reactions,
|
|
112
|
+
...refusals(403, 404)
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
handler: async (req) => {
|
|
116
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
117
|
+
return discussion.setReaction(req.orgId, req.params.commentId, orgUser, req.body.emoji);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
r.route({
|
|
121
|
+
method: "DELETE",
|
|
122
|
+
url: "/api/member/comments/:commentId/reaction",
|
|
123
|
+
preHandler: app.requireOrgSession,
|
|
124
|
+
schema: {
|
|
125
|
+
operationId: "clearCommentReaction",
|
|
126
|
+
tags,
|
|
127
|
+
summary: "Withdraw your reaction from a comment",
|
|
128
|
+
description: "For anyone who can read the comment. Returns the new counts.",
|
|
129
|
+
params: CommentIdParam,
|
|
130
|
+
response: {
|
|
131
|
+
200: Reactions,
|
|
132
|
+
...refusals(403, 404)
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
handler: async (req) => {
|
|
136
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
137
|
+
return discussion.setReaction(req.orgId, req.params.commentId, orgUser, null);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
r.route({
|
|
141
|
+
method: "POST",
|
|
142
|
+
url: "/api/member/comments/:commentId/reports",
|
|
143
|
+
preHandler: app.requireOrgSession,
|
|
144
|
+
schema: {
|
|
145
|
+
operationId: "reportComment",
|
|
146
|
+
tags,
|
|
147
|
+
summary: "Flag a comment for the moderators",
|
|
148
|
+
description: "For anyone who can read the comment. Flagging it again while your flag is open returns that flag.",
|
|
149
|
+
params: CommentIdParam,
|
|
150
|
+
body: ReportComment,
|
|
151
|
+
response: {
|
|
152
|
+
200: CommentReport,
|
|
153
|
+
...refusals(403, 404)
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
handler: async (req) => {
|
|
157
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
158
|
+
return discussion.reportComment(req.orgId, req.params.commentId, orgUser, req.body.reason);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
r.route({
|
|
162
|
+
method: "POST",
|
|
163
|
+
url: "/api/member/comments/:commentId/flags/resolution",
|
|
164
|
+
preHandler: app.requireOrgSession,
|
|
165
|
+
schema: {
|
|
166
|
+
operationId: "resolveCommentFlags",
|
|
167
|
+
tags,
|
|
168
|
+
summary: "Dismiss the open flags on a comment in a space you moderate",
|
|
169
|
+
description: "For a moderator of a post comment, or staff for an activity comment. Closes every open flag and leaves the comment up.",
|
|
170
|
+
params: CommentIdParam,
|
|
171
|
+
body: ResolveCommentFlags,
|
|
172
|
+
response: {
|
|
173
|
+
204: z.void(),
|
|
174
|
+
...refusals(403, 404)
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
handler: async (req, reply) => {
|
|
178
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
179
|
+
await discussion.resolveReports(req.orgId, req.params.commentId, orgUser);
|
|
180
|
+
return reply.code(204).send();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
export { memberCommentsRoutes };
|
|
186
|
+
|
|
187
|
+
//# sourceMappingURL=comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.js","names":[],"sources":["../../../../src/http/routes/member/comments.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport {\n ActivityComments,\n CommentIdParam,\n CommentReport,\n CommentView,\n DiscussionActivityParam,\n EditComment,\n PostComment,\n Reactions,\n ReportComment,\n ResolveCommentFlags,\n SetReaction,\n refusals,\n} from '../../schemas/index.js';\nimport type { Container } from '../../../app/container.js';\nimport { actorOf } from './actor.js';\n\nexport async function memberCommentsRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const discussion = container.discussion;\n const tags = ['Discussion'];\n\n r.route({\n method: 'GET',\n url: '/api/member/activities/:activityId/comments',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listActivityComments',\n tags,\n summary: \"Read an activity's comments\",\n description:\n \"For a student who can open the course, and staff. Returns the activity's resolved comment settings with the comments; removed comments keep their place without their body.\",\n params: DiscussionActivityParam,\n response: { 200: ActivityComments, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n return discussion.activityComments(req.orgId, req.params.activityId, orgUser);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/activities/:activityId/comments',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'postComment',\n tags,\n summary: 'Post a comment or reply on an activity',\n description:\n 'For a student who can open the course, and staff, while discussion is on for the activity (403 otherwise). Lands pending when the course requires review and you are not staff. Replies nest one level and need threading on.',\n params: DiscussionActivityParam,\n body: PostComment,\n response: { 201: CommentView, ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n const comment = await discussion.postComment(req.orgId, {\n actor: orgUser,\n activityId: req.params.activityId,\n parentId: req.body.parentId,\n body: req.body.body,\n });\n return reply.code(201).send(comment);\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/member/comments/:commentId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'editComment',\n tags,\n summary: 'Revise your own comment',\n description:\n 'Author only; not even staff may revise it. Discussion must be open where the comment is, and a removed comment cannot be revised.',\n params: CommentIdParam,\n body: EditComment,\n response: { 200: CommentView, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n return discussion.edit(req.orgId, req.params.commentId, orgUser, req.body.body);\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/member/comments/:commentId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'deleteComment',\n tags,\n summary: 'Delete your comment, or one you moderate',\n description:\n 'For the author, staff on an activity comment, or a moderator on a post comment. The comment is marked removed and keeps its place in the thread. Deleting a removed comment returns it unchanged.',\n params: CommentIdParam,\n response: { 200: CommentView, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n return discussion.remove(req.orgId, req.params.commentId, orgUser);\n },\n });\n\n r.route({\n method: 'PUT',\n url: '/api/member/comments/:commentId/reaction',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'setCommentReaction',\n tags,\n summary: 'Set your reaction on a comment',\n description:\n 'For anyone who can read the comment, while reactions are on where it is (403 otherwise). Replaces any reaction you already had and returns the new counts.',\n params: CommentIdParam,\n body: SetReaction,\n response: { 200: Reactions, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n return discussion.setReaction(req.orgId, req.params.commentId, orgUser, req.body.emoji);\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/member/comments/:commentId/reaction',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'clearCommentReaction',\n tags,\n summary: 'Withdraw your reaction from a comment',\n description: 'For anyone who can read the comment. Returns the new counts.',\n params: CommentIdParam,\n response: { 200: Reactions, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n return discussion.setReaction(req.orgId, req.params.commentId, orgUser, null);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/comments/:commentId/reports',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'reportComment',\n tags,\n summary: 'Flag a comment for the moderators',\n description:\n 'For anyone who can read the comment. Flagging it again while your flag is open returns that flag.',\n params: CommentIdParam,\n body: ReportComment,\n response: { 200: CommentReport, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n return discussion.reportComment(req.orgId, req.params.commentId, orgUser, req.body.reason);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/comments/:commentId/flags/resolution',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'resolveCommentFlags',\n tags,\n summary: 'Dismiss the open flags on a comment in a space you moderate',\n description:\n 'For a moderator of a post comment, or staff for an activity comment. Closes every open flag and leaves the comment up.',\n params: CommentIdParam,\n body: ResolveCommentFlags,\n response: { 204: z.void(), ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const orgUser = await actorOf(container, req.orgId, req.userId);\n await discussion.resolveReports(req.orgId, req.params.commentId, orgUser);\n return reply.code(204).send();\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Container } from "../../../app/container.js";
|
|
2
|
+
import { FastifyInstance } from "fastify";
|
|
3
|
+
//#region src/http/routes/member/community.d.ts
|
|
4
|
+
declare function memberCommunityRoutes(app: FastifyInstance, container: Container): Promise<void>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { memberCommunityRoutes };
|
|
7
|
+
//# sourceMappingURL=community.d.ts.map
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { PageQuery, refusals } from "../../schemas/shared.js";
|
|
2
|
+
import { CommunityHome, CommunityHomeSpace, CommunitySpaceParam, DirectoryPage, DirectoryQuery, SpaceMember, SpaceMemberParam, SpaceMembersPage } from "../../schemas/community.js";
|
|
3
|
+
import { CommunityParam, OrgUserBody } from "../../schemas/chats.js";
|
|
4
|
+
import "../../schemas/index.js";
|
|
5
|
+
import { actorOf } from "./actor.js";
|
|
6
|
+
import { NotFoundError } from "@headless-lms/core/shared/errors";
|
|
7
|
+
//#region src/http/routes/member/community.ts
|
|
8
|
+
async function memberCommunityRoutes(app, container) {
|
|
9
|
+
const r = app.withTypeProvider();
|
|
10
|
+
const tags = ["Communities"];
|
|
11
|
+
r.route({
|
|
12
|
+
method: "GET",
|
|
13
|
+
url: "/api/member/communities/:communityId/home",
|
|
14
|
+
preHandler: app.requireOrgSession,
|
|
15
|
+
schema: {
|
|
16
|
+
operationId: "getMemberCommunityHome",
|
|
17
|
+
tags,
|
|
18
|
+
summary: "The spaces a member can see in a community",
|
|
19
|
+
description: "For a member of the community. Lists its spaces in order. Spaces the viewer can open come back in full; spaces they can see but not open come back locked, with only their name, count, rule and the viewer's standing. A by-invite space the viewer is not invited to or a member of is left out. 404 when the viewer is not a member.",
|
|
20
|
+
params: CommunityParam,
|
|
21
|
+
response: {
|
|
22
|
+
200: CommunityHome,
|
|
23
|
+
...refusals(403, 404)
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
handler: async (req) => {
|
|
27
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
28
|
+
const home = await container.reporting.member.communityHome(req.orgId, actor, req.params.communityId);
|
|
29
|
+
if (!home) throw new NotFoundError("Community", req.params.communityId);
|
|
30
|
+
return home;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
r.route({
|
|
34
|
+
method: "GET",
|
|
35
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId",
|
|
36
|
+
preHandler: app.requireOrgSession,
|
|
37
|
+
schema: {
|
|
38
|
+
operationId: "getMemberSpace",
|
|
39
|
+
tags,
|
|
40
|
+
summary: "One space as a member sees it",
|
|
41
|
+
description: "For a member of the community: the space with its topics, links, settings and where the viewer stands. A space the viewer cannot open comes back locked, without its content. 404 when the viewer is not a member, the space is not in the community, or it is a by-invite space the viewer is not invited to or a member of.",
|
|
42
|
+
params: CommunitySpaceParam,
|
|
43
|
+
response: {
|
|
44
|
+
200: CommunityHomeSpace,
|
|
45
|
+
...refusals(403, 404)
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
handler: async (req) => {
|
|
49
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
50
|
+
const space = await container.reporting.member.communitySpace(req.orgId, actor, req.params.communityId, req.params.spaceId);
|
|
51
|
+
if (!space) throw new NotFoundError("Space", req.params.spaceId);
|
|
52
|
+
return space;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
r.route({
|
|
56
|
+
method: "GET",
|
|
57
|
+
url: "/api/member/communities/:communityId/directory",
|
|
58
|
+
preHandler: app.requireOrgSession,
|
|
59
|
+
schema: {
|
|
60
|
+
operationId: "getMemberCommunityDirectory",
|
|
61
|
+
tags,
|
|
62
|
+
summary: "People in a community",
|
|
63
|
+
description: "For a member of the community: everyone who holds it, with their public profile. 404 when the viewer is not a member.",
|
|
64
|
+
params: CommunityParam,
|
|
65
|
+
querystring: DirectoryQuery,
|
|
66
|
+
response: {
|
|
67
|
+
200: DirectoryPage,
|
|
68
|
+
...refusals(403, 404)
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
handler: async (req) => {
|
|
72
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
73
|
+
const page = await container.reporting.member.directory(req.orgId, actor, req.params.communityId, req.query);
|
|
74
|
+
if (!page) throw new NotFoundError("Community", req.params.communityId);
|
|
75
|
+
return page;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
r.route({
|
|
79
|
+
method: "GET",
|
|
80
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/members",
|
|
81
|
+
preHandler: app.requireOrgSession,
|
|
82
|
+
schema: {
|
|
83
|
+
operationId: "listSpaceMembers",
|
|
84
|
+
tags,
|
|
85
|
+
summary: "List the members of a space",
|
|
86
|
+
description: "For anyone who can open the space. Members see the active members; moderators also see open requests and invitations.",
|
|
87
|
+
params: CommunitySpaceParam,
|
|
88
|
+
querystring: PageQuery,
|
|
89
|
+
response: {
|
|
90
|
+
200: SpaceMembersPage,
|
|
91
|
+
...refusals(403, 404)
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
handler: async (req) => {
|
|
95
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
96
|
+
return container.entitlements.listSpaceMembers(req.orgId, actor, req.params.communityId, req.params.spaceId, req.query);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
r.route({
|
|
100
|
+
method: "POST",
|
|
101
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/requests",
|
|
102
|
+
preHandler: app.requireOrgSession,
|
|
103
|
+
schema: {
|
|
104
|
+
operationId: "requestSpaceMembership",
|
|
105
|
+
tags,
|
|
106
|
+
summary: "Ask to join a space",
|
|
107
|
+
description: "For a member of the community who is not staff. Opens a request on a `by_request` space for a moderator to approve. 409 when the space is not `by_request` or you are already placed in it.",
|
|
108
|
+
params: CommunitySpaceParam,
|
|
109
|
+
response: {
|
|
110
|
+
201: SpaceMember,
|
|
111
|
+
...refusals(403, 404, 409)
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
handler: async (req, reply) => {
|
|
115
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
116
|
+
const member = await container.entitlements.requestJoin(req.orgId, actor, req.params.communityId, req.params.spaceId);
|
|
117
|
+
return reply.code(201).send(member);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
r.route({
|
|
121
|
+
method: "POST",
|
|
122
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/invites",
|
|
123
|
+
preHandler: app.requireOrgSession,
|
|
124
|
+
schema: {
|
|
125
|
+
operationId: "inviteSpaceMember",
|
|
126
|
+
tags,
|
|
127
|
+
summary: "Invite a person into a space you moderate",
|
|
128
|
+
description: "For a moderator who is a member of the community. Invites another member into a `by_invite` space; they join when they accept. 403 when the person is staff or does not hold the community; 409 when the space is not invite-only or the person is already placed.",
|
|
129
|
+
params: CommunitySpaceParam,
|
|
130
|
+
body: OrgUserBody,
|
|
131
|
+
response: {
|
|
132
|
+
201: SpaceMember,
|
|
133
|
+
...refusals(403, 404, 409)
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
handler: async (req, reply) => {
|
|
137
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
138
|
+
const member = await container.entitlements.invite(req.orgId, actor, req.params.communityId, req.params.spaceId, req.body.orgUserId);
|
|
139
|
+
return reply.code(201).send(member);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
r.route({
|
|
143
|
+
method: "POST",
|
|
144
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/members",
|
|
145
|
+
preHandler: app.requireOrgSession,
|
|
146
|
+
schema: {
|
|
147
|
+
operationId: "addSpaceMember",
|
|
148
|
+
tags,
|
|
149
|
+
summary: "Add a person to a space you moderate",
|
|
150
|
+
description: "For a moderator who is a member of the community. Places another member straight into the space, with no request or invitation. 409 when the space is open to all members, the person is already placed, or the space is full.",
|
|
151
|
+
params: CommunitySpaceParam,
|
|
152
|
+
body: OrgUserBody,
|
|
153
|
+
response: {
|
|
154
|
+
201: SpaceMember,
|
|
155
|
+
...refusals(403, 404, 409)
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
handler: async (req, reply) => {
|
|
159
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
160
|
+
const member = await container.entitlements.addSpaceMember(req.orgId, actor, req.params.communityId, req.params.spaceId, req.body.orgUserId);
|
|
161
|
+
return reply.code(201).send(member);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
r.route({
|
|
165
|
+
method: "POST",
|
|
166
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/acceptance",
|
|
167
|
+
preHandler: app.requireOrgSession,
|
|
168
|
+
schema: {
|
|
169
|
+
operationId: "acceptSpaceInvite",
|
|
170
|
+
tags,
|
|
171
|
+
summary: "Accept your invitation to a space",
|
|
172
|
+
description: "For a member of the community who is not staff. Makes you an active member. 409 when you have no open invitation, are already a member, or the space is full.",
|
|
173
|
+
params: CommunitySpaceParam,
|
|
174
|
+
response: {
|
|
175
|
+
200: SpaceMember,
|
|
176
|
+
...refusals(403, 404, 409)
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
handler: async (req) => {
|
|
180
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
181
|
+
return container.entitlements.accept(req.orgId, actor, req.params.communityId, req.params.spaceId);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
r.route({
|
|
185
|
+
method: "POST",
|
|
186
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/members/:orgUserId/approval",
|
|
187
|
+
preHandler: app.requireOrgSession,
|
|
188
|
+
schema: {
|
|
189
|
+
operationId: "approveSpaceRequest",
|
|
190
|
+
tags,
|
|
191
|
+
summary: "Approve a person's request to join a space you moderate",
|
|
192
|
+
description: "For a moderator who is a member of the community. Makes the requester an active member. 404 when the person has no open request; 409 when the space is full or they are already a member.",
|
|
193
|
+
params: SpaceMemberParam,
|
|
194
|
+
response: {
|
|
195
|
+
200: SpaceMember,
|
|
196
|
+
...refusals(403, 404, 409)
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
handler: async (req) => {
|
|
200
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
201
|
+
return container.entitlements.approve(req.orgId, actor, req.params.communityId, req.params.spaceId, req.params.orgUserId);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
r.route({
|
|
205
|
+
method: "POST",
|
|
206
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/members/:orgUserId/decline",
|
|
207
|
+
preHandler: app.requireOrgSession,
|
|
208
|
+
schema: {
|
|
209
|
+
operationId: "declineSpaceRequest",
|
|
210
|
+
tags,
|
|
211
|
+
summary: "Decline a person's request to join a space you moderate",
|
|
212
|
+
description: "For a moderator who is a member of the community. Closes the open request. 404 when the person has no open request; 409 when they are already a member.",
|
|
213
|
+
params: SpaceMemberParam,
|
|
214
|
+
response: {
|
|
215
|
+
200: SpaceMember,
|
|
216
|
+
...refusals(403, 404, 409)
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
handler: async (req) => {
|
|
220
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
221
|
+
return container.entitlements.decline(req.orgId, actor, req.params.communityId, req.params.spaceId, req.params.orgUserId);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
r.route({
|
|
225
|
+
method: "POST",
|
|
226
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/refusal",
|
|
227
|
+
preHandler: app.requireOrgSession,
|
|
228
|
+
schema: {
|
|
229
|
+
operationId: "refuseSpaceInvite",
|
|
230
|
+
tags,
|
|
231
|
+
summary: "Refuse your invitation to a space",
|
|
232
|
+
description: "For a member of the community who is not staff. 409 when you have no open invitation or are already a member.",
|
|
233
|
+
params: CommunitySpaceParam,
|
|
234
|
+
response: {
|
|
235
|
+
200: SpaceMember,
|
|
236
|
+
...refusals(403, 404, 409)
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
handler: async (req) => {
|
|
240
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
241
|
+
return container.entitlements.refuse(req.orgId, actor, req.params.communityId, req.params.spaceId);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
r.route({
|
|
245
|
+
method: "POST",
|
|
246
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/departure",
|
|
247
|
+
preHandler: app.requireOrgSession,
|
|
248
|
+
schema: {
|
|
249
|
+
operationId: "leaveSpace",
|
|
250
|
+
tags,
|
|
251
|
+
summary: "Leave a space",
|
|
252
|
+
description: "For a member of the community who is not staff. 409 when you are not a member of the space.",
|
|
253
|
+
params: CommunitySpaceParam,
|
|
254
|
+
response: {
|
|
255
|
+
200: SpaceMember,
|
|
256
|
+
...refusals(403, 404, 409)
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
handler: async (req) => {
|
|
260
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
261
|
+
return container.entitlements.leave(req.orgId, actor, req.params.communityId, req.params.spaceId);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
r.route({
|
|
265
|
+
method: "POST",
|
|
266
|
+
url: "/api/member/communities/:communityId/spaces/:spaceId/members/:orgUserId/removal",
|
|
267
|
+
preHandler: app.requireOrgSession,
|
|
268
|
+
schema: {
|
|
269
|
+
operationId: "removeSpaceMember",
|
|
270
|
+
tags,
|
|
271
|
+
summary: "Remove a person from a space you moderate",
|
|
272
|
+
description: "For a moderator who is a member of the community. Revokes the placement, whether it is a membership, a request or an invitation. 409 when the space is open to all members or the placement is already revoked.",
|
|
273
|
+
params: SpaceMemberParam,
|
|
274
|
+
response: {
|
|
275
|
+
200: SpaceMember,
|
|
276
|
+
...refusals(403, 404, 409)
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
handler: async (req) => {
|
|
280
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
281
|
+
return container.entitlements.remove(req.orgId, actor, req.params.communityId, req.params.spaceId, req.params.orgUserId);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
286
|
+
export { memberCommunityRoutes };
|
|
287
|
+
|
|
288
|
+
//# sourceMappingURL=community.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community.js","names":[],"sources":["../../../../src/http/routes/member/community.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport type { Container } from '../../../app/container.js';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport { actorOf } from './actor.js';\nimport {\n CommunityHome,\n CommunityHomeSpace,\n CommunityParam,\n CommunitySpaceParam,\n DirectoryPage,\n DirectoryQuery,\n OrgUserBody,\n PageQuery,\n SpaceMember,\n SpaceMemberParam,\n SpaceMembersPage,\n refusals,\n} from '../../schemas/index.js';\n\nexport async function memberCommunityRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const tags = ['Communities'];\n\n r.route({\n method: 'GET',\n url: '/api/member/communities/:communityId/home',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getMemberCommunityHome',\n tags,\n summary: 'The spaces a member can see in a community',\n description:\n \"For a member of the community. Lists its spaces in order. Spaces the viewer can open come back in full; spaces they can see but not open come back locked, with only their name, count, rule and the viewer's standing. A by-invite space the viewer is not invited to or a member of is left out. 404 when the viewer is not a member.\",\n params: CommunityParam,\n response: { 200: CommunityHome, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const home = await container.reporting.member.communityHome(\n req.orgId,\n actor,\n req.params.communityId,\n );\n if (!home) {\n throw new NotFoundError('Community', req.params.communityId);\n }\n return home;\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/member/communities/:communityId/spaces/:spaceId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getMemberSpace',\n tags,\n summary: 'One space as a member sees it',\n description:\n 'For a member of the community: the space with its topics, links, settings and where the viewer stands. A space the viewer cannot open comes back locked, without its content. 404 when the viewer is not a member, the space is not in the community, or it is a by-invite space the viewer is not invited to or a member of.',\n params: CommunitySpaceParam,\n response: { 200: CommunityHomeSpace, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const space = await container.reporting.member.communitySpace(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n );\n if (!space) {\n throw new NotFoundError('Space', req.params.spaceId);\n }\n return space;\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/member/communities/:communityId/directory',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getMemberCommunityDirectory',\n tags,\n summary: 'People in a community',\n description:\n 'For a member of the community: everyone who holds it, with their public profile. 404 when the viewer is not a member.',\n params: CommunityParam,\n querystring: DirectoryQuery,\n response: { 200: DirectoryPage, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const page = await container.reporting.member.directory(\n req.orgId,\n actor,\n req.params.communityId,\n req.query,\n );\n if (!page) {\n throw new NotFoundError('Community', req.params.communityId);\n }\n return page;\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/member/communities/:communityId/spaces/:spaceId/members',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listSpaceMembers',\n tags,\n summary: 'List the members of a space',\n description:\n 'For anyone who can open the space. Members see the active members; moderators also see open requests and invitations.',\n params: CommunitySpaceParam,\n querystring: PageQuery,\n response: { 200: SpaceMembersPage, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.listSpaceMembers(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n req.query,\n );\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/requests',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'requestSpaceMembership',\n tags,\n summary: 'Ask to join a space',\n description:\n 'For a member of the community who is not staff. Opens a request on a `by_request` space for a moderator to approve. 409 when the space is not `by_request` or you are already placed in it.',\n params: CommunitySpaceParam,\n response: { 201: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const member = await container.entitlements.requestJoin(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n );\n return reply.code(201).send(member);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/invites',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'inviteSpaceMember',\n tags,\n summary: 'Invite a person into a space you moderate',\n description:\n 'For a moderator who is a member of the community. Invites another member into a `by_invite` space; they join when they accept. 403 when the person is staff or does not hold the community; 409 when the space is not invite-only or the person is already placed.',\n params: CommunitySpaceParam,\n body: OrgUserBody,\n response: { 201: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const member = await container.entitlements.invite(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n req.body.orgUserId,\n );\n return reply.code(201).send(member);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/members',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'addSpaceMember',\n tags,\n summary: 'Add a person to a space you moderate',\n description:\n 'For a moderator who is a member of the community. Places another member straight into the space, with no request or invitation. 409 when the space is open to all members, the person is already placed, or the space is full.',\n params: CommunitySpaceParam,\n body: OrgUserBody,\n response: { 201: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const member = await container.entitlements.addSpaceMember(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n req.body.orgUserId,\n );\n return reply.code(201).send(member);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/acceptance',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'acceptSpaceInvite',\n tags,\n summary: 'Accept your invitation to a space',\n description:\n 'For a member of the community who is not staff. Makes you an active member. 409 when you have no open invitation, are already a member, or the space is full.',\n params: CommunitySpaceParam,\n response: { 200: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.accept(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n );\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/members/:orgUserId/approval',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'approveSpaceRequest',\n tags,\n summary: \"Approve a person's request to join a space you moderate\",\n description:\n 'For a moderator who is a member of the community. Makes the requester an active member. 404 when the person has no open request; 409 when the space is full or they are already a member.',\n params: SpaceMemberParam,\n response: { 200: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.approve(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n req.params.orgUserId,\n );\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/members/:orgUserId/decline',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'declineSpaceRequest',\n tags,\n summary: \"Decline a person's request to join a space you moderate\",\n description:\n 'For a moderator who is a member of the community. Closes the open request. 404 when the person has no open request; 409 when they are already a member.',\n params: SpaceMemberParam,\n response: { 200: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.decline(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n req.params.orgUserId,\n );\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/refusal',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'refuseSpaceInvite',\n tags,\n summary: 'Refuse your invitation to a space',\n description:\n 'For a member of the community who is not staff. 409 when you have no open invitation or are already a member.',\n params: CommunitySpaceParam,\n response: { 200: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.refuse(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n );\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/departure',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'leaveSpace',\n tags,\n summary: 'Leave a space',\n description:\n 'For a member of the community who is not staff. 409 when you are not a member of the space.',\n params: CommunitySpaceParam,\n response: { 200: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.leave(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n );\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/communities/:communityId/spaces/:spaceId/members/:orgUserId/removal',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'removeSpaceMember',\n tags,\n summary: 'Remove a person from a space you moderate',\n description:\n 'For a moderator who is a member of the community. Revokes the placement, whether it is a membership, a request or an invitation. 409 when the space is open to all members or the placement is already revoked.',\n params: SpaceMemberParam,\n response: { 200: SpaceMember, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return container.entitlements.remove(\n req.orgId,\n actor,\n req.params.communityId,\n req.params.spaceId,\n req.params.orgUserId,\n );\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Container } from "../../../app/container.js";
|
|
2
|
+
import { FastifyInstance } from "fastify";
|
|
3
|
+
//#region src/http/routes/member/courses.d.ts
|
|
4
|
+
declare function memberCoursesRoutes(app: FastifyInstance, container: Container): Promise<void>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { memberCoursesRoutes };
|
|
7
|
+
//# sourceMappingURL=courses.d.ts.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { refusals } from "../../schemas/shared.js";
|
|
2
|
+
import { Course } from "../../schemas/content.js";
|
|
3
|
+
import { ActivityList } from "../../schemas/activities.js";
|
|
4
|
+
import { MemberCourseIdParam, MemberCourses, MemberModules } from "../../schemas/member.js";
|
|
5
|
+
import "../../schemas/index.js";
|
|
6
|
+
import { actorOf } from "./actor.js";
|
|
7
|
+
import { NotFoundError } from "@headless-lms/core/shared/errors";
|
|
8
|
+
//#region src/http/routes/member/courses.ts
|
|
9
|
+
async function memberCoursesRoutes(app, container) {
|
|
10
|
+
const r = app.withTypeProvider();
|
|
11
|
+
const member = container.reporting.member;
|
|
12
|
+
r.route({
|
|
13
|
+
method: "GET",
|
|
14
|
+
url: "/api/member/courses",
|
|
15
|
+
preHandler: app.requireOrgSession,
|
|
16
|
+
schema: {
|
|
17
|
+
operationId: "listMemberCourses",
|
|
18
|
+
tags: ["Content"],
|
|
19
|
+
summary: "List the courses you can open",
|
|
20
|
+
description: "For a member of the organization. Published courses you hold, directly or through a bundle.",
|
|
21
|
+
response: {
|
|
22
|
+
200: MemberCourses,
|
|
23
|
+
...refusals(403)
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
handler: async (req) => {
|
|
27
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
28
|
+
return member.listCourses(req.orgId, orgUser.id);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
r.route({
|
|
32
|
+
method: "GET",
|
|
33
|
+
url: "/api/member/courses/:courseId",
|
|
34
|
+
preHandler: app.requireOrgSession,
|
|
35
|
+
schema: {
|
|
36
|
+
operationId: "getMemberCourse",
|
|
37
|
+
tags: ["Content"],
|
|
38
|
+
summary: "Get one course you can open",
|
|
39
|
+
description: "For a member of the organization. 404 when the course is not published or you do not hold it.",
|
|
40
|
+
params: MemberCourseIdParam,
|
|
41
|
+
response: {
|
|
42
|
+
200: Course,
|
|
43
|
+
...refusals(403, 404)
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
handler: async (req) => {
|
|
47
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
48
|
+
const course = await member.getCourse(req.orgId, orgUser.id, req.params.courseId);
|
|
49
|
+
if (!course) throw new NotFoundError("Course", req.params.courseId);
|
|
50
|
+
return course;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
r.route({
|
|
54
|
+
method: "GET",
|
|
55
|
+
url: "/api/member/courses/:courseId/modules",
|
|
56
|
+
preHandler: app.requireOrgSession,
|
|
57
|
+
schema: {
|
|
58
|
+
operationId: "listMemberModules",
|
|
59
|
+
tags: ["Content"],
|
|
60
|
+
summary: "List the modules and activities of a course you can open",
|
|
61
|
+
description: "For a member of the organization. Published activities only. 404 when the course is not published or you do not hold it.",
|
|
62
|
+
params: MemberCourseIdParam,
|
|
63
|
+
response: {
|
|
64
|
+
200: MemberModules,
|
|
65
|
+
...refusals(403, 404)
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
handler: async (req) => {
|
|
69
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
70
|
+
const modules = await member.listModules(req.orgId, orgUser.id, req.params.courseId);
|
|
71
|
+
if (!modules) throw new NotFoundError("Course", req.params.courseId);
|
|
72
|
+
return modules;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
r.route({
|
|
76
|
+
method: "GET",
|
|
77
|
+
url: "/api/member/courses/:courseId/activities",
|
|
78
|
+
preHandler: app.requireOrgSession,
|
|
79
|
+
schema: {
|
|
80
|
+
operationId: "listMemberActivities",
|
|
81
|
+
tags: ["Content"],
|
|
82
|
+
summary: "List the published activities of a course you can open",
|
|
83
|
+
description: "For a member of the organization. 404 when the course is not published or you do not hold it.",
|
|
84
|
+
params: MemberCourseIdParam,
|
|
85
|
+
response: {
|
|
86
|
+
200: ActivityList,
|
|
87
|
+
...refusals(403, 404)
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
handler: async (req) => {
|
|
91
|
+
const orgUser = await actorOf(container, req.orgId, req.userId);
|
|
92
|
+
const activities = await member.listActivities(req.orgId, orgUser.id, req.params.courseId);
|
|
93
|
+
if (!activities) throw new NotFoundError("Course", req.params.courseId);
|
|
94
|
+
return activities;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { memberCoursesRoutes };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=courses.js.map
|