@headless-lms/server 0.4.0 → 0.5.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/README.md +14 -0
- package/dist/app/community-mail.d.ts +5 -3
- package/dist/app/community-mail.js +60 -12
- package/dist/app/community-mail.js.map +1 -1
- package/dist/app/container.d.ts +24 -3
- package/dist/app/container.js +102 -38
- package/dist/app/container.js.map +1 -1
- package/dist/app/notification-channels.js +1 -0
- package/dist/app/notification-channels.js.map +1 -1
- package/dist/app/notification-reads.d.ts +3 -3
- package/dist/app/notification-reads.js +7 -28
- package/dist/app/notification-reads.js.map +1 -1
- package/dist/app/platform.d.ts +14 -0
- package/dist/app/platform.js +14 -0
- package/dist/app/platform.js.map +1 -0
- package/dist/http/config.d.ts +4 -0
- package/dist/http/errors.js +9 -4
- package/dist/http/errors.js.map +1 -1
- package/dist/http/fastify.d.ts +8 -0
- package/dist/http/mcp/catalogue.d.ts +11 -9
- package/dist/http/mcp/catalogue.js +15 -21
- package/dist/http/mcp/catalogue.js.map +1 -1
- package/dist/http/mcp/challenge.js +3 -3
- package/dist/http/mcp/challenge.js.map +1 -1
- package/dist/http/mcp/route.js +7 -7
- package/dist/http/mcp/route.js.map +1 -1
- package/dist/http/mcp/test-support.d.ts +6 -5
- package/dist/http/mcp/test-support.js +32 -11
- package/dist/http/mcp/test-support.js.map +1 -1
- package/dist/http/mcp/tool.d.ts +3 -9
- package/dist/http/mcp/tool.js +14 -6
- package/dist/http/mcp/tool.js.map +1 -1
- package/dist/http/mcp/tools/automations.js +10 -20
- package/dist/http/mcp/tools/automations.js.map +1 -1
- package/dist/http/mcp/tools/catalog.js +25 -42
- package/dist/http/mcp/tools/catalog.js.map +1 -1
- package/dist/http/mcp/tools/comments.js +9 -19
- package/dist/http/mcp/tools/comments.js.map +1 -1
- package/dist/http/mcp/tools/communities.js +16 -31
- package/dist/http/mcp/tools/communities.js.map +1 -1
- package/dist/http/mcp/tools/community-members.js +9 -16
- package/dist/http/mcp/tools/community-members.js.map +1 -1
- package/dist/http/mcp/tools/community-moderation.js +13 -25
- package/dist/http/mcp/tools/community-moderation.js.map +1 -1
- package/dist/http/mcp/tools/courses.js +11 -21
- package/dist/http/mcp/tools/courses.js.map +1 -1
- package/dist/http/mcp/tools/events.d.ts +6 -0
- package/dist/http/mcp/tools/events.js +170 -0
- package/dist/http/mcp/tools/events.js.map +1 -0
- package/dist/http/mcp/tools/index.d.ts +5 -1
- package/dist/http/mcp/tools/index.js +45 -10
- package/dist/http/mcp/tools/index.js.map +1 -1
- package/dist/http/mcp/tools/organization.d.ts +6 -0
- package/dist/http/mcp/tools/organization.js +214 -0
- package/dist/http/mcp/tools/organization.js.map +1 -0
- package/dist/http/mcp/tools/people.js +30 -49
- package/dist/http/mcp/tools/people.js.map +1 -1
- package/dist/http/plugins/auth.js +37 -8
- package/dist/http/plugins/auth.js.map +1 -1
- package/dist/http/plugins/error-handler.d.ts +5 -1
- package/dist/http/plugins/error-handler.js +10 -2
- package/dist/http/plugins/error-handler.js.map +1 -1
- package/dist/http/plugins/openapi.js +18 -2
- package/dist/http/plugins/openapi.js.map +1 -1
- package/dist/http/plugins/platform.d.ts +7 -0
- package/dist/http/plugins/platform.js +13 -0
- package/dist/http/plugins/platform.js.map +1 -0
- package/dist/http/routes/access.js +54 -36
- package/dist/http/routes/access.js.map +1 -1
- package/dist/http/routes/activities.js +45 -45
- package/dist/http/routes/activities.js.map +1 -1
- package/dist/http/routes/assets.js +30 -65
- package/dist/http/routes/assets.js.map +1 -1
- package/dist/http/routes/automations.js +37 -42
- package/dist/http/routes/automations.js.map +1 -1
- package/dist/http/routes/bundles.js +33 -36
- package/dist/http/routes/bundles.js.map +1 -1
- package/dist/http/routes/communities.js +93 -145
- package/dist/http/routes/communities.js.map +1 -1
- package/dist/http/routes/community-moderation.js +83 -137
- package/dist/http/routes/community-moderation.js.map +1 -1
- package/dist/http/routes/course-analytics.js +32 -15
- package/dist/http/routes/course-analytics.js.map +1 -1
- package/dist/http/routes/courses.js +25 -32
- package/dist/http/routes/courses.js.map +1 -1
- package/dist/http/routes/dashboard.js +9 -9
- package/dist/http/routes/dashboard.js.map +1 -1
- package/dist/http/routes/discussion.js +21 -39
- package/dist/http/routes/discussion.js.map +1 -1
- package/dist/http/routes/downloads.js +41 -47
- package/dist/http/routes/downloads.js.map +1 -1
- package/dist/http/routes/entitlements.js +19 -23
- package/dist/http/routes/entitlements.js.map +1 -1
- package/dist/http/routes/events.d.ts +7 -0
- package/dist/http/routes/events.js +333 -0
- package/dist/http/routes/events.js.map +1 -0
- package/dist/http/routes/integrations.js +40 -73
- package/dist/http/routes/integrations.js.map +1 -1
- package/dist/http/routes/member/assets.js +10 -13
- package/dist/http/routes/member/assets.js.map +1 -1
- package/dist/http/routes/member/chats.js +170 -47
- package/dist/http/routes/member/chats.js.map +1 -1
- package/dist/http/routes/member/comments.js +65 -26
- package/dist/http/routes/member/comments.js.map +1 -1
- package/dist/http/routes/member/community.js +45 -52
- package/dist/http/routes/member/community.js.map +1 -1
- package/dist/http/routes/member/courses.js +12 -19
- package/dist/http/routes/member/courses.js.map +1 -1
- package/dist/http/routes/member/devices.js +9 -10
- package/dist/http/routes/member/devices.js.map +1 -1
- package/dist/http/routes/member/downloads.js +6 -9
- package/dist/http/routes/member/downloads.js.map +1 -1
- package/dist/http/routes/member/events.d.ts +7 -0
- package/dist/http/routes/member/events.js +386 -0
- package/dist/http/routes/member/events.js.map +1 -0
- package/dist/http/routes/member/files.js +71 -46
- package/dist/http/routes/member/files.js.map +1 -1
- package/dist/http/routes/member/index.js +2 -0
- package/dist/http/routes/member/index.js.map +1 -1
- package/dist/http/routes/member/notification-settings.js +15 -23
- package/dist/http/routes/member/notification-settings.js.map +1 -1
- package/dist/http/routes/member/notifications.js +16 -16
- package/dist/http/routes/member/notifications.js.map +1 -1
- package/dist/http/routes/member/org.js +5 -15
- package/dist/http/routes/member/org.js.map +1 -1
- package/dist/http/routes/member/posts.js +67 -68
- package/dist/http/routes/member/posts.js.map +1 -1
- package/dist/http/routes/member/profile.js +15 -6
- package/dist/http/routes/member/profile.js.map +1 -1
- package/dist/http/routes/member/progress.js +7 -11
- package/dist/http/routes/member/progress.js.map +1 -1
- package/dist/http/routes/organizations.js +319 -135
- package/dist/http/routes/organizations.js.map +1 -1
- package/dist/http/routes/platform.d.ts +7 -0
- package/dist/http/routes/platform.js +61 -0
- package/dist/http/routes/platform.js.map +1 -0
- package/dist/http/routes/students.js +12 -75
- package/dist/http/routes/students.js.map +1 -1
- package/dist/http/routes/webhooks.js +30 -39
- package/dist/http/routes/webhooks.js.map +1 -1
- package/dist/http/routes.js +9 -0
- package/dist/http/routes.js.map +1 -1
- package/dist/http/schemas/access.d.ts +346 -64
- package/dist/http/schemas/access.js +39 -12
- package/dist/http/schemas/access.js.map +1 -1
- package/dist/http/schemas/assets.d.ts +19 -14
- package/dist/http/schemas/assets.js +6 -5
- package/dist/http/schemas/assets.js.map +1 -1
- package/dist/http/schemas/automations.d.ts +4 -4
- package/dist/http/schemas/chats.d.ts +211 -32
- package/dist/http/schemas/chats.js +13 -4
- package/dist/http/schemas/chats.js.map +1 -1
- package/dist/http/schemas/community.d.ts +91 -44
- package/dist/http/schemas/community.js +21 -8
- package/dist/http/schemas/community.js.map +1 -1
- package/dist/http/schemas/course-analytics.d.ts +51 -1
- package/dist/http/schemas/course-analytics.js +19 -1
- package/dist/http/schemas/course-analytics.js.map +1 -1
- package/dist/http/schemas/dashboard.d.ts +1 -0
- package/dist/http/schemas/dashboard.js +2 -1
- package/dist/http/schemas/dashboard.js.map +1 -1
- package/dist/http/schemas/discussion.d.ts +22 -72
- package/dist/http/schemas/discussion.js +2 -2
- package/dist/http/schemas/discussion.js.map +1 -1
- package/dist/http/schemas/entitlements.d.ts +9 -12
- package/dist/http/schemas/entitlements.js +11 -5
- package/dist/http/schemas/entitlements.js.map +1 -1
- package/dist/http/schemas/events.d.ts +527 -0
- package/dist/http/schemas/events.js +64 -0
- package/dist/http/schemas/events.js.map +1 -0
- package/dist/http/schemas/files.d.ts +15 -5
- package/dist/http/schemas/files.js +10 -2
- package/dist/http/schemas/files.js.map +1 -1
- package/dist/http/schemas/index.d.ts +11 -9
- package/dist/http/schemas/index.js +11 -9
- package/dist/http/schemas/integrations.d.ts +4 -4
- package/dist/http/schemas/invites.d.ts +3 -47
- package/dist/http/schemas/invites.js +4 -25
- package/dist/http/schemas/invites.js.map +1 -1
- package/dist/http/schemas/member.d.ts +94 -7
- package/dist/http/schemas/member.js +7 -3
- package/dist/http/schemas/member.js.map +1 -1
- package/dist/http/schemas/members.d.ts +333 -69
- package/dist/http/schemas/members.js +67 -25
- package/dist/http/schemas/members.js.map +1 -1
- package/dist/http/schemas/notifications.d.ts +57 -53
- package/dist/http/schemas/platform.d.ts +37 -0
- package/dist/http/schemas/platform.js +19 -0
- package/dist/http/schemas/platform.js.map +1 -0
- package/dist/http/schemas/posts.d.ts +55 -35
- package/dist/http/schemas/posts.js +4 -4
- package/dist/http/schemas/posts.js.map +1 -1
- package/dist/http/schemas/profile.d.ts +1 -1
- package/dist/http/schemas/shared.d.ts +1 -11
- package/dist/http/schemas/shared.js +1 -10
- package/dist/http/schemas/shared.js.map +1 -1
- package/dist/http/schemas/students.d.ts +25 -3
- package/dist/http/schemas/students.js +3 -1
- package/dist/http/schemas/students.js.map +1 -1
- package/dist/http/scope.d.ts +9 -13
- package/dist/http/scope.js +29 -40
- package/dist/http/scope.js.map +1 -1
- package/dist/http/server.js +9 -0
- package/dist/http/server.js.map +1 -1
- package/dist/http/shutdown.d.ts +11 -0
- package/dist/http/shutdown.js +40 -0
- package/dist/http/shutdown.js.map +1 -0
- package/dist/http/sse.d.ts +19 -0
- package/dist/http/sse.js +104 -0
- package/dist/http/sse.js.map +1 -0
- package/dist/http/test-caller.d.ts +13 -0
- package/dist/http/test-caller.js +14 -0
- package/dist/http/test-caller.js.map +1 -0
- package/dist/http/well-known.js +2 -2
- package/dist/http/well-known.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/packages/server/package.js +1 -1
- package/package.json +7 -6
- package/dist/http/routes/member/actor.d.ts +0 -14
- package/dist/http/routes/member/actor.js +0 -11
- package/dist/http/routes/member/actor.js.map +0 -1
|
@@ -15,13 +15,8 @@ declare const CommentAuthor: z.ZodObject<{
|
|
|
15
15
|
image: z.ZodNullable<z.ZodString>;
|
|
16
16
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
17
17
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
admin: "admin";
|
|
21
|
-
instructor: "instructor";
|
|
22
|
-
moderator: "moderator";
|
|
23
|
-
student: "student";
|
|
24
|
-
}>;
|
|
18
|
+
team: z.ZodBoolean;
|
|
19
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
25
20
|
}, z.core.$strict>;
|
|
26
21
|
type CommentAuthor = z.infer<typeof CommentAuthor>;
|
|
27
22
|
/** Any single emoji. Open, so widening the picker needs no schema change. */
|
|
@@ -59,13 +54,8 @@ declare const CommentView: z.ZodObject<{
|
|
|
59
54
|
image: z.ZodNullable<z.ZodString>;
|
|
60
55
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
61
56
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
admin: "admin";
|
|
65
|
-
instructor: "instructor";
|
|
66
|
-
moderator: "moderator";
|
|
67
|
-
student: "student";
|
|
68
|
-
}>;
|
|
57
|
+
team: z.ZodBoolean;
|
|
58
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
69
59
|
}, z.core.$strict>;
|
|
70
60
|
body: z.ZodNullable<z.ZodString>;
|
|
71
61
|
status: z.ZodEnum<{
|
|
@@ -82,13 +72,8 @@ declare const CommentView: z.ZodObject<{
|
|
|
82
72
|
image: z.ZodNullable<z.ZodString>;
|
|
83
73
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
84
74
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
admin: "admin";
|
|
88
|
-
instructor: "instructor";
|
|
89
|
-
moderator: "moderator";
|
|
90
|
-
student: "student";
|
|
91
|
-
}>;
|
|
75
|
+
team: z.ZodBoolean;
|
|
76
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
92
77
|
}, z.core.$strict>>;
|
|
93
78
|
reactions: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
94
79
|
viewerReaction: z.ZodOptional<z.ZodString>;
|
|
@@ -146,13 +131,8 @@ declare const ActivityComments: z.ZodObject<{
|
|
|
146
131
|
image: z.ZodNullable<z.ZodString>;
|
|
147
132
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
148
133
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
admin: "admin";
|
|
152
|
-
instructor: "instructor";
|
|
153
|
-
moderator: "moderator";
|
|
154
|
-
student: "student";
|
|
155
|
-
}>;
|
|
134
|
+
team: z.ZodBoolean;
|
|
135
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
156
136
|
}, z.core.$strict>;
|
|
157
137
|
body: z.ZodNullable<z.ZodString>;
|
|
158
138
|
status: z.ZodEnum<{
|
|
@@ -169,13 +149,8 @@ declare const ActivityComments: z.ZodObject<{
|
|
|
169
149
|
image: z.ZodNullable<z.ZodString>;
|
|
170
150
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
171
151
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
admin: "admin";
|
|
175
|
-
instructor: "instructor";
|
|
176
|
-
moderator: "moderator";
|
|
177
|
-
student: "student";
|
|
178
|
-
}>;
|
|
152
|
+
team: z.ZodBoolean;
|
|
153
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
179
154
|
}, z.core.$strict>>;
|
|
180
155
|
reactions: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
181
156
|
viewerReaction: z.ZodOptional<z.ZodString>;
|
|
@@ -197,7 +172,7 @@ declare const EditComment: z.ZodObject<{
|
|
|
197
172
|
body: z.ZodString;
|
|
198
173
|
}, z.core.$strict>;
|
|
199
174
|
type EditComment = z.infer<typeof EditComment>;
|
|
200
|
-
/** The
|
|
175
|
+
/** The moderator's PATCH writes status and nothing else: publishing covers approving
|
|
201
176
|
* a pending comment and restoring a removed one. Revising the text is the
|
|
202
177
|
* author's own edit, under /api/member. */
|
|
203
178
|
declare const PatchComment: z.ZodObject<{
|
|
@@ -264,19 +239,14 @@ declare const CommentReportSummary: z.ZodObject<{
|
|
|
264
239
|
image: z.ZodNullable<z.ZodString>;
|
|
265
240
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
266
241
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
admin: "admin";
|
|
270
|
-
instructor: "instructor";
|
|
271
|
-
moderator: "moderator";
|
|
272
|
-
student: "student";
|
|
273
|
-
}>;
|
|
242
|
+
team: z.ZodBoolean;
|
|
243
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
274
244
|
}, z.core.$strict>;
|
|
275
245
|
reason: z.ZodString;
|
|
276
246
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
277
247
|
}, z.core.$strict>;
|
|
278
248
|
type CommentReportSummary = z.infer<typeof CommentReportSummary>;
|
|
279
|
-
/** One row of the
|
|
249
|
+
/** One row of the moderation comment list: the comment plus the context a
|
|
280
250
|
* moderation decision needs, so the list needs no follow-up request. */
|
|
281
251
|
declare const CommentListItem: z.ZodObject<{
|
|
282
252
|
id: z.ZodString;
|
|
@@ -299,13 +269,8 @@ declare const CommentListItem: z.ZodObject<{
|
|
|
299
269
|
image: z.ZodNullable<z.ZodString>;
|
|
300
270
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
301
271
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
admin: "admin";
|
|
305
|
-
instructor: "instructor";
|
|
306
|
-
moderator: "moderator";
|
|
307
|
-
student: "student";
|
|
308
|
-
}>;
|
|
272
|
+
team: z.ZodBoolean;
|
|
273
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
309
274
|
}, z.core.$strict>;
|
|
310
275
|
authorEmail: z.ZodEmail;
|
|
311
276
|
removedBy: z.ZodNullable<z.ZodString>;
|
|
@@ -319,13 +284,8 @@ declare const CommentListItem: z.ZodObject<{
|
|
|
319
284
|
image: z.ZodNullable<z.ZodString>;
|
|
320
285
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
321
286
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
admin: "admin";
|
|
325
|
-
instructor: "instructor";
|
|
326
|
-
moderator: "moderator";
|
|
327
|
-
student: "student";
|
|
328
|
-
}>;
|
|
287
|
+
team: z.ZodBoolean;
|
|
288
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
329
289
|
}, z.core.$strict>;
|
|
330
290
|
reason: z.ZodString;
|
|
331
291
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
@@ -372,13 +332,8 @@ declare const CommentsPage: z.ZodObject<{
|
|
|
372
332
|
image: z.ZodNullable<z.ZodString>;
|
|
373
333
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
374
334
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
admin: "admin";
|
|
378
|
-
instructor: "instructor";
|
|
379
|
-
moderator: "moderator";
|
|
380
|
-
student: "student";
|
|
381
|
-
}>;
|
|
335
|
+
team: z.ZodBoolean;
|
|
336
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
382
337
|
}, z.core.$strict>;
|
|
383
338
|
authorEmail: z.ZodEmail;
|
|
384
339
|
removedBy: z.ZodNullable<z.ZodString>;
|
|
@@ -392,13 +347,8 @@ declare const CommentsPage: z.ZodObject<{
|
|
|
392
347
|
image: z.ZodNullable<z.ZodString>;
|
|
393
348
|
imageAssetId: z.ZodNullable<z.ZodString>;
|
|
394
349
|
imageUrl: z.ZodNullable<z.ZodString>;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
admin: "admin";
|
|
398
|
-
instructor: "instructor";
|
|
399
|
-
moderator: "moderator";
|
|
400
|
-
student: "student";
|
|
401
|
-
}>;
|
|
350
|
+
team: z.ZodBoolean;
|
|
351
|
+
roleName: z.ZodNullable<z.ZodString>;
|
|
402
352
|
}, z.core.$strict>;
|
|
403
353
|
reason: z.ZodString;
|
|
404
354
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
@@ -46,7 +46,7 @@ const PostComment = z.object({
|
|
|
46
46
|
parentId: idSchema.nullable().default(null).describe("The comment this replies to. Replies nest one level, under a root comment")
|
|
47
47
|
}).strict();
|
|
48
48
|
const EditComment = z.object({ body: z.string().min(1).max(1e4) }).strict();
|
|
49
|
-
/** The
|
|
49
|
+
/** The moderator's PATCH writes status and nothing else: publishing covers approving
|
|
50
50
|
* a pending comment and restoring a removed one. Revising the text is the
|
|
51
51
|
* author's own edit, under /api/member. */
|
|
52
52
|
const PatchComment = z.object({ status: z.literal("published") });
|
|
@@ -68,7 +68,7 @@ const CommentReport = z.object({
|
|
|
68
68
|
/** An unresolved report on a listed comment. Resolved ones are history and are
|
|
69
69
|
* never served here. */
|
|
70
70
|
const CommentReportSummary = commentReportSummarySchema;
|
|
71
|
-
/** One row of the
|
|
71
|
+
/** One row of the moderation comment list: the comment plus the context a
|
|
72
72
|
* moderation decision needs, so the list needs no follow-up request. */
|
|
73
73
|
const CommentListItem = commentListItemSchema;
|
|
74
74
|
const CommentsQuery = ListQuery.extend({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discussion.js","names":[],"sources":["../../../src/http/schemas/discussion.ts"],"sourcesContent":["// Discussion resource schemas. Comments attach to an activity; settings are\n// per course, with a per-activity override carried on the activity's own\n// settings blob rather than a resource of its own.\n//\n// The author is the org user's profile minus its email — learners read each\n// other's comments and the list must not be a directory of the cohort's\n// addresses. The staff-facing comment list carries `authorEmail` separately.\nimport type { CommentSettings as DomainCommentSettings } from '@headless-lms/core/types';\nimport {\n commentAuthorSchema,\n commentListItemSchema,\n commentReportSummarySchema,\n commentSchema,\n commentFlagResolutionSchema,\n commentStatusSchema,\n commentViewSchema,\n idSchema,\n} from '@headless-lms/core/schemas';\nimport { z } from 'zod';\nimport { DateTimeInput, ListQuery, type Matches, paginated } from './shared.js';\n\nexport const CommentStatus = commentStatusSchema;\nexport type CommentStatus = z.infer<typeof CommentStatus>;\n\nexport const CommentAuthor = commentAuthorSchema;\nexport type CommentAuthor = z.infer<typeof CommentAuthor>;\n\n/** Any single emoji. Open, so widening the picker needs no schema change. */\nexport const ReactionEmoji = z.string().min(1).max(16);\nexport type ReactionEmoji = z.infer<typeof ReactionEmoji>;\n\n/** Counts by emoji; unused ones are absent, so no reactions serves `{}`. */\nexport const ReactionCounts = z.record(z.string(), z.number().int());\nexport type ReactionCounts = z.infer<typeof ReactionCounts>;\n\nconst Following = z\n .object({ state: z.literal('following') })\n .strict()\n .describe('Follow the post: you are notified of its new comments');\nconst Muted = z\n .object({\n state: z.literal('muted'),\n mutedUntil: DateTimeInput.nullable()\n .optional()\n .describe('When the mute ends. Omit or null to mute until you change it'),\n })\n .strict()\n .describe('Mute it: its activity stops notifying you, except mentions and actions on you');\nconst Unsubscribed = z\n .object({ state: z.literal('none') })\n .strict()\n .describe('Neither follow nor mute it');\n\nexport const SetPostSubscription = z.discriminatedUnion('state', [Following, Muted, Unsubscribed]);\nexport const SetMute = z.discriminatedUnion('state', [Muted, Unsubscribed]);\n\nexport const CommentView = commentViewSchema;\nexport type CommentView = z.infer<typeof CommentView>;\n\n/** What a reaction write on a post, message or comment returns, so the client never recomputes a count. */\nexport const Reactions = z.object({\n reactions: ReactionCounts,\n viewerReaction: ReactionEmoji.optional().describe('Absent when you have no reaction'),\n});\nexport type Reactions = z.infer<typeof Reactions>;\n\n/** A course's comment settings. Stored under the course, carried on the course\n * payload as `settings.comments`. */\nexport const CommentSettings = z.object({\n enabled: z.boolean(),\n threaded: z.boolean(),\n requireReview: z.boolean(),\n reactions: z.boolean(),\n});\nexport type CommentSettings = z.infer<typeof CommentSettings>;\ntype _CommentSettingsMatchesDomain = Matches<DomainCommentSettings, CommentSettings> &\n Matches<CommentSettings, DomainCommentSettings>;\n\n/** The course settings with the activity's override applied: `enabled` is the\n * resolved answer for this activity, not the course switch. */\nexport const CommentsConfig = CommentSettings;\nexport type CommentsConfig = z.infer<typeof CommentsConfig>;\n\nexport const ActivityComments = z.object({\n config: CommentsConfig,\n comments: z.array(CommentView),\n});\nexport type ActivityComments = z.infer<typeof ActivityComments>;\n\nexport const PostComment = z\n .object({\n body: z.string().min(1).max(10_000),\n parentId: idSchema\n .nullable()\n .default(null)\n .describe('The comment this replies to. Replies nest one level, under a root comment'),\n })\n .strict();\nexport type PostComment = z.infer<typeof PostComment>;\n\nexport const EditComment = z.object({ body: z.string().min(1).max(10_000) }).strict();\nexport type EditComment = z.infer<typeof EditComment>;\n\n/** The
|
|
1
|
+
{"version":3,"file":"discussion.js","names":[],"sources":["../../../src/http/schemas/discussion.ts"],"sourcesContent":["// Discussion resource schemas. Comments attach to an activity; settings are\n// per course, with a per-activity override carried on the activity's own\n// settings blob rather than a resource of its own.\n//\n// The author is the org user's profile minus its email — learners read each\n// other's comments and the list must not be a directory of the cohort's\n// addresses. The staff-facing comment list carries `authorEmail` separately.\nimport type { CommentSettings as DomainCommentSettings } from '@headless-lms/core/types';\nimport {\n commentAuthorSchema,\n commentListItemSchema,\n commentReportSummarySchema,\n commentSchema,\n commentFlagResolutionSchema,\n commentStatusSchema,\n commentViewSchema,\n idSchema,\n} from '@headless-lms/core/schemas';\nimport { z } from 'zod';\nimport { DateTimeInput, ListQuery, type Matches, paginated } from './shared.js';\n\nexport const CommentStatus = commentStatusSchema;\nexport type CommentStatus = z.infer<typeof CommentStatus>;\n\nexport const CommentAuthor = commentAuthorSchema;\nexport type CommentAuthor = z.infer<typeof CommentAuthor>;\n\n/** Any single emoji. Open, so widening the picker needs no schema change. */\nexport const ReactionEmoji = z.string().min(1).max(16);\nexport type ReactionEmoji = z.infer<typeof ReactionEmoji>;\n\n/** Counts by emoji; unused ones are absent, so no reactions serves `{}`. */\nexport const ReactionCounts = z.record(z.string(), z.number().int());\nexport type ReactionCounts = z.infer<typeof ReactionCounts>;\n\nconst Following = z\n .object({ state: z.literal('following') })\n .strict()\n .describe('Follow the post: you are notified of its new comments');\nconst Muted = z\n .object({\n state: z.literal('muted'),\n mutedUntil: DateTimeInput.nullable()\n .optional()\n .describe('When the mute ends. Omit or null to mute until you change it'),\n })\n .strict()\n .describe('Mute it: its activity stops notifying you, except mentions and actions on you');\nconst Unsubscribed = z\n .object({ state: z.literal('none') })\n .strict()\n .describe('Neither follow nor mute it');\n\nexport const SetPostSubscription = z.discriminatedUnion('state', [Following, Muted, Unsubscribed]);\nexport const SetMute = z.discriminatedUnion('state', [Muted, Unsubscribed]);\n\nexport const CommentView = commentViewSchema;\nexport type CommentView = z.infer<typeof CommentView>;\n\n/** What a reaction write on a post, message or comment returns, so the client never recomputes a count. */\nexport const Reactions = z.object({\n reactions: ReactionCounts,\n viewerReaction: ReactionEmoji.optional().describe('Absent when you have no reaction'),\n});\nexport type Reactions = z.infer<typeof Reactions>;\n\n/** A course's comment settings. Stored under the course, carried on the course\n * payload as `settings.comments`. */\nexport const CommentSettings = z.object({\n enabled: z.boolean(),\n threaded: z.boolean(),\n requireReview: z.boolean(),\n reactions: z.boolean(),\n});\nexport type CommentSettings = z.infer<typeof CommentSettings>;\ntype _CommentSettingsMatchesDomain = Matches<DomainCommentSettings, CommentSettings> &\n Matches<CommentSettings, DomainCommentSettings>;\n\n/** The course settings with the activity's override applied: `enabled` is the\n * resolved answer for this activity, not the course switch. */\nexport const CommentsConfig = CommentSettings;\nexport type CommentsConfig = z.infer<typeof CommentsConfig>;\n\nexport const ActivityComments = z.object({\n config: CommentsConfig,\n comments: z.array(CommentView),\n});\nexport type ActivityComments = z.infer<typeof ActivityComments>;\n\nexport const PostComment = z\n .object({\n body: z.string().min(1).max(10_000),\n parentId: idSchema\n .nullable()\n .default(null)\n .describe('The comment this replies to. Replies nest one level, under a root comment'),\n })\n .strict();\nexport type PostComment = z.infer<typeof PostComment>;\n\nexport const EditComment = z.object({ body: z.string().min(1).max(10_000) }).strict();\nexport type EditComment = z.infer<typeof EditComment>;\n\n/** The moderator's PATCH writes status and nothing else: publishing covers approving\n * a pending comment and restoring a removed one. Revising the text is the\n * author's own edit, under /api/member. */\nexport const PatchComment = z.object({\n status: z.literal('published'),\n});\nexport type PatchComment = z.infer<typeof PatchComment>;\n\n/** Replaces whatever the reader had. Clearing is DELETE, which carries no body. */\nexport const SetReaction = z\n .object({ emoji: ReactionEmoji.describe('Replaces any reaction you already had') })\n .strict();\nexport type SetReaction = z.infer<typeof SetReaction>;\n\nexport const ResolveCommentFlags = z\n .object({\n resolution: commentFlagResolutionSchema\n .extract(['dismissed'])\n .describe(\n '`dismissed` closes the open flags and leaves the comment up. Removing the comment resolves its flags as `removed` instead.',\n ),\n })\n .strict();\nexport type ResolveCommentFlags = z.infer<typeof ResolveCommentFlags>;\n\n/** A moderator's reply, posted from the queue against the comment it answers. */\nexport const ReplyToComment = z.object({\n body: z.string().min(1).max(10_000),\n});\nexport type ReplyToComment = z.infer<typeof ReplyToComment>;\n\nexport const ReportComment = z.object({ reason: z.string().max(1_000).default('') }).strict();\nexport type ReportComment = z.infer<typeof ReportComment>;\n\nexport const Comment = commentSchema;\nexport type Comment = z.infer<typeof Comment>;\n\nexport const CommentReport = z.object({\n id: z.string(),\n commentId: z.string(),\n orgUserId: z.string(),\n reason: z.string(),\n resolvedAt: z.date().nullable(),\n createdAt: z.date(),\n});\nexport type CommentReport = z.infer<typeof CommentReport>;\n\n/** An unresolved report on a listed comment. Resolved ones are history and are\n * never served here. */\nexport const CommentReportSummary = commentReportSummarySchema;\nexport type CommentReportSummary = z.infer<typeof CommentReportSummary>;\n\n/** One row of the moderation comment list: the comment plus the context a\n * moderation decision needs, so the list needs no follow-up request. */\nexport const CommentListItem = commentListItemSchema;\nexport type CommentListItem = z.infer<typeof CommentListItem>;\n\nexport const CommentsQuery = ListQuery.extend({\n status: CommentStatus.optional(),\n /** true = only comments carrying an unresolved report, false = only those\n * carrying none. `z.stringbool` because query values arrive as strings and\n * `z.coerce.boolean()` would read \"false\" as true. */\n reported: z.stringbool().optional(),\n courseId: z.string().optional(),\n activityId: z.string().optional(),\n /** Scope to one author (org_users.id). */\n orgUserId: z.string().optional(),\n});\nexport type CommentsQuery = z.infer<typeof CommentsQuery>;\n\nexport const CommentsPage = paginated(CommentListItem);\nexport type CommentsPage = z.infer<typeof CommentsPage>;\n\nexport const DiscussionActivityParam = z.object({ activityId: z.string() });\nexport type DiscussionActivityParam = z.infer<typeof DiscussionActivityParam>;\n\nexport const CommentIdParam = z.object({ commentId: z.string() });\nexport type CommentIdParam = z.infer<typeof CommentIdParam>;\n"],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ type EntitlementStatus = z.infer<typeof EntitlementStatus>;
|
|
|
9
9
|
declare const ContentType: z.ZodEnum<{
|
|
10
10
|
course: "course";
|
|
11
11
|
download: "download";
|
|
12
|
+
event: "event";
|
|
12
13
|
}>;
|
|
13
14
|
type ContentType = z.infer<typeof ContentType>;
|
|
14
15
|
/** Reference to the granted content: identity + display name (join-derived).
|
|
@@ -18,6 +19,7 @@ declare const ContentRef: z.ZodObject<{
|
|
|
18
19
|
type: z.ZodEnum<{
|
|
19
20
|
course: "course";
|
|
20
21
|
download: "download";
|
|
22
|
+
event: "event";
|
|
21
23
|
}>;
|
|
22
24
|
title: z.ZodString;
|
|
23
25
|
}, z.core.$strip>;
|
|
@@ -55,6 +57,7 @@ declare const EntitlementsQuery: z.ZodObject<{
|
|
|
55
57
|
type: z.ZodOptional<z.ZodEnum<{
|
|
56
58
|
course: "course";
|
|
57
59
|
download: "download";
|
|
60
|
+
event: "event";
|
|
58
61
|
}>>;
|
|
59
62
|
}, z.core.$strip>;
|
|
60
63
|
type EntitlementsQuery = z.infer<typeof EntitlementsQuery>;
|
|
@@ -88,18 +91,12 @@ declare const GrantEntitlement: z.ZodObject<{
|
|
|
88
91
|
expiresAt: z.ZodNullable<z.ZodPipe<z.ZodISODateTime, z.ZodCoercedDate<string>>>;
|
|
89
92
|
}, z.core.$strip>;
|
|
90
93
|
type GrantEntitlement = z.infer<typeof GrantEntitlement>;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
revoked: "revoked";
|
|
96
|
-
}>;
|
|
97
|
-
}, z.core.$strip>;
|
|
98
|
-
type SetEntitlementStatus = z.infer<typeof SetEntitlementStatus>;
|
|
99
|
-
declare const EntitlementIdParam: z.ZodObject<{
|
|
100
|
-
id: z.ZodString;
|
|
94
|
+
declare const RevokeEntitlement: z.ZodObject<{
|
|
95
|
+
orgUserId: z.ZodString;
|
|
96
|
+
contentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
97
|
+
bundleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
101
98
|
}, z.core.$strip>;
|
|
102
|
-
type
|
|
99
|
+
type RevokeEntitlement = z.infer<typeof RevokeEntitlement>;
|
|
103
100
|
//#endregion
|
|
104
|
-
export { ContentRef, ContentType, Entitlement,
|
|
101
|
+
export { ContentRef, ContentType, Entitlement, EntitlementStatus, EntitlementsPage, EntitlementsQuery, GrantEntitlement, RevokeEntitlement };
|
|
105
102
|
//# sourceMappingURL=entitlements.d.ts.map
|
|
@@ -7,7 +7,11 @@ const EntitlementStatus = z.enum([
|
|
|
7
7
|
"expired",
|
|
8
8
|
"revoked"
|
|
9
9
|
]);
|
|
10
|
-
const ContentType = z.enum([
|
|
10
|
+
const ContentType = z.enum([
|
|
11
|
+
"course",
|
|
12
|
+
"download",
|
|
13
|
+
"event"
|
|
14
|
+
]);
|
|
11
15
|
/** Reference to the granted content: identity + display name (join-derived).
|
|
12
16
|
* The full content object lives on its own resource. */
|
|
13
17
|
const ContentRef = z.object({
|
|
@@ -34,10 +38,12 @@ const GrantEntitlement = z.object({
|
|
|
34
38
|
bundleId: idSchema.nullish(),
|
|
35
39
|
expiresAt: DateTimeInput.nullable().describe("When access ends; null never expires")
|
|
36
40
|
}).refine((v) => v.contentId != null !== (v.bundleId != null), { message: "Provide exactly one of contentId or bundleId" });
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
const RevokeEntitlement = z.object({
|
|
42
|
+
orgUserId: idSchema,
|
|
43
|
+
contentId: idSchema.nullish(),
|
|
44
|
+
bundleId: idSchema.nullish()
|
|
45
|
+
}).refine((v) => v.contentId != null !== (v.bundleId != null), { message: "Provide exactly one of contentId or bundleId" });
|
|
40
46
|
//#endregion
|
|
41
|
-
export { ContentRef, ContentType, Entitlement,
|
|
47
|
+
export { ContentRef, ContentType, Entitlement, EntitlementStatus, EntitlementsPage, EntitlementsQuery, GrantEntitlement, RevokeEntitlement };
|
|
42
48
|
|
|
43
49
|
//# sourceMappingURL=entitlements.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitlements.js","names":[],"sources":["../../../src/http/schemas/entitlements.ts"],"sourcesContent":["// Entitlements resource schemas. An entitlement is a student's access grant to\n// a piece of content — generic over content types (course today) — its\n// validity + source. Distinct from payment and from completion.\nimport { z } from 'zod';\nimport { entitlementSchema, idSchema } from '@headless-lms/core/schemas';\nimport { DateTimeInput, ListQuery, paginated } from './shared.js';\n\nexport const EntitlementStatus = z.enum(['active', 'expired', 'revoked']);\nexport type EntitlementStatus = z.infer<typeof EntitlementStatus>;\n\nexport const ContentType = z.enum(['course', 'download']);\nexport type ContentType = z.infer<typeof ContentType>;\n\n/** Reference to the granted content: identity + display name (join-derived).\n * The full content object lives on its own resource. */\nexport const ContentRef = z.object({\n id: z.string(),\n type: ContentType,\n title: z.string(),\n});\nexport type ContentRef = z.infer<typeof ContentRef>;\n\nexport const Entitlement = entitlementSchema;\nexport type Entitlement = z.infer<typeof Entitlement>;\n\nexport const EntitlementsQuery = ListQuery.extend({\n status: EntitlementStatus.optional(),\n source: z.string().optional(),\n /** Scope to a single student (used by the student detail view). */\n orgUserId: z.string().optional(),\n /** Scope to a single piece of content. */\n contentId: z.string().optional(),\n /** Scope to one content type. */\n type: ContentType.optional(),\n});\nexport type EntitlementsQuery = z.infer<typeof EntitlementsQuery>;\n\nexport const EntitlementsPage = paginated(Entitlement);\nexport type EntitlementsPage = z.infer<typeof EntitlementsPage>;\n\n/** A grant targets exactly one of: a single content item or a bundle. */\nexport const GrantEntitlement = z\n .object({\n orgUserId: idSchema,\n contentId: idSchema.nullish(),\n bundleId: idSchema.nullish(),\n expiresAt: DateTimeInput.nullable().describe('When access ends; null never expires'),\n })\n .refine((v) => (v.contentId != null) !== (v.bundleId != null), {\n message: 'Provide exactly one of contentId or bundleId',\n });\nexport type GrantEntitlement = z.infer<typeof GrantEntitlement>;\n\
|
|
1
|
+
{"version":3,"file":"entitlements.js","names":[],"sources":["../../../src/http/schemas/entitlements.ts"],"sourcesContent":["// Entitlements resource schemas. An entitlement is a student's access grant to\n// a piece of content — generic over content types (course today) — its\n// validity + source. Distinct from payment and from completion.\nimport { z } from 'zod';\nimport { entitlementSchema, idSchema } from '@headless-lms/core/schemas';\nimport { DateTimeInput, ListQuery, paginated } from './shared.js';\n\nexport const EntitlementStatus = z.enum(['active', 'expired', 'revoked']);\nexport type EntitlementStatus = z.infer<typeof EntitlementStatus>;\n\nexport const ContentType = z.enum(['course', 'download', 'event']);\nexport type ContentType = z.infer<typeof ContentType>;\n\n/** Reference to the granted content: identity + display name (join-derived).\n * The full content object lives on its own resource. */\nexport const ContentRef = z.object({\n id: z.string(),\n type: ContentType,\n title: z.string(),\n});\nexport type ContentRef = z.infer<typeof ContentRef>;\n\nexport const Entitlement = entitlementSchema;\nexport type Entitlement = z.infer<typeof Entitlement>;\n\nexport const EntitlementsQuery = ListQuery.extend({\n status: EntitlementStatus.optional(),\n source: z.string().optional(),\n /** Scope to a single student (used by the student detail view). */\n orgUserId: z.string().optional(),\n /** Scope to a single piece of content. */\n contentId: z.string().optional(),\n /** Scope to one content type. */\n type: ContentType.optional(),\n});\nexport type EntitlementsQuery = z.infer<typeof EntitlementsQuery>;\n\nexport const EntitlementsPage = paginated(Entitlement);\nexport type EntitlementsPage = z.infer<typeof EntitlementsPage>;\n\n/** A grant targets exactly one of: a single content item or a bundle. */\nexport const GrantEntitlement = z\n .object({\n orgUserId: idSchema,\n contentId: idSchema.nullish(),\n bundleId: idSchema.nullish(),\n expiresAt: DateTimeInput.nullable().describe('When access ends; null never expires'),\n })\n .refine((v) => (v.contentId != null) !== (v.bundleId != null), {\n message: 'Provide exactly one of contentId or bundleId',\n });\nexport type GrantEntitlement = z.infer<typeof GrantEntitlement>;\n\nexport const RevokeEntitlement = z\n .object({\n orgUserId: idSchema,\n contentId: idSchema.nullish(),\n bundleId: idSchema.nullish(),\n })\n .refine((v) => (v.contentId != null) !== (v.bundleId != null), {\n message: 'Provide exactly one of contentId or bundleId',\n });\nexport type RevokeEntitlement = z.infer<typeof RevokeEntitlement>;\n"],"mappings":";;;;AAOA,MAAa,oBAAoB,EAAE,KAAK;CAAC;CAAU;CAAW;AAAS,CAAC;AAGxE,MAAa,cAAc,EAAE,KAAK;CAAC;CAAU;CAAY;AAAO,CAAC;;;AAKjE,MAAa,aAAa,EAAE,OAAO;CACjC,IAAI,EAAE,OAAO;CACb,MAAM;CACN,OAAO,EAAE,OAAO;AAClB,CAAC;AAGD,MAAa,cAAc;AAG3B,MAAa,oBAAoB,UAAU,OAAO;CAChD,QAAQ,kBAAkB,SAAS;CACnC,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE5B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE/B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE/B,MAAM,YAAY,SAAS;AAC7B,CAAC;AAGD,MAAa,mBAAmB,UAAU,WAAW;;AAIrD,MAAa,mBAAmB,EAC7B,OAAO;CACN,WAAW;CACX,WAAW,SAAS,QAAQ;CAC5B,UAAU,SAAS,QAAQ;CAC3B,WAAW,cAAc,SAAS,CAAC,CAAC,SAAS,sCAAsC;AACrF,CAAC,CAAC,CACD,QAAQ,MAAO,EAAE,aAAa,UAAW,EAAE,YAAY,OAAO,EAC7D,SAAS,+CACX,CAAC;AAGH,MAAa,oBAAoB,EAC9B,OAAO;CACN,WAAW;CACX,WAAW,SAAS,QAAQ;CAC5B,UAAU,SAAS,QAAQ;AAC7B,CAAC,CAAC,CACD,QAAQ,MAAO,EAAE,aAAa,UAAW,EAAE,YAAY,OAAO,EAC7D,SAAS,+CACX,CAAC"}
|