@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
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { refusals } from "../schemas/shared.js";
|
|
1
2
|
import { resolveScope } from "../scope.js";
|
|
2
|
-
import {
|
|
3
|
-
import { Student, StudentAnalytics, StudentIdParam, StudentsPage, StudentsQuery, UpdateStudentBody } from "../schemas/students.js";
|
|
3
|
+
import { Student, StudentAnalytics, StudentIdParam, StudentsPage, StudentsQuery } from "../schemas/students.js";
|
|
4
4
|
import "../schemas/index.js";
|
|
5
|
-
import { NotFoundError } from "@headless-lms/core/shared/errors";
|
|
6
5
|
import { z } from "zod";
|
|
6
|
+
import { NotFoundError } from "@headless-lms/core/shared/errors";
|
|
7
7
|
//#region src/http/routes/students.ts
|
|
8
8
|
async function studentsRoutes(app, container) {
|
|
9
9
|
const r = app.withTypeProvider();
|
|
10
|
-
const students = container.reporting.
|
|
10
|
+
const students = container.reporting.admin;
|
|
11
11
|
r.route({
|
|
12
12
|
method: "GET",
|
|
13
13
|
url: "/api/students",
|
|
@@ -15,13 +15,17 @@ async function studentsRoutes(app, container) {
|
|
|
15
15
|
schema: {
|
|
16
16
|
operationId: "listStudents",
|
|
17
17
|
tags: ["Organizations"],
|
|
18
|
-
summary: "List students",
|
|
18
|
+
summary: "List students (staff)",
|
|
19
|
+
description: "Staff only (owner, admin, instructor).",
|
|
19
20
|
querystring: StudentsQuery,
|
|
20
|
-
response: {
|
|
21
|
+
response: {
|
|
22
|
+
200: StudentsPage,
|
|
23
|
+
...refusals(403)
|
|
24
|
+
}
|
|
21
25
|
},
|
|
22
26
|
handler: async (req) => {
|
|
23
27
|
const scope = await resolveScope(container, req);
|
|
24
|
-
return students.
|
|
28
|
+
return students.listStudents(scope.orgId, req.query);
|
|
25
29
|
}
|
|
26
30
|
});
|
|
27
31
|
r.route({
|
|
@@ -31,16 +35,17 @@ async function studentsRoutes(app, container) {
|
|
|
31
35
|
schema: {
|
|
32
36
|
operationId: "getStudent",
|
|
33
37
|
tags: ["Organizations"],
|
|
34
|
-
summary: "Get a student
|
|
38
|
+
summary: "Get a student (staff)",
|
|
39
|
+
description: "Staff only (owner, admin, instructor).",
|
|
35
40
|
params: StudentIdParam,
|
|
36
41
|
response: {
|
|
37
42
|
200: Student,
|
|
38
|
-
404
|
|
43
|
+
...refusals(403, 404)
|
|
39
44
|
}
|
|
40
45
|
},
|
|
41
46
|
handler: async (req) => {
|
|
42
47
|
const scope = await resolveScope(container, req);
|
|
43
|
-
const student = await students.
|
|
48
|
+
const student = await students.getStudent(scope.orgId, req.params.id);
|
|
44
49
|
if (!student) throw new NotFoundError("Student", req.params.id);
|
|
45
50
|
return student;
|
|
46
51
|
}
|
|
@@ -52,48 +57,21 @@ async function studentsRoutes(app, container) {
|
|
|
52
57
|
schema: {
|
|
53
58
|
operationId: "getStudentAnalytics",
|
|
54
59
|
tags: ["Reporting"],
|
|
55
|
-
summary: "A student's learner record
|
|
60
|
+
summary: "A student's learner record (staff)",
|
|
61
|
+
description: "Staff only (owner, admin, instructor). Per-course progress and completion.",
|
|
56
62
|
params: StudentIdParam,
|
|
57
63
|
response: {
|
|
58
64
|
200: StudentAnalytics,
|
|
59
|
-
404
|
|
65
|
+
...refusals(403, 404)
|
|
60
66
|
}
|
|
61
67
|
},
|
|
62
68
|
handler: async (req) => {
|
|
63
69
|
const scope = await resolveScope(container, req);
|
|
64
|
-
const analytics = await students.
|
|
70
|
+
const analytics = await students.studentAnalytics(scope.orgId, req.params.id);
|
|
65
71
|
if (!analytics) throw new NotFoundError("Student", req.params.id);
|
|
66
72
|
return analytics;
|
|
67
73
|
}
|
|
68
74
|
});
|
|
69
|
-
r.route({
|
|
70
|
-
method: "PATCH",
|
|
71
|
-
url: "/api/students/:id",
|
|
72
|
-
preHandler: app.requireOrgSession,
|
|
73
|
-
schema: {
|
|
74
|
-
operationId: "updateStudent",
|
|
75
|
-
tags: ["Organizations"],
|
|
76
|
-
summary: "Update a student's profile",
|
|
77
|
-
params: StudentIdParam,
|
|
78
|
-
body: UpdateStudentBody,
|
|
79
|
-
response: {
|
|
80
|
-
200: Student,
|
|
81
|
-
404: ErrorBody,
|
|
82
|
-
409: ErrorBody
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
handler: async (req) => {
|
|
86
|
-
const scope = await resolveScope(container, req);
|
|
87
|
-
await container.organizations.updateStudent({
|
|
88
|
-
orgId: scope.orgId,
|
|
89
|
-
orgUserId: req.params.id,
|
|
90
|
-
...req.body
|
|
91
|
-
});
|
|
92
|
-
const student = await students.get(scope.orgId, req.params.id);
|
|
93
|
-
if (!student) throw new NotFoundError("Student", req.params.id);
|
|
94
|
-
return student;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
75
|
r.route({
|
|
98
76
|
method: "POST",
|
|
99
77
|
url: "/api/students/:id/invite/resend",
|
|
@@ -101,17 +79,20 @@ async function studentsRoutes(app, container) {
|
|
|
101
79
|
schema: {
|
|
102
80
|
operationId: "resendStudentInvite",
|
|
103
81
|
tags: ["Organizations"],
|
|
104
|
-
summary: "Re-send a pending student's invite email",
|
|
82
|
+
summary: "Re-send a pending student's invite email (staff)",
|
|
83
|
+
description: "Owner or admin only. Issues a new token, so the previous link stops working. 404 when the student has no pending invite; 409 when it was already accepted.",
|
|
105
84
|
params: StudentIdParam,
|
|
106
85
|
response: {
|
|
107
86
|
204: z.void(),
|
|
108
|
-
404
|
|
109
|
-
409: ErrorBody
|
|
87
|
+
...refusals(403, 404, 409)
|
|
110
88
|
}
|
|
111
89
|
},
|
|
112
90
|
handler: async (req, reply) => {
|
|
113
91
|
const scope = await resolveScope(container, req);
|
|
114
92
|
await container.organizations.resendStudentInvite({
|
|
93
|
+
id: scope.orgUserId,
|
|
94
|
+
role: scope.role
|
|
95
|
+
}, {
|
|
115
96
|
orgId: scope.orgId,
|
|
116
97
|
orgUserId: req.params.id,
|
|
117
98
|
inviterUserId: scope.userId
|
|
@@ -126,16 +107,20 @@ async function studentsRoutes(app, container) {
|
|
|
126
107
|
schema: {
|
|
127
108
|
operationId: "deleteStudent",
|
|
128
109
|
tags: ["Organizations"],
|
|
129
|
-
summary: "Delete a student",
|
|
110
|
+
summary: "Delete a student (staff)",
|
|
111
|
+
description: "Owner or admin only. 409 when the person has written posts, comments or messages.",
|
|
130
112
|
params: StudentIdParam,
|
|
131
113
|
response: {
|
|
132
114
|
204: z.void(),
|
|
133
|
-
404
|
|
115
|
+
...refusals(403, 404, 409)
|
|
134
116
|
}
|
|
135
117
|
},
|
|
136
118
|
handler: async (req, reply) => {
|
|
137
119
|
const scope = await resolveScope(container, req);
|
|
138
|
-
await container.organizations.deleteOrgUser(scope.orgId,
|
|
120
|
+
await container.organizations.deleteOrgUser(scope.orgId, {
|
|
121
|
+
id: scope.orgUserId,
|
|
122
|
+
role: scope.role
|
|
123
|
+
}, req.params.id);
|
|
139
124
|
return reply.code(204).send();
|
|
140
125
|
}
|
|
141
126
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"students.js","names":[],"sources":["../../../src/http/routes/students.ts"],"sourcesContent":["// HTTP routes for students: the reporting-backed list/read endpoints, the\n// delete, and re-issuing a pending invite. There is no create here — adding a\n// student IS inviting one, at /api/organizations/invites, which provisions the\n// student record up front.\nimport type { FastifyInstance } from 'fastify';\nimport { z } from 'zod';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport {\n
|
|
1
|
+
{"version":3,"file":"students.js","names":[],"sources":["../../../src/http/routes/students.ts"],"sourcesContent":["// HTTP routes for students: the reporting-backed list/read endpoints, the\n// delete, and re-issuing a pending invite. There is no create here — adding a\n// student IS inviting one, at /api/organizations/invites, which provisions the\n// student record up front.\nimport type { FastifyInstance } from 'fastify';\nimport { z } from 'zod';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport {\n Student,\n StudentAnalytics,\n StudentIdParam,\n StudentsPage,\n StudentsQuery,\n refusals,\n} from '../schemas/index.js';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../app/container.js';\nimport { resolveScope } from '../scope.js';\n\nexport async function studentsRoutes(app: FastifyInstance, container: Container): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const students = container.reporting.admin;\n\n r.route({\n method: 'GET',\n url: '/api/students',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listStudents',\n tags: ['Organizations'],\n summary: 'List students (staff)',\n description: 'Staff only (owner, admin, instructor).',\n querystring: StudentsQuery,\n response: { 200: StudentsPage, ...refusals(403) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n return students.listStudents(scope.orgId, req.query);\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/students/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getStudent',\n tags: ['Organizations'],\n summary: 'Get a student (staff)',\n description: 'Staff only (owner, admin, instructor).',\n params: StudentIdParam,\n response: { 200: Student, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const student = await students.getStudent(scope.orgId, req.params.id);\n if (!student) {\n throw new NotFoundError('Student', req.params.id);\n }\n return student;\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/students/:id/analytics',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getStudentAnalytics',\n tags: ['Reporting'],\n summary: \"A student's learner record (staff)\",\n description: 'Staff only (owner, admin, instructor). Per-course progress and completion.',\n params: StudentIdParam,\n response: { 200: StudentAnalytics, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const analytics = await students.studentAnalytics(scope.orgId, req.params.id);\n if (!analytics) {\n throw new NotFoundError('Student', req.params.id);\n }\n return analytics;\n },\n });\n\n // Re-mints the token on the student's pending invite and emails it. Lives\n // here rather than under invites because the admin app knows the student,\n // not the invitation.\n r.route({\n method: 'POST',\n url: '/api/students/:id/invite/resend',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'resendStudentInvite',\n tags: ['Organizations'],\n summary: \"Re-send a pending student's invite email (staff)\",\n description:\n 'Owner or admin only. Issues a new token, so the previous link stops working. 404 when the student has no pending invite; 409 when it was already accepted.',\n params: StudentIdParam,\n response: { 204: z.void(), ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n await container.organizations.resendStudentInvite(\n { id: scope.orgUserId, role: scope.role },\n {\n orgId: scope.orgId,\n orgUserId: req.params.id,\n inviterUserId: scope.userId,\n },\n );\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/students/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'deleteStudent',\n tags: ['Organizations'],\n summary: 'Delete a student (staff)',\n description:\n 'Owner or admin only. 409 when the person has written posts, comments or messages.',\n params: StudentIdParam,\n response: { 204: z.void(), ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n await container.organizations.deleteOrgUser(\n scope.orgId,\n { id: scope.orgUserId, role: scope.role },\n req.params.id,\n );\n return reply.code(204).send();\n },\n });\n}\n"],"mappings":";;;;;;;AAmBA,eAAsB,eAAe,KAAsB,WAAqC;CAC9F,MAAM,IAAI,IAAI,iBAAkC;CAChD,MAAM,WAAW,UAAU,UAAU;CAErC,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb,MAAM,CAAC,eAAe;GACtB,SAAS;GACT,aAAa;GACb,aAAa;GACb,UAAU;IAAE,KAAK;IAAc,GAAG,SAAS,GAAG;GAAE;EAClD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,OAAO,SAAS,aAAa,MAAM,OAAO,IAAI,KAAK;EACrD;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb,MAAM,CAAC,eAAe;GACtB,SAAS;GACT,aAAa;GACb,QAAQ;GACR,UAAU;IAAE,KAAK;IAAS,GAAG,SAAS,KAAK,GAAG;GAAE;EAClD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,UAAU,MAAM,SAAS,WAAW,MAAM,OAAO,IAAI,OAAO,EAAE;GACpE,IAAI,CAAC,SACH,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO;EACT;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb,MAAM,CAAC,WAAW;GAClB,SAAS;GACT,aAAa;GACb,QAAQ;GACR,UAAU;IAAE,KAAK;IAAkB,GAAG,SAAS,KAAK,GAAG;GAAE;EAC3D;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,YAAY,MAAM,SAAS,iBAAiB,MAAM,OAAO,IAAI,OAAO,EAAE;GAC5E,IAAI,CAAC,WACH,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO;EACT;CACF,CAAC;CAKD,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb,MAAM,CAAC,eAAe;GACtB,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK,EAAE,KAAK;IAAG,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EACxD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,UAAU,cAAc,oBAC5B;IAAE,IAAI,MAAM;IAAW,MAAM,MAAM;GAAK,GACxC;IACE,OAAO,MAAM;IACb,WAAW,IAAI,OAAO;IACtB,eAAe,MAAM;GACvB,CACF;GACA,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;EAC9B;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb,MAAM,CAAC,eAAe;GACtB,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK,EAAE,KAAK;IAAG,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EACxD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,UAAU,cAAc,cAC5B,MAAM,OACN;IAAE,IAAI,MAAM;IAAW,MAAM,MAAM;GAAK,GACxC,IAAI,OAAO,EACb;GACA,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;EAC9B;CACF,CAAC;AACH"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { refusals } from "../schemas/shared.js";
|
|
1
2
|
import { resolveScope } from "../scope.js";
|
|
2
|
-
import { ErrorBody } from "../schemas/shared.js";
|
|
3
3
|
import { AutomationIdParam, CreateWebhookBody, CreatedWebhook, UpdateWebhookBody, Webhook, WebhookSecret } from "../schemas/automations.js";
|
|
4
4
|
import "../schemas/index.js";
|
|
5
|
-
import { NotFoundError } from "@headless-lms/core/shared/errors";
|
|
6
5
|
import { z } from "zod";
|
|
6
|
+
import { NotFoundError } from "@headless-lms/core/shared/errors";
|
|
7
7
|
//#region src/http/routes/webhooks.ts
|
|
8
|
-
const DELIVERY_DESCRIPTION = "Each subscribed event is POSTed to `url` as the JSON event envelope (`id`, `type`, `version`, `orgId`, `occurredAt`, `data`), signed per the Standard Webhooks spec: `webhook-id` (the event id, stable across retries), `webhook-timestamp` (unix seconds) and `webhook-signature` (`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{body}`, keyed with the base64-decoded part of the `whsec_` secret). Any non-2xx response or timeout is a failed attempt and is retried. Deliveries are the webhook's automation runs: `GET /api/automations/{id}/runs`.";
|
|
8
|
+
const DELIVERY_DESCRIPTION = "Staff only (owner, admin, instructor). `url` must be a public address: localhost and private network addresses are refused when saved and when delivering. Each subscribed event is POSTed to `url` as the JSON event envelope (`id`, `type`, `version`, `orgId`, `occurredAt`, `data`), signed per the Standard Webhooks spec: `webhook-id` (the event id, stable across retries), `webhook-timestamp` (unix seconds) and `webhook-signature` (`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{body}`, keyed with the base64-decoded part of the `whsec_` secret). Any non-2xx response or timeout is a failed attempt and is retried. Deliveries are the webhook's automation runs: `GET /api/automations/{id}/runs`.";
|
|
9
9
|
async function webhooksRoutes(app, container) {
|
|
10
10
|
const r = app.withTypeProvider();
|
|
11
11
|
const automations = container.automations;
|
|
@@ -17,8 +17,12 @@ async function webhooksRoutes(app, container) {
|
|
|
17
17
|
schema: {
|
|
18
18
|
operationId: "listWebhooks",
|
|
19
19
|
tags,
|
|
20
|
-
summary: "List the organization's webhooks",
|
|
21
|
-
|
|
20
|
+
summary: "List the organization's webhooks (staff)",
|
|
21
|
+
description: "Staff only (owner, admin, instructor). Signing secrets are not included.",
|
|
22
|
+
response: {
|
|
23
|
+
200: z.array(Webhook),
|
|
24
|
+
...refusals(403)
|
|
25
|
+
}
|
|
22
26
|
},
|
|
23
27
|
handler: async (req) => {
|
|
24
28
|
const scope = await resolveScope(container, req);
|
|
@@ -32,12 +36,12 @@ async function webhooksRoutes(app, container) {
|
|
|
32
36
|
schema: {
|
|
33
37
|
operationId: "createWebhook",
|
|
34
38
|
tags,
|
|
35
|
-
summary: "Create a webhook
|
|
39
|
+
summary: "Create a webhook (staff)",
|
|
36
40
|
description: DELIVERY_DESCRIPTION,
|
|
37
41
|
body: CreateWebhookBody,
|
|
38
42
|
response: {
|
|
39
43
|
201: CreatedWebhook,
|
|
40
|
-
400
|
|
44
|
+
...refusals(400, 403)
|
|
41
45
|
}
|
|
42
46
|
},
|
|
43
47
|
handler: async (req, reply) => {
|
|
@@ -53,11 +57,12 @@ async function webhooksRoutes(app, container) {
|
|
|
53
57
|
schema: {
|
|
54
58
|
operationId: "getWebhook",
|
|
55
59
|
tags,
|
|
56
|
-
summary: "Get a webhook
|
|
60
|
+
summary: "Get a webhook (staff)",
|
|
61
|
+
description: "Staff only (owner, admin, instructor). The signing secret is not included.",
|
|
57
62
|
params: AutomationIdParam,
|
|
58
63
|
response: {
|
|
59
64
|
200: Webhook,
|
|
60
|
-
404
|
|
65
|
+
...refusals(403, 404)
|
|
61
66
|
}
|
|
62
67
|
},
|
|
63
68
|
handler: async (req) => {
|
|
@@ -74,13 +79,13 @@ async function webhooksRoutes(app, container) {
|
|
|
74
79
|
schema: {
|
|
75
80
|
operationId: "updateWebhook",
|
|
76
81
|
tags,
|
|
77
|
-
summary: "Change a webhook's URL, events, description or enabled flag",
|
|
82
|
+
summary: "Change a webhook's URL, events, description or enabled flag (staff)",
|
|
83
|
+
description: "Staff only (owner, admin, instructor). Changes only the fields sent. 400 when an event is reserved or unknown.",
|
|
78
84
|
params: AutomationIdParam,
|
|
79
85
|
body: UpdateWebhookBody,
|
|
80
86
|
response: {
|
|
81
87
|
200: Webhook,
|
|
82
|
-
400
|
|
83
|
-
404: ErrorBody
|
|
88
|
+
...refusals(400, 403, 404)
|
|
84
89
|
}
|
|
85
90
|
},
|
|
86
91
|
handler: async (req) => {
|
|
@@ -97,11 +102,12 @@ async function webhooksRoutes(app, container) {
|
|
|
97
102
|
schema: {
|
|
98
103
|
operationId: "deleteWebhook",
|
|
99
104
|
tags,
|
|
100
|
-
summary: "Delete a webhook and its signing secret
|
|
105
|
+
summary: "Delete a webhook and its signing secret (staff)",
|
|
106
|
+
description: "Staff only (owner, admin, instructor). Its delivery history is kept.",
|
|
101
107
|
params: AutomationIdParam,
|
|
102
108
|
response: {
|
|
103
109
|
204: z.void(),
|
|
104
|
-
404
|
|
110
|
+
...refusals(403, 404)
|
|
105
111
|
}
|
|
106
112
|
},
|
|
107
113
|
handler: async (req, reply) => {
|
|
@@ -117,11 +123,12 @@ async function webhooksRoutes(app, container) {
|
|
|
117
123
|
schema: {
|
|
118
124
|
operationId: "getWebhookSecret",
|
|
119
125
|
tags,
|
|
120
|
-
summary: "Reveal a webhook's signing secret",
|
|
126
|
+
summary: "Reveal a webhook's signing secret (staff)",
|
|
127
|
+
description: "Staff only (owner, admin, instructor).",
|
|
121
128
|
params: AutomationIdParam,
|
|
122
129
|
response: {
|
|
123
130
|
200: WebhookSecret,
|
|
124
|
-
404
|
|
131
|
+
...refusals(403, 404)
|
|
125
132
|
}
|
|
126
133
|
},
|
|
127
134
|
handler: async (req) => {
|
|
@@ -138,11 +145,12 @@ async function webhooksRoutes(app, container) {
|
|
|
138
145
|
schema: {
|
|
139
146
|
operationId: "rotateWebhookSecret",
|
|
140
147
|
tags,
|
|
141
|
-
summary: "Replace a webhook's signing secret
|
|
148
|
+
summary: "Replace a webhook's signing secret (staff)",
|
|
149
|
+
description: "Staff only (owner, admin, instructor). The old secret stops working immediately.",
|
|
142
150
|
params: AutomationIdParam,
|
|
143
151
|
response: {
|
|
144
152
|
200: WebhookSecret,
|
|
145
|
-
404
|
|
153
|
+
...refusals(403, 404)
|
|
146
154
|
}
|
|
147
155
|
},
|
|
148
156
|
handler: async (req) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","names":[],"sources":["../../../src/http/routes/webhooks.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport { z } from 'zod';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport {\n AutomationIdParam,\n CreatedWebhook,\n CreateWebhookBody,\n
|
|
1
|
+
{"version":3,"file":"webhooks.js","names":[],"sources":["../../../src/http/routes/webhooks.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport { z } from 'zod';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport {\n AutomationIdParam,\n CreatedWebhook,\n CreateWebhookBody,\n UpdateWebhookBody,\n Webhook,\n WebhookSecret,\n refusals,\n} from '../schemas/index.js';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../app/container.js';\nimport { resolveScope } from '../scope.js';\n\nconst DELIVERY_DESCRIPTION =\n \"Staff only (owner, admin, instructor). `url` must be a public address: localhost and private network addresses are refused when saved and when delivering. Each subscribed event is POSTed to `url` as the JSON event envelope (`id`, `type`, `version`, `orgId`, `occurredAt`, `data`), signed per the Standard Webhooks spec: `webhook-id` (the event id, stable across retries), `webhook-timestamp` (unix seconds) and `webhook-signature` (`v1,` + base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{body}`, keyed with the base64-decoded part of the `whsec_` secret). Any non-2xx response or timeout is a failed attempt and is retried. Deliveries are the webhook's automation runs: `GET /api/automations/{id}/runs`.\";\n\nexport async function webhooksRoutes(app: FastifyInstance, container: Container): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const automations = container.automations;\n const tags = ['Automations'];\n\n r.route({\n method: 'GET',\n url: '/api/automations/webhooks',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listWebhooks',\n tags,\n summary: \"List the organization's webhooks (staff)\",\n description: 'Staff only (owner, admin, instructor). Signing secrets are not included.',\n response: { 200: z.array(Webhook), ...refusals(403) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n return automations.listWebhooks(scope.orgId);\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/automations/webhooks',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'createWebhook',\n tags,\n summary: 'Create a webhook (staff)',\n description: DELIVERY_DESCRIPTION,\n body: CreateWebhookBody,\n response: { 201: CreatedWebhook, ...refusals(400, 403) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n const webhook = await automations.createWebhook(scope.orgId, req.body);\n return reply.code(201).send(webhook);\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/automations/webhooks/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getWebhook',\n tags,\n summary: 'Get a webhook (staff)',\n description: 'Staff only (owner, admin, instructor). The signing secret is not included.',\n params: AutomationIdParam,\n response: { 200: Webhook, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const webhook = await automations.getWebhook(scope.orgId, req.params.id);\n if (!webhook) {\n throw new NotFoundError('Webhook', req.params.id);\n }\n return webhook;\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/automations/webhooks/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'updateWebhook',\n tags,\n summary: \"Change a webhook's URL, events, description or enabled flag (staff)\",\n description:\n 'Staff only (owner, admin, instructor). Changes only the fields sent. 400 when an event is reserved or unknown.',\n params: AutomationIdParam,\n body: UpdateWebhookBody,\n response: { 200: Webhook, ...refusals(400, 403, 404) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const webhook = await automations.updateWebhook(scope.orgId, req.params.id, req.body);\n if (!webhook) {\n throw new NotFoundError('Webhook', req.params.id);\n }\n return webhook;\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/automations/webhooks/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'deleteWebhook',\n tags,\n summary: 'Delete a webhook and its signing secret (staff)',\n description: 'Staff only (owner, admin, instructor). Its delivery history is kept.',\n params: AutomationIdParam,\n response: { 204: z.void(), ...refusals(403, 404) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n const deleted = await automations.deleteWebhook(scope.orgId, req.params.id);\n if (!deleted) {\n throw new NotFoundError('Webhook', req.params.id);\n }\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/automations/webhooks/:id/secret',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getWebhookSecret',\n tags,\n summary: \"Reveal a webhook's signing secret (staff)\",\n description: 'Staff only (owner, admin, instructor).',\n params: AutomationIdParam,\n response: { 200: WebhookSecret, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const secret = await automations.revealWebhookSecret(scope.orgId, req.params.id);\n if (!secret) {\n throw new NotFoundError('Webhook', req.params.id);\n }\n return secret;\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/automations/webhooks/:id/secret/rotate',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'rotateWebhookSecret',\n tags,\n summary: \"Replace a webhook's signing secret (staff)\",\n description:\n 'Staff only (owner, admin, instructor). The old secret stops working immediately.',\n params: AutomationIdParam,\n response: { 200: WebhookSecret, ...refusals(403, 404) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const secret = await automations.rotateWebhookSecret(scope.orgId, req.params.id);\n if (!secret) {\n throw new NotFoundError('Webhook', req.params.id);\n }\n return secret;\n },\n });\n}\n"],"mappings":";;;;;;;AAgBA,MAAM,uBACJ;AAEF,eAAsB,eAAe,KAAsB,WAAqC;CAC9F,MAAM,IAAI,IAAI,iBAAkC;CAChD,MAAM,cAAc,UAAU;CAC9B,MAAM,OAAO,CAAC,aAAa;CAE3B,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aAAa;GACb,UAAU;IAAE,KAAK,EAAE,MAAM,OAAO;IAAG,GAAG,SAAS,GAAG;GAAE;EACtD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,OAAO,YAAY,aAAa,MAAM,KAAK;EAC7C;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aAAa;GACb,MAAM;GACN,UAAU;IAAE,KAAK;IAAgB,GAAG,SAAS,KAAK,GAAG;GAAE;EACzD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,UAAU,MAAM,YAAY,cAAc,MAAM,OAAO,IAAI,IAAI;GACrE,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,OAAO;EACrC;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aAAa;GACb,QAAQ;GACR,UAAU;IAAE,KAAK;IAAS,GAAG,SAAS,KAAK,GAAG;GAAE;EAClD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,UAAU,MAAM,YAAY,WAAW,MAAM,OAAO,IAAI,OAAO,EAAE;GACvE,IAAI,CAAC,SACH,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO;EACT;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,QAAQ;GACR,MAAM;GACN,UAAU;IAAE,KAAK;IAAS,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EACvD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,UAAU,MAAM,YAAY,cAAc,MAAM,OAAO,IAAI,OAAO,IAAI,IAAI,IAAI;GACpF,IAAI,CAAC,SACH,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO;EACT;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aAAa;GACb,QAAQ;GACR,UAAU;IAAE,KAAK,EAAE,KAAK;IAAG,GAAG,SAAS,KAAK,GAAG;GAAE;EACnD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAE/C,IAAI,CAAC,MADiB,YAAY,cAAc,MAAM,OAAO,IAAI,OAAO,EAAE,GAExE,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;EAC9B;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aAAa;GACb,QAAQ;GACR,UAAU;IAAE,KAAK;IAAe,GAAG,SAAS,KAAK,GAAG;GAAE;EACxD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,SAAS,MAAM,YAAY,oBAAoB,MAAM,OAAO,IAAI,OAAO,EAAE;GAC/E,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO;EACT;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK;IAAe,GAAG,SAAS,KAAK,GAAG;GAAE;EACxD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,SAAS,MAAM,YAAY,oBAAoB,MAAM,OAAO,IAAI,OAAO,EAAE;GAC/E,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,WAAW,IAAI,OAAO,EAAE;GAElD,OAAO;EACT;CACF,CAAC;AACH"}
|
package/dist/http/routes.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { communitiesRoutes } from "./routes/communities.js";
|
|
2
|
+
import { communityModerationRoutes } from "./routes/community-moderation.js";
|
|
1
3
|
import { coursesRoutes } from "./routes/courses.js";
|
|
2
4
|
import { downloadsRoutes } from "./routes/downloads.js";
|
|
3
5
|
import { bundlesRoutes } from "./routes/bundles.js";
|
|
4
|
-
import {
|
|
6
|
+
import { memberRoutes } from "./routes/member/index.js";
|
|
5
7
|
import { discussionRoutes } from "./routes/discussion.js";
|
|
6
8
|
import { activitiesRoutes } from "./routes/activities.js";
|
|
7
9
|
import { studentsRoutes } from "./routes/students.js";
|
|
@@ -13,6 +15,7 @@ import { dashboardRoutes } from "./routes/dashboard.js";
|
|
|
13
15
|
import { courseAnalyticsRoutes } from "./routes/course-analytics.js";
|
|
14
16
|
import { assetsRoutes } from "./routes/assets.js";
|
|
15
17
|
import { integrationsRoutes } from "./routes/integrations.js";
|
|
18
|
+
import { accessRoutes } from "./routes/access.js";
|
|
16
19
|
//#region src/http/routes.ts
|
|
17
20
|
function registerRoutes(app, container) {
|
|
18
21
|
app.get("/health", async () => ({ status: "ok" }));
|
|
@@ -22,9 +25,11 @@ function registerRoutes(app, container) {
|
|
|
22
25
|
app.register(async (instance) => {
|
|
23
26
|
instance.addHook("onRequest", instance.requireOrgSession);
|
|
24
27
|
await coursesRoutes(instance, container);
|
|
28
|
+
await communitiesRoutes(instance, container);
|
|
29
|
+
await communityModerationRoutes(instance, container);
|
|
25
30
|
await downloadsRoutes(instance, container);
|
|
26
31
|
await bundlesRoutes(instance, container);
|
|
27
|
-
await
|
|
32
|
+
await memberRoutes(instance, container);
|
|
28
33
|
await discussionRoutes(instance, container);
|
|
29
34
|
await activitiesRoutes(instance, container);
|
|
30
35
|
await studentsRoutes(instance, container);
|
|
@@ -35,6 +40,7 @@ function registerRoutes(app, container) {
|
|
|
35
40
|
await courseAnalyticsRoutes(instance, container);
|
|
36
41
|
await assetsRoutes(instance, container);
|
|
37
42
|
await integrationsRoutes(instance, container);
|
|
43
|
+
await accessRoutes(instance, container);
|
|
38
44
|
});
|
|
39
45
|
}
|
|
40
46
|
//#endregion
|
package/dist/http/routes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","names":[],"sources":["../../src/http/routes.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { Container } from '../app/container.js';\nimport { coursesRoutes } from './routes/courses.js';\nimport { downloadsRoutes } from './routes/downloads.js';\nimport { bundlesRoutes } from './routes/bundles.js';\nimport {
|
|
1
|
+
{"version":3,"file":"routes.js","names":[],"sources":["../../src/http/routes.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { Container } from '../app/container.js';\nimport { communitiesRoutes } from './routes/communities.js';\nimport { communityModerationRoutes } from './routes/community-moderation.js';\nimport { coursesRoutes } from './routes/courses.js';\nimport { downloadsRoutes } from './routes/downloads.js';\nimport { bundlesRoutes } from './routes/bundles.js';\nimport { memberRoutes } from './routes/member/index.js';\nimport { discussionRoutes } from './routes/discussion.js';\nimport { activitiesRoutes } from './routes/activities.js';\nimport { studentsRoutes } from './routes/students.js';\nimport { entitlementsRoutes } from './routes/entitlements.js';\nimport { automationsRoutes } from './routes/automations.js';\nimport { webhooksRoutes } from './routes/webhooks.js';\nimport { organizationsRoutes } from './routes/organizations.js';\nimport { dashboardRoutes } from './routes/dashboard.js';\nimport { courseAnalyticsRoutes } from './routes/course-analytics.js';\nimport { assetsRoutes } from './routes/assets.js';\nimport { integrationsRoutes } from './routes/integrations.js';\nimport { accessRoutes } from './routes/access.js';\n\nexport function registerRoutes(app: FastifyInstance, container: Container): void {\n app.get('/health', async () => ({ status: 'ok' }));\n\n app.register(async (instance) => {\n // instance.addHook('onRequest', instance.requireSession);\n await organizationsRoutes(instance, container);\n });\n\n app.register(async (instance) => {\n instance.addHook('onRequest', instance.requireOrgSession);\n await coursesRoutes(instance, container);\n await communitiesRoutes(instance, container);\n await communityModerationRoutes(instance, container);\n await downloadsRoutes(instance, container);\n await bundlesRoutes(instance, container);\n await memberRoutes(instance, container);\n await discussionRoutes(instance, container);\n await activitiesRoutes(instance, container);\n await studentsRoutes(instance, container);\n await entitlementsRoutes(instance, container);\n await automationsRoutes(instance, container);\n await webhooksRoutes(instance, container);\n await dashboardRoutes(instance, container);\n await courseAnalyticsRoutes(instance, container);\n await assetsRoutes(instance, container);\n await integrationsRoutes(instance, container);\n await accessRoutes(instance, container);\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,eAAe,KAAsB,WAA4B;CAC/E,IAAI,IAAI,WAAW,aAAa,EAAE,QAAQ,KAAK,EAAE;CAEjD,IAAI,SAAS,OAAO,aAAa;EAE/B,MAAM,oBAAoB,UAAU,SAAS;CAC/C,CAAC;CAED,IAAI,SAAS,OAAO,aAAa;EAC/B,SAAS,QAAQ,aAAa,SAAS,iBAAiB;EACxD,MAAM,cAAc,UAAU,SAAS;EACvC,MAAM,kBAAkB,UAAU,SAAS;EAC3C,MAAM,0BAA0B,UAAU,SAAS;EACnD,MAAM,gBAAgB,UAAU,SAAS;EACzC,MAAM,cAAc,UAAU,SAAS;EACvC,MAAM,aAAa,UAAU,SAAS;EACtC,MAAM,iBAAiB,UAAU,SAAS;EAC1C,MAAM,iBAAiB,UAAU,SAAS;EAC1C,MAAM,eAAe,UAAU,SAAS;EACxC,MAAM,mBAAmB,UAAU,SAAS;EAC5C,MAAM,kBAAkB,UAAU,SAAS;EAC3C,MAAM,eAAe,UAAU,SAAS;EACxC,MAAM,gBAAgB,UAAU,SAAS;EACzC,MAAM,sBAAsB,UAAU,SAAS;EAC/C,MAAM,aAAa,UAAU,SAAS;EACtC,MAAM,mBAAmB,UAAU,SAAS;EAC5C,MAAM,aAAa,UAAU,SAAS;CACxC,CAAC;AACH"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/http/schemas/access.d.ts
|
|
3
|
+
declare const ScopeOption: z.ZodObject<{
|
|
4
|
+
scope: z.ZodEnum<{
|
|
5
|
+
"courses:read": "courses:read";
|
|
6
|
+
"courses:write": "courses:write";
|
|
7
|
+
"courses:delete": "courses:delete";
|
|
8
|
+
"downloads:read": "downloads:read";
|
|
9
|
+
"downloads:write": "downloads:write";
|
|
10
|
+
"downloads:delete": "downloads:delete";
|
|
11
|
+
"bundles:read": "bundles:read";
|
|
12
|
+
"bundles:write": "bundles:write";
|
|
13
|
+
"bundles:delete": "bundles:delete";
|
|
14
|
+
"media:read": "media:read";
|
|
15
|
+
"students:read": "students:read";
|
|
16
|
+
"students:invite": "students:invite";
|
|
17
|
+
"access:read": "access:read";
|
|
18
|
+
"access:write": "access:write";
|
|
19
|
+
"analytics:read": "analytics:read";
|
|
20
|
+
"automations:read": "automations:read";
|
|
21
|
+
"automations:write": "automations:write";
|
|
22
|
+
"automations:delete": "automations:delete";
|
|
23
|
+
"comments:read": "comments:read";
|
|
24
|
+
"comments:moderate": "comments:moderate";
|
|
25
|
+
"communities:read": "communities:read";
|
|
26
|
+
"communities:write": "communities:write";
|
|
27
|
+
"communities:delete": "communities:delete";
|
|
28
|
+
"community_members:read": "community_members:read";
|
|
29
|
+
"community_members:write": "community_members:write";
|
|
30
|
+
"community_moderation:read": "community_moderation:read";
|
|
31
|
+
"community_moderation:write": "community_moderation:write";
|
|
32
|
+
}>;
|
|
33
|
+
allowed: z.ZodBoolean;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
declare const ScopeOptionList: z.ZodArray<z.ZodObject<{
|
|
36
|
+
scope: z.ZodEnum<{
|
|
37
|
+
"courses:read": "courses:read";
|
|
38
|
+
"courses:write": "courses:write";
|
|
39
|
+
"courses:delete": "courses:delete";
|
|
40
|
+
"downloads:read": "downloads:read";
|
|
41
|
+
"downloads:write": "downloads:write";
|
|
42
|
+
"downloads:delete": "downloads:delete";
|
|
43
|
+
"bundles:read": "bundles:read";
|
|
44
|
+
"bundles:write": "bundles:write";
|
|
45
|
+
"bundles:delete": "bundles:delete";
|
|
46
|
+
"media:read": "media:read";
|
|
47
|
+
"students:read": "students:read";
|
|
48
|
+
"students:invite": "students:invite";
|
|
49
|
+
"access:read": "access:read";
|
|
50
|
+
"access:write": "access:write";
|
|
51
|
+
"analytics:read": "analytics:read";
|
|
52
|
+
"automations:read": "automations:read";
|
|
53
|
+
"automations:write": "automations:write";
|
|
54
|
+
"automations:delete": "automations:delete";
|
|
55
|
+
"comments:read": "comments:read";
|
|
56
|
+
"comments:moderate": "comments:moderate";
|
|
57
|
+
"communities:read": "communities:read";
|
|
58
|
+
"communities:write": "communities:write";
|
|
59
|
+
"communities:delete": "communities:delete";
|
|
60
|
+
"community_members:read": "community_members:read";
|
|
61
|
+
"community_members:write": "community_members:write";
|
|
62
|
+
"community_moderation:read": "community_moderation:read";
|
|
63
|
+
"community_moderation:write": "community_moderation:write";
|
|
64
|
+
}>;
|
|
65
|
+
allowed: z.ZodBoolean;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
declare const ConnectedApp: z.ZodObject<{
|
|
68
|
+
clientId: z.ZodString;
|
|
69
|
+
name: z.ZodString;
|
|
70
|
+
iconUrl: z.ZodNullable<z.ZodString>;
|
|
71
|
+
scopes: z.ZodArray<z.ZodString>;
|
|
72
|
+
connectedAt: z.ZodCoercedDate<unknown>;
|
|
73
|
+
}, z.core.$strip>;
|
|
74
|
+
declare const ConnectedAppList: z.ZodArray<z.ZodObject<{
|
|
75
|
+
clientId: z.ZodString;
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
iconUrl: z.ZodNullable<z.ZodString>;
|
|
78
|
+
scopes: z.ZodArray<z.ZodString>;
|
|
79
|
+
connectedAt: z.ZodCoercedDate<unknown>;
|
|
80
|
+
}, z.core.$strip>>;
|
|
81
|
+
declare const ClientIdParam: z.ZodObject<{
|
|
82
|
+
clientId: z.ZodString;
|
|
83
|
+
}, z.core.$strip>;
|
|
84
|
+
declare const ApiKey: z.ZodObject<{
|
|
85
|
+
id: z.ZodString;
|
|
86
|
+
name: z.ZodNullable<z.ZodString>;
|
|
87
|
+
start: z.ZodNullable<z.ZodString>;
|
|
88
|
+
scopes: z.ZodArray<z.ZodString>;
|
|
89
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
90
|
+
lastUsedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
declare const ApiKeyList: z.ZodArray<z.ZodObject<{
|
|
93
|
+
id: z.ZodString;
|
|
94
|
+
name: z.ZodNullable<z.ZodString>;
|
|
95
|
+
start: z.ZodNullable<z.ZodString>;
|
|
96
|
+
scopes: z.ZodArray<z.ZodString>;
|
|
97
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
98
|
+
lastUsedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
99
|
+
}, z.core.$strip>>;
|
|
100
|
+
declare const CreatedApiKey: z.ZodObject<{
|
|
101
|
+
id: z.ZodString;
|
|
102
|
+
name: z.ZodNullable<z.ZodString>;
|
|
103
|
+
start: z.ZodNullable<z.ZodString>;
|
|
104
|
+
scopes: z.ZodArray<z.ZodString>;
|
|
105
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
106
|
+
lastUsedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
107
|
+
key: z.ZodString;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
declare const CreateApiKey: z.ZodObject<{
|
|
110
|
+
name: z.ZodString;
|
|
111
|
+
scopes: z.ZodArray<z.ZodEnum<{
|
|
112
|
+
"courses:read": "courses:read";
|
|
113
|
+
"courses:write": "courses:write";
|
|
114
|
+
"courses:delete": "courses:delete";
|
|
115
|
+
"downloads:read": "downloads:read";
|
|
116
|
+
"downloads:write": "downloads:write";
|
|
117
|
+
"downloads:delete": "downloads:delete";
|
|
118
|
+
"bundles:read": "bundles:read";
|
|
119
|
+
"bundles:write": "bundles:write";
|
|
120
|
+
"bundles:delete": "bundles:delete";
|
|
121
|
+
"media:read": "media:read";
|
|
122
|
+
"students:read": "students:read";
|
|
123
|
+
"students:invite": "students:invite";
|
|
124
|
+
"access:read": "access:read";
|
|
125
|
+
"access:write": "access:write";
|
|
126
|
+
"analytics:read": "analytics:read";
|
|
127
|
+
"automations:read": "automations:read";
|
|
128
|
+
"automations:write": "automations:write";
|
|
129
|
+
"automations:delete": "automations:delete";
|
|
130
|
+
"comments:read": "comments:read";
|
|
131
|
+
"comments:moderate": "comments:moderate";
|
|
132
|
+
"communities:read": "communities:read";
|
|
133
|
+
"communities:write": "communities:write";
|
|
134
|
+
"communities:delete": "communities:delete";
|
|
135
|
+
"community_members:read": "community_members:read";
|
|
136
|
+
"community_members:write": "community_members:write";
|
|
137
|
+
"community_moderation:read": "community_moderation:read";
|
|
138
|
+
"community_moderation:write": "community_moderation:write";
|
|
139
|
+
}>>;
|
|
140
|
+
}, z.core.$strip>;
|
|
141
|
+
declare const ApiKeyIdParam: z.ZodObject<{
|
|
142
|
+
id: z.ZodString;
|
|
143
|
+
}, z.core.$strip>;
|
|
144
|
+
//#endregion
|
|
145
|
+
export { ApiKey, ApiKeyIdParam, ApiKeyList, ClientIdParam, ConnectedApp, ConnectedAppList, CreateApiKey, CreatedApiKey, ScopeOption, ScopeOptionList };
|
|
146
|
+
//# sourceMappingURL=access.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ACCESS_SCOPES } from "@headless-lms/core/organizations";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/http/schemas/access.ts
|
|
4
|
+
const ScopeOption = z.object({
|
|
5
|
+
scope: z.enum(ACCESS_SCOPES),
|
|
6
|
+
allowed: z.boolean()
|
|
7
|
+
});
|
|
8
|
+
const ScopeOptionList = z.array(ScopeOption);
|
|
9
|
+
const ConnectedApp = z.object({
|
|
10
|
+
clientId: z.string(),
|
|
11
|
+
name: z.string(),
|
|
12
|
+
iconUrl: z.string().nullable(),
|
|
13
|
+
scopes: z.array(z.string()),
|
|
14
|
+
connectedAt: z.coerce.date()
|
|
15
|
+
});
|
|
16
|
+
const ConnectedAppList = z.array(ConnectedApp);
|
|
17
|
+
const ClientIdParam = z.object({ clientId: z.string() });
|
|
18
|
+
const ApiKey = z.object({
|
|
19
|
+
id: z.string(),
|
|
20
|
+
name: z.string().nullable(),
|
|
21
|
+
start: z.string().nullable(),
|
|
22
|
+
scopes: z.array(z.string()),
|
|
23
|
+
createdAt: z.coerce.date(),
|
|
24
|
+
lastUsedAt: z.coerce.date().nullable()
|
|
25
|
+
});
|
|
26
|
+
const ApiKeyList = z.array(ApiKey);
|
|
27
|
+
const CreatedApiKey = ApiKey.extend({ key: z.string() });
|
|
28
|
+
const CreateApiKey = z.object({
|
|
29
|
+
name: z.string().trim().min(1).max(80),
|
|
30
|
+
scopes: z.array(z.enum(ACCESS_SCOPES)).min(1)
|
|
31
|
+
});
|
|
32
|
+
const ApiKeyIdParam = z.object({ id: z.string() });
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ApiKey, ApiKeyIdParam, ApiKeyList, ClientIdParam, ConnectedApp, ConnectedAppList, CreateApiKey, CreatedApiKey, ScopeOption, ScopeOptionList };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.js","names":[],"sources":["../../../src/http/schemas/access.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ACCESS_SCOPES } from '@headless-lms/core/organizations';\n\nexport const ScopeOption = z.object({ scope: z.enum(ACCESS_SCOPES), allowed: z.boolean() });\nexport const ScopeOptionList = z.array(ScopeOption);\n\nexport const ConnectedApp = z.object({\n clientId: z.string(),\n name: z.string(),\n iconUrl: z.string().nullable(),\n scopes: z.array(z.string()),\n connectedAt: z.coerce.date(),\n});\nexport const ConnectedAppList = z.array(ConnectedApp);\nexport const ClientIdParam = z.object({ clientId: z.string() });\n\nexport const ApiKey = z.object({\n id: z.string(),\n name: z.string().nullable(),\n start: z.string().nullable(),\n scopes: z.array(z.string()),\n createdAt: z.coerce.date(),\n lastUsedAt: z.coerce.date().nullable(),\n});\nexport const ApiKeyList = z.array(ApiKey);\nexport const CreatedApiKey = ApiKey.extend({ key: z.string() });\nexport const CreateApiKey = z.object({\n name: z.string().trim().min(1).max(80),\n scopes: z.array(z.enum(ACCESS_SCOPES)).min(1),\n});\nexport const ApiKeyIdParam = z.object({ id: z.string() });\n"],"mappings":";;;AAGA,MAAa,cAAc,EAAE,OAAO;CAAE,OAAO,EAAE,KAAK,aAAa;CAAG,SAAS,EAAE,QAAQ;AAAE,CAAC;AAC1F,MAAa,kBAAkB,EAAE,MAAM,WAAW;AAElD,MAAa,eAAe,EAAE,OAAO;CACnC,UAAU,EAAE,OAAO;CACnB,MAAM,EAAE,OAAO;CACf,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;CAC1B,aAAa,EAAE,OAAO,KAAK;AAC7B,CAAC;AACD,MAAa,mBAAmB,EAAE,MAAM,YAAY;AACpD,MAAa,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AAE9D,MAAa,SAAS,EAAE,OAAO;CAC7B,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;CAC1B,WAAW,EAAE,OAAO,KAAK;CACzB,YAAY,EAAE,OAAO,KAAK,CAAC,CAAC,SAAS;AACvC,CAAC;AACD,MAAa,aAAa,EAAE,MAAM,MAAM;AACxC,MAAa,gBAAgB,OAAO,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC9D,MAAa,eAAe,EAAE,OAAO;CACnC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;CACrC,QAAQ,EAAE,MAAM,EAAE,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AACD,MAAa,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -9,6 +9,7 @@ declare const Activity: z.ZodObject<{
|
|
|
9
9
|
settings: z.ZodNullable<z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>>;
|
|
10
10
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
11
11
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
12
|
+
assetUrls: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
12
13
|
}, z.core.$strict>;
|
|
13
14
|
type Activity = z.infer<typeof Activity>;
|
|
14
15
|
declare const ActivityAsset: z.ZodObject<{
|
|
@@ -42,7 +43,7 @@ declare const ModuleList: z.ZodArray<z.ZodObject<{
|
|
|
42
43
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
43
44
|
}, z.core.$strict>>;
|
|
44
45
|
type ModuleList = z.infer<typeof ModuleList>;
|
|
45
|
-
/** A course's activities
|
|
46
|
+
/** A course's activities, each with the stable file URLs of the files it links, ordered by (moduleId, seq). */
|
|
46
47
|
declare const ActivityList: z.ZodArray<z.ZodObject<{
|
|
47
48
|
orgId: z.ZodString;
|
|
48
49
|
id: z.ZodString;
|
|
@@ -52,6 +53,7 @@ declare const ActivityList: z.ZodArray<z.ZodObject<{
|
|
|
52
53
|
settings: z.ZodNullable<z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>>;
|
|
53
54
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
54
55
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
56
|
+
assetUrls: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
55
57
|
}, z.core.$strict>>;
|
|
56
58
|
type ActivityList = z.infer<typeof ActivityList>;
|
|
57
59
|
/** A course's activity→asset link rows, ordered by (activityId, seq). */
|