@headless-lms/server 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.js +5 -0
- package/dist/app/community-mail.d.ts +26 -0
- package/dist/app/community-mail.js +96 -0
- package/dist/app/community-mail.js.map +1 -0
- package/dist/app/container.d.ts +18 -14
- package/dist/app/container.js +136 -43
- package/dist/app/container.js.map +1 -1
- package/dist/app/mcp-endpoints.d.ts +13 -0
- package/dist/app/mcp-endpoints.js +25 -0
- package/dist/app/mcp-endpoints.js.map +1 -0
- package/dist/http/config.d.ts +2 -1
- package/dist/http/errors.d.ts +14 -0
- package/dist/http/errors.js +147 -0
- package/dist/http/errors.js.map +1 -0
- package/dist/http/mcp/catalogue.d.ts +37 -0
- package/dist/http/mcp/catalogue.js +69 -0
- package/dist/http/mcp/catalogue.js.map +1 -0
- package/dist/http/mcp/challenge.d.ts +7 -0
- package/dist/http/mcp/challenge.js +35 -0
- package/dist/http/mcp/challenge.js.map +1 -0
- package/dist/http/mcp/input-schema.d.ts +7 -0
- package/dist/http/mcp/input-schema.js +28 -0
- package/dist/http/mcp/input-schema.js.map +1 -0
- package/dist/http/mcp/route.d.ts +8 -0
- package/dist/http/mcp/route.js +75 -0
- package/dist/http/mcp/route.js.map +1 -0
- package/dist/http/mcp/server.d.ts +8 -0
- package/dist/http/mcp/server.js +31 -0
- package/dist/http/mcp/server.js.map +1 -0
- package/dist/http/mcp/test-support.d.ts +55 -0
- package/dist/http/mcp/test-support.js +151 -0
- package/dist/http/mcp/test-support.js.map +1 -0
- package/dist/http/mcp/tool.d.ts +48 -0
- package/dist/http/mcp/tool.js +58 -0
- package/dist/http/mcp/tool.js.map +1 -0
- package/dist/http/mcp/tools/automations.d.ts +6 -0
- package/dist/http/mcp/tools/automations.js +120 -0
- package/dist/http/mcp/tools/automations.js.map +1 -0
- package/dist/http/mcp/tools/catalog.d.ts +6 -0
- package/dist/http/mcp/tools/catalog.js +200 -0
- package/dist/http/mcp/tools/catalog.js.map +1 -0
- package/dist/http/mcp/tools/comments.d.ts +6 -0
- package/dist/http/mcp/tools/comments.js +70 -0
- package/dist/http/mcp/tools/comments.js.map +1 -0
- package/dist/http/mcp/tools/communities.d.ts +6 -0
- package/dist/http/mcp/tools/communities.js +175 -0
- package/dist/http/mcp/tools/communities.js.map +1 -0
- package/dist/http/mcp/tools/community-members.d.ts +6 -0
- package/dist/http/mcp/tools/community-members.js +89 -0
- package/dist/http/mcp/tools/community-members.js.map +1 -0
- package/dist/http/mcp/tools/community-moderation.d.ts +6 -0
- package/dist/http/mcp/tools/community-moderation.js +144 -0
- package/dist/http/mcp/tools/community-moderation.js.map +1 -0
- package/dist/http/mcp/tools/courses.d.ts +6 -0
- package/dist/http/mcp/tools/courses.js +121 -0
- package/dist/http/mcp/tools/courses.js.map +1 -0
- package/dist/http/mcp/tools/index.d.ts +6 -0
- package/dist/http/mcp/tools/index.js +23 -0
- package/dist/http/mcp/tools/index.js.map +1 -0
- package/dist/http/mcp/tools/people.d.ts +6 -0
- package/dist/http/mcp/tools/people.js +145 -0
- package/dist/http/mcp/tools/people.js.map +1 -0
- package/dist/http/plugins/auth.js +13 -5
- package/dist/http/plugins/auth.js.map +1 -1
- package/dist/http/plugins/error-handler.d.ts +2 -1
- package/dist/http/plugins/error-handler.js +49 -65
- package/dist/http/plugins/error-handler.js.map +1 -1
- package/dist/http/plugins/openapi.js +49 -2
- package/dist/http/plugins/openapi.js.map +1 -1
- package/dist/http/routes/access.d.ts +7 -0
- package/dist/http/routes/access.js +140 -0
- package/dist/http/routes/access.js.map +1 -0
- package/dist/http/routes/activities.js +68 -23
- package/dist/http/routes/activities.js.map +1 -1
- package/dist/http/routes/assets.js +60 -55
- package/dist/http/routes/assets.js.map +1 -1
- package/dist/http/routes/automations.js +44 -24
- package/dist/http/routes/automations.js.map +1 -1
- package/dist/http/routes/bundles.js +29 -18
- package/dist/http/routes/bundles.js.map +1 -1
- package/dist/http/routes/communities.d.ts +7 -0
- package/dist/http/routes/communities.js +462 -0
- package/dist/http/routes/communities.js.map +1 -0
- package/dist/http/routes/community-moderation.d.ts +7 -0
- package/dist/http/routes/community-moderation.js +425 -0
- package/dist/http/routes/community-moderation.js.map +1 -0
- package/dist/http/routes/course-analytics.js +9 -7
- package/dist/http/routes/course-analytics.js.map +1 -1
- package/dist/http/routes/courses.js +30 -15
- package/dist/http/routes/courses.js.map +1 -1
- package/dist/http/routes/dashboard.js +15 -6
- package/dist/http/routes/dashboard.js.map +1 -1
- package/dist/http/routes/discussion.js +34 -26
- package/dist/http/routes/discussion.js.map +1 -1
- package/dist/http/routes/downloads.js +48 -30
- package/dist/http/routes/downloads.js.map +1 -1
- package/dist/http/routes/entitlements.js +16 -7
- package/dist/http/routes/entitlements.js.map +1 -1
- package/dist/http/routes/integrations.js +38 -41
- package/dist/http/routes/integrations.js.map +1 -1
- package/dist/http/routes/member/actor.d.ts +14 -0
- package/dist/http/routes/member/actor.js +11 -0
- package/dist/http/routes/member/actor.js.map +1 -0
- package/dist/http/routes/member/assets.d.ts +7 -0
- package/dist/http/routes/member/assets.js +79 -0
- package/dist/http/routes/member/assets.js.map +1 -0
- package/dist/http/routes/member/chats.d.ts +7 -0
- package/dist/http/routes/member/chats.js +456 -0
- package/dist/http/routes/member/chats.js.map +1 -0
- package/dist/http/routes/member/comments.d.ts +7 -0
- package/dist/http/routes/member/comments.js +187 -0
- package/dist/http/routes/member/comments.js.map +1 -0
- package/dist/http/routes/member/community.d.ts +7 -0
- package/dist/http/routes/member/community.js +288 -0
- package/dist/http/routes/member/community.js.map +1 -0
- package/dist/http/routes/member/courses.d.ts +7 -0
- package/dist/http/routes/member/courses.js +101 -0
- package/dist/http/routes/member/courses.js.map +1 -0
- package/dist/http/routes/member/downloads.d.ts +7 -0
- package/dist/http/routes/member/downloads.js +56 -0
- package/dist/http/routes/member/downloads.js.map +1 -0
- package/dist/http/routes/member/files.d.ts +7 -0
- package/dist/http/routes/member/files.js +184 -0
- package/dist/http/routes/member/files.js.map +1 -0
- package/dist/http/routes/member/index.d.ts +7 -0
- package/dist/http/routes/member/index.js +31 -0
- package/dist/http/routes/member/index.js.map +1 -0
- package/dist/http/routes/member/notifications.d.ts +7 -0
- package/dist/http/routes/member/notifications.js +101 -0
- package/dist/http/routes/member/notifications.js.map +1 -0
- package/dist/http/routes/member/org.d.ts +7 -0
- package/dist/http/routes/member/org.js +56 -0
- package/dist/http/routes/member/org.js.map +1 -0
- package/dist/http/routes/member/posts.d.ts +7 -0
- package/dist/http/routes/member/posts.js +612 -0
- package/dist/http/routes/member/posts.js.map +1 -0
- package/dist/http/routes/member/profile.d.ts +7 -0
- package/dist/http/routes/member/profile.js +48 -0
- package/dist/http/routes/member/profile.js.map +1 -0
- package/dist/http/routes/member/progress.d.ts +7 -0
- package/dist/http/routes/member/progress.js +60 -0
- package/dist/http/routes/member/progress.js.map +1 -0
- package/dist/http/routes/organizations.js +49 -24
- package/dist/http/routes/organizations.js.map +1 -1
- package/dist/http/routes/students.js +32 -47
- package/dist/http/routes/students.js.map +1 -1
- package/dist/http/routes/webhooks.js +26 -18
- package/dist/http/routes/webhooks.js.map +1 -1
- package/dist/http/routes.js +8 -2
- package/dist/http/routes.js.map +1 -1
- package/dist/http/schemas/access.d.ts +146 -0
- package/dist/http/schemas/access.js +36 -0
- package/dist/http/schemas/access.js.map +1 -0
- package/dist/http/schemas/activities.d.ts +3 -1
- package/dist/http/schemas/activities.js +4 -4
- package/dist/http/schemas/activities.js.map +1 -1
- package/dist/http/schemas/assets.d.ts +73 -74
- package/dist/http/schemas/assets.js +23 -13
- package/dist/http/schemas/assets.js.map +1 -1
- package/dist/http/schemas/automations.d.ts +10 -0
- package/dist/http/schemas/bundles.js +6 -6
- package/dist/http/schemas/bundles.js.map +1 -1
- package/dist/http/schemas/chats.d.ts +386 -0
- package/dist/http/schemas/chats.js +58 -0
- package/dist/http/schemas/chats.js.map +1 -0
- package/dist/http/schemas/community.d.ts +537 -0
- package/dist/http/schemas/community.js +129 -0
- package/dist/http/schemas/community.js.map +1 -0
- package/dist/http/schemas/content.d.ts +4 -2
- package/dist/http/schemas/content.js +11 -8
- package/dist/http/schemas/content.js.map +1 -1
- package/dist/http/schemas/discussion.d.ts +76 -14
- package/dist/http/schemas/discussion.js +12 -11
- package/dist/http/schemas/discussion.js.map +1 -1
- package/dist/http/schemas/downloads.d.ts +11 -5
- package/dist/http/schemas/downloads.js +14 -11
- package/dist/http/schemas/downloads.js.map +1 -1
- package/dist/http/schemas/entitlements.d.ts +6 -6
- package/dist/http/schemas/entitlements.js +6 -6
- package/dist/http/schemas/entitlements.js.map +1 -1
- package/dist/http/schemas/files.d.ts +45 -0
- package/dist/http/schemas/files.js +25 -0
- package/dist/http/schemas/files.js.map +1 -0
- package/dist/http/schemas/index.d.ts +15 -8
- package/dist/http/schemas/index.js +15 -8
- package/dist/http/schemas/integrations.d.ts +2 -2
- package/dist/http/schemas/invites.d.ts +4 -0
- package/dist/http/schemas/invites.js +1 -0
- package/dist/http/schemas/invites.js.map +1 -1
- package/dist/http/schemas/{learn.d.ts → member.d.ts} +31 -18
- package/dist/http/schemas/{learn.js → member.js} +17 -13
- package/dist/http/schemas/member.js.map +1 -0
- package/dist/http/schemas/members.d.ts +39 -6
- package/dist/http/schemas/members.js +17 -3
- package/dist/http/schemas/members.js.map +1 -1
- package/dist/http/schemas/notifications.d.ts +227 -0
- package/dist/http/schemas/notifications.js +44 -0
- package/dist/http/schemas/notifications.js.map +1 -0
- package/dist/http/schemas/posts.d.ts +316 -0
- package/dist/http/schemas/posts.js +47 -0
- package/dist/http/schemas/posts.js.map +1 -0
- package/dist/http/schemas/profile.d.ts +23 -0
- package/dist/http/schemas/profile.js +15 -0
- package/dist/http/schemas/profile.js.map +1 -0
- package/dist/http/schemas/shared.d.ts +25 -1
- package/dist/http/schemas/shared.js +19 -2
- package/dist/http/schemas/shared.js.map +1 -1
- package/dist/http/schemas/students.d.ts +4 -10
- package/dist/http/schemas/students.js +1 -7
- package/dist/http/schemas/students.js.map +1 -1
- package/dist/http/scope.d.ts +2 -1
- package/dist/http/scope.js +20 -4
- package/dist/http/scope.js.map +1 -1
- package/dist/http/server.js +6 -1
- package/dist/http/server.js.map +1 -1
- package/dist/http/web-bridge.d.ts +1 -1
- package/dist/http/web-bridge.js +2 -2
- package/dist/http/web-bridge.js.map +1 -1
- package/dist/http/well-known.d.ts +7 -0
- package/dist/http/well-known.js +22 -0
- package/dist/http/well-known.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +78 -0
- package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js +1267 -0
- package/dist/node_modules/.pnpm/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js +814 -0
- package/dist/node_modules/.pnpm/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js +43 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js +527 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/utils.js +2 -0
- package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js +1737 -0
- package/dist/node_modules/.pnpm/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js +137 -0
- package/dist/node_modules/.pnpm/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +118 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js +1222 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js +91 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js +113 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js +449 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js +163 -0
- package/dist/node_modules/.pnpm/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.js.map +1 -0
- package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js +3187 -0
- package/dist/node_modules/.pnpm/chai@5.3.3/node_modules/chai/index.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js +11 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js +16 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js +11 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js +15 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js +13 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js +34 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js +12 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js +122 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js +39 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js +99 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js +25 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js +14 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js +21 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js +6 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js +12 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js +18 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js +24 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js +9 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js.map +1 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js +30 -0
- package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js.map +1 -0
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +939 -0
- package/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js.map +1 -0
- package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js +82 -0
- package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.js.map +1 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +82 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js.map +1 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js +8 -0
- package/dist/node_modules/.pnpm/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.js.map +1 -0
- package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js +83 -0
- package/dist/node_modules/.pnpm/tinyspy@3.0.2/node_modules/tinyspy/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js +9 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js.map +1 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/date.W2xKR2qe.js +51 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/date.W2xKR2qe.js.map +1 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/utils.C8RiOc4B.js +48 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/utils.C8RiOc4B.js.map +1 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/vi.DgezovHB.js +2426 -0
- package/dist/node_modules/.pnpm/vitest@2.1.9_@types_node@22.20.0_jsdom@25.0.1_lightningcss@1.32.0/node_modules/vitest/dist/chunks/vi.DgezovHB.js.map +1 -0
- package/dist/packages/server/package.js +6 -0
- package/dist/packages/server/package.js.map +1 -0
- package/package.json +9 -7
- package/dist/app/notifications.d.ts +0 -7
- package/dist/app/notifications.js +0 -26
- package/dist/app/notifications.js.map +0 -1
- package/dist/http/routes/learn/assets.d.ts +0 -8
- package/dist/http/routes/learn/assets.js +0 -32
- package/dist/http/routes/learn/assets.js.map +0 -1
- package/dist/http/routes/learn/comments.d.ts +0 -7
- package/dist/http/routes/learn/comments.js +0 -175
- package/dist/http/routes/learn/comments.js.map +0 -1
- package/dist/http/routes/learn/courses.d.ts +0 -7
- package/dist/http/routes/learn/courses.js +0 -98
- package/dist/http/routes/learn/courses.js.map +0 -1
- package/dist/http/routes/learn/downloads.d.ts +0 -7
- package/dist/http/routes/learn/downloads.js +0 -76
- package/dist/http/routes/learn/downloads.js.map +0 -1
- package/dist/http/routes/learn/index.d.ts +0 -7
- package/dist/http/routes/learn/index.js +0 -19
- package/dist/http/routes/learn/index.js.map +0 -1
- package/dist/http/routes/learn/org.d.ts +0 -7
- package/dist/http/routes/learn/org.js +0 -50
- package/dist/http/routes/learn/org.js.map +0 -1
- package/dist/http/routes/learn/progress.d.ts +0 -7
- package/dist/http/routes/learn/progress.js +0 -63
- package/dist/http/routes/learn/progress.js.map +0 -1
- package/dist/http/schemas/learn.js.map +0 -1
- package/dist/package.js +0 -6
- package/dist/package.js.map +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { DateTimeInput, PageQuery, paginated } from "./shared.js";
|
|
2
|
+
import { CommentView } from "./discussion.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { boundedJsonSchema, flaggedCommentSchema, idSchema, postFlagResolutionSchema, postFlagSchema, postViewSchema } from "@headless-lms/core/schemas";
|
|
5
|
+
//#region src/http/schemas/posts.ts
|
|
6
|
+
const PostView = postViewSchema;
|
|
7
|
+
const PostFlag = postFlagSchema;
|
|
8
|
+
const PostFeedPage = paginated(PostView);
|
|
9
|
+
const PostIdParam = z.object({ postId: z.string() });
|
|
10
|
+
const FeedQuery = PageQuery.extend({ topicId: z.string().optional().describe("Only posts under this topic") }).strict();
|
|
11
|
+
const PostTitle = z.string().trim().min(1).max(200);
|
|
12
|
+
const PostBody = z.string().max(5e4);
|
|
13
|
+
const PostExtra = boundedJsonSchema(16 * 1024);
|
|
14
|
+
const CreatePost = z.object({
|
|
15
|
+
title: PostTitle,
|
|
16
|
+
body: PostBody,
|
|
17
|
+
topicId: idSchema.nullable().describe("One of the space's topics. Required when the space has topics, else null"),
|
|
18
|
+
extra: PostExtra.default({}),
|
|
19
|
+
coverAssetId: idSchema.nullable().describe("A finalized image you uploaded through `requestMemberUpload`"),
|
|
20
|
+
mode: z.enum([
|
|
21
|
+
"draft",
|
|
22
|
+
"submit",
|
|
23
|
+
"schedule"
|
|
24
|
+
]).describe("`draft` keeps the post to yourself. `submit` publishes it, or holds it for review when the space requires review and you are not staff. `schedule` submits it at `scheduledAt`."),
|
|
25
|
+
scheduledAt: DateTimeInput.nullable().describe("When a scheduled post is submitted. Required, and in the future, when `mode` is `schedule`; ignored otherwise.")
|
|
26
|
+
}).strict();
|
|
27
|
+
const UpdatePost = z.object({
|
|
28
|
+
title: PostTitle.optional(),
|
|
29
|
+
body: PostBody.optional(),
|
|
30
|
+
topicId: idSchema.nullable().optional(),
|
|
31
|
+
extra: PostExtra.optional(),
|
|
32
|
+
coverAssetId: idSchema.nullable().optional()
|
|
33
|
+
}).strict();
|
|
34
|
+
const SchedulePost = z.object({ scheduledAt: DateTimeInput.describe("When the post is submitted; must be in the future") }).strict();
|
|
35
|
+
const SetPostReactions = z.object({ enabled: z.boolean().describe("Whether readers may react to this post") }).strict();
|
|
36
|
+
const FlagReason = z.object({ reason: z.string().trim().min(1).max(1e3) }).strict();
|
|
37
|
+
const ResolvePostFlags = z.object({ resolution: postFlagResolutionSchema.extract(["dismissed"]).describe("`dismissed` closes the open flags and leaves the post up. Removing the post resolves its flags as `removed` instead.") }).strict();
|
|
38
|
+
const SpaceQueue = z.object({
|
|
39
|
+
pending: z.array(PostView),
|
|
40
|
+
flags: z.array(PostFlag),
|
|
41
|
+
commentFlags: z.array(flaggedCommentSchema)
|
|
42
|
+
});
|
|
43
|
+
const PostCommentsPage = paginated(CommentView);
|
|
44
|
+
//#endregion
|
|
45
|
+
export { CreatePost, FeedQuery, FlagReason, PostCommentsPage, PostFeedPage, PostFlag, PostIdParam, PostView, ResolvePostFlags, SchedulePost, SetPostReactions, SpaceQueue, UpdatePost };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=posts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts.js","names":[],"sources":["../../../src/http/schemas/posts.ts"],"sourcesContent":["import { z } from 'zod';\nimport {\n boundedJsonSchema,\n flaggedCommentSchema,\n idSchema,\n postFlagResolutionSchema,\n postFlagSchema,\n postViewSchema,\n} from '@headless-lms/core/schemas';\nimport { CommentView } from './discussion.js';\nimport { DateTimeInput, PageQuery, paginated } from './shared.js';\n\nexport const PostView = postViewSchema;\nexport const PostFlag = postFlagSchema;\nexport const PostFeedPage = paginated(PostView);\nexport const PostIdParam = z.object({ postId: z.string() });\nexport const FeedQuery = PageQuery.extend({\n topicId: z.string().optional().describe('Only posts under this topic'),\n}).strict();\n\nconst PostTitle = z.string().trim().min(1).max(200);\nconst PostBody = z.string().max(50_000);\nconst PostExtra = boundedJsonSchema(16 * 1024);\n\nexport const CreatePost = z\n .object({\n title: PostTitle,\n body: PostBody,\n topicId: idSchema\n .nullable()\n .describe(\"One of the space's topics. Required when the space has topics, else null\"),\n extra: PostExtra.default({}),\n coverAssetId: idSchema\n .nullable()\n .describe('A finalized image you uploaded through `requestMemberUpload`'),\n mode: z\n .enum(['draft', 'submit', 'schedule'])\n .describe(\n '`draft` keeps the post to yourself. `submit` publishes it, or holds it for review when the space requires review and you are not staff. `schedule` submits it at `scheduledAt`.',\n ),\n scheduledAt: DateTimeInput.nullable().describe(\n 'When a scheduled post is submitted. Required, and in the future, when `mode` is `schedule`; ignored otherwise.',\n ),\n })\n .strict();\n\nexport const UpdatePost = z\n .object({\n title: PostTitle.optional(),\n body: PostBody.optional(),\n topicId: idSchema.nullable().optional(),\n extra: PostExtra.optional(),\n coverAssetId: idSchema.nullable().optional(),\n })\n .strict();\n\nexport const SchedulePost = z\n .object({\n scheduledAt: DateTimeInput.describe('When the post is submitted; must be in the future'),\n })\n .strict();\nexport const SetPostReactions = z\n .object({ enabled: z.boolean().describe('Whether readers may react to this post') })\n .strict();\nexport const FlagReason = z.object({ reason: z.string().trim().min(1).max(1_000) }).strict();\nexport const ResolvePostFlags = z\n .object({\n resolution: postFlagResolutionSchema\n .extract(['dismissed'])\n .describe(\n '`dismissed` closes the open flags and leaves the post up. Removing the post resolves its flags as `removed` instead.',\n ),\n })\n .strict();\n\nexport const SpaceQueue = z.object({\n pending: z.array(PostView),\n flags: z.array(PostFlag),\n commentFlags: z.array(flaggedCommentSchema),\n});\n\nexport const PostCommentsPage = paginated(CommentView);\n"],"mappings":";;;;;AAYA,MAAa,WAAW;AACxB,MAAa,WAAW;AACxB,MAAa,eAAe,UAAU,QAAQ;AAC9C,MAAa,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC1D,MAAa,YAAY,UAAU,OAAO,EACxC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,6BAA6B,EACvE,CAAC,CAAC,CAAC,OAAO;AAEV,MAAM,YAAY,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG;AAClD,MAAM,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,GAAM;AACtC,MAAM,YAAY,kBAAkB,KAAK,IAAI;AAE7C,MAAa,aAAa,EACvB,OAAO;CACN,OAAO;CACP,MAAM;CACN,SAAS,SACN,SAAS,CAAC,CACV,SAAS,0EAA0E;CACtF,OAAO,UAAU,QAAQ,CAAC,CAAC;CAC3B,cAAc,SACX,SAAS,CAAC,CACV,SAAS,8DAA8D;CAC1E,MAAM,EACH,KAAK;EAAC;EAAS;EAAU;CAAU,CAAC,CAAC,CACrC,SACC,iLACF;CACF,aAAa,cAAc,SAAS,CAAC,CAAC,SACpC,gHACF;AACF,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,aAAa,EACvB,OAAO;CACN,OAAO,UAAU,SAAS;CAC1B,MAAM,SAAS,SAAS;CACxB,SAAS,SAAS,SAAS,CAAC,CAAC,SAAS;CACtC,OAAO,UAAU,SAAS;CAC1B,cAAc,SAAS,SAAS,CAAC,CAAC,SAAS;AAC7C,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,eAAe,EACzB,OAAO,EACN,aAAa,cAAc,SAAS,mDAAmD,EACzF,CAAC,CAAC,CACD,OAAO;AACV,MAAa,mBAAmB,EAC7B,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,SAAS,wCAAwC,EAAE,CAAC,CAAC,CACnF,OAAO;AACV,MAAa,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAK,EAAE,CAAC,CAAC,CAAC,OAAO;AAC3F,MAAa,mBAAmB,EAC7B,OAAO,EACN,YAAY,yBACT,QAAQ,CAAC,WAAW,CAAC,CAAC,CACtB,SACC,sHACF,EACJ,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,aAAa,EAAE,OAAO;CACjC,SAAS,EAAE,MAAM,QAAQ;CACzB,OAAO,EAAE,MAAM,QAAQ;CACvB,cAAc,EAAE,MAAM,oBAAoB;AAC5C,CAAC;AAED,MAAa,mBAAmB,UAAU,WAAW"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/http/schemas/profile.d.ts
|
|
3
|
+
declare const UserProfile: z.ZodObject<{
|
|
4
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
5
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
6
|
+
displayName: z.ZodNullable<z.ZodString>;
|
|
7
|
+
headline: z.ZodNullable<z.ZodString>;
|
|
8
|
+
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
9
|
+
imageUrl: z.ZodNullable<z.ZodString>;
|
|
10
|
+
bio: z.ZodNullable<z.ZodString>;
|
|
11
|
+
userId: z.ZodString;
|
|
12
|
+
extra: z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
declare const UpdateProfile: z.ZodObject<{
|
|
15
|
+
displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
16
|
+
headline: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
17
|
+
bio: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
|
+
imageAssetId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
19
|
+
extra: z.ZodOptional<z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>>;
|
|
20
|
+
}, z.core.$strict>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { UpdateProfile, UserProfile };
|
|
23
|
+
//# sourceMappingURL=profile.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { boundedJsonSchema, idSchema, userProfileViewSchema } from "@headless-lms/core/schemas";
|
|
3
|
+
//#region src/http/schemas/profile.ts
|
|
4
|
+
const UserProfile = userProfileViewSchema.omit({ imageAssetOrgId: true }).strip();
|
|
5
|
+
const UpdateProfile = z.object({
|
|
6
|
+
displayName: z.string().trim().max(80).nullable().optional(),
|
|
7
|
+
headline: z.string().trim().max(160).nullable().optional(),
|
|
8
|
+
bio: z.string().trim().max(2e3).nullable().optional(),
|
|
9
|
+
imageAssetId: idSchema.nullable().optional().describe("A finalized image you uploaded through `requestMemberUpload`; null clears it"),
|
|
10
|
+
extra: boundedJsonSchema(16 * 1024).optional()
|
|
11
|
+
}).strict();
|
|
12
|
+
//#endregion
|
|
13
|
+
export { UpdateProfile, UserProfile };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","names":[],"sources":["../../../src/http/schemas/profile.ts"],"sourcesContent":["import { z } from 'zod';\nimport { boundedJsonSchema, idSchema, userProfileViewSchema } from '@headless-lms/core/schemas';\n\nexport const UserProfile = userProfileViewSchema.omit({ imageAssetOrgId: true }).strip();\nexport const UpdateProfile = z\n .object({\n displayName: z.string().trim().max(80).nullable().optional(),\n headline: z.string().trim().max(160).nullable().optional(),\n bio: z.string().trim().max(2_000).nullable().optional(),\n imageAssetId: idSchema\n .nullable()\n .optional()\n .describe('A finalized image you uploaded through `requestMemberUpload`; null clears it'),\n extra: boundedJsonSchema(16 * 1024).optional(),\n })\n .strict();\n"],"mappings":";;;AAGA,MAAa,cAAc,sBAAsB,KAAK,EAAE,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM;AACvF,MAAa,gBAAgB,EAC1B,OAAO;CACN,aAAa,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CAC3D,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACzD,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,GAAK,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACtD,cAAc,SACX,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SAAS,8EAA8E;CAC1F,OAAO,kBAAkB,KAAK,IAAI,CAAC,CAAC,SAAS;AAC/C,CAAC,CAAC,CACD,OAAO"}
|
|
@@ -9,6 +9,29 @@ declare const ErrorBody: z.ZodObject<{
|
|
|
9
9
|
requestId: z.ZodOptional<z.ZodString>;
|
|
10
10
|
}, z.core.$strip>;
|
|
11
11
|
type ErrorBody = z.infer<typeof ErrorBody>;
|
|
12
|
+
/** A 400 from request validation: `message` names the first problem, `issues` lists them all. */
|
|
13
|
+
declare const ValidationErrorBody: z.ZodObject<{
|
|
14
|
+
error: z.ZodString;
|
|
15
|
+
message: z.ZodOptional<z.ZodString>;
|
|
16
|
+
requestId: z.ZodOptional<z.ZodString>;
|
|
17
|
+
issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
18
|
+
path: z.ZodString;
|
|
19
|
+
message: z.ZodString;
|
|
20
|
+
}, z.core.$strip>>>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
type ValidationErrorBody = z.infer<typeof ValidationErrorBody>;
|
|
23
|
+
type RefusalStatus = 400 | 403 | 404 | 409 | 413 | 415 | 502;
|
|
24
|
+
type RefusalBodies<S extends RefusalStatus> = { [K in S]: K extends 400 ? typeof ValidationErrorBody : typeof ErrorBody; };
|
|
25
|
+
/** Response schemas for the refusals a route can answer. A 400 keeps the validation `issues`. */
|
|
26
|
+
declare function refusals<S extends RefusalStatus>(...statuses: S[]): RefusalBodies<S>;
|
|
27
|
+
/** An RFC 3339 date-time in a request, such as `2026-10-29T12:00:00Z`, read as a Date. */
|
|
28
|
+
declare const DateTimeInput: z.ZodPipe<z.ZodISODateTime, z.ZodCoercedDate<string>>;
|
|
29
|
+
/** Page position only, for lists that take no search or sort. */
|
|
30
|
+
declare const PageQuery: z.ZodObject<{
|
|
31
|
+
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
32
|
+
pageSize: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
type PageQuery = z.infer<typeof PageQuery>;
|
|
12
35
|
/**
|
|
13
36
|
* Common list query for page-based collections. `z.coerce` because query-string
|
|
14
37
|
* values arrive as strings; defaults make the params optional for callers.
|
|
@@ -33,6 +56,7 @@ declare const OrgRole: z.ZodEnum<{
|
|
|
33
56
|
owner: "owner";
|
|
34
57
|
admin: "admin";
|
|
35
58
|
instructor: "instructor";
|
|
59
|
+
moderator: "moderator";
|
|
36
60
|
student: "student";
|
|
37
61
|
}>;
|
|
38
62
|
type OrgRole = z.infer<typeof OrgRole>;
|
|
@@ -54,5 +78,5 @@ declare const OrgUserProfileSchema: z.ZodObject<{
|
|
|
54
78
|
}, z.core.$strip>;
|
|
55
79
|
type OrgUserProfileSchema = z.infer<typeof OrgUserProfileSchema>;
|
|
56
80
|
//#endregion
|
|
57
|
-
export { ErrorBody, ListQuery, Matches, OrgRole, OrgUserProfileSchema, UserProfileSchema, paginated };
|
|
81
|
+
export { DateTimeInput, ErrorBody, ListQuery, Matches, OrgRole, OrgUserProfileSchema, PageQuery, UserProfileSchema, ValidationErrorBody, paginated, refusals };
|
|
58
82
|
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -7,6 +7,22 @@ const ErrorBody = z.object({
|
|
|
7
7
|
/** Server-side correlation id — quote it to find the matching API log line. */
|
|
8
8
|
requestId: z.string().optional()
|
|
9
9
|
});
|
|
10
|
+
/** A 400 from request validation: `message` names the first problem, `issues` lists them all. */
|
|
11
|
+
const ValidationErrorBody = ErrorBody.extend({ issues: z.array(z.object({
|
|
12
|
+
path: z.string().describe("Where in the request, such as `body.topics[1].name`"),
|
|
13
|
+
message: z.string()
|
|
14
|
+
})).optional() });
|
|
15
|
+
/** Response schemas for the refusals a route can answer. A 400 keeps the validation `issues`. */
|
|
16
|
+
function refusals(...statuses) {
|
|
17
|
+
return Object.fromEntries(statuses.map((status) => [status, status === 400 ? ValidationErrorBody : ErrorBody]));
|
|
18
|
+
}
|
|
19
|
+
/** An RFC 3339 date-time in a request, such as `2026-10-29T12:00:00Z`, read as a Date. */
|
|
20
|
+
const DateTimeInput = z.iso.datetime({ offset: true }).pipe(z.coerce.date());
|
|
21
|
+
/** Page position only, for lists that take no search or sort. */
|
|
22
|
+
const PageQuery = z.object({
|
|
23
|
+
page: z.coerce.number().int().min(1).default(1),
|
|
24
|
+
pageSize: z.coerce.number().int().min(1).max(100).default(20)
|
|
25
|
+
}).strict();
|
|
10
26
|
/**
|
|
11
27
|
* Common list query for page-based collections. `z.coerce` because query-string
|
|
12
28
|
* values arrive as strings; defaults make the params optional for callers.
|
|
@@ -14,7 +30,7 @@ const ErrorBody = z.object({
|
|
|
14
30
|
const ListQuery = z.object({
|
|
15
31
|
page: z.coerce.number().int().min(1).default(1),
|
|
16
32
|
pageSize: z.coerce.number().int().min(1).max(100).default(20),
|
|
17
|
-
search: z.string().trim().optional(),
|
|
33
|
+
search: z.string().trim().max(200).optional(),
|
|
18
34
|
/** Sort field, optionally prefixed with `-` for descending (e.g. `-updatedAt`). */
|
|
19
35
|
sort: z.string().optional()
|
|
20
36
|
});
|
|
@@ -33,6 +49,7 @@ const OrgRole = z.enum([
|
|
|
33
49
|
"owner",
|
|
34
50
|
"admin",
|
|
35
51
|
"instructor",
|
|
52
|
+
"moderator",
|
|
36
53
|
"student"
|
|
37
54
|
]);
|
|
38
55
|
/** Mirrors UserProfile in @headless-lms/core/types — keyed on the auth user id. */
|
|
@@ -51,6 +68,6 @@ const OrgUserProfileSchema = z.object({
|
|
|
51
68
|
image: z.string().nullable()
|
|
52
69
|
});
|
|
53
70
|
//#endregion
|
|
54
|
-
export { ErrorBody, ListQuery, OrgRole, OrgUserProfileSchema, UserProfileSchema, paginated };
|
|
71
|
+
export { DateTimeInput, ErrorBody, ListQuery, OrgRole, OrgUserProfileSchema, PageQuery, UserProfileSchema, ValidationErrorBody, paginated, refusals };
|
|
55
72
|
|
|
56
73
|
//# sourceMappingURL=shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","names":[],"sources":["../../../src/http/schemas/shared.ts"],"sourcesContent":["// Shared contract primitives reused across resource contracts.\nimport { z } from 'zod';\n\n/** Fails typecheck when a schema and its domain type drift apart. */\nexport type Matches<A, _B extends A> = true;\n\n/** Uniform error envelope returned by every non-2xx response. */\nexport const ErrorBody = z.object({\n error: z.string(),\n message: z.string().optional(),\n /** Server-side correlation id — quote it to find the matching API log line. */\n requestId: z.string().optional(),\n});\nexport type ErrorBody = z.infer<typeof ErrorBody>;\n\n/**\n * Common list query for page-based collections. `z.coerce` because query-string\n * values arrive as strings; defaults make the params optional for callers.\n */\nexport const ListQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().trim().optional(),\n /** Sort field, optionally prefixed with `-` for descending (e.g. `-updatedAt`). */\n sort: z.string().optional(),\n});\nexport type ListQuery = z.infer<typeof ListQuery>;\n\n/** Wrap a row schema into the standard paginated envelope. */\nexport function paginated<T extends z.ZodTypeAny>(row: T) {\n return z.object({\n rows: z.array(row),\n total: z.number().int(),\n page: z.number().int(),\n pageSize: z.number().int(),\n });\n}\n\n/** All four org roles. `members.ts` exports a staff-only three-value `Role`;\n * this is the full set, used wherever a learner can also appear. */\nexport const OrgRole = z.enum(['owner', 'admin', 'instructor', 'student']);\nexport type OrgRole = z.infer<typeof OrgRole>;\n\n/** Mirrors UserProfile in @headless-lms/core/types — keyed on the auth user id. */\nexport const UserProfileSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type UserProfileSchema = z.infer<typeof UserProfileSchema>;\n\n/** Mirrors OrgUserProfile in @headless-lms/core/types — keyed on org_users.id. */\nexport const OrgUserProfileSchema = z.object({\n id: z.string(),\n firstName: z.string().nullable(),\n lastName: z.string().nullable(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type OrgUserProfileSchema = z.infer<typeof OrgUserProfileSchema>;\n"],"mappings":";;;AAOA,MAAa,YAAY,EAAE,OAAO;CAChC,OAAO,EAAE,OAAO;CAChB,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;;
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../../src/http/schemas/shared.ts"],"sourcesContent":["// Shared contract primitives reused across resource contracts.\nimport { z } from 'zod';\n\n/** Fails typecheck when a schema and its domain type drift apart. */\nexport type Matches<A, _B extends A> = true;\n\n/** Uniform error envelope returned by every non-2xx response. */\nexport const ErrorBody = z.object({\n error: z.string(),\n message: z.string().optional(),\n /** Server-side correlation id — quote it to find the matching API log line. */\n requestId: z.string().optional(),\n});\nexport type ErrorBody = z.infer<typeof ErrorBody>;\n\n/** A 400 from request validation: `message` names the first problem, `issues` lists them all. */\nexport const ValidationErrorBody = ErrorBody.extend({\n issues: z\n .array(\n z.object({\n path: z.string().describe('Where in the request, such as `body.topics[1].name`'),\n message: z.string(),\n }),\n )\n .optional(),\n});\nexport type ValidationErrorBody = z.infer<typeof ValidationErrorBody>;\n\ntype RefusalStatus = 400 | 403 | 404 | 409 | 413 | 415 | 502;\ntype RefusalBodies<S extends RefusalStatus> = {\n [K in S]: K extends 400 ? typeof ValidationErrorBody : typeof ErrorBody;\n};\n\n/** Response schemas for the refusals a route can answer. A 400 keeps the validation `issues`. */\nexport function refusals<S extends RefusalStatus>(...statuses: S[]): RefusalBodies<S> {\n return Object.fromEntries(\n statuses.map((status) => [status, status === 400 ? ValidationErrorBody : ErrorBody]),\n ) as RefusalBodies<S>;\n}\n\n/** An RFC 3339 date-time in a request, such as `2026-10-29T12:00:00Z`, read as a Date. */\nexport const DateTimeInput = z.iso.datetime({ offset: true }).pipe(z.coerce.date());\n\n/** Page position only, for lists that take no search or sort. */\nexport const PageQuery = z\n .object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n })\n .strict();\nexport type PageQuery = z.infer<typeof PageQuery>;\n\n/**\n * Common list query for page-based collections. `z.coerce` because query-string\n * values arrive as strings; defaults make the params optional for callers.\n */\nexport const ListQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().trim().max(200).optional(),\n /** Sort field, optionally prefixed with `-` for descending (e.g. `-updatedAt`). */\n sort: z.string().optional(),\n});\nexport type ListQuery = z.infer<typeof ListQuery>;\n\n/** Wrap a row schema into the standard paginated envelope. */\nexport function paginated<T extends z.ZodTypeAny>(row: T) {\n return z.object({\n rows: z.array(row),\n total: z.number().int(),\n page: z.number().int(),\n pageSize: z.number().int(),\n });\n}\n\n/** All four org roles. `members.ts` exports a staff-only three-value `Role`;\n * this is the full set, used wherever a learner can also appear. */\nexport const OrgRole = z.enum(['owner', 'admin', 'instructor', 'moderator', 'student']);\nexport type OrgRole = z.infer<typeof OrgRole>;\n\n/** Mirrors UserProfile in @headless-lms/core/types — keyed on the auth user id. */\nexport const UserProfileSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type UserProfileSchema = z.infer<typeof UserProfileSchema>;\n\n/** Mirrors OrgUserProfile in @headless-lms/core/types — keyed on org_users.id. */\nexport const OrgUserProfileSchema = z.object({\n id: z.string(),\n firstName: z.string().nullable(),\n lastName: z.string().nullable(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type OrgUserProfileSchema = z.infer<typeof OrgUserProfileSchema>;\n"],"mappings":";;;AAOA,MAAa,YAAY,EAAE,OAAO;CAChC,OAAO,EAAE,OAAO;CAChB,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;AAID,MAAa,sBAAsB,UAAU,OAAO,EAClD,QAAQ,EACL,MACC,EAAE,OAAO;CACP,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,qDAAqD;CAC/E,SAAS,EAAE,OAAO;AACpB,CAAC,CACH,CAAC,CACA,SAAS,EACd,CAAC;;AASD,SAAgB,SAAkC,GAAG,UAAiC;CACpF,OAAO,OAAO,YACZ,SAAS,KAAK,WAAW,CAAC,QAAQ,WAAW,MAAM,sBAAsB,SAAS,CAAC,CACrF;AACF;;AAGA,MAAa,gBAAgB,EAAE,IAAI,SAAS,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC;;AAGlF,MAAa,YAAY,EACtB,OAAO;CACN,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;CAC9C,UAAU,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE;AAC9D,CAAC,CAAC,CACD,OAAO;;;;;AAOV,MAAa,YAAY,EAAE,OAAO;CAChC,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;CAC9C,UAAU,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE;CAC5D,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS;;CAE5C,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;AAC5B,CAAC;;AAID,SAAgB,UAAkC,KAAQ;CACxD,OAAO,EAAE,OAAO;EACd,MAAM,EAAE,MAAM,GAAG;EACjB,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI;EACtB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI;EACrB,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CAC3B,CAAC;AACH;;;AAIA,MAAa,UAAU,EAAE,KAAK;CAAC;CAAS;CAAS;CAAc;CAAa;AAAS,CAAC;;AAItF,MAAa,oBAAoB,EAAE,OAAO;CACxC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC;;AAID,MAAa,uBAAuB,EAAE,OAAO;CAC3C,IAAI,EAAE,OAAO;CACb,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
//#region src/http/schemas/students.d.ts
|
|
3
3
|
declare const OrgUserStatus: z.ZodEnum<{
|
|
4
|
-
active: "active";
|
|
5
4
|
invited: "invited";
|
|
5
|
+
active: "active";
|
|
6
6
|
}>;
|
|
7
7
|
type OrgUserStatus = z.infer<typeof OrgUserStatus>;
|
|
8
8
|
declare const Student: z.ZodObject<{
|
|
@@ -14,8 +14,8 @@ declare const Student: z.ZodObject<{
|
|
|
14
14
|
entitlementCount: z.ZodNumber;
|
|
15
15
|
avgProgress: z.ZodNumber;
|
|
16
16
|
status: z.ZodEnum<{
|
|
17
|
-
active: "active";
|
|
18
17
|
invited: "invited";
|
|
18
|
+
active: "active";
|
|
19
19
|
}>;
|
|
20
20
|
joinedAt: z.ZodString;
|
|
21
21
|
lastActiveAt: z.ZodNullable<z.ZodString>;
|
|
@@ -66,8 +66,8 @@ declare const StudentsPage: z.ZodObject<{
|
|
|
66
66
|
entitlementCount: z.ZodNumber;
|
|
67
67
|
avgProgress: z.ZodNumber;
|
|
68
68
|
status: z.ZodEnum<{
|
|
69
|
-
active: "active";
|
|
70
69
|
invited: "invited";
|
|
70
|
+
active: "active";
|
|
71
71
|
}>;
|
|
72
72
|
joinedAt: z.ZodString;
|
|
73
73
|
lastActiveAt: z.ZodNullable<z.ZodString>;
|
|
@@ -81,12 +81,6 @@ declare const StudentIdParam: z.ZodObject<{
|
|
|
81
81
|
id: z.ZodString;
|
|
82
82
|
}, z.core.$strip>;
|
|
83
83
|
type StudentIdParam = z.infer<typeof StudentIdParam>;
|
|
84
|
-
declare const UpdateStudentBody: z.ZodObject<{
|
|
85
|
-
firstName: z.ZodString;
|
|
86
|
-
lastName: z.ZodString;
|
|
87
|
-
email: z.ZodEmail;
|
|
88
|
-
}, z.core.$strip>;
|
|
89
|
-
type UpdateStudentBody = z.infer<typeof UpdateStudentBody>;
|
|
90
84
|
//#endregion
|
|
91
|
-
export { OrgUserStatus, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery
|
|
85
|
+
export { OrgUserStatus, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery };
|
|
92
86
|
//# sourceMappingURL=students.d.ts.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ListQuery, OrgUserProfileSchema, paginated } from "./shared.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { emailSchema } from "@headless-lms/core/schemas";
|
|
4
3
|
//#region src/http/schemas/students.ts
|
|
5
4
|
const OrgUserStatus = z.enum(["invited", "active"]);
|
|
6
5
|
const Student = OrgUserProfileSchema.extend({
|
|
@@ -33,12 +32,7 @@ const StudentAnalytics = z.object({
|
|
|
33
32
|
const StudentsQuery = ListQuery;
|
|
34
33
|
const StudentsPage = paginated(Student);
|
|
35
34
|
const StudentIdParam = z.object({ id: z.string() });
|
|
36
|
-
const UpdateStudentBody = z.object({
|
|
37
|
-
firstName: z.string().trim().min(1),
|
|
38
|
-
lastName: z.string().trim().min(1),
|
|
39
|
-
email: emailSchema
|
|
40
|
-
});
|
|
41
35
|
//#endregion
|
|
42
|
-
export { OrgUserStatus, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery
|
|
36
|
+
export { OrgUserStatus, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery };
|
|
43
37
|
|
|
44
38
|
//# sourceMappingURL=students.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"students.js","names":[],"sources":["../../../src/http/schemas/students.ts"],"sourcesContent":["// Students resource schemas.\nimport { z } from 'zod';\nimport {
|
|
1
|
+
{"version":3,"file":"students.js","names":[],"sources":["../../../src/http/schemas/students.ts"],"sourcesContent":["// Students resource schemas.\nimport { z } from 'zod';\nimport { ListQuery, paginated, OrgUserProfileSchema } from './shared.js';\n\nexport const OrgUserStatus = z.enum(['invited', 'active']);\nexport type OrgUserStatus = z.infer<typeof OrgUserStatus>;\n\nexport const Student = OrgUserProfileSchema.extend({\n entitlementCount: z.number().int(),\n /** 0–100, averaged across active entitlements. */\n avgProgress: z.number().int(),\n /** `invited` means an admin added them and they have not accepted yet. */\n status: OrgUserStatus,\n joinedAt: z.string(),\n lastActiveAt: z.string().nullable(),\n});\nexport type Student = z.infer<typeof Student>;\n\nexport const StudentCourseProgress = z.object({\n courseId: z.string(),\n title: z.string(),\n totalActivities: z.number().int(),\n completedActivities: z.number().int(),\n /** 0–100, completed published activities over the course's total. */\n progress: z.number().int(),\n startedAt: z.string().nullable(),\n lastActivityAt: z.string().nullable(),\n completedAt: z.string().nullable(),\n});\nexport type StudentCourseProgress = z.infer<typeof StudentCourseProgress>;\n\nexport const StudentAnalytics = z.object({\n enrolled: z.number().int(),\n started: z.number().int(),\n completed: z.number().int(),\n avgProgress: z.number().int(),\n courses: z.array(StudentCourseProgress),\n});\nexport type StudentAnalytics = z.infer<typeof StudentAnalytics>;\n\nexport const StudentsQuery = ListQuery;\nexport type StudentsQuery = z.infer<typeof StudentsQuery>;\n\nexport const StudentsPage = paginated(Student);\nexport type StudentsPage = z.infer<typeof StudentsPage>;\n\nexport const StudentIdParam = z.object({ id: z.string() });\nexport type StudentIdParam = z.infer<typeof StudentIdParam>;\n"],"mappings":";;;AAIA,MAAa,gBAAgB,EAAE,KAAK,CAAC,WAAW,QAAQ,CAAC;AAGzD,MAAa,UAAU,qBAAqB,OAAO;CACjD,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI;;CAEjC,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI;;CAE5B,QAAQ;CACR,UAAU,EAAE,OAAO;CACnB,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;AACpC,CAAC;AAGD,MAAa,wBAAwB,EAAE,OAAO;CAC5C,UAAU,EAAE,OAAO;CACnB,OAAO,EAAE,OAAO;CAChB,iBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI;CAChC,qBAAqB,EAAE,OAAO,CAAC,CAAC,IAAI;;CAEpC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CACzB,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,gBAAgB,EAAE,OAAO,CAAC,CAAC,SAAS;CACpC,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS;AACnC,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO;CACvC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CACzB,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI;CACxB,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI;CAC1B,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI;CAC5B,SAAS,EAAE,MAAM,qBAAqB;AACxC,CAAC;AAGD,MAAa,gBAAgB;AAG7B,MAAa,eAAe,UAAU,OAAO;AAG7C,MAAa,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/http/scope.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ interface OrgScope {
|
|
|
17
17
|
/** Thrown when the session has no resolvable active org / domain user. */
|
|
18
18
|
declare class NoActiveOrgError extends Error {}
|
|
19
19
|
declare function resolveScope(container: Container, req: FastifyRequest): Promise<OrgScope>;
|
|
20
|
+
declare function resolveScopeFor(container: Container, authUserId: string, authOrgId: string): Promise<OrgScope>;
|
|
20
21
|
//#endregion
|
|
21
|
-
export { NoActiveOrgError, OrgScope, resolveScope };
|
|
22
|
+
export { NoActiveOrgError, OrgScope, resolveScope, resolveScopeFor };
|
|
22
23
|
//# sourceMappingURL=scope.d.ts.map
|
package/dist/http/scope.js
CHANGED
|
@@ -5,11 +5,27 @@ var NoActiveOrgError = class extends Error {};
|
|
|
5
5
|
async function resolveScope(container, req) {
|
|
6
6
|
const authUser = req.authUser;
|
|
7
7
|
const authOrgId = req.authOrgId ?? null;
|
|
8
|
-
if (!authUser) throw new NoActiveOrgError("
|
|
9
|
-
if (!authOrgId || !req.orgId) throw new NoActiveOrgError("
|
|
8
|
+
if (!authUser) throw new NoActiveOrgError("Sign in to continue");
|
|
9
|
+
if (!authOrgId || !req.orgId) throw new NoActiveOrgError("Choose an organization to continue");
|
|
10
10
|
const org = await container.organizations.getById(req.orgId);
|
|
11
|
-
if (!org) throw new NoActiveOrgError("active organization
|
|
11
|
+
if (!org) throw new NoActiveOrgError("The active organization no longer exists");
|
|
12
12
|
const user = await container.identity.getUserByExternalId(authUser.id);
|
|
13
|
+
if (!user) throw new NoActiveOrgError("Your account is not set up yet");
|
|
14
|
+
const orgUser = await container.organizations.getOrgUser(org.id, user.id);
|
|
15
|
+
if (!orgUser || !isStaffRole(orgUser.role)) throw new NoActiveOrgError("Only staff of this organization can do this");
|
|
16
|
+
container.requestContext.set({ orgId: org.id });
|
|
17
|
+
return {
|
|
18
|
+
orgId: org.id,
|
|
19
|
+
userId: user.id,
|
|
20
|
+
orgUserId: orgUser.id,
|
|
21
|
+
role: orgUser.role,
|
|
22
|
+
authOrgId
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async function resolveScopeFor(container, authUserId, authOrgId) {
|
|
26
|
+
const org = await container.organizations.getByExternalId(authOrgId);
|
|
27
|
+
if (!org) throw new NoActiveOrgError("active organization not found");
|
|
28
|
+
const user = await container.identity.getUserByExternalId(authUserId);
|
|
13
29
|
if (!user) throw new NoActiveOrgError("no domain user for the current user");
|
|
14
30
|
const orgUser = await container.organizations.getOrgUser(org.id, user.id);
|
|
15
31
|
if (!orgUser || !isStaffRole(orgUser.role)) throw new NoActiveOrgError("not a staff member of the active organization");
|
|
@@ -23,6 +39,6 @@ async function resolveScope(container, req) {
|
|
|
23
39
|
};
|
|
24
40
|
}
|
|
25
41
|
//#endregion
|
|
26
|
-
export { NoActiveOrgError, resolveScope };
|
|
42
|
+
export { NoActiveOrgError, resolveScope, resolveScopeFor };
|
|
27
43
|
|
|
28
44
|
//# sourceMappingURL=scope.js.map
|
package/dist/http/scope.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.js","names":[],"sources":["../../src/http/scope.ts"],"sourcesContent":["import type { FastifyRequest } from 'fastify';\nimport type { Container } from '../app/container.js';\nimport { isStaffRole, type StaffRole } from '@headless-lms/core/organizations';\n\nexport interface OrgScope {\n /** Domain `organizations.id` for the session's active org. */\n orgId: string;\n /** Domain `users.id` of the acting person. */\n userId: string;\n /** Domain `org_users.id` — the acting org user in this org. */\n orgUserId: string;\n /** The role held in this org. */\n role: StaffRole;\n /** Better-auth organization id (for writes that go through the auth provider). */\n authOrgId: string;\n}\n\n/** Thrown when the session has no resolvable active org / domain user. */\nexport class NoActiveOrgError extends Error {}\n\nexport async function resolveScope(container: Container, req: FastifyRequest): Promise<OrgScope> {\n const authUser = req.authUser;\n const authOrgId = req.authOrgId ?? null;\n if (!authUser) {\n throw new NoActiveOrgError('
|
|
1
|
+
{"version":3,"file":"scope.js","names":[],"sources":["../../src/http/scope.ts"],"sourcesContent":["import type { FastifyRequest } from 'fastify';\nimport type { Container } from '../app/container.js';\nimport { isStaffRole, type StaffRole } from '@headless-lms/core/organizations';\n\nexport interface OrgScope {\n /** Domain `organizations.id` for the session's active org. */\n orgId: string;\n /** Domain `users.id` of the acting person. */\n userId: string;\n /** Domain `org_users.id` — the acting org user in this org. */\n orgUserId: string;\n /** The role held in this org. */\n role: StaffRole;\n /** Better-auth organization id (for writes that go through the auth provider). */\n authOrgId: string;\n}\n\n/** Thrown when the session has no resolvable active org / domain user. */\nexport class NoActiveOrgError extends Error {}\n\nexport async function resolveScope(container: Container, req: FastifyRequest): Promise<OrgScope> {\n const authUser = req.authUser;\n const authOrgId = req.authOrgId ?? null;\n if (!authUser) {\n throw new NoActiveOrgError('Sign in to continue');\n }\n if (!authOrgId || !req.orgId) {\n throw new NoActiveOrgError('Choose an organization to continue');\n }\n // The session guard already translated the auth org id to the domain org.\n const org = await container.organizations.getById(req.orgId);\n if (!org) {\n throw new NoActiveOrgError('The active organization no longer exists');\n }\n const user = await container.identity.getUserByExternalId(authUser.id);\n if (!user) {\n throw new NoActiveOrgError('Your account is not set up yet');\n }\n const orgUser = await container.organizations.getOrgUser(org.id, user.id);\n if (!orgUser || !isStaffRole(orgUser.role)) {\n throw new NoActiveOrgError('Only staff of this organization can do this');\n }\n container.requestContext.set({ orgId: org.id });\n return {\n orgId: org.id,\n userId: user.id,\n orgUserId: orgUser.id,\n role: orgUser.role,\n authOrgId,\n };\n}\n\nexport async function resolveScopeFor(\n container: Container,\n authUserId: string,\n authOrgId: string,\n): Promise<OrgScope> {\n const org = await container.organizations.getByExternalId(authOrgId);\n if (!org) {\n throw new NoActiveOrgError('active organization not found');\n }\n const user = await container.identity.getUserByExternalId(authUserId);\n if (!user) {\n throw new NoActiveOrgError('no domain user for the current user');\n }\n const orgUser = await container.organizations.getOrgUser(org.id, user.id);\n if (!orgUser || !isStaffRole(orgUser.role)) {\n throw new NoActiveOrgError('not a staff member of the active organization');\n }\n container.requestContext.set({ orgId: org.id });\n return { orgId: org.id, userId: user.id, orgUserId: orgUser.id, role: orgUser.role, authOrgId };\n}\n"],"mappings":";;;AAkBA,IAAa,mBAAb,cAAsC,MAAM,CAAC;AAE7C,eAAsB,aAAa,WAAsB,KAAwC;CAC/F,MAAM,WAAW,IAAI;CACrB,MAAM,YAAY,IAAI,aAAa;CACnC,IAAI,CAAC,UACH,MAAM,IAAI,iBAAiB,qBAAqB;CAElD,IAAI,CAAC,aAAa,CAAC,IAAI,OACrB,MAAM,IAAI,iBAAiB,oCAAoC;CAGjE,MAAM,MAAM,MAAM,UAAU,cAAc,QAAQ,IAAI,KAAK;CAC3D,IAAI,CAAC,KACH,MAAM,IAAI,iBAAiB,0CAA0C;CAEvE,MAAM,OAAO,MAAM,UAAU,SAAS,oBAAoB,SAAS,EAAE;CACrE,IAAI,CAAC,MACH,MAAM,IAAI,iBAAiB,gCAAgC;CAE7D,MAAM,UAAU,MAAM,UAAU,cAAc,WAAW,IAAI,IAAI,KAAK,EAAE;CACxE,IAAI,CAAC,WAAW,CAAC,YAAY,QAAQ,IAAI,GACvC,MAAM,IAAI,iBAAiB,6CAA6C;CAE1E,UAAU,eAAe,IAAI,EAAE,OAAO,IAAI,GAAG,CAAC;CAC9C,OAAO;EACL,OAAO,IAAI;EACX,QAAQ,KAAK;EACb,WAAW,QAAQ;EACnB,MAAM,QAAQ;EACd;CACF;AACF;AAEA,eAAsB,gBACpB,WACA,YACA,WACmB;CACnB,MAAM,MAAM,MAAM,UAAU,cAAc,gBAAgB,SAAS;CACnE,IAAI,CAAC,KACH,MAAM,IAAI,iBAAiB,+BAA+B;CAE5D,MAAM,OAAO,MAAM,UAAU,SAAS,oBAAoB,UAAU;CACpE,IAAI,CAAC,MACH,MAAM,IAAI,iBAAiB,qCAAqC;CAElE,MAAM,UAAU,MAAM,UAAU,cAAc,WAAW,IAAI,IAAI,KAAK,EAAE;CACxE,IAAI,CAAC,WAAW,CAAC,YAAY,QAAQ,IAAI,GACvC,MAAM,IAAI,iBAAiB,+CAA+C;CAE5E,UAAU,eAAe,IAAI,EAAE,OAAO,IAAI,GAAG,CAAC;CAC9C,OAAO;EAAE,OAAO,IAAI;EAAI,QAAQ,KAAK;EAAI,WAAW,QAAQ;EAAI,MAAM,QAAQ;EAAM;CAAU;AAChG"}
|
package/dist/http/server.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { registerCors } from "./plugins/cors.js";
|
|
2
2
|
import { registerOpenApi } from "./plugins/openapi.js";
|
|
3
3
|
import { registerAuth } from "./plugins/auth.js";
|
|
4
|
-
import {
|
|
4
|
+
import { registerWellKnown } from "./well-known.js";
|
|
5
|
+
import { errorHandler, notFoundHandler } from "./plugins/error-handler.js";
|
|
5
6
|
import { registerRoutes } from "./routes.js";
|
|
7
|
+
import { registerMcp } from "./mcp/route.js";
|
|
6
8
|
import Fastify from "fastify";
|
|
7
9
|
import { serializerCompiler, validatorCompiler } from "fastify-type-provider-zod";
|
|
8
10
|
//#region src/http/server.ts
|
|
@@ -19,10 +21,13 @@ async function buildServer(config, container) {
|
|
|
19
21
|
app.setValidatorCompiler(validatorCompiler);
|
|
20
22
|
app.setSerializerCompiler(serializerCompiler);
|
|
21
23
|
app.setErrorHandler(errorHandler);
|
|
24
|
+
app.setNotFoundHandler(notFoundHandler);
|
|
22
25
|
registerCors(app, config);
|
|
23
26
|
registerOpenApi(app, config);
|
|
24
27
|
registerAuth(app, container);
|
|
28
|
+
if (container.mcp.oauthEnabled) registerWellKnown(app, container);
|
|
25
29
|
registerRoutes(app, container);
|
|
30
|
+
registerMcp(app, container);
|
|
26
31
|
app.addHook("onClose", async () => {
|
|
27
32
|
await container.outboxRelay.stop();
|
|
28
33
|
await container.automationEngine.stop();
|
package/dist/http/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","names":[],"sources":["../../src/http/server.ts"],"sourcesContent":["import Fastify, { type FastifyBaseLogger, type FastifyInstance } from 'fastify';\nimport { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod';\nimport type { Container } from '../app/container.js';\nimport type { ServerConfig } from './config.js';\nimport { registerCors } from './plugins/cors.js';\nimport { registerOpenApi } from './plugins/openapi.js';\nimport { registerAuth } from './plugins/auth.js';\nimport { errorHandler } from './plugins/error-handler.js';\nimport { registerRoutes } from './routes.js';\n\nexport async function buildServer(\n config: ServerConfig,\n container: Container,\n): Promise<FastifyInstance> {\n // One log stream for the whole process: HTTP shares the container's pino root.\n // Widened to FastifyBaseLogger so the instance keeps the default logger\n // generic (a concrete pino type would ripple through every plugin signature).\n const app = Fastify({\n loggerInstance: container.loggerInstance as FastifyBaseLogger,\n // Fastify's own request/response pair per call — noisy in a dev console,\n // useful as an access log in production. Our own logs are unaffected.\n disableRequestLogging: config.requestLogging === false,\n // Adopt the caller's correlation id when it sends one, so one id joins\n // the client's log line to this process's.\n requestIdHeader: 'x-request-id',\n });\n\n // Enter the request-scoped log context: every line logged inside this\n // request's async scope carries its reqId (and orgId once resolveScope runs),\n // wherever it is emitted. The id is echoed on the response so callers can\n // quote it when reporting a failure.\n app.addHook('onRequest', (request, reply, done) => {\n reply.header('x-request-id', request.id);\n container.requestContext.run({ reqId: request.id }, done);\n });\n\n // Validate + serialize request/response bodies from the shared Zod contract.\n app.setValidatorCompiler(validatorCompiler);\n app.setSerializerCompiler(serializerCompiler);\n app.setErrorHandler(errorHandler);\n\n registerCors(app, config);\n registerOpenApi(app, config);\n registerAuth(app, container);\n\n registerRoutes(app, container);\n\n // Drain + stop the outbox relay and the automation engine on shutdown.\n // Harmless when neither was started (gen-openapi boots this app with\n // ready() + close() only).\n app.addHook('onClose', async () => {\n await container.outboxRelay.stop();\n await container.automationEngine.stop();\n });\n\n return app;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.js","names":[],"sources":["../../src/http/server.ts"],"sourcesContent":["import Fastify, { type FastifyBaseLogger, type FastifyInstance } from 'fastify';\nimport { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod';\nimport type { Container } from '../app/container.js';\nimport type { ServerConfig } from './config.js';\nimport { registerCors } from './plugins/cors.js';\nimport { registerOpenApi } from './plugins/openapi.js';\nimport { registerAuth } from './plugins/auth.js';\nimport { registerWellKnown } from './well-known.js';\nimport { errorHandler, notFoundHandler } from './plugins/error-handler.js';\nimport { registerRoutes } from './routes.js';\nimport { registerMcp } from './mcp/route.js';\n\nexport async function buildServer(\n config: ServerConfig,\n container: Container,\n): Promise<FastifyInstance> {\n // One log stream for the whole process: HTTP shares the container's pino root.\n // Widened to FastifyBaseLogger so the instance keeps the default logger\n // generic (a concrete pino type would ripple through every plugin signature).\n const app = Fastify({\n loggerInstance: container.loggerInstance as FastifyBaseLogger,\n // Fastify's own request/response pair per call — noisy in a dev console,\n // useful as an access log in production. Our own logs are unaffected.\n disableRequestLogging: config.requestLogging === false,\n // Adopt the caller's correlation id when it sends one, so one id joins\n // the client's log line to this process's.\n requestIdHeader: 'x-request-id',\n });\n\n // Enter the request-scoped log context: every line logged inside this\n // request's async scope carries its reqId (and orgId once resolveScope runs),\n // wherever it is emitted. The id is echoed on the response so callers can\n // quote it when reporting a failure.\n app.addHook('onRequest', (request, reply, done) => {\n reply.header('x-request-id', request.id);\n container.requestContext.run({ reqId: request.id }, done);\n });\n\n // Validate + serialize request/response bodies from the shared Zod contract.\n app.setValidatorCompiler(validatorCompiler);\n app.setSerializerCompiler(serializerCompiler);\n app.setErrorHandler(errorHandler);\n app.setNotFoundHandler(notFoundHandler);\n\n registerCors(app, config);\n registerOpenApi(app, config);\n registerAuth(app, container);\n if (container.mcp.oauthEnabled) {\n registerWellKnown(app, container);\n }\n\n registerRoutes(app, container);\n registerMcp(app, container);\n\n // Drain + stop the outbox relay and the automation engine on shutdown.\n // Harmless when neither was started (gen-openapi boots this app with\n // ready() + close() only).\n app.addHook('onClose', async () => {\n await container.outboxRelay.stop();\n await container.automationEngine.stop();\n });\n\n return app;\n}\n"],"mappings":";;;;;;;;;;AAYA,eAAsB,YACpB,QACA,WAC0B;CAI1B,MAAM,MAAM,QAAQ;EAClB,gBAAgB,UAAU;EAG1B,uBAAuB,OAAO,mBAAmB;EAGjD,iBAAiB;CACnB,CAAC;CAMD,IAAI,QAAQ,cAAc,SAAS,OAAO,SAAS;EACjD,MAAM,OAAO,gBAAgB,QAAQ,EAAE;EACvC,UAAU,eAAe,IAAI,EAAE,OAAO,QAAQ,GAAG,GAAG,IAAI;CAC1D,CAAC;CAGD,IAAI,qBAAqB,iBAAiB;CAC1C,IAAI,sBAAsB,kBAAkB;CAC5C,IAAI,gBAAgB,YAAY;CAChC,IAAI,mBAAmB,eAAe;CAEtC,aAAa,KAAK,MAAM;CACxB,gBAAgB,KAAK,MAAM;CAC3B,aAAa,KAAK,SAAS;CAC3B,IAAI,UAAU,IAAI,cAChB,kBAAkB,KAAK,SAAS;CAGlC,eAAe,KAAK,SAAS;CAC7B,YAAY,KAAK,SAAS;CAK1B,IAAI,QAAQ,WAAW,YAAY;EACjC,MAAM,UAAU,YAAY,KAAK;EACjC,MAAM,UAAU,iBAAiB,KAAK;CACxC,CAAC;CAED,OAAO;AACT"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
2
2
|
//#region src/http/web-bridge.d.ts
|
|
3
3
|
/** Builds a Web `Request` from an incoming Fastify request. */
|
|
4
|
-
declare function toWebRequest(request: FastifyRequest): Request;
|
|
4
|
+
declare function toWebRequest(request: FastifyRequest, origin: string): Request;
|
|
5
5
|
/** Copies a Web `Response` back onto a Fastify reply, preserving multiple cookies. */
|
|
6
6
|
declare function bridgeWebResponse(response: Response, reply: FastifyReply): Promise<void>;
|
|
7
7
|
//#endregion
|
package/dist/http/web-bridge.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fromNodeHeaders } from "better-auth/node";
|
|
2
2
|
//#region src/http/web-bridge.ts
|
|
3
3
|
/** Builds a Web `Request` from an incoming Fastify request. */
|
|
4
|
-
function toWebRequest(request) {
|
|
5
|
-
const url = new URL(request.url,
|
|
4
|
+
function toWebRequest(request, origin) {
|
|
5
|
+
const url = new URL(request.url, origin);
|
|
6
6
|
const body = request.method !== "GET" && request.method !== "HEAD" && request.method !== "DELETE" ? typeof request.body === "string" ? request.body : request.body ? JSON.stringify(request.body) : void 0 : void 0;
|
|
7
7
|
return new Request(url.toString(), {
|
|
8
8
|
method: request.method,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-bridge.js","names":[],"sources":["../../src/http/web-bridge.ts"],"sourcesContent":["// Bridges between Fastify's request/reply and the Web `Request`/`Response` that\n// better-auth speaks. The auth catch-all hands a Fastify request to a\n// Web-standard handler and forwards the\n// Web response back, so the conversion lives here once.\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { fromNodeHeaders } from 'better-auth/node';\n\n/** Builds a Web `Request` from an incoming Fastify request. */\nexport function toWebRequest(request: FastifyRequest): Request {\n const url = new URL(request.url,
|
|
1
|
+
{"version":3,"file":"web-bridge.js","names":[],"sources":["../../src/http/web-bridge.ts"],"sourcesContent":["// Bridges between Fastify's request/reply and the Web `Request`/`Response` that\n// better-auth speaks. The auth catch-all hands a Fastify request to a\n// Web-standard handler and forwards the\n// Web response back, so the conversion lives here once.\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { fromNodeHeaders } from 'better-auth/node';\n\n/** Builds a Web `Request` from an incoming Fastify request. */\nexport function toWebRequest(request: FastifyRequest, origin: string): Request {\n const url = new URL(request.url, origin);\n // GET/HEAD/DELETE never carry a body; passing one to `Request` throws. For the\n // rest, forward a string body verbatim and JSON-encode a parsed object.\n const hasBody =\n request.method !== 'GET' && request.method !== 'HEAD' && request.method !== 'DELETE';\n const body = hasBody\n ? typeof request.body === 'string'\n ? request.body\n : request.body\n ? JSON.stringify(request.body)\n : undefined\n : undefined;\n return new Request(url.toString(), {\n method: request.method,\n headers: fromNodeHeaders(request.headers),\n body,\n });\n}\n\n/** Copies a Web `Response` back onto a Fastify reply, preserving multiple cookies. */\nexport async function bridgeWebResponse(response: Response, reply: FastifyReply): Promise<void> {\n reply.status(response.status);\n // Emit each Set-Cookie value individually — forEach() collapses multiple\n // Set-Cookie headers into one comma-joined string (undici behaviour), which\n // corrupts multi-cookie auth responses. getSetCookie() returns them as an\n // array so each one is forwarded as a separate header.\n const cookies = response.headers.getSetCookie();\n if (cookies.length > 0) {\n reply.raw.setHeader('set-cookie', cookies);\n }\n response.headers.forEach((value, key) => {\n if (key.toLowerCase() === 'set-cookie') {\n return;\n } // already handled above\n reply.header(key, value);\n });\n reply.send(response.body ? await response.text() : null);\n}\n"],"mappings":";;;AAQA,SAAgB,aAAa,SAAyB,QAAyB;CAC7E,MAAM,MAAM,IAAI,IAAI,QAAQ,KAAK,MAAM;CAKvC,MAAM,OADJ,QAAQ,WAAW,SAAS,QAAQ,WAAW,UAAU,QAAQ,WAAW,WAE1E,OAAO,QAAQ,SAAS,WACtB,QAAQ,OACR,QAAQ,OACN,KAAK,UAAU,QAAQ,IAAI,IAC3B,KAAA,IACJ,KAAA;CACJ,OAAO,IAAI,QAAQ,IAAI,SAAS,GAAG;EACjC,QAAQ,QAAQ;EAChB,SAAS,gBAAgB,QAAQ,OAAO;EACxC;CACF,CAAC;AACH;;AAGA,eAAsB,kBAAkB,UAAoB,OAAoC;CAC9F,MAAM,OAAO,SAAS,MAAM;CAK5B,MAAM,UAAU,SAAS,QAAQ,aAAa;CAC9C,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,UAAU,cAAc,OAAO;CAE3C,SAAS,QAAQ,SAAS,OAAO,QAAQ;EACvC,IAAI,IAAI,YAAY,MAAM,cACxB;EAEF,MAAM,OAAO,KAAK,KAAK;CACzB,CAAC;CACD,MAAM,KAAK,SAAS,OAAO,MAAM,SAAS,KAAK,IAAI,IAAI;AACzD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Container } from "../app/container.js";
|
|
2
|
+
import { FastifyInstance } from "fastify";
|
|
3
|
+
//#region src/http/well-known.d.ts
|
|
4
|
+
declare function registerWellKnown(app: FastifyInstance, container: Container): void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { registerWellKnown };
|
|
7
|
+
//# sourceMappingURL=well-known.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { bridgeWebResponse, toWebRequest } from "./web-bridge.js";
|
|
2
|
+
import { ACCESS_SCOPES } from "@headless-lms/core/organizations";
|
|
3
|
+
//#region src/http/well-known.ts
|
|
4
|
+
function registerWellKnown(app, container) {
|
|
5
|
+
const origin = new URL(container.mcp.issuer).origin;
|
|
6
|
+
const resourceMetadata = () => ({
|
|
7
|
+
resource: container.mcp.resource,
|
|
8
|
+
authorization_servers: [container.mcp.issuer],
|
|
9
|
+
scopes_supported: [...ACCESS_SCOPES],
|
|
10
|
+
bearer_methods_supported: ["header"]
|
|
11
|
+
});
|
|
12
|
+
const hidden = { schema: { hide: true } };
|
|
13
|
+
app.get("/.well-known/oauth-protected-resource/mcp", hidden, async () => resourceMetadata());
|
|
14
|
+
app.get("/.well-known/oauth-protected-resource", hidden, async () => resourceMetadata());
|
|
15
|
+
app.get("/.well-known/oauth-authorization-server/api/auth", hidden, async (request, reply) => {
|
|
16
|
+
await bridgeWebResponse(await container.auth.authorizationServerMetadata(toWebRequest(request, origin)), reply);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { registerWellKnown };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=well-known.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.js","names":[],"sources":["../../src/http/well-known.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport { ACCESS_SCOPES } from '@headless-lms/core/organizations';\nimport type { Container } from '../app/container.js';\nimport { bridgeWebResponse, toWebRequest } from './web-bridge.js';\n\nexport function registerWellKnown(app: FastifyInstance, container: Container): void {\n const origin = new URL(container.mcp.issuer).origin;\n const resourceMetadata = () => ({\n resource: container.mcp.resource,\n authorization_servers: [container.mcp.issuer],\n scopes_supported: [...ACCESS_SCOPES],\n bearer_methods_supported: ['header'],\n });\n const hidden = { schema: { hide: true } };\n\n app.get('/.well-known/oauth-protected-resource/mcp', hidden, async () => resourceMetadata());\n app.get('/.well-known/oauth-protected-resource', hidden, async () => resourceMetadata());\n app.get('/.well-known/oauth-authorization-server/api/auth', hidden, async (request, reply) => {\n await bridgeWebResponse(\n await container.auth.authorizationServerMetadata(toWebRequest(request, origin)),\n reply,\n );\n });\n}\n"],"mappings":";;;AAKA,SAAgB,kBAAkB,KAAsB,WAA4B;CAClF,MAAM,SAAS,IAAI,IAAI,UAAU,IAAI,MAAM,CAAC,CAAC;CAC7C,MAAM,0BAA0B;EAC9B,UAAU,UAAU,IAAI;EACxB,uBAAuB,CAAC,UAAU,IAAI,MAAM;EAC5C,kBAAkB,CAAC,GAAG,aAAa;EACnC,0BAA0B,CAAC,QAAQ;CACrC;CACA,MAAM,SAAS,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE;CAExC,IAAI,IAAI,6CAA6C,QAAQ,YAAY,iBAAiB,CAAC;CAC3F,IAAI,IAAI,yCAAyC,QAAQ,YAAY,iBAAiB,CAAC;CACvF,IAAI,IAAI,oDAAoD,QAAQ,OAAO,SAAS,UAAU;EAC5F,MAAM,kBACJ,MAAM,UAAU,KAAK,4BAA4B,aAAa,SAAS,MAAM,CAAC,GAC9E,KACF;CACF,CAAC;AACH"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { AuthUser } from "./http/fastify.js";
|
|
|
2
2
|
import { AdapterOverrides, BuildContainerOptions, Config, Container, LoggingConfig } from "./app/container.js";
|
|
3
3
|
import { loadIntegrations } from "./app/integrations.js";
|
|
4
4
|
import { ServerConfig } from "./http/config.js";
|
|
5
|
+
import { CatalogueField, CatalogueScope, CatalogueTool, McpCatalogue, mcpCatalogue } from "./http/mcp/catalogue.js";
|
|
5
6
|
import { buildServer } from "./http/server.js";
|
|
6
7
|
import { runMigrations } from "@headless-lms/adapter-db";
|
|
7
8
|
import { InlineAutomationEngine } from "@headless-lms/adapter-defaults/workflows";
|
|
@@ -11,5 +12,5 @@ import { EmailMessage, EmailSender, ObjectStorage } from "@headless-lms/core/sha
|
|
|
11
12
|
//#region src/index.d.ts
|
|
12
13
|
declare function createContainer(config: ServerConfig, options?: BuildContainerOptions): Promise<Container>;
|
|
13
14
|
//#endregion
|
|
14
|
-
export { type AdapterOverrides, type AuthUser, type AutomationEngine, type BuildContainerOptions, type Container, type Config as ContainerConfig, type EmailMessage, type EmailSender, InlineAutomationEngine, type LoggingConfig, type Mailer, type ObjectStorage, type ServerConfig, type WebhookSender, buildServer, createContainer, loadIntegrations, runMigrations };
|
|
15
|
+
export { type AdapterOverrides, type AuthUser, type AutomationEngine, type BuildContainerOptions, type CatalogueField, type CatalogueScope, type CatalogueTool, type Container, type Config as ContainerConfig, type EmailMessage, type EmailSender, InlineAutomationEngine, type LoggingConfig, type Mailer, type McpCatalogue, type ObjectStorage, type ServerConfig, type WebhookSender, buildServer, createContainer, loadIntegrations, mcpCatalogue, runMigrations };
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { loadIntegrations } from "./app/integrations.js";
|
|
2
2
|
import { buildContainer } from "./app/container.js";
|
|
3
3
|
import { buildServer } from "./http/server.js";
|
|
4
|
+
import { mcpCatalogue } from "./http/mcp/catalogue.js";
|
|
4
5
|
import { runMigrations } from "@headless-lms/adapter-db";
|
|
5
6
|
import { InlineAutomationEngine } from "@headless-lms/adapter-defaults/workflows";
|
|
6
7
|
//#region src/index.ts
|
|
7
8
|
async function createContainer(config, options) {
|
|
8
9
|
return buildContainer({
|
|
9
10
|
...config.container,
|
|
10
|
-
deliveryExpirySeconds: config.deliveryExpirySeconds
|
|
11
|
+
deliveryExpirySeconds: config.deliveryExpirySeconds,
|
|
12
|
+
memberImageMaxBytes: config.memberImageMaxBytes
|
|
11
13
|
}, options);
|
|
12
14
|
}
|
|
13
15
|
//#endregion
|
|
14
|
-
export { InlineAutomationEngine, buildServer, createContainer, loadIntegrations, runMigrations };
|
|
16
|
+
export { InlineAutomationEngine, buildServer, createContainer, loadIntegrations, mcpCatalogue, runMigrations };
|
|
15
17
|
|
|
16
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["// Public surface of @headless-lms/server. Installations compose these:\n// const container = await createContainer(config, { pluginsDir, adapters })\n// const app = await buildServer(config, container)\nimport { buildContainer, type BuildContainerOptions, type Container } from './app/container.js';\nimport type { ServerConfig } from './http/config.js';\n\nexport { buildServer } from './http/server.js';\nexport { loadIntegrations } from './app/integrations.js';\nexport { InlineAutomationEngine } from '@headless-lms/adapter-defaults/workflows';\n// Operational functions consumed by the @headless-lms/cli bin.\nexport { runMigrations } from '@headless-lms/adapter-db';\nexport type { ServerConfig } from './http/config.js';\n// Re-exporting AuthUser also pulls its module into any program that imports\n// this file (directly or via the workspace path mapping), which is what\n// applies its ambient `declare module \"fastify\"` augmentation\n// (FastifyRequest.authUser/orgId, FastifyInstance.requireOrgSession) —\n// otherwise nothing imports fastify.d.ts and the augmentation never loads.\nexport type { AuthUser } from './http/fastify.js';\nexport type {\n Config as ContainerConfig,\n Container,\n AdapterOverrides,\n BuildContainerOptions,\n LoggingConfig,\n} from './app/container.js';\nexport type { EmailSender, EmailMessage, ObjectStorage } from '@headless-lms/core/shared/ports';\nexport type { Mailer } from '@headless-lms/core/shared/mailer';\nexport type { AutomationEngine, WebhookSender } from '@headless-lms/core/automations';\n\nexport async function createContainer(\n config: ServerConfig,\n options?: BuildContainerOptions,\n): Promise<Container> {\n return buildContainer(\n {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["// Public surface of @headless-lms/server. Installations compose these:\n// const container = await createContainer(config, { pluginsDir, adapters })\n// const app = await buildServer(config, container)\nimport { buildContainer, type BuildContainerOptions, type Container } from './app/container.js';\nimport type { ServerConfig } from './http/config.js';\n\nexport { buildServer } from './http/server.js';\nexport { mcpCatalogue } from './http/mcp/catalogue.js';\nexport type {\n CatalogueField,\n CatalogueScope,\n CatalogueTool,\n McpCatalogue,\n} from './http/mcp/catalogue.js';\nexport { loadIntegrations } from './app/integrations.js';\nexport { InlineAutomationEngine } from '@headless-lms/adapter-defaults/workflows';\n// Operational functions consumed by the @headless-lms/cli bin.\nexport { runMigrations } from '@headless-lms/adapter-db';\nexport type { ServerConfig } from './http/config.js';\n// Re-exporting AuthUser also pulls its module into any program that imports\n// this file (directly or via the workspace path mapping), which is what\n// applies its ambient `declare module \"fastify\"` augmentation\n// (FastifyRequest.authUser/orgId, FastifyInstance.requireOrgSession) —\n// otherwise nothing imports fastify.d.ts and the augmentation never loads.\nexport type { AuthUser } from './http/fastify.js';\nexport type {\n Config as ContainerConfig,\n Container,\n AdapterOverrides,\n BuildContainerOptions,\n LoggingConfig,\n} from './app/container.js';\nexport type { EmailSender, EmailMessage, ObjectStorage } from '@headless-lms/core/shared/ports';\nexport type { Mailer } from '@headless-lms/core/shared/mailer';\nexport type { AutomationEngine, WebhookSender } from '@headless-lms/core/automations';\n\nexport async function createContainer(\n config: ServerConfig,\n options?: BuildContainerOptions,\n): Promise<Container> {\n return buildContainer(\n {\n ...config.container,\n deliveryExpirySeconds: config.deliveryExpirySeconds,\n memberImageMaxBytes: config.memberImageMaxBytes,\n },\n options,\n );\n}\n"],"mappings":";;;;;;;AAoCA,eAAsB,gBACpB,QACA,SACoB;CACpB,OAAO,eACL;EACE,GAAG,OAAO;EACV,uBAAuB,OAAO;EAC9B,qBAAqB,OAAO;CAC9B,GACA,OACF;AACF"}
|