@headless-lms/server 0.3.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/app/community-mail.d.ts +6 -8
- package/dist/app/community-mail.js +13 -17
- package/dist/app/community-mail.js.map +1 -1
- package/dist/app/container.d.ts +27 -10
- package/dist/app/container.js +178 -22
- package/dist/app/container.js.map +1 -1
- 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/errors.d.ts +1 -0
- package/dist/http/errors.js +16 -1
- package/dist/http/errors.js.map +1 -1
- package/dist/http/mcp/tools/communities.js +1 -1
- package/dist/http/mcp/tools/communities.js.map +1 -1
- package/dist/http/plugins/error-handler.js +3 -1
- package/dist/http/plugins/error-handler.js.map +1 -1
- package/dist/http/routes/automations.js +3 -3
- package/dist/http/routes/automations.js.map +1 -1
- package/dist/http/routes/communities.js +67 -7
- package/dist/http/routes/communities.js.map +1 -1
- package/dist/http/routes/member/actor.d.ts +1 -1
- package/dist/http/routes/member/chats.js +9 -30
- package/dist/http/routes/member/chats.js.map +1 -1
- package/dist/http/routes/member/community.js +25 -1
- package/dist/http/routes/member/community.js.map +1 -1
- 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/index.js +4 -0
- package/dist/http/routes/member/index.js.map +1 -1
- 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.js +66 -42
- package/dist/http/routes/member/notifications.js.map +1 -1
- package/dist/http/routes/member/posts.js +33 -33
- package/dist/http/routes/member/posts.js.map +1 -1
- package/dist/http/routes/organizations.js +122 -1
- package/dist/http/routes/organizations.js.map +1 -1
- package/dist/http/schemas/assets.d.ts +6 -6
- package/dist/http/schemas/automations.d.ts +0 -4
- package/dist/http/schemas/chats.d.ts +34 -11
- package/dist/http/schemas/chats.js +4 -6
- package/dist/http/schemas/chats.js.map +1 -1
- package/dist/http/schemas/community.d.ts +77 -17
- package/dist/http/schemas/community.js +6 -3
- package/dist/http/schemas/community.js.map +1 -1
- package/dist/http/schemas/discussion.d.ts +23 -1
- package/dist/http/schemas/discussion.js +14 -2
- package/dist/http/schemas/discussion.js.map +1 -1
- package/dist/http/schemas/index.d.ts +6 -6
- package/dist/http/schemas/index.js +6 -6
- package/dist/http/schemas/integrations.d.ts +4 -4
- package/dist/http/schemas/members.d.ts +5 -5
- package/dist/http/schemas/notifications.d.ts +498 -175
- package/dist/http/schemas/notifications.js +148 -28
- package/dist/http/schemas/notifications.js.map +1 -1
- package/dist/http/schemas/posts.d.ts +37 -3
- package/dist/http/schemas/profile.d.ts +2 -2
- package/dist/http/schemas/shared.d.ts +10 -3
- package/dist/http/schemas/shared.js +3 -2
- package/dist/http/schemas/shared.js.map +1 -1
- package/dist/http/schemas/students.d.ts +3 -3
- package/dist/http/scope.d.ts +2 -1
- package/dist/http/scope.js +7 -1
- package/dist/http/scope.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/packages/server/package.js +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations.js","names":[],"sources":["../../../src/http/routes/organizations.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport {\n AcceptInvite,\n AcceptInviteResult,\n CreateInvite,\n CreateOrganization,\n Invite,\n MemberIdParam,\n MemberRoleChange,\n MembersPage,\n MembersQuery,\n GetInviteResult,\n InviteTokenParam,\n Organization,\n UpdateMemberRole,\n UpdateOrganization,\n refusals,\n} from '../schemas/index.js';\nimport type { MemberWriteContext } from '@headless-lms/core/organizations';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../app/container.js';\nimport { resolveScope } from '../scope.js';\n\nexport async function organizationsRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const organizations = container.organizations;\n const tags = ['Organizations'];\n\n // Create a new organization on the caller's behalf and make it their active\n // org. This is the API's own front door for org creation — it drives Better\n // Auth internally, so callers use the typed SDK, not the auth namespace. No\n // resolveScope here: the caller has no active org yet, only a session.\n r.route({\n method: 'POST',\n url: '/api/organizations',\n // Session only: a first-time signup has no active org yet, so requiring one\n // here would 401 the very call that produces it.\n preHandler: app.requireSession,\n schema: {\n operationId: 'createOrganization',\n tags,\n summary: 'Create an organization and make it active',\n description:\n 'For any signed-in person, including one with no organization yet. The caller becomes its owner.',\n body: CreateOrganization,\n response: { 201: Organization },\n },\n handler: async (req, reply) => {\n const org = await container.orgProvider.createOrganization(req.headers, req.body);\n return reply.code(201).send({\n name: org.name,\n slug: org.slug,\n id: org.id,\n createdAt: org.createdAt.toISOString(),\n });\n },\n });\n\n // Update the caller's active organization (name/slug). Writes go through Better\n // Auth, which enforces the caller's org-update permission (owner/admin).\n r.route({\n method: 'PATCH',\n url: '/api/organizations',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'updateOrganization',\n tags,\n summary: 'Update the active organization (staff)',\n description: 'Owner or admin. Changes its name or slug; 409 when the slug is taken.',\n body: UpdateOrganization,\n response: { 200: Organization, ...refusals(403, 409) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n const org = await container.orgProvider.updateOrganization(\n req.headers,\n scope.authOrgId,\n req.body,\n );\n return reply.send({\n id: org.id,\n name: org.name,\n slug: org.slug,\n createdAt: org.createdAt.toISOString(),\n });\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/organizations/members',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listMembers',\n tags,\n summary: \"List the organization's team members (staff)\",\n description:\n 'Staff only (owner, admin, instructor). The team: everyone in the organization who is not a student.',\n querystring: MembersQuery,\n response: { 200: MembersPage, ...refusals(403) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n return organizations.listMembers(scope.orgId, req.query);\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/organizations/members/:id/role',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'updateMemberRole',\n tags,\n summary: \"Change a member's role (staff)\",\n description:\n 'Owner or admin only. The owner role can be neither granted nor changed (409), and only a moderator can become a student.',\n params: MemberIdParam,\n body: UpdateMemberRole,\n response: { 200: MemberRoleChange, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const ctx: MemberWriteContext = {\n orgId: scope.orgId,\n authOrgId: scope.authOrgId,\n headers: req.headers,\n };\n const member = await organizations.updateMemberRole(\n ctx,\n { id: scope.orgUserId, role: scope.role },\n req.params.id,\n req.body.role,\n );\n if (!member) {\n throw new NotFoundError('Member', req.params.id);\n }\n return member;\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/organizations/members/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'removeMember',\n tags,\n summary: 'Remove an organization member (staff)',\n description:\n 'Owner or admin only. Removing a pending member cancels their invite. The owner cannot be removed (409).',\n params: MemberIdParam,\n response: { 204: z.void(), ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n const ctx: MemberWriteContext = {\n orgId: scope.orgId,\n authOrgId: scope.authOrgId,\n headers: req.headers,\n };\n const removed = await organizations.removeMember(\n ctx,\n { id: scope.orgUserId, role: scope.role },\n req.params.id,\n );\n if (!removed) {\n throw new NotFoundError('Member', req.params.id);\n }\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/organizations/invites',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'createInvite',\n tags,\n summary: 'Invite a member or student into the active organization (staff)',\n description:\n 'Owner or admin only. A student is created by this call, so their access can be granted before they accept. 409 when a student with that email is already in the organization.',\n body: CreateInvite,\n response: { 201: Invite, ...refusals(403, 409) },\n },\n handler: async (req, reply) => {\n // Domain ids, not the session's auth ids: invites FK to organizations.id\n // and users.id.\n const scope = await resolveScope(container, req);\n const invite = await organizations.createInvite(\n { id: scope.orgUserId, role: scope.role },\n {\n orgId: scope.orgId,\n inviterUserId: scope.userId,\n email: req.body.email,\n role: req.body.role,\n ...(req.body.firstName !== undefined && { firstName: req.body.firstName }),\n ...(req.body.lastName !== undefined && { lastName: req.body.lastName }),\n sendEmail: req.body.sendEmail,\n },\n );\n\n req.log.debug({ inviteId: invite.id }, 'created invite');\n return reply.code(201).send({\n id: invite.id,\n email: invite.email,\n role: invite.role,\n status: invite.status,\n expiresAt: invite.expiresAt,\n createdAt: invite.createdAt,\n });\n },\n });\n\n // The invite landing page's first call, made before the invitee has any\n // session — so no guard. It turns the emailed token into the two facts the\n // page needs: who the invitation is for, and whether that address already has\n // an account. The email comes from the invitation row rather than the URL, so\n // it cannot be steered by editing the link.\n r.route({\n method: 'GET',\n url: '/api/organizations/invites/:token',\n schema: {\n operationId: 'getInvite',\n tags,\n summary: 'Read an invite by its token',\n description:\n 'Public: no session needed. The same 404 answers forged, expired and accepted tokens, so a probe learns nothing.',\n params: InviteTokenParam,\n response: { 200: GetInviteResult, ...refusals(404) },\n },\n handler: async (req) => {\n const invite = await organizations.peekInvite(req.params.token);\n if (!invite) {\n // Same answer for forged, expired, and already-accepted tokens: a\n // probe learns nothing about which invitations exist.\n throw new NotFoundError('Invite', 'token');\n }\n // Whether the address already has a login is deliberately not answered\n // here. The mirror cannot say — an admin's student is a person long\n // before they are an account — and asking the auth engine would mean\n // reading its tables for one boolean. The sign-up form discovers it\n // instead: a duplicate signup comes back 422 and the page flips to\n // sign-in.\n const person = await container.identity.getUserByEmail(invite.email);\n return {\n email: invite.email,\n firstName: person?.firstName ?? null,\n lastName: person?.lastName ?? null,\n };\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/organizations/invites/accept',\n preHandler: app.requireSession,\n schema: {\n operationId: 'acceptInvite',\n tags,\n summary: 'Accept an invite with the signed-in account',\n description:\n \"For any signed-in person whose email matches the invitation. Makes the invite's organization the session's active one. 400 when the token is invalid or expired, or the email does not match.\",\n body: AcceptInvite,\n response: { 200: AcceptInviteResult, ...refusals(400, 404) },\n },\n handler: async (req) => {\n // No active org yet, so no resolveScope — but acceptInvite links a domain\n // users.id, never the auth account id.\n const user = await container.identity.getUserByExternalId(req.authUser.id);\n if (!user) {\n throw new NotFoundError('User', req.authUser.id);\n }\n const accepted = await container.organizations.acceptInvite({\n token: req.body.token,\n userId: user.id,\n email: req.authUser.email,\n });\n\n // The session predates this grant, so it carries no active org and every\n // org-scoped read would 401. Students are never org members, so the org\n // plugin's set-active cannot do it — stamp the session row directly.\n const org = await container.organizations.getById(accepted.orgId);\n if (!org) {\n throw new NotFoundError('Organization', accepted.orgId);\n }\n const stamped = await container.sessions.stampActiveOrganization(req.headers, org.id);\n\n req.log.info({ accepted, stamped }, 'accepted invite');\n return {};\n },\n });\n}\n"],"mappings":";;;;;;;;;AAyBA,eAAsB,oBACpB,KACA,WACe;CACf,MAAM,IAAI,IAAI,iBAAkC;CAChD,MAAM,gBAAgB,UAAU;CAChC,MAAM,OAAO,CAAC,eAAe;CAM7B,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EAGL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,MAAM;GACN,UAAU,EAAE,KAAK,aAAa;EAChC;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,MAAM,MAAM,UAAU,YAAY,mBAAmB,IAAI,SAAS,IAAI,IAAI;GAChF,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;IAC1B,MAAM,IAAI;IACV,MAAM,IAAI;IACV,IAAI,IAAI;IACR,WAAW,IAAI,UAAU,YAAY;GACvC,CAAC;EACH;CACF,CAAC;CAID,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aAAa;GACb,MAAM;GACN,UAAU;IAAE,KAAK;IAAc,GAAG,SAAS,KAAK,GAAG;GAAE;EACvD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,MAAM,MAAM,UAAU,YAAY,mBACtC,IAAI,SACJ,MAAM,WACN,IAAI,IACN;GACA,OAAO,MAAM,KAAK;IAChB,IAAI,IAAI;IACR,MAAM,IAAI;IACV,MAAM,IAAI;IACV,WAAW,IAAI,UAAU,YAAY;GACvC,CAAC;EACH;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,aAAa;GACb,UAAU;IAAE,KAAK;IAAa,GAAG,SAAS,GAAG;GAAE;EACjD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,OAAO,cAAc,YAAY,MAAM,OAAO,IAAI,KAAK;EACzD;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;IAAkB,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EAChE;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,MAA0B;IAC9B,OAAO,MAAM;IACb,WAAW,MAAM;IACjB,SAAS,IAAI;GACf;GACA,MAAM,SAAS,MAAM,cAAc,iBACjC,KACA;IAAE,IAAI,MAAM;IAAW,MAAM,MAAM;GAAK,GACxC,IAAI,OAAO,IACX,IAAI,KAAK,IACX;GACA,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,UAAU,IAAI,OAAO,EAAE;GAEjD,OAAO;EACT;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK,EAAE,KAAK;IAAG,GAAG,SAAS,KAAK,KAAK,GAAG;GAAE;EACxD;EACA,SAAS,OAAO,KAAK,UAAU;GAC7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,MAA0B;IAC9B,OAAO,MAAM;IACb,WAAW,MAAM;IACjB,SAAS,IAAI;GACf;GAMA,IAAI,CAAC,MALiB,cAAc,aAClC,KACA;IAAE,IAAI,MAAM;IAAW,MAAM,MAAM;GAAK,GACxC,IAAI,OAAO,EACb,GAEE,MAAM,IAAI,cAAc,UAAU,IAAI,OAAO,EAAE;GAEjD,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,aACE;GACF,MAAM;GACN,UAAU;IAAE,KAAK;IAAQ,GAAG,SAAS,KAAK,GAAG;GAAE;EACjD;EACA,SAAS,OAAO,KAAK,UAAU;GAG7B,MAAM,QAAQ,MAAM,aAAa,WAAW,GAAG;GAC/C,MAAM,SAAS,MAAM,cAAc,aACjC;IAAE,IAAI,MAAM;IAAW,MAAM,MAAM;GAAK,GACxC;IACE,OAAO,MAAM;IACb,eAAe,MAAM;IACrB,OAAO,IAAI,KAAK;IAChB,MAAM,IAAI,KAAK;IACf,GAAI,IAAI,KAAK,cAAc,KAAA,KAAa,EAAE,WAAW,IAAI,KAAK,UAAU;IACxE,GAAI,IAAI,KAAK,aAAa,KAAA,KAAa,EAAE,UAAU,IAAI,KAAK,SAAS;IACrE,WAAW,IAAI,KAAK;GACtB,CACF;GAEA,IAAI,IAAI,MAAM,EAAE,UAAU,OAAO,GAAG,GAAG,gBAAgB;GACvD,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK;IAC1B,IAAI,OAAO;IACX,OAAO,OAAO;IACd,MAAM,OAAO;IACb,QAAQ,OAAO;IACf,WAAW,OAAO;IAClB,WAAW,OAAO;GACpB,CAAC;EACH;CACF,CAAC;CAOD,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,QAAQ;GACR,UAAU;IAAE,KAAK;IAAiB,GAAG,SAAS,GAAG;GAAE;EACrD;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,SAAS,MAAM,cAAc,WAAW,IAAI,OAAO,KAAK;GAC9D,IAAI,CAAC,QAGH,MAAM,IAAI,cAAc,UAAU,OAAO;GAQ3C,MAAM,SAAS,MAAM,UAAU,SAAS,eAAe,OAAO,KAAK;GACnE,OAAO;IACL,OAAO,OAAO;IACd,WAAW,QAAQ,aAAa;IAChC,UAAU,QAAQ,YAAY;GAChC;EACF;CACF,CAAC;CAED,EAAE,MAAM;EACN,QAAQ;EACR,KAAK;EACL,YAAY,IAAI;EAChB,QAAQ;GACN,aAAa;GACb;GACA,SAAS;GACT,aACE;GACF,MAAM;GACN,UAAU;IAAE,KAAK;IAAoB,GAAG,SAAS,KAAK,GAAG;GAAE;EAC7D;EACA,SAAS,OAAO,QAAQ;GAGtB,MAAM,OAAO,MAAM,UAAU,SAAS,oBAAoB,IAAI,SAAS,EAAE;GACzE,IAAI,CAAC,MACH,MAAM,IAAI,cAAc,QAAQ,IAAI,SAAS,EAAE;GAEjD,MAAM,WAAW,MAAM,UAAU,cAAc,aAAa;IAC1D,OAAO,IAAI,KAAK;IAChB,QAAQ,KAAK;IACb,OAAO,IAAI,SAAS;GACtB,CAAC;GAKD,MAAM,MAAM,MAAM,UAAU,cAAc,QAAQ,SAAS,KAAK;GAChE,IAAI,CAAC,KACH,MAAM,IAAI,cAAc,gBAAgB,SAAS,KAAK;GAExD,MAAM,UAAU,MAAM,UAAU,SAAS,wBAAwB,IAAI,SAAS,IAAI,EAAE;GAEpF,IAAI,IAAI,KAAK;IAAE;IAAU;GAAQ,GAAG,iBAAiB;GACrD,OAAO,CAAC;EACV;CACF,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"organizations.js","names":[],"sources":["../../../src/http/routes/organizations.ts"],"sourcesContent":["import type { FastifyInstance } from 'fastify';\nimport type { ZodTypeProvider } from 'fastify-type-provider-zod';\nimport { z } from 'zod';\nimport {\n AcceptInvite,\n AcceptInviteResult,\n CreateInvite,\n CreateOrganization,\n Invite,\n MemberIdParam,\n NotificationCategoryDefaults,\n NotificationCategoryList,\n NotificationChannelInfos,\n NotificationListScopeQuery,\n NotificationTypeInfos,\n ReplaceNotificationCategories,\n MemberRoleChange,\n MembersPage,\n MembersQuery,\n GetInviteResult,\n InviteTokenParam,\n Organization,\n UpdateMemberRole,\n UpdateOrganization,\n refusals,\n} from '../schemas/index.js';\nimport type { MemberWriteContext } from '@headless-lms/core/organizations';\nimport { NotFoundError } from '@headless-lms/core/shared/errors';\nimport type { Container } from '../../app/container.js';\nimport { resolveConfiguratorScope, resolveScope } from '../scope.js';\nimport { typesForList } from '@headless-lms/core/shared/notification-categories';\n\nexport async function organizationsRoutes(\n app: FastifyInstance,\n container: Container,\n): Promise<void> {\n const r = app.withTypeProvider<ZodTypeProvider>();\n const organizations = container.organizations;\n const tags = ['Organizations'];\n\n // Create a new organization on the caller's behalf and make it their active\n // org. This is the API's own front door for org creation — it drives Better\n // Auth internally, so callers use the typed SDK, not the auth namespace. No\n // resolveScope here: the caller has no active org yet, only a session.\n r.route({\n method: 'POST',\n url: '/api/organizations',\n // Session only: a first-time signup has no active org yet, so requiring one\n // here would 401 the very call that produces it.\n preHandler: app.requireSession,\n schema: {\n operationId: 'createOrganization',\n tags,\n summary: 'Create an organization and make it active',\n description:\n 'For any signed-in person, including one with no organization yet. The caller becomes its owner.',\n body: CreateOrganization,\n response: { 201: Organization },\n },\n handler: async (req, reply) => {\n const org = await container.orgProvider.createOrganization(req.headers, req.body);\n return reply.code(201).send({\n name: org.name,\n slug: org.slug,\n id: org.id,\n createdAt: org.createdAt.toISOString(),\n });\n },\n });\n\n // Update the caller's active organization (name/slug). Writes go through Better\n // Auth, which enforces the caller's org-update permission (owner/admin).\n r.route({\n method: 'PATCH',\n url: '/api/organizations',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'updateOrganization',\n tags,\n summary: 'Update the active organization (staff)',\n description: 'Owner or admin. Changes its name or slug; 409 when the slug is taken.',\n body: UpdateOrganization,\n response: { 200: Organization, ...refusals(403, 409) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n const org = await container.orgProvider.updateOrganization(\n req.headers,\n scope.authOrgId,\n req.body,\n );\n return reply.send({\n id: org.id,\n name: org.name,\n slug: org.slug,\n createdAt: org.createdAt.toISOString(),\n });\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/organizations/members',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listMembers',\n tags,\n summary: \"List the organization's team members (staff)\",\n description:\n 'Staff only (owner, admin, instructor). The team: everyone in the organization who is not a student.',\n querystring: MembersQuery,\n response: { 200: MembersPage, ...refusals(403) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n return organizations.listMembers(scope.orgId, req.query);\n },\n });\n\n r.route({\n method: 'PATCH',\n url: '/api/organizations/members/:id/role',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'updateMemberRole',\n tags,\n summary: \"Change a member's role (staff)\",\n description:\n 'Owner or admin only. The owner role can be neither granted nor changed (409), and only a moderator can become a student.',\n params: MemberIdParam,\n body: UpdateMemberRole,\n response: { 200: MemberRoleChange, ...refusals(403, 404, 409) },\n },\n handler: async (req) => {\n const scope = await resolveScope(container, req);\n const ctx: MemberWriteContext = {\n orgId: scope.orgId,\n authOrgId: scope.authOrgId,\n headers: req.headers,\n };\n const member = await organizations.updateMemberRole(\n ctx,\n { id: scope.orgUserId, role: scope.role },\n req.params.id,\n req.body.role,\n );\n if (!member) {\n throw new NotFoundError('Member', req.params.id);\n }\n return member;\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/organizations/members/:id',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'removeMember',\n tags,\n summary: 'Remove an organization member (staff)',\n description:\n 'Owner or admin only. Removing a pending member cancels their invite. The owner cannot be removed (409).',\n params: MemberIdParam,\n response: { 204: z.void(), ...refusals(403, 404, 409) },\n },\n handler: async (req, reply) => {\n const scope = await resolveScope(container, req);\n const ctx: MemberWriteContext = {\n orgId: scope.orgId,\n authOrgId: scope.authOrgId,\n headers: req.headers,\n };\n const removed = await organizations.removeMember(\n ctx,\n { id: scope.orgUserId, role: scope.role },\n req.params.id,\n );\n if (!removed) {\n throw new NotFoundError('Member', req.params.id);\n }\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/organizations/invites',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'createInvite',\n tags,\n summary: 'Invite a member or student into the active organization (staff)',\n description:\n 'Owner or admin only. A student is created by this call, so their access can be granted before they accept. 409 when a student with that email is already in the organization.',\n body: CreateInvite,\n response: { 201: Invite, ...refusals(403, 409) },\n },\n handler: async (req, reply) => {\n // Domain ids, not the session's auth ids: invites FK to organizations.id\n // and users.id.\n const scope = await resolveScope(container, req);\n const invite = await organizations.createInvite(\n { id: scope.orgUserId, role: scope.role },\n {\n orgId: scope.orgId,\n inviterUserId: scope.userId,\n email: req.body.email,\n role: req.body.role,\n ...(req.body.firstName !== undefined && { firstName: req.body.firstName }),\n ...(req.body.lastName !== undefined && { lastName: req.body.lastName }),\n sendEmail: req.body.sendEmail,\n },\n );\n\n req.log.debug({ inviteId: invite.id }, 'created invite');\n return reply.code(201).send({\n id: invite.id,\n email: invite.email,\n role: invite.role,\n status: invite.status,\n expiresAt: invite.expiresAt,\n createdAt: invite.createdAt,\n });\n },\n });\n\n // The invite landing page's first call, made before the invitee has any\n // session — so no guard. It turns the emailed token into the two facts the\n // page needs: who the invitation is for, and whether that address already has\n // an account. The email comes from the invitation row rather than the URL, so\n // it cannot be steered by editing the link.\n r.route({\n method: 'GET',\n url: '/api/organizations/invites/:token',\n schema: {\n operationId: 'getInvite',\n tags,\n summary: 'Read an invite by its token',\n description:\n 'Public: no session needed. The same 404 answers forged, expired and accepted tokens, so a probe learns nothing.',\n params: InviteTokenParam,\n response: { 200: GetInviteResult, ...refusals(404) },\n },\n handler: async (req) => {\n const invite = await organizations.peekInvite(req.params.token);\n if (!invite) {\n // Same answer for forged, expired, and already-accepted tokens: a\n // probe learns nothing about which invitations exist.\n throw new NotFoundError('Invite', 'token');\n }\n // Whether the address already has a login is deliberately not answered\n // here. The mirror cannot say — an admin's student is a person long\n // before they are an account — and asking the auth engine would mean\n // reading its tables for one boolean. The sign-up form discovers it\n // instead: a duplicate signup comes back 422 and the page flips to\n // sign-in.\n const person = await container.identity.getUserByEmail(invite.email);\n return {\n email: invite.email,\n firstName: person?.firstName ?? null,\n lastName: person?.lastName ?? null,\n };\n },\n });\n\n r.route({\n method: 'POST',\n url: '/api/organizations/invites/accept',\n preHandler: app.requireSession,\n schema: {\n operationId: 'acceptInvite',\n tags,\n summary: 'Accept an invite with the signed-in account',\n description:\n \"For any signed-in person whose email matches the invitation. Makes the invite's organization the session's active one. 400 when the token is invalid or expired, or the email does not match.\",\n body: AcceptInvite,\n response: { 200: AcceptInviteResult, ...refusals(400, 404) },\n },\n handler: async (req) => {\n // No active org yet, so no resolveScope — but acceptInvite links a domain\n // users.id, never the auth account id.\n const user = await container.identity.getUserByExternalId(req.authUser.id);\n if (!user) {\n throw new NotFoundError('User', req.authUser.id);\n }\n const accepted = await container.organizations.acceptInvite({\n token: req.body.token,\n userId: user.id,\n email: req.authUser.email,\n });\n\n // The session predates this grant, so it carries no active org and every\n // org-scoped read would 401. Students are never org members, so the org\n // plugin's set-active cannot do it — stamp the session row directly.\n const org = await container.organizations.getById(accepted.orgId);\n if (!org) {\n throw new NotFoundError('Organization', accepted.orgId);\n }\n const stamped = await container.sessions.stampActiveOrganization(req.headers, org.id);\n\n req.log.info({ accepted, stamped }, 'accepted invite');\n return {};\n },\n });\n\n const notificationTags = ['Notifications'];\n\n r.route({\n method: 'GET',\n url: '/api/notification-types',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listNotificationTypes',\n tags: notificationTags,\n summary: 'List the notification types a category list can cover (staff)',\n description:\n 'Owner or admin only. `scope=org` lists the types the org list can cover, `scope=community` those a community list can cover. Each type carries all its scopes, so an editor can tell which types can be per space.',\n querystring: NotificationListScopeQuery,\n response: { 200: NotificationTypeInfos, ...refusals(403) },\n },\n handler: async (req) => {\n await resolveConfiguratorScope(container, req);\n return typesForList(container.notificationTypes, req.query.scope);\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/notification-channels',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'listNotificationChannels',\n tags: notificationTags,\n summary: 'List the notification channels this deployment can deliver on (staff)',\n description: 'Owner or admin only. `inApp` is always first.',\n response: { 200: NotificationChannelInfos, ...refusals(403) },\n },\n handler: async (req) => {\n await resolveConfiguratorScope(container, req);\n return container.notificationChannels.list().map((channel) => ({ channel }));\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/notification-categories',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getOrgNotificationCategories',\n tags: notificationTags,\n summary: \"Get the organization's notification categories (staff)\",\n description:\n 'Owner or admin only. The list in use for notifications outside any community, with `source` saying whether it is the default or a stored list.',\n response: { 200: NotificationCategoryList, ...refusals(403) },\n },\n handler: async (req) => {\n const scope = await resolveConfiguratorScope(container, req);\n return container.notificationCategories.org.get(scope.orgId, scope.orgId);\n },\n });\n\n r.route({\n method: 'PUT',\n url: '/api/notification-categories',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'replaceOrgNotificationCategories',\n tags: notificationTags,\n summary: \"Replace the organization's notification categories (staff)\",\n description:\n 'Owner or admin only. Stores the whole list. 422 when a key repeats, a type cannot be in the org list, a reason is not allowed for its type, a channel is not configured, or earlier categories already cover everything a category covers.',\n body: ReplaceNotificationCategories,\n response: { 200: NotificationCategoryList, ...refusals(400, 403, 422) },\n },\n handler: async (req) => {\n const scope = await resolveConfiguratorScope(container, req);\n return container.notificationCategories.org.replace(\n scope.orgId,\n scope.orgId,\n req.body.categories,\n );\n },\n });\n\n r.route({\n method: 'DELETE',\n url: '/api/notification-categories',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'resetOrgNotificationCategories',\n tags: notificationTags,\n summary: 'Go back to the default notification categories for the organization (staff)',\n description: 'Owner or admin only. Removes the stored list; the default applies again.',\n response: { 204: z.void(), ...refusals(403) },\n },\n handler: async (req, reply) => {\n const scope = await resolveConfiguratorScope(container, req);\n await container.notificationCategories.org.reset(scope.orgId, scope.orgId);\n return reply.code(204).send();\n },\n });\n\n r.route({\n method: 'GET',\n url: '/api/notification-categories/defaults',\n preHandler: app.requireOrgSession,\n schema: {\n operationId: 'getDefaultNotificationCategories',\n tags: notificationTags,\n summary: 'Get the default notification categories (staff)',\n description:\n 'Owner or admin only. The default org list (`scope=org`) or community list (`scope=community`), offering only the configured channels.',\n querystring: NotificationListScopeQuery,\n response: { 200: NotificationCategoryDefaults, ...refusals(403) },\n },\n handler: async (req) => {\n await resolveConfiguratorScope(container, req);\n const service =\n req.query.scope === 'org'\n ? container.notificationCategories.org\n : container.notificationCategories.community;\n return { categories: service.defaults() };\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -18,13 +18,13 @@ declare const AssetStatus: z.ZodEnum<{
|
|
|
18
18
|
}>;
|
|
19
19
|
type AssetStatus = z.infer<typeof AssetStatus>;
|
|
20
20
|
declare const Asset: z.ZodObject<{
|
|
21
|
-
orgId: z.ZodString;
|
|
22
21
|
id: z.ZodString;
|
|
22
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
23
23
|
status: z.ZodEnum<{
|
|
24
24
|
pending: "pending";
|
|
25
25
|
ready: "ready";
|
|
26
26
|
}>;
|
|
27
|
-
|
|
27
|
+
orgId: z.ZodString;
|
|
28
28
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
29
29
|
uploadedBy: z.ZodString;
|
|
30
30
|
filename: z.ZodString;
|
|
@@ -63,13 +63,13 @@ declare const AssetsQuery: z.ZodObject<{
|
|
|
63
63
|
type AssetsQuery = z.infer<typeof AssetsQuery>;
|
|
64
64
|
declare const AssetsPage: z.ZodObject<{
|
|
65
65
|
rows: z.ZodArray<z.ZodObject<{
|
|
66
|
-
orgId: z.ZodString;
|
|
67
66
|
id: z.ZodString;
|
|
67
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
68
68
|
status: z.ZodEnum<{
|
|
69
69
|
pending: "pending";
|
|
70
70
|
ready: "ready";
|
|
71
71
|
}>;
|
|
72
|
-
|
|
72
|
+
orgId: z.ZodString;
|
|
73
73
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
74
74
|
uploadedBy: z.ZodString;
|
|
75
75
|
filename: z.ZodString;
|
|
@@ -113,13 +113,13 @@ declare const UploadTicket: z.ZodObject<{
|
|
|
113
113
|
expiresInSeconds: z.ZodNumber;
|
|
114
114
|
headers: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
115
115
|
asset: z.ZodObject<{
|
|
116
|
-
orgId: z.ZodString;
|
|
117
116
|
id: z.ZodString;
|
|
117
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
118
118
|
status: z.ZodEnum<{
|
|
119
119
|
pending: "pending";
|
|
120
120
|
ready: "ready";
|
|
121
121
|
}>;
|
|
122
|
-
|
|
122
|
+
orgId: z.ZodString;
|
|
123
123
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
124
124
|
uploadedBy: z.ZodString;
|
|
125
125
|
filename: z.ZodString;
|
|
@@ -30,10 +30,6 @@ declare const Automation: z.ZodObject<{
|
|
|
30
30
|
}, z.core.$strict>>;
|
|
31
31
|
enabled: z.ZodBoolean;
|
|
32
32
|
filter: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>>>;
|
|
33
|
-
source: z.ZodEnum<{
|
|
34
|
-
system: "system";
|
|
35
|
-
user: "user";
|
|
36
|
-
}>;
|
|
37
33
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
38
34
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
39
35
|
}, z.core.$strict>;
|
|
@@ -28,9 +28,9 @@ declare const MessageFlag: z.ZodObject<{
|
|
|
28
28
|
reason: z.ZodString;
|
|
29
29
|
resolvedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
30
30
|
resolution: z.ZodNullable<z.ZodEnum<{
|
|
31
|
+
locked: "locked";
|
|
31
32
|
dismissed: "dismissed";
|
|
32
33
|
deleted: "deleted";
|
|
33
|
-
locked: "locked";
|
|
34
34
|
}>>;
|
|
35
35
|
resolvedBy: z.ZodNullable<z.ZodString>;
|
|
36
36
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
@@ -71,6 +71,10 @@ declare const MessageView: z.ZodObject<{
|
|
|
71
71
|
}, z.core.$strict>>;
|
|
72
72
|
reactions: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
73
73
|
viewerReaction: z.ZodNullable<z.ZodString>;
|
|
74
|
+
mentions: z.ZodArray<z.ZodObject<{
|
|
75
|
+
orgUserId: z.ZodString;
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
}, z.core.$strict>>;
|
|
74
78
|
}, z.core.$strict>;
|
|
75
79
|
declare const MessagesPage: z.ZodObject<{
|
|
76
80
|
rows: z.ZodArray<z.ZodObject<{
|
|
@@ -108,6 +112,10 @@ declare const MessagesPage: z.ZodObject<{
|
|
|
108
112
|
}, z.core.$strict>>;
|
|
109
113
|
reactions: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
110
114
|
viewerReaction: z.ZodNullable<z.ZodString>;
|
|
115
|
+
mentions: z.ZodArray<z.ZodObject<{
|
|
116
|
+
orgUserId: z.ZodString;
|
|
117
|
+
name: z.ZodString;
|
|
118
|
+
}, z.core.$strict>>;
|
|
111
119
|
}, z.core.$strict>>;
|
|
112
120
|
total: z.ZodNumber;
|
|
113
121
|
page: z.ZodNumber;
|
|
@@ -135,8 +143,13 @@ declare const ChatListItem: z.ZodObject<{
|
|
|
135
143
|
}, z.core.$strict>;
|
|
136
144
|
participantIds: z.ZodArray<z.ZodString>;
|
|
137
145
|
lastReadMessageId: z.ZodNullable<z.ZodString>;
|
|
138
|
-
|
|
139
|
-
|
|
146
|
+
subscription: z.ZodNullable<z.ZodObject<{
|
|
147
|
+
state: z.ZodEnum<{
|
|
148
|
+
following: "following";
|
|
149
|
+
muted: "muted";
|
|
150
|
+
}>;
|
|
151
|
+
mutedUntil: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
152
|
+
}, z.core.$strict>>;
|
|
140
153
|
unread: z.ZodNumber;
|
|
141
154
|
lastMessage: z.ZodNullable<z.ZodObject<{
|
|
142
155
|
id: z.ZodString;
|
|
@@ -169,8 +182,13 @@ declare const ChatsPage: z.ZodObject<{
|
|
|
169
182
|
}, z.core.$strict>;
|
|
170
183
|
participantIds: z.ZodArray<z.ZodString>;
|
|
171
184
|
lastReadMessageId: z.ZodNullable<z.ZodString>;
|
|
172
|
-
|
|
173
|
-
|
|
185
|
+
subscription: z.ZodNullable<z.ZodObject<{
|
|
186
|
+
state: z.ZodEnum<{
|
|
187
|
+
following: "following";
|
|
188
|
+
muted: "muted";
|
|
189
|
+
}>;
|
|
190
|
+
mutedUntil: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
191
|
+
}, z.core.$strict>>;
|
|
174
192
|
unread: z.ZodNumber;
|
|
175
193
|
lastMessage: z.ZodNullable<z.ZodObject<{
|
|
176
194
|
id: z.ZodString;
|
|
@@ -220,6 +238,10 @@ declare const MessageQueueEntry: z.ZodObject<{
|
|
|
220
238
|
}, z.core.$strict>>;
|
|
221
239
|
reactions: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
222
240
|
viewerReaction: z.ZodNullable<z.ZodString>;
|
|
241
|
+
mentions: z.ZodArray<z.ZodObject<{
|
|
242
|
+
orgUserId: z.ZodString;
|
|
243
|
+
name: z.ZodString;
|
|
244
|
+
}, z.core.$strict>>;
|
|
223
245
|
}, z.core.$strict>;
|
|
224
246
|
flags: z.ZodArray<z.ZodObject<{
|
|
225
247
|
orgId: z.ZodString;
|
|
@@ -230,9 +252,9 @@ declare const MessageQueueEntry: z.ZodObject<{
|
|
|
230
252
|
reason: z.ZodString;
|
|
231
253
|
resolvedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
232
254
|
resolution: z.ZodNullable<z.ZodEnum<{
|
|
255
|
+
locked: "locked";
|
|
233
256
|
dismissed: "dismissed";
|
|
234
257
|
deleted: "deleted";
|
|
235
|
-
locked: "locked";
|
|
236
258
|
}>>;
|
|
237
259
|
resolvedBy: z.ZodNullable<z.ZodString>;
|
|
238
260
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
@@ -296,6 +318,10 @@ declare const MessageQueue: z.ZodObject<{
|
|
|
296
318
|
}, z.core.$strict>>;
|
|
297
319
|
reactions: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
298
320
|
viewerReaction: z.ZodNullable<z.ZodString>;
|
|
321
|
+
mentions: z.ZodArray<z.ZodObject<{
|
|
322
|
+
orgUserId: z.ZodString;
|
|
323
|
+
name: z.ZodString;
|
|
324
|
+
}, z.core.$strict>>;
|
|
299
325
|
}, z.core.$strict>;
|
|
300
326
|
flags: z.ZodArray<z.ZodObject<{
|
|
301
327
|
orgId: z.ZodString;
|
|
@@ -306,9 +332,9 @@ declare const MessageQueue: z.ZodObject<{
|
|
|
306
332
|
reason: z.ZodString;
|
|
307
333
|
resolvedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
308
334
|
resolution: z.ZodNullable<z.ZodEnum<{
|
|
335
|
+
locked: "locked";
|
|
309
336
|
dismissed: "dismissed";
|
|
310
337
|
deleted: "deleted";
|
|
311
|
-
locked: "locked";
|
|
312
338
|
}>>;
|
|
313
339
|
resolvedBy: z.ZodNullable<z.ZodString>;
|
|
314
340
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
@@ -357,9 +383,6 @@ declare const EditMessage: z.ZodObject<{
|
|
|
357
383
|
declare const MarkRead: z.ZodObject<{
|
|
358
384
|
messageId: z.ZodString;
|
|
359
385
|
}, z.core.$strict>;
|
|
360
|
-
declare const MuteChat: z.ZodObject<{
|
|
361
|
-
until: z.ZodOptional<z.ZodPipe<z.ZodISODateTime, z.ZodCoercedDate<string>>>;
|
|
362
|
-
}, z.core.$strict>;
|
|
363
386
|
declare const OrgUserBody: z.ZodObject<{
|
|
364
387
|
orgUserId: z.ZodString;
|
|
365
388
|
}, z.core.$strict>;
|
|
@@ -382,5 +405,5 @@ declare const BlockParam: z.ZodObject<{
|
|
|
382
405
|
orgUserId: z.ZodString;
|
|
383
406
|
}, z.core.$strip>;
|
|
384
407
|
//#endregion
|
|
385
|
-
export { BlockParam, Chat, ChatIdParam, ChatListItem, ChatsPage, CommunityParam, EditMessage, MarkRead, MessageFlag, MessageIdParam, MessageQueue, MessageQueueEntry, MessageView, MessagesPage,
|
|
408
|
+
export { BlockParam, Chat, ChatIdParam, ChatListItem, ChatsPage, CommunityParam, EditMessage, MarkRead, MessageFlag, MessageIdParam, MessageQueue, MessageQueueEntry, MessageView, MessagesPage, OrgUserBody, ResolveMessageFlags, SendMessage, StartDirectChat, StartGroupChat };
|
|
386
409
|
//# sourceMappingURL=chats.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { paginated } from "./shared.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { chatLastMessageSchema, chatSchema, idSchema, messageFlagResolutionSchema, messageFlagSchema, messageViewSchema } from "@headless-lms/core/schemas";
|
|
3
|
+
import { chatLastMessageSchema, chatSchema, idSchema, messageFlagResolutionSchema, messageFlagSchema, messageViewSchema, subscriptionViewSchema } from "@headless-lms/core/schemas";
|
|
4
4
|
//#region src/http/schemas/chats.ts
|
|
5
5
|
const Chat = chatSchema;
|
|
6
6
|
const MessageFlag = messageFlagSchema;
|
|
@@ -10,8 +10,7 @@ const ChatListItem = z.object({
|
|
|
10
10
|
chat: Chat,
|
|
11
11
|
participantIds: z.array(z.string()),
|
|
12
12
|
lastReadMessageId: z.string().nullable(),
|
|
13
|
-
|
|
14
|
-
mutedUntil: z.coerce.date().nullable(),
|
|
13
|
+
subscription: subscriptionViewSchema.nullable().describe("Your mute on this chat while it applies; null when none"),
|
|
15
14
|
unread: z.number().int(),
|
|
16
15
|
lastMessage: chatLastMessageSchema.nullable()
|
|
17
16
|
});
|
|
@@ -42,7 +41,6 @@ const SendMessage = z.object({
|
|
|
42
41
|
}).strict();
|
|
43
42
|
const EditMessage = z.object({ body: MessageBody }).strict();
|
|
44
43
|
const MarkRead = z.object({ messageId: idSchema.describe("The newest message you have read in this chat") }).strict();
|
|
45
|
-
const MuteChat = z.object({ until: DateTimeInput.optional().describe("When the mute ends. Omit to mute until you unmute") }).strict();
|
|
46
44
|
const OrgUserBody = z.object({ orgUserId: idSchema }).strict();
|
|
47
45
|
const ResolveMessageFlags = z.object({ resolution: messageFlagResolutionSchema.extract(["dismissed"]).describe("`dismissed` closes the open flags and leaves the message up. Deleting the message or locking the chat resolves its flags as `deleted` or `locked` instead.") }).strict();
|
|
48
46
|
const ChatIdParam = z.object({ chatId: z.string() });
|
|
@@ -53,6 +51,6 @@ const BlockParam = z.object({
|
|
|
53
51
|
orgUserId: z.string()
|
|
54
52
|
});
|
|
55
53
|
//#endregion
|
|
56
|
-
export { BlockParam, Chat, ChatIdParam, ChatListItem, ChatsPage, CommunityParam, EditMessage, MarkRead, MessageFlag, MessageIdParam, MessageQueue, MessageQueueEntry, MessageView, MessagesPage,
|
|
54
|
+
export { BlockParam, Chat, ChatIdParam, ChatListItem, ChatsPage, CommunityParam, EditMessage, MarkRead, MessageFlag, MessageIdParam, MessageQueue, MessageQueueEntry, MessageView, MessagesPage, OrgUserBody, ResolveMessageFlags, SendMessage, StartDirectChat, StartGroupChat };
|
|
57
55
|
|
|
58
56
|
//# sourceMappingURL=chats.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chats.js","names":[],"sources":["../../../src/http/schemas/chats.ts"],"sourcesContent":["import { z } from 'zod';\nimport {\n chatLastMessageSchema,\n chatSchema,\n idSchema,\n messageFlagResolutionSchema,\n messageFlagSchema,\n messageViewSchema,\n} from '@headless-lms/core/schemas';\nimport {
|
|
1
|
+
{"version":3,"file":"chats.js","names":[],"sources":["../../../src/http/schemas/chats.ts"],"sourcesContent":["import { z } from 'zod';\nimport {\n chatLastMessageSchema,\n chatSchema,\n idSchema,\n messageFlagResolutionSchema,\n messageFlagSchema,\n messageViewSchema,\n subscriptionViewSchema,\n} from '@headless-lms/core/schemas';\nimport { paginated } from './shared.js';\n\nexport const Chat = chatSchema;\nexport const MessageFlag = messageFlagSchema;\nexport const MessageView = messageViewSchema;\nexport const MessagesPage = paginated(MessageView);\n\nexport const ChatListItem = z.object({\n chat: Chat,\n participantIds: z.array(z.string()),\n lastReadMessageId: z.string().nullable(),\n subscription: subscriptionViewSchema\n .nullable()\n .describe('Your mute on this chat while it applies; null when none'),\n unread: z.number().int(),\n lastMessage: chatLastMessageSchema.nullable(),\n});\nexport const ChatsPage = paginated(ChatListItem);\n\nexport const MessageQueueEntry = z.object({\n message: MessageView,\n flags: z.array(MessageFlag),\n chat: Chat,\n participantIds: z.array(z.string()),\n});\n\nexport const MessageQueue = z.object({\n entries: z.array(MessageQueueEntry),\n});\n\nconst MessageBody = z.string().trim().min(1).max(10_000);\nconst Attachments = z\n .array(idSchema)\n .max(10)\n .default([])\n .describe('Up to 10 finalized images you uploaded through `requestMemberUpload`');\n\nexport const StartDirectChat = z\n .object({\n communityId: idSchema,\n orgUserId: idSchema.describe('The person to talk to'),\n body: MessageBody.nullable().describe(\n 'The first message. Null opens the chat without one; a new chat that starts as a message request needs one, and attachments need one.',\n ),\n assetIds: Attachments,\n })\n .strict();\n\nexport const StartGroupChat = z\n .object({\n communityId: idSchema,\n orgUserIds: z\n .array(idSchema)\n .min(2)\n .max(99)\n .describe(\n \"The people to add besides you. The chat may not exceed the community's group size.\",\n ),\n })\n .strict();\n\nexport const SendMessage = z\n .object({\n body: MessageBody,\n replyToId: idSchema\n .nullable()\n .default(null)\n .describe('A message in the same chat this one answers'),\n assetIds: Attachments,\n })\n .strict();\n\nexport const EditMessage = z.object({ body: MessageBody }).strict();\nexport const MarkRead = z\n .object({ messageId: idSchema.describe('The newest message you have read in this chat') })\n .strict();\nexport const OrgUserBody = z.object({ orgUserId: idSchema }).strict();\nexport const ResolveMessageFlags = z\n .object({\n resolution: messageFlagResolutionSchema\n .extract(['dismissed'])\n .describe(\n '`dismissed` closes the open flags and leaves the message up. Deleting the message or locking the chat resolves its flags as `deleted` or `locked` instead.',\n ),\n })\n .strict();\n\nexport const ChatIdParam = z.object({ chatId: z.string() });\nexport const MessageIdParam = z.object({ messageId: z.string() });\nexport const CommunityParam = z.object({ communityId: z.string() });\nexport const BlockParam = z.object({ communityId: z.string(), orgUserId: z.string() });\n"],"mappings":";;;;AAYA,MAAa,OAAO;AACpB,MAAa,cAAc;AAC3B,MAAa,cAAc;AAC3B,MAAa,eAAe,UAAU,WAAW;AAEjD,MAAa,eAAe,EAAE,OAAO;CACnC,MAAM;CACN,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC;CAClC,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;CACvC,cAAc,uBACX,SAAS,CAAC,CACV,SAAS,yDAAyD;CACrE,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI;CACvB,aAAa,sBAAsB,SAAS;AAC9C,CAAC;AACD,MAAa,YAAY,UAAU,YAAY;AAE/C,MAAa,oBAAoB,EAAE,OAAO;CACxC,SAAS;CACT,OAAO,EAAE,MAAM,WAAW;CAC1B,MAAM;CACN,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC;AACpC,CAAC;AAED,MAAa,eAAe,EAAE,OAAO,EACnC,SAAS,EAAE,MAAM,iBAAiB,EACpC,CAAC;AAED,MAAM,cAAc,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM;AACvD,MAAM,cAAc,EACjB,MAAM,QAAQ,CAAC,CACf,IAAI,EAAE,CAAC,CACP,QAAQ,CAAC,CAAC,CAAC,CACX,SAAS,sEAAsE;AAElF,MAAa,kBAAkB,EAC5B,OAAO;CACN,aAAa;CACb,WAAW,SAAS,SAAS,uBAAuB;CACpD,MAAM,YAAY,SAAS,CAAC,CAAC,SAC3B,sIACF;CACA,UAAU;AACZ,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,iBAAiB,EAC3B,OAAO;CACN,aAAa;CACb,YAAY,EACT,MAAM,QAAQ,CAAC,CACf,IAAI,CAAC,CAAC,CACN,IAAI,EAAE,CAAC,CACP,SACC,oFACF;AACJ,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,cAAc,EACxB,OAAO;CACN,MAAM;CACN,WAAW,SACR,SAAS,CAAC,CACV,QAAQ,IAAI,CAAC,CACb,SAAS,6CAA6C;CACzD,UAAU;AACZ,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,cAAc,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,OAAO;AAClE,MAAa,WAAW,EACrB,OAAO,EAAE,WAAW,SAAS,SAAS,+CAA+C,EAAE,CAAC,CAAC,CACzF,OAAO;AACV,MAAa,cAAc,EAAE,OAAO,EAAE,WAAW,SAAS,CAAC,CAAC,CAAC,OAAO;AACpE,MAAa,sBAAsB,EAChC,OAAO,EACN,YAAY,4BACT,QAAQ,CAAC,WAAW,CAAC,CAAC,CACtB,SACC,4JACF,EACJ,CAAC,CAAC,CACD,OAAO;AAEV,MAAa,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC1D,MAAa,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAChE,MAAa,iBAAiB,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;AAClE,MAAa,aAAa,EAAE,OAAO;CAAE,aAAa,EAAE,OAAO;CAAG,WAAW,EAAE,OAAO;AAAE,CAAC"}
|
|
@@ -22,6 +22,15 @@ declare const Community: z.ZodObject<{
|
|
|
22
22
|
groupChats: z.ZodBoolean;
|
|
23
23
|
groupSize: z.ZodNumber;
|
|
24
24
|
}, z.core.$strict>;
|
|
25
|
+
digest: z.ZodNullable<z.ZodObject<{
|
|
26
|
+
cadence: z.ZodEnum<{
|
|
27
|
+
daily: "daily";
|
|
28
|
+
weekly: "weekly";
|
|
29
|
+
}>;
|
|
30
|
+
weekday: z.ZodNumber;
|
|
31
|
+
hour: z.ZodNumber;
|
|
32
|
+
timeZone: z.ZodString;
|
|
33
|
+
}, z.core.$strict>>;
|
|
25
34
|
}, z.core.$strict>;
|
|
26
35
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
27
36
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
@@ -60,6 +69,15 @@ declare const CommunitiesPage: z.ZodObject<{
|
|
|
60
69
|
groupChats: z.ZodBoolean;
|
|
61
70
|
groupSize: z.ZodNumber;
|
|
62
71
|
}, z.core.$strict>;
|
|
72
|
+
digest: z.ZodNullable<z.ZodObject<{
|
|
73
|
+
cadence: z.ZodEnum<{
|
|
74
|
+
daily: "daily";
|
|
75
|
+
weekly: "weekly";
|
|
76
|
+
}>;
|
|
77
|
+
weekday: z.ZodNumber;
|
|
78
|
+
hour: z.ZodNumber;
|
|
79
|
+
timeZone: z.ZodString;
|
|
80
|
+
}, z.core.$strict>>;
|
|
63
81
|
}, z.core.$strict>;
|
|
64
82
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
65
83
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
@@ -91,6 +109,24 @@ declare const PatchDmSettings: z.ZodObject<{
|
|
|
91
109
|
groupChats: z.ZodOptional<z.ZodBoolean>;
|
|
92
110
|
groupSize: z.ZodOptional<z.ZodNumber>;
|
|
93
111
|
}, z.core.$strict>;
|
|
112
|
+
declare const PatchCommunitySettings: z.ZodObject<{
|
|
113
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
114
|
+
memberToMember: z.ZodOptional<z.ZodBoolean>;
|
|
115
|
+
memberToStaff: z.ZodOptional<z.ZodBoolean>;
|
|
116
|
+
staffToAnyone: z.ZodOptional<z.ZodBoolean>;
|
|
117
|
+
firstMessageIsRequest: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
groupChats: z.ZodOptional<z.ZodBoolean>;
|
|
119
|
+
groupSize: z.ZodOptional<z.ZodNumber>;
|
|
120
|
+
digest: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
121
|
+
cadence: z.ZodEnum<{
|
|
122
|
+
daily: "daily";
|
|
123
|
+
weekly: "weekly";
|
|
124
|
+
}>;
|
|
125
|
+
weekday: z.ZodNumber;
|
|
126
|
+
hour: z.ZodNumber;
|
|
127
|
+
timeZone: z.ZodString;
|
|
128
|
+
}, z.core.$strict>>>;
|
|
129
|
+
}, z.core.$strict>;
|
|
94
130
|
declare const DmSettings: z.ZodObject<{
|
|
95
131
|
enabled: z.ZodBoolean;
|
|
96
132
|
memberToMember: z.ZodBoolean;
|
|
@@ -146,9 +182,9 @@ declare const SpaceMember: z.ZodObject<{
|
|
|
146
182
|
spaceId: z.ZodString;
|
|
147
183
|
orgUserId: z.ZodString;
|
|
148
184
|
status: z.ZodEnum<{
|
|
149
|
-
requested: "requested";
|
|
150
|
-
invited: "invited";
|
|
151
185
|
active: "active";
|
|
186
|
+
invited: "invited";
|
|
187
|
+
requested: "requested";
|
|
152
188
|
revoked: "revoked";
|
|
153
189
|
}>;
|
|
154
190
|
source: z.ZodEnum<{
|
|
@@ -167,9 +203,9 @@ declare const SpaceMembersPage: z.ZodObject<{
|
|
|
167
203
|
spaceId: z.ZodString;
|
|
168
204
|
orgUserId: z.ZodString;
|
|
169
205
|
status: z.ZodEnum<{
|
|
170
|
-
requested: "requested";
|
|
171
|
-
invited: "invited";
|
|
172
206
|
active: "active";
|
|
207
|
+
invited: "invited";
|
|
208
|
+
requested: "requested";
|
|
173
209
|
revoked: "revoked";
|
|
174
210
|
}>;
|
|
175
211
|
source: z.ZodEnum<{
|
|
@@ -233,6 +269,9 @@ declare const CommunitySpaceParam: z.ZodObject<{
|
|
|
233
269
|
communityId: z.ZodString;
|
|
234
270
|
spaceId: z.ZodString;
|
|
235
271
|
}, z.core.$strip>;
|
|
272
|
+
declare const SpaceIdParam: z.ZodObject<{
|
|
273
|
+
spaceId: z.ZodString;
|
|
274
|
+
}, z.core.$strip>;
|
|
236
275
|
declare const SpaceLinkParam: z.ZodObject<{
|
|
237
276
|
communityId: z.ZodString;
|
|
238
277
|
spaceId: z.ZodString;
|
|
@@ -335,10 +374,10 @@ declare const LockedCommunitySpace: z.ZodObject<{
|
|
|
335
374
|
by_invite: "by_invite";
|
|
336
375
|
}>;
|
|
337
376
|
standing: z.ZodEnum<{
|
|
338
|
-
|
|
377
|
+
invited: "invited";
|
|
339
378
|
member: "member";
|
|
379
|
+
open: "open";
|
|
340
380
|
requested: "requested";
|
|
341
|
-
invited: "invited";
|
|
342
381
|
full: "full";
|
|
343
382
|
none: "none";
|
|
344
383
|
}>;
|
|
@@ -354,10 +393,10 @@ declare const OpenCommunitySpace: z.ZodObject<{
|
|
|
354
393
|
by_invite: "by_invite";
|
|
355
394
|
}>;
|
|
356
395
|
standing: z.ZodEnum<{
|
|
357
|
-
|
|
396
|
+
invited: "invited";
|
|
358
397
|
member: "member";
|
|
398
|
+
open: "open";
|
|
359
399
|
requested: "requested";
|
|
360
|
-
invited: "invited";
|
|
361
400
|
full: "full";
|
|
362
401
|
none: "none";
|
|
363
402
|
}>;
|
|
@@ -383,6 +422,13 @@ declare const OpenCommunitySpace: z.ZodObject<{
|
|
|
383
422
|
}>;
|
|
384
423
|
title: z.ZodString;
|
|
385
424
|
}, z.core.$strip>>;
|
|
425
|
+
subscription: z.ZodNullable<z.ZodObject<{
|
|
426
|
+
state: z.ZodEnum<{
|
|
427
|
+
following: "following";
|
|
428
|
+
muted: "muted";
|
|
429
|
+
}>;
|
|
430
|
+
mutedUntil: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
431
|
+
}, z.core.$strict>>;
|
|
386
432
|
}, z.core.$strip>;
|
|
387
433
|
declare const CommunityHomeSpace: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
388
434
|
id: z.ZodString;
|
|
@@ -394,10 +440,10 @@ declare const CommunityHomeSpace: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
394
440
|
by_invite: "by_invite";
|
|
395
441
|
}>;
|
|
396
442
|
standing: z.ZodEnum<{
|
|
397
|
-
|
|
443
|
+
invited: "invited";
|
|
398
444
|
member: "member";
|
|
445
|
+
open: "open";
|
|
399
446
|
requested: "requested";
|
|
400
|
-
invited: "invited";
|
|
401
447
|
full: "full";
|
|
402
448
|
none: "none";
|
|
403
449
|
}>;
|
|
@@ -412,10 +458,10 @@ declare const CommunityHomeSpace: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
412
458
|
by_invite: "by_invite";
|
|
413
459
|
}>;
|
|
414
460
|
standing: z.ZodEnum<{
|
|
415
|
-
|
|
461
|
+
invited: "invited";
|
|
416
462
|
member: "member";
|
|
463
|
+
open: "open";
|
|
417
464
|
requested: "requested";
|
|
418
|
-
invited: "invited";
|
|
419
465
|
full: "full";
|
|
420
466
|
none: "none";
|
|
421
467
|
}>;
|
|
@@ -441,6 +487,13 @@ declare const CommunityHomeSpace: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
441
487
|
}>;
|
|
442
488
|
title: z.ZodString;
|
|
443
489
|
}, z.core.$strip>>;
|
|
490
|
+
subscription: z.ZodNullable<z.ZodObject<{
|
|
491
|
+
state: z.ZodEnum<{
|
|
492
|
+
following: "following";
|
|
493
|
+
muted: "muted";
|
|
494
|
+
}>;
|
|
495
|
+
mutedUntil: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
496
|
+
}, z.core.$strict>>;
|
|
444
497
|
}, z.core.$strip>], "locked">;
|
|
445
498
|
declare const CommunityHome: z.ZodObject<{
|
|
446
499
|
communityId: z.ZodString;
|
|
@@ -466,10 +519,10 @@ declare const CommunityHome: z.ZodObject<{
|
|
|
466
519
|
by_invite: "by_invite";
|
|
467
520
|
}>;
|
|
468
521
|
standing: z.ZodEnum<{
|
|
469
|
-
|
|
522
|
+
invited: "invited";
|
|
470
523
|
member: "member";
|
|
524
|
+
open: "open";
|
|
471
525
|
requested: "requested";
|
|
472
|
-
invited: "invited";
|
|
473
526
|
full: "full";
|
|
474
527
|
none: "none";
|
|
475
528
|
}>;
|
|
@@ -484,10 +537,10 @@ declare const CommunityHome: z.ZodObject<{
|
|
|
484
537
|
by_invite: "by_invite";
|
|
485
538
|
}>;
|
|
486
539
|
standing: z.ZodEnum<{
|
|
487
|
-
|
|
540
|
+
invited: "invited";
|
|
488
541
|
member: "member";
|
|
542
|
+
open: "open";
|
|
489
543
|
requested: "requested";
|
|
490
|
-
invited: "invited";
|
|
491
544
|
full: "full";
|
|
492
545
|
none: "none";
|
|
493
546
|
}>;
|
|
@@ -513,6 +566,13 @@ declare const CommunityHome: z.ZodObject<{
|
|
|
513
566
|
}>;
|
|
514
567
|
title: z.ZodString;
|
|
515
568
|
}, z.core.$strip>>;
|
|
569
|
+
subscription: z.ZodNullable<z.ZodObject<{
|
|
570
|
+
state: z.ZodEnum<{
|
|
571
|
+
following: "following";
|
|
572
|
+
muted: "muted";
|
|
573
|
+
}>;
|
|
574
|
+
mutedUntil: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
575
|
+
}, z.core.$strict>>;
|
|
516
576
|
}, z.core.$strip>], "locked">>;
|
|
517
577
|
}, z.core.$strip>;
|
|
518
578
|
declare const CommunityAnalytics: z.ZodObject<{
|
|
@@ -533,5 +593,5 @@ declare const CommunityAnalytics: z.ZodObject<{
|
|
|
533
593
|
grantsRenewed: z.ZodNumber;
|
|
534
594
|
}, z.core.$strip>;
|
|
535
595
|
//#endregion
|
|
536
|
-
export { CommunitiesPage, CommunitiesQuery, Community, CommunityAnalytics, CommunityChatParam, CommunityCommentParam, CommunityHome, CommunityHomeSpace, CommunityIdParam, CommunityMember, CommunityMembersPage, CommunityMembersQuery, CommunityMessageParam, CommunityPostParam, CommunitySpaceParam, CreateCommunity, CreateSpace, DirectoryEntry, DirectoryPage, DirectoryQuery, DmSettings, LockedCommunitySpace, OpenCommunitySpace, OrderedIds, PatchDmSettings, SetSpaceTopics, SpaceDetail, SpaceLinkBody, SpaceLinkParam, SpaceMember, SpaceMemberParam, SpaceMembersPage, UpdateCommunity, UpdateSpace };
|
|
596
|
+
export { CommunitiesPage, CommunitiesQuery, Community, CommunityAnalytics, CommunityChatParam, CommunityCommentParam, CommunityHome, CommunityHomeSpace, CommunityIdParam, CommunityMember, CommunityMembersPage, CommunityMembersQuery, CommunityMessageParam, CommunityPostParam, CommunitySpaceParam, CreateCommunity, CreateSpace, DirectoryEntry, DirectoryPage, DirectoryQuery, DmSettings, LockedCommunitySpace, OpenCommunitySpace, OrderedIds, PatchCommunitySettings, PatchDmSettings, SetSpaceTopics, SpaceDetail, SpaceIdParam, SpaceLinkBody, SpaceLinkParam, SpaceMember, SpaceMemberParam, SpaceMembersPage, UpdateCommunity, UpdateSpace };
|
|
537
597
|
//# sourceMappingURL=community.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ListQuery, OrgUserProfileSchema, PageQuery, paginated } from "./shared.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { communityStatusSchema, communityViewSchema, createCommunityInputSchema, createSpaceInputSchema, dmSettingsSchema, idSchema, patchDmSettingsInputSchema, roleSchema, setSpaceTopicsInputSchema, spaceDetailSchema, spaceMemberSchema, updateCommunityInputSchema, updateSpaceInputSchema } from "@headless-lms/core/schemas";
|
|
3
|
+
import { communityStatusSchema, communityViewSchema, createCommunityInputSchema, createSpaceInputSchema, dmSettingsSchema, idSchema, patchCommunitySettingsInputSchema, patchDmSettingsInputSchema, roleSchema, setSpaceTopicsInputSchema, spaceDetailSchema, spaceMemberSchema, subscriptionViewSchema, updateCommunityInputSchema, updateSpaceInputSchema } from "@headless-lms/core/schemas";
|
|
4
4
|
//#region src/http/schemas/community.ts
|
|
5
5
|
const Community = communityViewSchema;
|
|
6
6
|
const CommunitiesQuery = ListQuery.extend({ status: communityStatusSchema.optional() });
|
|
@@ -8,6 +8,7 @@ const CommunitiesPage = paginated(Community);
|
|
|
8
8
|
const CreateCommunity = createCommunityInputSchema;
|
|
9
9
|
const UpdateCommunity = updateCommunityInputSchema;
|
|
10
10
|
const PatchDmSettings = patchDmSettingsInputSchema;
|
|
11
|
+
const PatchCommunitySettings = patchCommunitySettingsInputSchema;
|
|
11
12
|
const DmSettings = dmSettingsSchema;
|
|
12
13
|
const SpaceDetail = spaceDetailSchema;
|
|
13
14
|
const SpaceMember = spaceMemberSchema;
|
|
@@ -22,6 +23,7 @@ const CommunitySpaceParam = z.object({
|
|
|
22
23
|
communityId: z.string(),
|
|
23
24
|
spaceId: z.string()
|
|
24
25
|
});
|
|
26
|
+
const SpaceIdParam = z.object({ spaceId: z.string() });
|
|
25
27
|
const SpaceLinkParam = CommunitySpaceParam.extend({ linkId: z.string() });
|
|
26
28
|
const SpaceMemberParam = CommunitySpaceParam.extend({ orgUserId: z.string() });
|
|
27
29
|
const CommunityPostParam = z.object({
|
|
@@ -95,7 +97,8 @@ const OpenCommunitySpace = CommunityHomeSpaceBase.extend({
|
|
|
95
97
|
"community"
|
|
96
98
|
]),
|
|
97
99
|
title: z.string()
|
|
98
|
-
})).describe("Linked content that is published; staff also see unpublished targets")
|
|
100
|
+
})).describe("Linked content that is published; staff also see unpublished targets"),
|
|
101
|
+
subscription: subscriptionViewSchema.nullable().describe("Your mute on this space while it applies; null when none")
|
|
99
102
|
});
|
|
100
103
|
const CommunityHomeSpace = z.discriminatedUnion("locked", [LockedCommunitySpace, OpenCommunitySpace]).describe("A space as the viewer sees it. A by-invite space the viewer is not invited to or a member of is never served");
|
|
101
104
|
const CommunityHome = z.object({
|
|
@@ -124,6 +127,6 @@ const CommunityAnalytics = z.object({
|
|
|
124
127
|
grantsRenewed: z.number().int()
|
|
125
128
|
});
|
|
126
129
|
//#endregion
|
|
127
|
-
export { CommunitiesPage, CommunitiesQuery, Community, CommunityAnalytics, CommunityChatParam, CommunityCommentParam, CommunityHome, CommunityHomeSpace, CommunityIdParam, CommunityMember, CommunityMembersPage, CommunityMembersQuery, CommunityMessageParam, CommunityPostParam, CommunitySpaceParam, CreateCommunity, CreateSpace, DirectoryEntry, DirectoryPage, DirectoryQuery, DmSettings, LockedCommunitySpace, OpenCommunitySpace, OrderedIds, PatchDmSettings, SetSpaceTopics, SpaceDetail, SpaceLinkBody, SpaceLinkParam, SpaceMember, SpaceMemberParam, SpaceMembersPage, UpdateCommunity, UpdateSpace };
|
|
130
|
+
export { CommunitiesPage, CommunitiesQuery, Community, CommunityAnalytics, CommunityChatParam, CommunityCommentParam, CommunityHome, CommunityHomeSpace, CommunityIdParam, CommunityMember, CommunityMembersPage, CommunityMembersQuery, CommunityMessageParam, CommunityPostParam, CommunitySpaceParam, CreateCommunity, CreateSpace, DirectoryEntry, DirectoryPage, DirectoryQuery, DmSettings, LockedCommunitySpace, OpenCommunitySpace, OrderedIds, PatchCommunitySettings, PatchDmSettings, SetSpaceTopics, SpaceDetail, SpaceIdParam, SpaceLinkBody, SpaceLinkParam, SpaceMember, SpaceMemberParam, SpaceMembersPage, UpdateCommunity, UpdateSpace };
|
|
128
131
|
|
|
129
132
|
//# sourceMappingURL=community.js.map
|