@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.
- package/dist/_virtual/_rolldown/runtime.js +5 -0
- package/dist/app/community-mail.d.ts +24 -0
- package/dist/app/community-mail.js +92 -0
- package/dist/app/community-mail.js.map +1 -0
- package/dist/app/container.d.ts +40 -19
- package/dist/app/container.js +294 -45
- 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/app/notification-channels.d.ts +47 -0
- package/dist/app/notification-channels.js +174 -0
- package/dist/app/notification-channels.js.map +1 -0
- package/dist/app/notification-reads.d.ts +23 -0
- package/dist/app/notification-reads.js +95 -0
- package/dist/app/notification-reads.js.map +1 -0
- package/dist/http/config.d.ts +2 -1
- package/dist/http/errors.d.ts +15 -0
- package/dist/http/errors.js +162 -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 +51 -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 +522 -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 +435 -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 +312 -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/devices.d.ts +7 -0
- package/dist/http/routes/member/devices.js +98 -0
- package/dist/http/routes/member/devices.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 +35 -0
- package/dist/http/routes/member/index.js.map +1 -0
- package/dist/http/routes/member/notification-settings.d.ts +7 -0
- package/dist/http/routes/member/notification-settings.js +108 -0
- package/dist/http/routes/member/notification-settings.js.map +1 -0
- package/dist/http/routes/member/notifications.d.ts +7 -0
- package/dist/http/routes/member/notifications.js +125 -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 +171 -25
- 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 +79 -80
- package/dist/http/schemas/assets.js +23 -13
- package/dist/http/schemas/assets.js.map +1 -1
- package/dist/http/schemas/automations.d.ts +6 -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 +409 -0
- package/dist/http/schemas/chats.js +56 -0
- package/dist/http/schemas/chats.js.map +1 -0
- package/dist/http/schemas/community.d.ts +597 -0
- package/dist/http/schemas/community.js +132 -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 +98 -14
- package/dist/http/schemas/discussion.js +25 -12
- 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 +4 -4
- 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 +35 -2
- package/dist/http/schemas/members.js +17 -3
- package/dist/http/schemas/members.js.map +1 -1
- package/dist/http/schemas/notifications.d.ts +550 -0
- package/dist/http/schemas/notifications.js +164 -0
- package/dist/http/schemas/notifications.js.map +1 -0
- package/dist/http/schemas/posts.d.ts +350 -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 +32 -1
- package/dist/http/schemas/shared.js +20 -2
- package/dist/http/schemas/shared.js.map +1 -1
- package/dist/http/schemas/students.d.ts +1 -7
- package/dist/http/schemas/students.js +1 -7
- package/dist/http/schemas/students.js.map +1 -1
- package/dist/http/scope.d.ts +3 -1
- package/dist/http/scope.js +26 -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 +3 -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,435 @@
|
|
|
1
|
+
import { PageQuery, refusals } from "../../schemas/shared.js";
|
|
2
|
+
import { Reactions, SetMute, SetReaction } from "../../schemas/discussion.js";
|
|
3
|
+
import { FlagReason } from "../../schemas/posts.js";
|
|
4
|
+
import { BlockParam, Chat, ChatIdParam, ChatsPage, CommunityParam, EditMessage, MarkRead, MessageFlag, MessageIdParam, MessageView, MessagesPage, OrgUserBody, ResolveMessageFlags, SendMessage, StartDirectChat, StartGroupChat } from "../../schemas/chats.js";
|
|
5
|
+
import "../../schemas/index.js";
|
|
6
|
+
import { actorOf } from "./actor.js";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region src/http/routes/member/chats.ts
|
|
9
|
+
async function memberChatRoutes(app, container) {
|
|
10
|
+
const r = app.withTypeProvider();
|
|
11
|
+
const chats = container.chats;
|
|
12
|
+
const tags = ["Chats"];
|
|
13
|
+
r.route({
|
|
14
|
+
method: "GET",
|
|
15
|
+
url: "/api/member/communities/:communityId/chats",
|
|
16
|
+
preHandler: app.requireOrgSession,
|
|
17
|
+
schema: {
|
|
18
|
+
operationId: "listMemberChats",
|
|
19
|
+
tags,
|
|
20
|
+
summary: "List your chats in a community",
|
|
21
|
+
description: "For a member of the community. Every chat you are in, with your unread count and its last message.",
|
|
22
|
+
params: CommunityParam,
|
|
23
|
+
querystring: PageQuery,
|
|
24
|
+
response: {
|
|
25
|
+
200: ChatsPage,
|
|
26
|
+
...refusals(403, 404)
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
handler: async (req) => {
|
|
30
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
31
|
+
return chats.listChats(req.orgId, actor, req.params.communityId, req.query);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
r.route({
|
|
35
|
+
method: "POST",
|
|
36
|
+
url: "/api/member/chats/direct",
|
|
37
|
+
preHandler: app.requireOrgSession,
|
|
38
|
+
schema: {
|
|
39
|
+
operationId: "startDirectChat",
|
|
40
|
+
tags,
|
|
41
|
+
summary: "Start a direct chat, or return the one that already exists",
|
|
42
|
+
description: "For a member of the community, within its direct-message settings (403 otherwise). With the community set so a first message is a request, a new chat starts `pending` until the other person accepts it. 409 when you message yourself, send attachments without a body, or start a request without a message.",
|
|
43
|
+
body: StartDirectChat,
|
|
44
|
+
response: {
|
|
45
|
+
200: Chat,
|
|
46
|
+
...refusals(403, 404, 409)
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
handler: async (req) => {
|
|
50
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
51
|
+
return chats.startDirect(req.orgId, actor, req.body);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
r.route({
|
|
55
|
+
method: "POST",
|
|
56
|
+
url: "/api/member/chats/group",
|
|
57
|
+
preHandler: app.requireOrgSession,
|
|
58
|
+
schema: {
|
|
59
|
+
operationId: "startGroupChat",
|
|
60
|
+
tags,
|
|
61
|
+
summary: "Start a group chat",
|
|
62
|
+
description: "For a member of the community while group chats are on (403 otherwise). Everyone named must hold the community and be someone you may message. 409 when fewer than two others are named or the group would exceed the community's group size.",
|
|
63
|
+
body: StartGroupChat,
|
|
64
|
+
response: {
|
|
65
|
+
201: Chat,
|
|
66
|
+
...refusals(403, 404, 409)
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
handler: async (req, reply) => {
|
|
70
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
71
|
+
const chat = await chats.startGroup(req.orgId, actor, req.body);
|
|
72
|
+
return reply.code(201).send(chat);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
r.route({
|
|
76
|
+
method: "POST",
|
|
77
|
+
url: "/api/member/chats/:chatId/participants",
|
|
78
|
+
preHandler: app.requireOrgSession,
|
|
79
|
+
schema: {
|
|
80
|
+
operationId: "addChatParticipant",
|
|
81
|
+
tags,
|
|
82
|
+
summary: "Add a person to a group chat you are in",
|
|
83
|
+
description: "For a participant of a group chat. 409 when the chat is direct, the person is already in it, or it is full.",
|
|
84
|
+
params: ChatIdParam,
|
|
85
|
+
body: OrgUserBody,
|
|
86
|
+
response: {
|
|
87
|
+
200: Chat,
|
|
88
|
+
...refusals(403, 404, 409)
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
handler: async (req) => {
|
|
92
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
93
|
+
return chats.addParticipant(req.orgId, actor, req.params.chatId, req.body.orgUserId);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
r.route({
|
|
97
|
+
method: "POST",
|
|
98
|
+
url: "/api/member/chats/:chatId/leave",
|
|
99
|
+
preHandler: app.requireOrgSession,
|
|
100
|
+
schema: {
|
|
101
|
+
operationId: "leaveChat",
|
|
102
|
+
tags,
|
|
103
|
+
summary: "Leave a chat",
|
|
104
|
+
description: "For a participant. The chat stays for the others.",
|
|
105
|
+
params: ChatIdParam,
|
|
106
|
+
response: {
|
|
107
|
+
200: Chat,
|
|
108
|
+
...refusals(403, 404)
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
handler: async (req) => {
|
|
112
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
113
|
+
return chats.leave(req.orgId, actor, req.params.chatId);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
r.route({
|
|
117
|
+
method: "POST",
|
|
118
|
+
url: "/api/member/chats/:chatId/acceptance",
|
|
119
|
+
preHandler: app.requireOrgSession,
|
|
120
|
+
schema: {
|
|
121
|
+
operationId: "acceptChat",
|
|
122
|
+
tags,
|
|
123
|
+
summary: "Accept a message request",
|
|
124
|
+
description: "For the person the request was sent to. The chat opens for both sides. 409 when the chat is not a pending request.",
|
|
125
|
+
params: ChatIdParam,
|
|
126
|
+
response: {
|
|
127
|
+
200: Chat,
|
|
128
|
+
...refusals(403, 404, 409)
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
handler: async (req) => {
|
|
132
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
133
|
+
return chats.accept(req.orgId, actor, req.params.chatId);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
r.route({
|
|
137
|
+
method: "GET",
|
|
138
|
+
url: "/api/member/chats/:chatId/messages",
|
|
139
|
+
preHandler: app.requireOrgSession,
|
|
140
|
+
schema: {
|
|
141
|
+
operationId: "listChatMessages",
|
|
142
|
+
tags,
|
|
143
|
+
summary: "Read the messages in a chat, newest first",
|
|
144
|
+
description: "For a participant of the chat.",
|
|
145
|
+
params: ChatIdParam,
|
|
146
|
+
querystring: PageQuery,
|
|
147
|
+
response: {
|
|
148
|
+
200: MessagesPage,
|
|
149
|
+
...refusals(403, 404)
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
handler: async (req) => {
|
|
153
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
154
|
+
return chats.messages(req.orgId, actor, req.params.chatId, req.query);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
r.route({
|
|
158
|
+
method: "POST",
|
|
159
|
+
url: "/api/member/chats/:chatId/messages",
|
|
160
|
+
preHandler: app.requireOrgSession,
|
|
161
|
+
schema: {
|
|
162
|
+
operationId: "sendChatMessage",
|
|
163
|
+
tags,
|
|
164
|
+
summary: "Send a message",
|
|
165
|
+
description: "For a participant while the chat is open and not locked, and nobody in it has blocked the other (403 otherwise). A request's sender cannot send more until it is accepted.",
|
|
166
|
+
params: ChatIdParam,
|
|
167
|
+
body: SendMessage,
|
|
168
|
+
response: {
|
|
169
|
+
201: MessageView,
|
|
170
|
+
...refusals(403, 404)
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
handler: async (req, reply) => {
|
|
174
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
175
|
+
const message = await chats.send(req.orgId, actor, req.params.chatId, req.body);
|
|
176
|
+
return reply.code(201).send(message);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
r.route({
|
|
180
|
+
method: "PATCH",
|
|
181
|
+
url: "/api/member/messages/:messageId",
|
|
182
|
+
preHandler: app.requireOrgSession,
|
|
183
|
+
schema: {
|
|
184
|
+
operationId: "editChatMessage",
|
|
185
|
+
tags,
|
|
186
|
+
summary: "Edit your own message",
|
|
187
|
+
description: "Sender only, while the chat is open and not locked. 409 when the message is deleted.",
|
|
188
|
+
params: MessageIdParam,
|
|
189
|
+
body: EditMessage,
|
|
190
|
+
response: {
|
|
191
|
+
200: MessageView,
|
|
192
|
+
...refusals(403, 404, 409)
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
handler: async (req) => {
|
|
196
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
197
|
+
return chats.editMessage(req.orgId, actor, req.params.messageId, req.body.body);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
r.route({
|
|
201
|
+
method: "DELETE",
|
|
202
|
+
url: "/api/member/messages/:messageId",
|
|
203
|
+
preHandler: app.requireOrgSession,
|
|
204
|
+
schema: {
|
|
205
|
+
operationId: "deleteChatMessage",
|
|
206
|
+
tags,
|
|
207
|
+
summary: "Delete your message, or one in a community you moderate",
|
|
208
|
+
description: "For the sender, or a moderator of the community. The message stays in the history, marked deleted. 409 when it is already deleted.",
|
|
209
|
+
params: MessageIdParam,
|
|
210
|
+
response: {
|
|
211
|
+
200: MessageView,
|
|
212
|
+
...refusals(403, 404, 409)
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
handler: async (req) => {
|
|
216
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
217
|
+
return chats.deleteMessage(req.orgId, actor, req.params.messageId);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
r.route({
|
|
221
|
+
method: "PUT",
|
|
222
|
+
url: "/api/member/messages/:messageId/reaction",
|
|
223
|
+
preHandler: app.requireOrgSession,
|
|
224
|
+
schema: {
|
|
225
|
+
operationId: "setMessageReaction",
|
|
226
|
+
tags,
|
|
227
|
+
summary: "Set your reaction on a message",
|
|
228
|
+
description: "For a participant of the chat. Replaces any reaction you already had and returns the new counts.",
|
|
229
|
+
params: MessageIdParam,
|
|
230
|
+
body: SetReaction,
|
|
231
|
+
response: {
|
|
232
|
+
200: Reactions,
|
|
233
|
+
...refusals(403, 404)
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
handler: async (req) => {
|
|
237
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
238
|
+
return chats.setReaction(req.orgId, actor, req.params.messageId, req.body.emoji);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
r.route({
|
|
242
|
+
method: "DELETE",
|
|
243
|
+
url: "/api/member/messages/:messageId/reaction",
|
|
244
|
+
preHandler: app.requireOrgSession,
|
|
245
|
+
schema: {
|
|
246
|
+
operationId: "clearMessageReaction",
|
|
247
|
+
tags,
|
|
248
|
+
summary: "Withdraw your reaction from a message",
|
|
249
|
+
description: "For a participant of the chat. Returns the new counts.",
|
|
250
|
+
params: MessageIdParam,
|
|
251
|
+
response: {
|
|
252
|
+
200: Reactions,
|
|
253
|
+
...refusals(403, 404)
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
handler: async (req) => {
|
|
257
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
258
|
+
return chats.setReaction(req.orgId, actor, req.params.messageId, null);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
r.route({
|
|
262
|
+
method: "POST",
|
|
263
|
+
url: "/api/member/messages/:messageId/flags",
|
|
264
|
+
preHandler: app.requireOrgSession,
|
|
265
|
+
schema: {
|
|
266
|
+
operationId: "flagMessage",
|
|
267
|
+
tags,
|
|
268
|
+
summary: "Flag a message for the moderators",
|
|
269
|
+
description: "For a participant of the chat. Flagging it again while your flag is open returns that flag.",
|
|
270
|
+
params: MessageIdParam,
|
|
271
|
+
body: FlagReason,
|
|
272
|
+
response: {
|
|
273
|
+
201: MessageFlag,
|
|
274
|
+
...refusals(403, 404)
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
handler: async (req, reply) => {
|
|
278
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
279
|
+
const flag = await chats.flagMessage(req.orgId, actor, req.params.messageId, req.body.reason);
|
|
280
|
+
return reply.code(201).send(flag);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
r.route({
|
|
284
|
+
method: "POST",
|
|
285
|
+
url: "/api/member/messages/:messageId/flags/resolution",
|
|
286
|
+
preHandler: app.requireOrgSession,
|
|
287
|
+
schema: {
|
|
288
|
+
operationId: "resolveMessageFlags",
|
|
289
|
+
tags,
|
|
290
|
+
summary: "Dismiss the open flags on a message in a community you moderate",
|
|
291
|
+
description: "For a moderator who is a member of the community. Closes every open flag and leaves the message up.",
|
|
292
|
+
params: MessageIdParam,
|
|
293
|
+
body: ResolveMessageFlags,
|
|
294
|
+
response: {
|
|
295
|
+
204: z.void(),
|
|
296
|
+
...refusals(403, 404)
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
handler: async (req, reply) => {
|
|
300
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
301
|
+
await chats.resolveMessageFlags(req.orgId, actor, req.params.messageId, req.body.resolution);
|
|
302
|
+
return reply.code(204).send();
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
r.route({
|
|
306
|
+
method: "POST",
|
|
307
|
+
url: "/api/member/chats/:chatId/read",
|
|
308
|
+
preHandler: app.requireOrgSession,
|
|
309
|
+
schema: {
|
|
310
|
+
operationId: "markChatRead",
|
|
311
|
+
tags,
|
|
312
|
+
summary: "Mark a chat read up to a message",
|
|
313
|
+
description: "For a participant. The message must be in the chat (404 otherwise).",
|
|
314
|
+
params: ChatIdParam,
|
|
315
|
+
body: MarkRead,
|
|
316
|
+
response: {
|
|
317
|
+
204: z.void(),
|
|
318
|
+
...refusals(403, 404)
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
handler: async (req, reply) => {
|
|
322
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
323
|
+
await chats.markRead(req.orgId, actor, req.params.chatId, req.body.messageId);
|
|
324
|
+
return reply.code(204).send();
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
r.route({
|
|
328
|
+
method: "PUT",
|
|
329
|
+
url: "/api/member/chats/:chatId/subscription",
|
|
330
|
+
preHandler: app.requireOrgSession,
|
|
331
|
+
schema: {
|
|
332
|
+
operationId: "setChatSubscription",
|
|
333
|
+
tags,
|
|
334
|
+
summary: "Mute a chat, or clear your mute",
|
|
335
|
+
description: "For a participant. `muted` stops its messages notifying you, until `mutedUntil` when given; a mention still notifies you. `none` clears the mute.",
|
|
336
|
+
params: ChatIdParam,
|
|
337
|
+
body: SetMute,
|
|
338
|
+
response: {
|
|
339
|
+
204: z.void(),
|
|
340
|
+
...refusals(403, 404)
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
handler: async (req, reply) => {
|
|
344
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
345
|
+
await container.subscriptions.setChat(req.orgId, actor, req.params.chatId, req.body);
|
|
346
|
+
return reply.code(204).send();
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
r.route({
|
|
350
|
+
method: "POST",
|
|
351
|
+
url: "/api/member/chats/:chatId/lock",
|
|
352
|
+
preHandler: app.requireOrgSession,
|
|
353
|
+
schema: {
|
|
354
|
+
operationId: "lockChat",
|
|
355
|
+
tags,
|
|
356
|
+
summary: "Lock a chat in a community you moderate",
|
|
357
|
+
description: "For a moderator who is a member of the community. Nobody can send or edit messages until it is unlocked; its open message flags are resolved as `locked`. Locking a locked chat returns it unchanged.",
|
|
358
|
+
params: ChatIdParam,
|
|
359
|
+
response: {
|
|
360
|
+
200: Chat,
|
|
361
|
+
...refusals(403, 404)
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
handler: async (req) => {
|
|
365
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
366
|
+
return chats.lock(req.orgId, actor, req.params.chatId);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
r.route({
|
|
370
|
+
method: "POST",
|
|
371
|
+
url: "/api/member/chats/:chatId/unlock",
|
|
372
|
+
preHandler: app.requireOrgSession,
|
|
373
|
+
schema: {
|
|
374
|
+
operationId: "unlockChat",
|
|
375
|
+
tags,
|
|
376
|
+
summary: "Unlock a chat in a community you moderate",
|
|
377
|
+
description: "For a moderator who is a member of the community. Unlocking an unlocked chat returns it unchanged.",
|
|
378
|
+
params: ChatIdParam,
|
|
379
|
+
response: {
|
|
380
|
+
200: Chat,
|
|
381
|
+
...refusals(403, 404)
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
handler: async (req) => {
|
|
385
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
386
|
+
return chats.unlock(req.orgId, actor, req.params.chatId);
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
r.route({
|
|
390
|
+
method: "PUT",
|
|
391
|
+
url: "/api/member/communities/:communityId/blocks/:orgUserId",
|
|
392
|
+
preHandler: app.requireOrgSession,
|
|
393
|
+
schema: {
|
|
394
|
+
operationId: "blockMember",
|
|
395
|
+
tags,
|
|
396
|
+
summary: "Block a person in a community",
|
|
397
|
+
description: "For a member of the community. Neither of you can message the other there; a direct chat between you closes. Blocking twice is harmless. 409 when you block yourself.",
|
|
398
|
+
params: BlockParam,
|
|
399
|
+
response: {
|
|
400
|
+
204: z.void(),
|
|
401
|
+
...refusals(403, 404, 409)
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
handler: async (req, reply) => {
|
|
405
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
406
|
+
await chats.block(req.orgId, actor, req.params.communityId, req.params.orgUserId);
|
|
407
|
+
return reply.code(204).send();
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
r.route({
|
|
411
|
+
method: "DELETE",
|
|
412
|
+
url: "/api/member/communities/:communityId/blocks/:orgUserId",
|
|
413
|
+
preHandler: app.requireOrgSession,
|
|
414
|
+
schema: {
|
|
415
|
+
operationId: "unblockMember",
|
|
416
|
+
tags,
|
|
417
|
+
summary: "Unblock a person in a community",
|
|
418
|
+
description: "For a member of the community. A direct chat closed by the block reopens unless a moderator locked it. 409 when you unblock yourself.",
|
|
419
|
+
params: BlockParam,
|
|
420
|
+
response: {
|
|
421
|
+
204: z.void(),
|
|
422
|
+
...refusals(403, 404, 409)
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
handler: async (req, reply) => {
|
|
426
|
+
const actor = await actorOf(container, req.orgId, req.userId);
|
|
427
|
+
await chats.unblock(req.orgId, actor, req.params.communityId, req.params.orgUserId);
|
|
428
|
+
return reply.code(204).send();
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
//#endregion
|
|
433
|
+
export { memberChatRoutes };
|
|
434
|
+
|
|
435
|
+
//# sourceMappingURL=chats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chats.js","names":[],"sources":["../../../../src/http/routes/member/chats.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport type { Container } from '../../../app/container.js';\nimport { actorOf } from './actor.js';\nimport {\n BlockParam,\n Chat,\n ChatIdParam,\n ChatsPage,\n CommunityParam,\n EditMessage,\n FlagReason,\n PageQuery,\n MarkRead,\n MessageFlag,\n MessageIdParam,\n MessagesPage,\n MessageView,\n OrgUserBody,\n Reactions,\n ResolveMessageFlags,\n SendMessage,\n SetMute,\n SetReaction,\n StartDirectChat,\n StartGroupChat,\n refusals,\n} from '../../schemas/index.js';\n\nexport async function memberChatRoutes(app: FastifyInstance, container: Container): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const chats = container.chats;\n const tags = ['Chats'];\n\n r.route({\n method: 'GET',\n url: '/api/member/communities/:communityId/chats',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listMemberChats',\n tags,\n summary: 'List your chats in a community',\n description:\n 'For a member of the community. Every chat you are in, with your unread count and its last message.',\n params: CommunityParam,\n querystring: PageQuery,\n response: { 200: ChatsPage, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.listChats(req.orgId, actor, req.params.communityId, req.query);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/direct',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'startDirectChat',\n tags,\n summary: 'Start a direct chat, or return the one that already exists',\n description:\n 'For a member of the community, within its direct-message settings (403 otherwise). With the community set so a first message is a request, a new chat starts `pending` until the other person accepts it. 409 when you message yourself, send attachments without a body, or start a request without a message.',\n body: StartDirectChat,\n response: { 200: Chat, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.startDirect(req.orgId, actor, req.body);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/group',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'startGroupChat',\n tags,\n summary: 'Start a group chat',\n description:\n \"For a member of the community while group chats are on (403 otherwise). Everyone named must hold the community and be someone you may message. 409 when fewer than two others are named or the group would exceed the community's group size.\",\n body: StartGroupChat,\n response: { 201: Chat, ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const chat = await chats.startGroup(req.orgId, actor, req.body);\n return reply.code(201).send(chat);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/participants',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'addChatParticipant',\n tags,\n summary: 'Add a person to a group chat you are in',\n description:\n 'For a participant of a group chat. 409 when the chat is direct, the person is already in it, or it is full.',\n params: ChatIdParam,\n body: OrgUserBody,\n response: { 200: Chat, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.addParticipant(req.orgId, actor, req.params.chatId, req.body.orgUserId);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/leave',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'leaveChat',\n tags,\n summary: 'Leave a chat',\n description: 'For a participant. The chat stays for the others.',\n params: ChatIdParam,\n response: { 200: Chat, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.leave(req.orgId, actor, req.params.chatId);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/acceptance',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'acceptChat',\n tags,\n summary: 'Accept a message request',\n description:\n 'For the person the request was sent to. The chat opens for both sides. 409 when the chat is not a pending request.',\n params: ChatIdParam,\n response: { 200: Chat, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.accept(req.orgId, actor, req.params.chatId);\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/member/chats/:chatId/messages',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listChatMessages',\n tags,\n summary: 'Read the messages in a chat, newest first',\n description: 'For a participant of the chat.',\n params: ChatIdParam,\n querystring: PageQuery,\n response: { 200: MessagesPage, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.messages(req.orgId, actor, req.params.chatId, req.query);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/messages',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'sendChatMessage',\n tags,\n summary: 'Send a message',\n description:\n \"For a participant while the chat is open and not locked, and nobody in it has blocked the other (403 otherwise). A request's sender cannot send more until it is accepted.\",\n params: ChatIdParam,\n body: SendMessage,\n response: { 201: MessageView, ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const message = await chats.send(req.orgId, actor, req.params.chatId, req.body);\n return reply.code(201).send(message);\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/member/messages/:messageId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'editChatMessage',\n tags,\n summary: 'Edit your own message',\n description:\n 'Sender only, while the chat is open and not locked. 409 when the message is deleted.',\n params: MessageIdParam,\n body: EditMessage,\n response: { 200: MessageView, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.editMessage(req.orgId, actor, req.params.messageId, req.body.body);\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/member/messages/:messageId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'deleteChatMessage',\n tags,\n summary: 'Delete your message, or one in a community you moderate',\n description:\n 'For the sender, or a moderator of the community. The message stays in the history, marked deleted. 409 when it is already deleted.',\n params: MessageIdParam,\n response: { 200: MessageView, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.deleteMessage(req.orgId, actor, req.params.messageId);\n },\n });\n\n r.route({\n method: 'PUT',\n url: '/api/member/messages/:messageId/reaction',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'setMessageReaction',\n tags,\n summary: 'Set your reaction on a message',\n description:\n 'For a participant of the chat. Replaces any reaction you already had and returns the new counts.',\n params: MessageIdParam,\n body: SetReaction,\n response: { 200: Reactions, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.setReaction(req.orgId, actor, req.params.messageId, req.body.emoji);\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/member/messages/:messageId/reaction',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'clearMessageReaction',\n tags,\n summary: 'Withdraw your reaction from a message',\n description: 'For a participant of the chat. Returns the new counts.',\n params: MessageIdParam,\n response: { 200: Reactions, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.setReaction(req.orgId, actor, req.params.messageId, null);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/messages/:messageId/flags',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'flagMessage',\n tags,\n summary: 'Flag a message for the moderators',\n description:\n 'For a participant of the chat. Flagging it again while your flag is open returns that flag.',\n params: MessageIdParam,\n body: FlagReason,\n response: { 201: MessageFlag, ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n const flag = await chats.flagMessage(req.orgId, actor, req.params.messageId, req.body.reason);\n return reply.code(201).send(flag);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/messages/:messageId/flags/resolution',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'resolveMessageFlags',\n tags,\n summary: 'Dismiss the open flags on a message in a community you moderate',\n description:\n 'For a moderator who is a member of the community. Closes every open flag and leaves the message up.',\n params: MessageIdParam,\n body: ResolveMessageFlags,\n response: { 204: z.void(), ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n await chats.resolveMessageFlags(req.orgId, actor, req.params.messageId, req.body.resolution);\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/read',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'markChatRead',\n tags,\n summary: 'Mark a chat read up to a message',\n description: 'For a participant. The message must be in the chat (404 otherwise).',\n params: ChatIdParam,\n body: MarkRead,\n response: { 204: z.void(), ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n await chats.markRead(req.orgId, actor, req.params.chatId, req.body.messageId);\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'PUT',\n url: '/api/member/chats/:chatId/subscription',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'setChatSubscription',\n tags,\n summary: 'Mute a chat, or clear your mute',\n description:\n 'For a participant. `muted` stops its messages notifying you, until `mutedUntil` when given; a mention still notifies you. `none` clears the mute.',\n params: ChatIdParam,\n body: SetMute,\n response: { 204: z.void(), ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n await container.subscriptions.setChat(req.orgId, actor, req.params.chatId, req.body);\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/lock',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'lockChat',\n tags,\n summary: 'Lock a chat in a community you moderate',\n description:\n 'For a moderator who is a member of the community. Nobody can send or edit messages until it is unlocked; its open message flags are resolved as `locked`. Locking a locked chat returns it unchanged.',\n params: ChatIdParam,\n response: { 200: Chat, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.lock(req.orgId, actor, req.params.chatId);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/member/chats/:chatId/unlock',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'unlockChat',\n tags,\n summary: 'Unlock a chat in a community you moderate',\n description:\n 'For a moderator who is a member of the community. Unlocking an unlocked chat returns it unchanged.',\n params: ChatIdParam,\n response: { 200: Chat, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const actor = await actorOf(container, req.orgId, req.userId);\n return chats.unlock(req.orgId, actor, req.params.chatId);\n },\n });\n\n r.route({\n method: 'PUT',\n url: '/api/member/communities/:communityId/blocks/:orgUserId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'blockMember',\n tags,\n summary: 'Block a person in a community',\n description:\n 'For a member of the community. Neither of you can message the other there; a direct chat between you closes. Blocking twice is harmless. 409 when you block yourself.',\n params: BlockParam,\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 await chats.block(req.orgId, actor, req.params.communityId, req.params.orgUserId);\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/member/communities/:communityId/blocks/:orgUserId',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'unblockMember',\n tags,\n summary: 'Unblock a person in a community',\n description:\n 'For a member of the community. A direct chat closed by the block reopens unless a moderator locked it. 409 when you unblock yourself.',\n params: BlockParam,\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 await chats.unblock(req.orgId, actor, req.params.communityId, req.params.orgUserId);\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/comments.d.ts
|
|
4
|
+
declare function memberCommentsRoutes(app: FastifyInstance, container: Container): Promise<void>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { memberCommentsRoutes };
|
|
7
|
+
//# sourceMappingURL=comments.d.ts.map
|
|
@@ -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
|