@headless-lms/server 0.1.0 → 0.2.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.
Files changed (101) hide show
  1. package/README.md +1 -1
  2. package/dist/app/container.d.ts +7 -3
  3. package/dist/app/container.js +57 -26
  4. package/dist/app/container.js.map +1 -1
  5. package/dist/app/notifications.js +4 -1
  6. package/dist/app/notifications.js.map +1 -1
  7. package/dist/http/plugins/error-handler.d.ts +1 -1
  8. package/dist/http/plugins/error-handler.js +15 -4
  9. package/dist/http/plugins/error-handler.js.map +1 -1
  10. package/dist/http/plugins/openapi.js +25 -22
  11. package/dist/http/plugins/openapi.js.map +1 -1
  12. package/dist/http/routes/activities.js +34 -2
  13. package/dist/http/routes/activities.js.map +1 -1
  14. package/dist/http/routes/assets.js +4 -0
  15. package/dist/http/routes/assets.js.map +1 -1
  16. package/dist/http/routes/automations.js +32 -8
  17. package/dist/http/routes/automations.js.map +1 -1
  18. package/dist/http/routes/bundles.d.ts +7 -0
  19. package/dist/http/routes/bundles.js +170 -0
  20. package/dist/http/routes/bundles.js.map +1 -0
  21. package/dist/http/routes/course-analytics.d.ts +7 -0
  22. package/dist/http/routes/course-analytics.js +58 -0
  23. package/dist/http/routes/course-analytics.js.map +1 -0
  24. package/dist/http/routes/courses.js +8 -8
  25. package/dist/http/routes/courses.js.map +1 -1
  26. package/dist/http/routes/dashboard.js +2 -2
  27. package/dist/http/routes/dashboard.js.map +1 -1
  28. package/dist/http/routes/discussion.js +1 -1
  29. package/dist/http/routes/discussion.js.map +1 -1
  30. package/dist/http/routes/downloads.js +10 -10
  31. package/dist/http/routes/downloads.js.map +1 -1
  32. package/dist/http/routes/integrations.js.map +1 -1
  33. package/dist/http/routes/learn/assets.js +1 -1
  34. package/dist/http/routes/learn/assets.js.map +1 -1
  35. package/dist/http/routes/learn/comments.js +7 -7
  36. package/dist/http/routes/learn/comments.js.map +1 -1
  37. package/dist/http/routes/learn/courses.js +26 -3
  38. package/dist/http/routes/learn/courses.js.map +1 -1
  39. package/dist/http/routes/learn/downloads.js +3 -3
  40. package/dist/http/routes/learn/downloads.js.map +1 -1
  41. package/dist/http/routes/learn/org.js +2 -2
  42. package/dist/http/routes/learn/org.js.map +1 -1
  43. package/dist/http/routes/learn/progress.js +2 -2
  44. package/dist/http/routes/learn/progress.js.map +1 -1
  45. package/dist/http/routes/organizations.js.map +1 -1
  46. package/dist/http/routes/students.js +27 -6
  47. package/dist/http/routes/students.js.map +1 -1
  48. package/dist/http/routes/webhooks.d.ts +7 -0
  49. package/dist/http/routes/webhooks.js +159 -0
  50. package/dist/http/routes/webhooks.js.map +1 -0
  51. package/dist/http/routes.js +6 -0
  52. package/dist/http/routes.js.map +1 -1
  53. package/dist/http/schemas/activities.d.ts +34 -1
  54. package/dist/http/schemas/activities.js +7 -2
  55. package/dist/http/schemas/activities.js.map +1 -1
  56. package/dist/http/schemas/assets.d.ts +11 -7
  57. package/dist/http/schemas/assets.js.map +1 -1
  58. package/dist/http/schemas/automations.d.ts +75 -8
  59. package/dist/http/schemas/automations.js +13 -2
  60. package/dist/http/schemas/automations.js.map +1 -1
  61. package/dist/http/schemas/bundles.d.ts +63 -0
  62. package/dist/http/schemas/bundles.js +23 -0
  63. package/dist/http/schemas/bundles.js.map +1 -0
  64. package/dist/http/schemas/content.d.ts +18 -11
  65. package/dist/http/schemas/content.js +1 -2
  66. package/dist/http/schemas/content.js.map +1 -1
  67. package/dist/http/schemas/course-analytics.d.ts +29 -0
  68. package/dist/http/schemas/course-analytics.js +21 -0
  69. package/dist/http/schemas/course-analytics.js.map +1 -0
  70. package/dist/http/schemas/dashboard.js.map +1 -1
  71. package/dist/http/schemas/discussion.d.ts +9 -9
  72. package/dist/http/schemas/discussion.js.map +1 -1
  73. package/dist/http/schemas/downloads.d.ts +2 -0
  74. package/dist/http/schemas/downloads.js.map +1 -1
  75. package/dist/http/schemas/entitlements.d.ts +14 -6
  76. package/dist/http/schemas/entitlements.js +4 -2
  77. package/dist/http/schemas/entitlements.js.map +1 -1
  78. package/dist/http/schemas/index.d.ts +6 -4
  79. package/dist/http/schemas/index.js +6 -4
  80. package/dist/http/schemas/integrations.d.ts +4 -4
  81. package/dist/http/schemas/integrations.js.map +1 -1
  82. package/dist/http/schemas/invites.js +2 -1
  83. package/dist/http/schemas/invites.js.map +1 -1
  84. package/dist/http/schemas/learn.d.ts +11 -1
  85. package/dist/http/schemas/learn.js.map +1 -1
  86. package/dist/http/schemas/members.js.map +1 -1
  87. package/dist/http/schemas/organizations.js.map +1 -1
  88. package/dist/http/schemas/settings.js.map +1 -1
  89. package/dist/http/schemas/shared.d.ts +1 -0
  90. package/dist/http/schemas/shared.js +3 -1
  91. package/dist/http/schemas/shared.js.map +1 -1
  92. package/dist/http/schemas/students.d.ts +30 -2
  93. package/dist/http/schemas/students.js +21 -2
  94. package/dist/http/schemas/students.js.map +1 -1
  95. package/dist/http/server.js +4 -2
  96. package/dist/http/server.js.map +1 -1
  97. package/dist/index.d.ts +2 -2
  98. package/dist/index.js.map +1 -1
  99. package/dist/package.js +6 -0
  100. package/dist/package.js.map +1 -0
  101. package/package.json +5 -5
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
2
  //#region src/http/schemas/discussion.d.ts
3
3
  declare const CommentStatus: z.ZodEnum<{
4
- published: "published";
5
4
  pending: "pending";
5
+ published: "published";
6
6
  removed: "removed";
7
7
  }>;
8
8
  type CommentStatus = z.infer<typeof CommentStatus>;
@@ -43,8 +43,8 @@ declare const CommentView: z.ZodObject<{
43
43
  }, z.core.$strict>;
44
44
  body: z.ZodNullable<z.ZodString>;
45
45
  status: z.ZodEnum<{
46
- published: "published";
47
46
  pending: "pending";
47
+ published: "published";
48
48
  removed: "removed";
49
49
  }>;
50
50
  removedBy: z.ZodNullable<z.ZodObject<{
@@ -114,8 +114,8 @@ declare const ActivityComments: z.ZodObject<{
114
114
  }, z.core.$strict>;
115
115
  body: z.ZodNullable<z.ZodString>;
116
116
  status: z.ZodEnum<{
117
- published: "published";
118
117
  pending: "pending";
118
+ published: "published";
119
119
  removed: "removed";
120
120
  }>;
121
121
  removedBy: z.ZodNullable<z.ZodObject<{
@@ -175,8 +175,8 @@ declare const Comment: z.ZodObject<{
175
175
  orgUserId: z.ZodString;
176
176
  body: z.ZodString;
177
177
  status: z.ZodEnum<{
178
- published: "published";
179
178
  pending: "pending";
179
+ published: "published";
180
180
  removed: "removed";
181
181
  }>;
182
182
  removedBy: z.ZodNullable<z.ZodString>;
@@ -222,8 +222,8 @@ declare const CommentListItem: z.ZodObject<{
222
222
  courseId: z.ZodString;
223
223
  body: z.ZodString;
224
224
  status: z.ZodEnum<{
225
- published: "published";
226
225
  pending: "pending";
226
+ published: "published";
227
227
  removed: "removed";
228
228
  }>;
229
229
  author: z.ZodObject<{
@@ -238,7 +238,7 @@ declare const CommentListItem: z.ZodObject<{
238
238
  student: "student";
239
239
  }>;
240
240
  }, z.core.$strict>;
241
- authorEmail: z.ZodString;
241
+ authorEmail: z.ZodEmail;
242
242
  removedBy: z.ZodNullable<z.ZodString>;
243
243
  reports: z.ZodArray<z.ZodObject<{
244
244
  reporter: z.ZodObject<{
@@ -266,8 +266,8 @@ declare const CommentsQuery: z.ZodObject<{
266
266
  search: z.ZodOptional<z.ZodString>;
267
267
  sort: z.ZodOptional<z.ZodString>;
268
268
  status: z.ZodOptional<z.ZodEnum<{
269
- published: "published";
270
269
  pending: "pending";
270
+ published: "published";
271
271
  removed: "removed";
272
272
  }>>;
273
273
  reported: z.ZodOptional<z.ZodCodec<z.ZodString, z.ZodBoolean>>;
@@ -285,8 +285,8 @@ declare const CommentsPage: z.ZodObject<{
285
285
  courseId: z.ZodString;
286
286
  body: z.ZodString;
287
287
  status: z.ZodEnum<{
288
- published: "published";
289
288
  pending: "pending";
289
+ published: "published";
290
290
  removed: "removed";
291
291
  }>;
292
292
  author: z.ZodObject<{
@@ -301,7 +301,7 @@ declare const CommentsPage: z.ZodObject<{
301
301
  student: "student";
302
302
  }>;
303
303
  }, z.core.$strict>;
304
- authorEmail: z.ZodString;
304
+ authorEmail: z.ZodEmail;
305
305
  removedBy: z.ZodNullable<z.ZodString>;
306
306
  reports: z.ZodArray<z.ZodObject<{
307
307
  reporter: z.ZodObject<{
@@ -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 commentStatusSchema,\n commentViewSchema,\n} from \"@headless-lms/core/schemas\";\nimport { z } from \"zod\";\nimport { 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\nexport const CommentView = commentViewSchema;\nexport type CommentView = z.infer<typeof CommentView>;\n\n/** What the reaction write returns, so the client never recomputes a count. */\nexport const CommentReactions = z.object({\n reactions: ReactionCounts,\n viewerReaction: ReactionEmoji.optional(),\n});\nexport type CommentReactions = z.infer<typeof CommentReactions>;\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.object({\n body: z.string().min(1).max(10_000),\n parentId: z.string().nullable().default(null),\n});\nexport type PostComment = z.infer<typeof PostComment>;\n\nexport const EditComment = z.object({\n body: z.string().min(1).max(10_000),\n});\nexport type EditComment = z.infer<typeof EditComment>;\n\n/** The staff 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/learn. */\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 SetCommentReaction = z.object({\n emoji: ReactionEmoji,\n});\nexport type SetCommentReaction = z.infer<typeof SetCommentReaction>;\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({\n reason: z.string().max(1_000).default(\"\"),\n});\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 staff 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\n"],"mappings":";;;;AAmBA,MAAa,gBAAgB;AAG7B,MAAa,gBAAgB;;AAI7B,MAAa,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;;AAIrD,MAAa,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AAGnE,MAAa,cAAc;;AAI3B,MAAa,mBAAmB,EAAE,OAAO;CACvC,WAAW;CACX,gBAAgB,cAAc,SAAS;AACzC,CAAC;;;AAKD,MAAa,kBAAkB,EAAE,OAAO;CACtC,SAAS,EAAE,QAAQ;CACnB,UAAU,EAAE,QAAQ;CACpB,eAAe,EAAE,QAAQ;CACzB,WAAW,EAAE,QAAQ;AACvB,CAAC;;;AAOD,MAAa,iBAAiB;AAG9B,MAAa,mBAAmB,EAAE,OAAO;CACvC,QAAQ;CACR,UAAU,EAAE,MAAM,WAAW;AAC/B,CAAC;AAGD,MAAa,cAAc,EAAE,OAAO;CAClC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM;CAClC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,IAAI;AAC9C,CAAC;AAGD,MAAa,cAAc,EAAE,OAAO,EAClC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM,EACpC,CAAC;;;;AAMD,MAAa,eAAe,EAAE,OAAO,EACnC,QAAQ,EAAE,QAAQ,WAAW,EAC/B,CAAC;;AAID,MAAa,qBAAqB,EAAE,OAAO,EACzC,OAAO,cACT,CAAC;;AAID,MAAa,iBAAiB,EAAE,OAAO,EACrC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM,EACpC,CAAC;AAGD,MAAa,gBAAgB,EAAE,OAAO,EACpC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,GAAK,CAAC,CAAC,QAAQ,EAAE,EAC1C,CAAC;AAGD,MAAa,UAAU;AAGvB,MAAa,gBAAgB,EAAE,OAAO;CACpC,IAAI,EAAE,OAAO;CACb,WAAW,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO;CACpB,QAAQ,EAAE,OAAO;CACjB,YAAY,EAAE,KAAK,CAAC,CAAC,SAAS;CAC9B,WAAW,EAAE,KAAK;AACpB,CAAC;;;AAKD,MAAa,uBAAuB;;;AAKpC,MAAa,kBAAkB;AAG/B,MAAa,gBAAgB,UAAU,OAAO;CAC5C,QAAQ,cAAc,SAAS;;;;CAI/B,UAAU,EAAE,WAAW,CAAC,CAAC,SAAS;CAClC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;;CAEhC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AAGD,MAAa,eAAe,UAAU,eAAe;AAGrD,MAAa,0BAA0B,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAG1E,MAAa,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC"}
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 commentStatusSchema,\n commentViewSchema,\n} from '@headless-lms/core/schemas';\nimport { z } from 'zod';\nimport { 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\nexport const CommentView = commentViewSchema;\nexport type CommentView = z.infer<typeof CommentView>;\n\n/** What the reaction write returns, so the client never recomputes a count. */\nexport const CommentReactions = z.object({\n reactions: ReactionCounts,\n viewerReaction: ReactionEmoji.optional(),\n});\nexport type CommentReactions = z.infer<typeof CommentReactions>;\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.object({\n body: z.string().min(1).max(10_000),\n parentId: z.string().nullable().default(null),\n});\nexport type PostComment = z.infer<typeof PostComment>;\n\nexport const EditComment = z.object({\n body: z.string().min(1).max(10_000),\n});\nexport type EditComment = z.infer<typeof EditComment>;\n\n/** The staff 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/learn. */\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 SetCommentReaction = z.object({\n emoji: ReactionEmoji,\n});\nexport type SetCommentReaction = z.infer<typeof SetCommentReaction>;\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({\n reason: z.string().max(1_000).default(''),\n});\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 staff 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":";;;;AAmBA,MAAa,gBAAgB;AAG7B,MAAa,gBAAgB;;AAI7B,MAAa,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;;AAIrD,MAAa,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AAGnE,MAAa,cAAc;;AAI3B,MAAa,mBAAmB,EAAE,OAAO;CACvC,WAAW;CACX,gBAAgB,cAAc,SAAS;AACzC,CAAC;;;AAKD,MAAa,kBAAkB,EAAE,OAAO;CACtC,SAAS,EAAE,QAAQ;CACnB,UAAU,EAAE,QAAQ;CACpB,eAAe,EAAE,QAAQ;CACzB,WAAW,EAAE,QAAQ;AACvB,CAAC;;;AAOD,MAAa,iBAAiB;AAG9B,MAAa,mBAAmB,EAAE,OAAO;CACvC,QAAQ;CACR,UAAU,EAAE,MAAM,WAAW;AAC/B,CAAC;AAGD,MAAa,cAAc,EAAE,OAAO;CAClC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM;CAClC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,IAAI;AAC9C,CAAC;AAGD,MAAa,cAAc,EAAE,OAAO,EAClC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM,EACpC,CAAC;;;;AAMD,MAAa,eAAe,EAAE,OAAO,EACnC,QAAQ,EAAE,QAAQ,WAAW,EAC/B,CAAC;;AAID,MAAa,qBAAqB,EAAE,OAAO,EACzC,OAAO,cACT,CAAC;;AAID,MAAa,iBAAiB,EAAE,OAAO,EACrC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAM,EACpC,CAAC;AAGD,MAAa,gBAAgB,EAAE,OAAO,EACpC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,GAAK,CAAC,CAAC,QAAQ,EAAE,EAC1C,CAAC;AAGD,MAAa,UAAU;AAGvB,MAAa,gBAAgB,EAAE,OAAO;CACpC,IAAI,EAAE,OAAO;CACb,WAAW,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO;CACpB,QAAQ,EAAE,OAAO;CACjB,YAAY,EAAE,KAAK,CAAC,CAAC,SAAS;CAC9B,WAAW,EAAE,KAAK;AACpB,CAAC;;;AAKD,MAAa,uBAAuB;;;AAKpC,MAAa,kBAAkB;AAG/B,MAAa,gBAAgB,UAAU,OAAO;CAC5C,QAAQ,cAAc,SAAS;;;;CAI/B,UAAU,EAAE,WAAW,CAAC,CAAC,SAAS;CAClC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;;CAEhC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AAGD,MAAa,eAAe,UAAU,eAAe;AAGrD,MAAa,0BAA0B,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAG1E,MAAa,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC"}
@@ -29,6 +29,8 @@ declare const DownloadAsset: z.ZodObject<{
29
29
  assetId: z.ZodString;
30
30
  seq: z.ZodNumber;
31
31
  displayName: z.ZodNullable<z.ZodString>;
32
+ createdAt: z.ZodCoercedDate<unknown>;
33
+ updatedAt: z.ZodCoercedDate<unknown>;
32
34
  }, z.core.$strict>;
33
35
  type DownloadAsset = z.infer<typeof DownloadAsset>;
34
36
  declare const CreateDownload: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"downloads.js","names":[],"sources":["../../../src/http/schemas/downloads.ts"],"sourcesContent":["// Downloads resource schemas — a content type whose whole structure is an\n// ordered set of media-library assets. The Fastify routes validate\n// requests/responses against these, the OpenAPI spec is built from them, and\n// the frontend SDK is generated off that spec.\nimport { z } from \"zod\";\nimport {\n addDownloadAssetInputSchema,\n downloadAssetSchema,\n downloadSchema,\n downloadStatusSchema,\n reorderDownloadAssetsInputSchema,\n} from \"@headless-lms/core/schemas\";\nimport { ListQuery, paginated } from \"./shared.js\";\n\nexport const DownloadStatus = downloadStatusSchema;\nexport type DownloadStatus = z.infer<typeof DownloadStatus>;\n\nexport const Download = downloadSchema;\nexport type Download = z.infer<typeof Download>;\n\nexport const DownloadAsset = downloadAssetSchema;\nexport type DownloadAsset = z.infer<typeof DownloadAsset>;\n\nexport const CreateDownload = z.object({\n title: z.string().min(1),\n description: z.string().default(\"\"),\n category: z.string().default(\"\"),\n});\nexport type CreateDownload = z.infer<typeof CreateDownload>;\n\nexport const UpdateDownload = CreateDownload.partial().extend({\n status: DownloadStatus.optional(),\n thumbnailAssetId: z.string().nullable().optional(),\n});\nexport type UpdateDownload = z.infer<typeof UpdateDownload>;\n\nexport const DownloadsQuery = ListQuery.extend({\n status: DownloadStatus.optional(),\n category: z.string().optional(),\n});\nexport type DownloadsQuery = z.infer<typeof DownloadsQuery>;\n\nexport const DownloadsPage = paginated(Download);\nexport type DownloadsPage = z.infer<typeof DownloadsPage>;\n\nexport const AddDownloadAsset = addDownloadAssetInputSchema;\nexport type AddDownloadAsset = z.infer<typeof AddDownloadAsset>;\n\n/** `null` restores the `filename` fallback. */\nexport const RenameDownloadAsset = z.object({\n displayName: z.string().nullable(),\n});\nexport type RenameDownloadAsset = z.infer<typeof RenameDownloadAsset>;\n\nexport const ReorderDownloadAssets = reorderDownloadAssetsInputSchema;\nexport type ReorderDownloadAssets = z.infer<typeof ReorderDownloadAssets>;\n\nexport const DownloadIdParam = z.object({ downloadId: z.string() });\nexport type DownloadIdParam = z.infer<typeof DownloadIdParam>;\n\nexport const DownloadAssetParams = z.object({\n downloadId: z.string(),\n assetId: z.string(),\n});\nexport type DownloadAssetParams = z.infer<typeof DownloadAssetParams>;\n"],"mappings":";;;;AAcA,MAAa,iBAAiB;AAG9B,MAAa,WAAW;AAGxB,MAAa,gBAAgB;AAG7B,MAAa,iBAAiB,EAAE,OAAO;CACrC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,aAAa,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;CAClC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;AACjC,CAAC;AAGD,MAAa,iBAAiB,eAAe,QAAQ,CAAC,CAAC,OAAO;CAC5D,QAAQ,eAAe,SAAS;CAChC,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;AACnD,CAAC;AAGD,MAAa,iBAAiB,UAAU,OAAO;CAC7C,QAAQ,eAAe,SAAS;CAChC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;AAChC,CAAC;AAGD,MAAa,gBAAgB,UAAU,QAAQ;AAG/C,MAAa,mBAAmB;;AAIhC,MAAa,sBAAsB,EAAE,OAAO,EAC1C,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS,EACnC,CAAC;AAGD,MAAa,wBAAwB;AAGrC,MAAa,kBAAkB,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAGlE,MAAa,sBAAsB,EAAE,OAAO;CAC1C,YAAY,EAAE,OAAO;CACrB,SAAS,EAAE,OAAO;AACpB,CAAC"}
1
+ {"version":3,"file":"downloads.js","names":[],"sources":["../../../src/http/schemas/downloads.ts"],"sourcesContent":["// Downloads resource schemas — a content type whose whole structure is an\n// ordered set of media-library assets. The Fastify routes validate\n// requests/responses against these, the OpenAPI spec is built from them, and\n// the frontend SDK is generated off that spec.\nimport { z } from 'zod';\nimport {\n addDownloadAssetInputSchema,\n downloadAssetSchema,\n downloadSchema,\n downloadStatusSchema,\n reorderDownloadAssetsInputSchema,\n} from '@headless-lms/core/schemas';\nimport { ListQuery, paginated } from './shared.js';\n\nexport const DownloadStatus = downloadStatusSchema;\nexport type DownloadStatus = z.infer<typeof DownloadStatus>;\n\nexport const Download = downloadSchema;\nexport type Download = z.infer<typeof Download>;\n\nexport const DownloadAsset = downloadAssetSchema;\nexport type DownloadAsset = z.infer<typeof DownloadAsset>;\n\nexport const CreateDownload = z.object({\n title: z.string().min(1),\n description: z.string().default(''),\n category: z.string().default(''),\n});\nexport type CreateDownload = z.infer<typeof CreateDownload>;\n\nexport const UpdateDownload = CreateDownload.partial().extend({\n status: DownloadStatus.optional(),\n thumbnailAssetId: z.string().nullable().optional(),\n});\nexport type UpdateDownload = z.infer<typeof UpdateDownload>;\n\nexport const DownloadsQuery = ListQuery.extend({\n status: DownloadStatus.optional(),\n category: z.string().optional(),\n});\nexport type DownloadsQuery = z.infer<typeof DownloadsQuery>;\n\nexport const DownloadsPage = paginated(Download);\nexport type DownloadsPage = z.infer<typeof DownloadsPage>;\n\nexport const AddDownloadAsset = addDownloadAssetInputSchema;\nexport type AddDownloadAsset = z.infer<typeof AddDownloadAsset>;\n\n/** `null` restores the `filename` fallback. */\nexport const RenameDownloadAsset = z.object({\n displayName: z.string().nullable(),\n});\nexport type RenameDownloadAsset = z.infer<typeof RenameDownloadAsset>;\n\nexport const ReorderDownloadAssets = reorderDownloadAssetsInputSchema;\nexport type ReorderDownloadAssets = z.infer<typeof ReorderDownloadAssets>;\n\nexport const DownloadIdParam = z.object({ downloadId: z.string() });\nexport type DownloadIdParam = z.infer<typeof DownloadIdParam>;\n\nexport const DownloadAssetParams = z.object({\n downloadId: z.string(),\n assetId: z.string(),\n});\nexport type DownloadAssetParams = z.infer<typeof DownloadAssetParams>;\n"],"mappings":";;;;AAcA,MAAa,iBAAiB;AAG9B,MAAa,WAAW;AAGxB,MAAa,gBAAgB;AAG7B,MAAa,iBAAiB,EAAE,OAAO;CACrC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,aAAa,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;CAClC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE;AACjC,CAAC;AAGD,MAAa,iBAAiB,eAAe,QAAQ,CAAC,CAAC,OAAO;CAC5D,QAAQ,eAAe,SAAS;CAChC,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;AACnD,CAAC;AAGD,MAAa,iBAAiB,UAAU,OAAO;CAC7C,QAAQ,eAAe,SAAS;CAChC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;AAChC,CAAC;AAGD,MAAa,gBAAgB,UAAU,QAAQ;AAG/C,MAAa,mBAAmB;;AAIhC,MAAa,sBAAsB,EAAE,OAAO,EAC1C,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS,EACnC,CAAC;AAGD,MAAa,wBAAwB;AAGrC,MAAa,kBAAkB,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAGlE,MAAa,sBAAsB,EAAE,OAAO;CAC1C,YAAY,EAAE,OAAO;CACrB,SAAS,EAAE,OAAO;AACpB,CAAC"}
@@ -7,8 +7,8 @@ declare const EntitlementStatus: z.ZodEnum<{
7
7
  }>;
8
8
  type EntitlementStatus = z.infer<typeof EntitlementStatus>;
9
9
  declare const ContentType: z.ZodEnum<{
10
- course: "course";
11
10
  download: "download";
11
+ course: "course";
12
12
  }>;
13
13
  type ContentType = z.infer<typeof ContentType>;
14
14
  /** Reference to the granted content: identity + display name (join-derived).
@@ -16,8 +16,8 @@ type ContentType = z.infer<typeof ContentType>;
16
16
  declare const ContentRef: z.ZodObject<{
17
17
  id: z.ZodString;
18
18
  type: z.ZodEnum<{
19
- course: "course";
20
19
  download: "download";
20
+ course: "course";
21
21
  }>;
22
22
  title: z.ZodString;
23
23
  }, z.core.$strip>;
@@ -26,7 +26,8 @@ declare const Entitlement: z.ZodObject<{
26
26
  orgId: z.ZodString;
27
27
  id: z.ZodString;
28
28
  orgUserId: z.ZodString;
29
- contentId: z.ZodString;
29
+ bundleId: z.ZodNullable<z.ZodString>;
30
+ contentId: z.ZodNullable<z.ZodString>;
30
31
  status: z.ZodEnum<{
31
32
  active: "active";
32
33
  revoked: "revoked";
@@ -34,6 +35,8 @@ declare const Entitlement: z.ZodObject<{
34
35
  source: z.ZodString;
35
36
  grantedAt: z.ZodCoercedDate<unknown>;
36
37
  expiresAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
38
+ createdAt: z.ZodCoercedDate<unknown>;
39
+ updatedAt: z.ZodCoercedDate<unknown>;
37
40
  }, z.core.$strict>;
38
41
  type Entitlement = z.infer<typeof Entitlement>;
39
42
  declare const EntitlementsQuery: z.ZodObject<{
@@ -50,8 +53,8 @@ declare const EntitlementsQuery: z.ZodObject<{
50
53
  orgUserId: z.ZodOptional<z.ZodString>;
51
54
  contentId: z.ZodOptional<z.ZodString>;
52
55
  type: z.ZodOptional<z.ZodEnum<{
53
- course: "course";
54
56
  download: "download";
57
+ course: "course";
55
58
  }>>;
56
59
  }, z.core.$strip>;
57
60
  type EntitlementsQuery = z.infer<typeof EntitlementsQuery>;
@@ -60,7 +63,8 @@ declare const EntitlementsPage: z.ZodObject<{
60
63
  orgId: z.ZodString;
61
64
  id: z.ZodString;
62
65
  orgUserId: z.ZodString;
63
- contentId: z.ZodString;
66
+ bundleId: z.ZodNullable<z.ZodString>;
67
+ contentId: z.ZodNullable<z.ZodString>;
64
68
  status: z.ZodEnum<{
65
69
  active: "active";
66
70
  revoked: "revoked";
@@ -68,15 +72,19 @@ declare const EntitlementsPage: z.ZodObject<{
68
72
  source: z.ZodString;
69
73
  grantedAt: z.ZodCoercedDate<unknown>;
70
74
  expiresAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
75
+ createdAt: z.ZodCoercedDate<unknown>;
76
+ updatedAt: z.ZodCoercedDate<unknown>;
71
77
  }, z.core.$strict>>;
72
78
  total: z.ZodNumber;
73
79
  page: z.ZodNumber;
74
80
  pageSize: z.ZodNumber;
75
81
  }, z.core.$strip>;
76
82
  type EntitlementsPage = z.infer<typeof EntitlementsPage>;
83
+ /** A grant targets exactly one of: a single content item or a bundle. */
77
84
  declare const GrantEntitlement: z.ZodObject<{
78
85
  orgUserId: z.ZodString;
79
- contentId: z.ZodString;
86
+ contentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
87
+ bundleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
80
88
  expiresAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
81
89
  }, z.core.$strip>;
82
90
  type GrantEntitlement = z.infer<typeof GrantEntitlement>;
@@ -27,11 +27,13 @@ const EntitlementsQuery = ListQuery.extend({
27
27
  type: ContentType.optional()
28
28
  });
29
29
  const EntitlementsPage = paginated(Entitlement);
30
+ /** A grant targets exactly one of: a single content item or a bundle. */
30
31
  const GrantEntitlement = z.object({
31
32
  orgUserId: z.string(),
32
- contentId: z.string(),
33
+ contentId: z.string().nullish(),
34
+ bundleId: z.string().nullish(),
33
35
  expiresAt: z.coerce.date().nullable()
34
- });
36
+ }).refine((v) => v.contentId != null !== (v.bundleId != null), { message: "Provide exactly one of contentId or bundleId" });
35
37
  /** Revoke/reinstate access by setting the active|revoked status. */
36
38
  const SetEntitlementStatus = z.object({ status: z.enum(["active", "revoked"]) });
37
39
  const EntitlementIdParam = z.object({ id: z.string() });
@@ -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 } from \"@headless-lms/core/schemas\";\nimport { 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\nexport const GrantEntitlement = z.object({\n orgUserId: z.string(),\n contentId: z.string(),\n expiresAt: z.coerce.date().nullable(),\n});\nexport type GrantEntitlement = z.infer<typeof GrantEntitlement>;\n\n/** Revoke/reinstate access by setting the active|revoked status. */\nexport const SetEntitlementStatus = z.object({\n status: z.enum([\"active\", \"revoked\"]),\n});\nexport type SetEntitlementStatus = z.infer<typeof SetEntitlementStatus>;\n\nexport const EntitlementIdParam = z.object({ id: z.string() });\nexport type EntitlementIdParam = z.infer<typeof EntitlementIdParam>;\n"],"mappings":";;;;AAOA,MAAa,oBAAoB,EAAE,KAAK;CAAC;CAAU;CAAW;AAAS,CAAC;AAGxE,MAAa,cAAc,EAAE,KAAK,CAAC,UAAU,UAAU,CAAC;;;AAKxD,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;AAGrD,MAAa,mBAAmB,EAAE,OAAO;CACvC,WAAW,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO,KAAK,CAAC,CAAC,SAAS;AACtC,CAAC;;AAID,MAAa,uBAAuB,EAAE,OAAO,EAC3C,QAAQ,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EACtC,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
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 } from '@headless-lms/core/schemas';\nimport { 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: z.string(),\n contentId: z.string().nullish(),\n bundleId: z.string().nullish(),\n expiresAt: z.coerce.date().nullable(),\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\n/** Revoke/reinstate access by setting the active|revoked status. */\nexport const SetEntitlementStatus = z.object({\n status: z.enum(['active', 'revoked']),\n});\nexport type SetEntitlementStatus = z.infer<typeof SetEntitlementStatus>;\n\nexport const EntitlementIdParam = z.object({ id: z.string() });\nexport type EntitlementIdParam = z.infer<typeof EntitlementIdParam>;\n"],"mappings":";;;;AAOA,MAAa,oBAAoB,EAAE,KAAK;CAAC;CAAU;CAAW;AAAS,CAAC;AAGxE,MAAa,cAAc,EAAE,KAAK,CAAC,UAAU,UAAU,CAAC;;;AAKxD,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,EAAE,OAAO;CACpB,WAAW,EAAE,OAAO,CAAC,CAAC,QAAQ;CAC9B,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ;CAC7B,WAAW,EAAE,OAAO,KAAK,CAAC,CAAC,SAAS;AACtC,CAAC,CAAC,CACD,QAAQ,MAAO,EAAE,aAAa,UAAW,EAAE,YAAY,OAAO,EAC7D,SAAS,+CACX,CAAC;;AAIH,MAAa,uBAAuB,EAAE,OAAO,EAC3C,QAAQ,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EACtC,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
@@ -1,17 +1,19 @@
1
- import { Activity, ActivityPathParam, CourseIdPathParam, CreateModule, Module, ModuleList, ModulePathParam, ReorderInput, SaveActivity, UpdateModule } from "./activities.js";
1
+ import { Activity, ActivityAsset, ActivityAssetList, ActivityList, ActivityPathParam, CourseIdPathParam, CreateModule, Module, ModuleList, ModulePathParam, ReorderInput, SaveActivity, UpdateModule } from "./activities.js";
2
2
  import { Asset, AssetIdParam, AssetKind, AssetStatus, AssetsPage, AssetsQuery, DownloadTicket, RequestDownload, RequestUpload, UploadTicket } from "./assets.js";
3
- import { Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationRun, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AvailableAction, AvailableTriggers, CreateAutomationBody, UpdateAutomationBody } from "./automations.js";
3
+ import { Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationKind, AutomationRun, AutomationRunParams, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AutomationsQuery, AvailableAction, AvailableTriggers, CreateAutomationBody, CreateWebhookBody, CreatedWebhook, UpdateAutomationBody, UpdateWebhookBody, Webhook, WebhookSecret } from "./automations.js";
4
+ import { AddBundleItem, Bundle, BundleIdParam, BundleItem, BundleItemParams, BundlesPage, BundlesQuery, CreateBundle, UpdateBundle } from "./bundles.js";
4
5
  import { Course, CourseIdParam, CourseSettings, CourseStatus, CoursesPage, CoursesQuery, CreateCourse, PatchCourseSettings, UpdateCourse } from "./content.js";
6
+ import { CourseActivityEngagement, CourseAnalytics } from "./course-analytics.js";
5
7
  import { EnrollmentPoint, EnrollmentSeries, EnrollmentSeriesQuery, OverviewStats } from "./dashboard.js";
6
8
  import { ActivityComments, Comment, CommentAuthor, CommentIdParam, CommentListItem, CommentReactions, CommentReport, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, CommentsPage, CommentsQuery, DiscussionActivityParam, EditComment, PatchComment, PostComment, ReactionCounts, ReactionEmoji, ReplyToComment, ReportComment, SetCommentReaction } from "./discussion.js";
7
9
  import { AddDownloadAsset, CreateDownload, Download, DownloadAsset, DownloadAssetParams, DownloadIdParam, DownloadStatus, DownloadsPage, DownloadsQuery, RenameDownloadAsset, ReorderDownloadAssets, UpdateDownload } from "./downloads.js";
8
10
  import { ContentRef, ContentType, Entitlement, EntitlementIdParam, EntitlementStatus, EntitlementsPage, EntitlementsQuery, GrantEntitlement, SetEntitlementStatus } from "./entitlements.js";
9
11
  import { ErrorBody, ListQuery, Matches, OrgRole, OrgUserProfileSchema, UserProfileSchema, paginated } from "./shared.js";
10
12
  import { CourseProgress, LearnCourseIdParam, LearnCourses, LearnDownload, LearnDownloads, LearnModules, LearnOrg, LearnViewer, ProgressReportItem, ProgressStatus, ReportProgress } from "./learn.js";
11
- import { OrgUserStatus, Student, StudentIdParam, StudentsPage, StudentsQuery, UpdateStudentBody } from "./students.js";
13
+ import { OrgUserStatus, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery, UpdateStudentBody } from "./students.js";
12
14
  import { CreateOrganization, Organization, UpdateOrganization } from "./organizations.js";
13
15
  import { Member, MemberIdParam, MemberStatus, MembersPage, MembersQuery, Role, UpdateMemberRole } from "./members.js";
14
16
  import { AcceptInvite, AcceptInviteResult, ActivateInvite, ActivateInviteResult, CreateInvite, GetInviteResult, Invite, InviteRole, InviteTokenParam, RedeemInvite, RedeemInviteResult } from "./invites.js";
15
17
  import { ActionInvocationResult, AvailableIntegration, AvailableIntegrationsList, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, IntegrationActionInfo, InvokeActionRequest, ReconnectRequest } from "./integrations.js";
16
18
  import { PatchSettings, ScopeSettings, SettingsNamespaceParam, SettingsScopeParam, SettingsValue } from "./settings.js";
17
- export { AcceptInvite, AcceptInviteResult, ActionInvocationResult, ActivateInvite, ActivateInviteResult, Activity, ActivityComments, ActivityPathParam, AddDownloadAsset, Asset, AssetIdParam, AssetKind, AssetStatus, AssetsPage, AssetsQuery, Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationRun, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AvailableAction, AvailableIntegration, AvailableIntegrationsList, AvailableTriggers, Comment, CommentAuthor, CommentIdParam, CommentListItem, CommentReactions, CommentReport, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, CommentsPage, CommentsQuery, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, ContentRef, ContentType, Course, CourseIdParam, CourseIdPathParam, CourseProgress, CourseSettings, CourseStatus, CoursesPage, CoursesQuery, CreateAutomationBody, CreateCourse, CreateDownload, CreateInvite, CreateModule, CreateOrganization, DiscussionActivityParam, Download, DownloadAsset, DownloadAssetParams, DownloadIdParam, DownloadStatus, DownloadTicket, DownloadsPage, DownloadsQuery, EditComment, EnrollmentPoint, EnrollmentSeries, EnrollmentSeriesQuery, Entitlement, EntitlementIdParam, EntitlementStatus, EntitlementsPage, EntitlementsQuery, ErrorBody, GetInviteResult, GrantEntitlement, IntegrationActionInfo, Invite, InviteRole, InviteTokenParam, InvokeActionRequest, LearnCourseIdParam, LearnCourses, LearnDownload, LearnDownloads, LearnModules, LearnOrg, LearnViewer, ListQuery, Matches, Member, MemberIdParam, MemberStatus, MembersPage, MembersQuery, Module, ModuleList, ModulePathParam, OrgRole, OrgUserProfileSchema, OrgUserStatus, Organization, OverviewStats, PatchComment, PatchCourseSettings, PatchSettings, PostComment, ProgressReportItem, ProgressStatus, ReactionCounts, ReactionEmoji, ReconnectRequest, RedeemInvite, RedeemInviteResult, RenameDownloadAsset, ReorderDownloadAssets, ReorderInput, ReplyToComment, ReportComment, ReportProgress, RequestDownload, RequestUpload, Role, SaveActivity, ScopeSettings, SetCommentReaction, SetEntitlementStatus, SettingsNamespaceParam, SettingsScopeParam, SettingsValue, Student, StudentIdParam, StudentsPage, StudentsQuery, UpdateAutomationBody, UpdateCourse, UpdateDownload, UpdateMemberRole, UpdateModule, UpdateOrganization, UpdateStudentBody, UploadTicket, UserProfileSchema, paginated };
19
+ export { AcceptInvite, AcceptInviteResult, ActionInvocationResult, ActivateInvite, ActivateInviteResult, Activity, ActivityAsset, ActivityAssetList, ActivityComments, ActivityList, ActivityPathParam, AddBundleItem, AddDownloadAsset, Asset, AssetIdParam, AssetKind, AssetStatus, AssetsPage, AssetsQuery, Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationKind, AutomationRun, AutomationRunParams, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AutomationsQuery, AvailableAction, AvailableIntegration, AvailableIntegrationsList, AvailableTriggers, Bundle, BundleIdParam, BundleItem, BundleItemParams, BundlesPage, BundlesQuery, Comment, CommentAuthor, CommentIdParam, CommentListItem, CommentReactions, CommentReport, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, CommentsPage, CommentsQuery, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, ContentRef, ContentType, Course, CourseActivityEngagement, CourseAnalytics, CourseIdParam, CourseIdPathParam, CourseProgress, CourseSettings, CourseStatus, CoursesPage, CoursesQuery, CreateAutomationBody, CreateBundle, CreateCourse, CreateDownload, CreateInvite, CreateModule, CreateOrganization, CreateWebhookBody, CreatedWebhook, DiscussionActivityParam, Download, DownloadAsset, DownloadAssetParams, DownloadIdParam, DownloadStatus, DownloadTicket, DownloadsPage, DownloadsQuery, EditComment, EnrollmentPoint, EnrollmentSeries, EnrollmentSeriesQuery, Entitlement, EntitlementIdParam, EntitlementStatus, EntitlementsPage, EntitlementsQuery, ErrorBody, GetInviteResult, GrantEntitlement, IntegrationActionInfo, Invite, InviteRole, InviteTokenParam, InvokeActionRequest, LearnCourseIdParam, LearnCourses, LearnDownload, LearnDownloads, LearnModules, LearnOrg, LearnViewer, ListQuery, Matches, Member, MemberIdParam, MemberStatus, MembersPage, MembersQuery, Module, ModuleList, ModulePathParam, OrgRole, OrgUserProfileSchema, OrgUserStatus, Organization, OverviewStats, PatchComment, PatchCourseSettings, PatchSettings, PostComment, ProgressReportItem, ProgressStatus, ReactionCounts, ReactionEmoji, ReconnectRequest, RedeemInvite, RedeemInviteResult, RenameDownloadAsset, ReorderDownloadAssets, ReorderInput, ReplyToComment, ReportComment, ReportProgress, RequestDownload, RequestUpload, Role, SaveActivity, ScopeSettings, SetCommentReaction, SetEntitlementStatus, SettingsNamespaceParam, SettingsScopeParam, SettingsValue, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery, UpdateAutomationBody, UpdateBundle, UpdateCourse, UpdateDownload, UpdateMemberRole, UpdateModule, UpdateOrganization, UpdateStudentBody, UpdateWebhookBody, UploadTicket, UserProfileSchema, Webhook, WebhookSecret, paginated };
@@ -1,17 +1,19 @@
1
1
  import { ErrorBody, ListQuery, OrgRole, OrgUserProfileSchema, UserProfileSchema, paginated } from "./shared.js";
2
2
  import { Course, CourseIdParam, CourseSettings, CourseStatus, CoursesPage, CoursesQuery, CreateCourse, PatchCourseSettings, UpdateCourse } from "./content.js";
3
3
  import { AddDownloadAsset, CreateDownload, Download, DownloadAsset, DownloadAssetParams, DownloadIdParam, DownloadStatus, DownloadsPage, DownloadsQuery, RenameDownloadAsset, ReorderDownloadAssets, UpdateDownload } from "./downloads.js";
4
- import { Activity, ActivityPathParam, CourseIdPathParam, CreateModule, Module, ModuleList, ModulePathParam, ReorderInput, SaveActivity, UpdateModule } from "./activities.js";
4
+ import { AddBundleItem, Bundle, BundleIdParam, BundleItem, BundleItemParams, BundlesPage, BundlesQuery, CreateBundle, UpdateBundle } from "./bundles.js";
5
+ import { Activity, ActivityAsset, ActivityAssetList, ActivityList, ActivityPathParam, CourseIdPathParam, CreateModule, Module, ModuleList, ModulePathParam, ReorderInput, SaveActivity, UpdateModule } from "./activities.js";
5
6
  import { CourseProgress, LearnCourseIdParam, LearnCourses, LearnDownload, LearnDownloads, LearnModules, LearnOrg, LearnViewer, ProgressReportItem, ProgressStatus, ReportProgress } from "./learn.js";
6
- import { OrgUserStatus, Student, StudentIdParam, StudentsPage, StudentsQuery, UpdateStudentBody } from "./students.js";
7
+ import { OrgUserStatus, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery, UpdateStudentBody } from "./students.js";
7
8
  import { ContentRef, ContentType, Entitlement, EntitlementIdParam, EntitlementStatus, EntitlementsPage, EntitlementsQuery, GrantEntitlement, SetEntitlementStatus } from "./entitlements.js";
8
- import { Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationRun, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AvailableAction, AvailableTriggers, CreateAutomationBody, UpdateAutomationBody } from "./automations.js";
9
+ import { Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationKind, AutomationRun, AutomationRunParams, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AutomationsQuery, AvailableAction, AvailableTriggers, CreateAutomationBody, CreateWebhookBody, CreatedWebhook, UpdateAutomationBody, UpdateWebhookBody, Webhook, WebhookSecret } from "./automations.js";
9
10
  import { CreateOrganization, Organization, UpdateOrganization } from "./organizations.js";
10
11
  import { Member, MemberIdParam, MemberStatus, MembersPage, MembersQuery, Role, UpdateMemberRole } from "./members.js";
11
12
  import { AcceptInvite, AcceptInviteResult, ActivateInvite, ActivateInviteResult, CreateInvite, GetInviteResult, Invite, InviteRole, InviteTokenParam, RedeemInvite, RedeemInviteResult } from "./invites.js";
12
13
  import { EnrollmentPoint, EnrollmentSeries, EnrollmentSeriesQuery, OverviewStats } from "./dashboard.js";
14
+ import { CourseActivityEngagement, CourseAnalytics } from "./course-analytics.js";
13
15
  import { Asset, AssetIdParam, AssetKind, AssetStatus, AssetsPage, AssetsQuery, DownloadTicket, RequestDownload, RequestUpload, UploadTicket } from "./assets.js";
14
16
  import { ActionInvocationResult, AvailableIntegration, AvailableIntegrationsList, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, IntegrationActionInfo, InvokeActionRequest, ReconnectRequest } from "./integrations.js";
15
17
  import { PatchSettings, ScopeSettings, SettingsNamespaceParam, SettingsScopeParam, SettingsValue } from "./settings.js";
16
18
  import { ActivityComments, Comment, CommentAuthor, CommentIdParam, CommentListItem, CommentReactions, CommentReport, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, CommentsPage, CommentsQuery, DiscussionActivityParam, EditComment, PatchComment, PostComment, ReactionCounts, ReactionEmoji, ReplyToComment, ReportComment, SetCommentReaction } from "./discussion.js";
17
- export { AcceptInvite, AcceptInviteResult, ActionInvocationResult, ActivateInvite, ActivateInviteResult, Activity, ActivityComments, ActivityPathParam, AddDownloadAsset, Asset, AssetIdParam, AssetKind, AssetStatus, AssetsPage, AssetsQuery, Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationRun, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AvailableAction, AvailableIntegration, AvailableIntegrationsList, AvailableTriggers, Comment, CommentAuthor, CommentIdParam, CommentListItem, CommentReactions, CommentReport, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, CommentsPage, CommentsQuery, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, ContentRef, ContentType, Course, CourseIdParam, CourseIdPathParam, CourseProgress, CourseSettings, CourseStatus, CoursesPage, CoursesQuery, CreateAutomationBody, CreateCourse, CreateDownload, CreateInvite, CreateModule, CreateOrganization, DiscussionActivityParam, Download, DownloadAsset, DownloadAssetParams, DownloadIdParam, DownloadStatus, DownloadTicket, DownloadsPage, DownloadsQuery, EditComment, EnrollmentPoint, EnrollmentSeries, EnrollmentSeriesQuery, Entitlement, EntitlementIdParam, EntitlementStatus, EntitlementsPage, EntitlementsQuery, ErrorBody, GetInviteResult, GrantEntitlement, IntegrationActionInfo, Invite, InviteRole, InviteTokenParam, InvokeActionRequest, LearnCourseIdParam, LearnCourses, LearnDownload, LearnDownloads, LearnModules, LearnOrg, LearnViewer, ListQuery, Member, MemberIdParam, MemberStatus, MembersPage, MembersQuery, Module, ModuleList, ModulePathParam, OrgRole, OrgUserProfileSchema, OrgUserStatus, Organization, OverviewStats, PatchComment, PatchCourseSettings, PatchSettings, PostComment, ProgressReportItem, ProgressStatus, ReactionCounts, ReactionEmoji, ReconnectRequest, RedeemInvite, RedeemInviteResult, RenameDownloadAsset, ReorderDownloadAssets, ReorderInput, ReplyToComment, ReportComment, ReportProgress, RequestDownload, RequestUpload, Role, SaveActivity, ScopeSettings, SetCommentReaction, SetEntitlementStatus, SettingsNamespaceParam, SettingsScopeParam, SettingsValue, Student, StudentIdParam, StudentsPage, StudentsQuery, UpdateAutomationBody, UpdateCourse, UpdateDownload, UpdateMemberRole, UpdateModule, UpdateOrganization, UpdateStudentBody, UploadTicket, UserProfileSchema, paginated };
19
+ export { AcceptInvite, AcceptInviteResult, ActionInvocationResult, ActivateInvite, ActivateInviteResult, Activity, ActivityAsset, ActivityAssetList, ActivityComments, ActivityList, ActivityPathParam, AddBundleItem, AddDownloadAsset, Asset, AssetIdParam, AssetKind, AssetStatus, AssetsPage, AssetsQuery, Automation, AutomationAction, AutomationActionResult, AutomationIdParam, AutomationKind, AutomationRun, AutomationRunParams, AutomationRunStatus, AutomationRunsPage, AutomationRunsQuery, AutomationTrigger, AutomationsQuery, AvailableAction, AvailableIntegration, AvailableIntegrationsList, AvailableTriggers, Bundle, BundleIdParam, BundleItem, BundleItemParams, BundlesPage, BundlesQuery, Comment, CommentAuthor, CommentIdParam, CommentListItem, CommentReactions, CommentReport, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, CommentsPage, CommentsQuery, ConfigureRequest, ConnectRequest, Connection, ConnectionActionParams, ConnectionIdParam, ConnectionsList, ContentRef, ContentType, Course, CourseActivityEngagement, CourseAnalytics, CourseIdParam, CourseIdPathParam, CourseProgress, CourseSettings, CourseStatus, CoursesPage, CoursesQuery, CreateAutomationBody, CreateBundle, CreateCourse, CreateDownload, CreateInvite, CreateModule, CreateOrganization, CreateWebhookBody, CreatedWebhook, DiscussionActivityParam, Download, DownloadAsset, DownloadAssetParams, DownloadIdParam, DownloadStatus, DownloadTicket, DownloadsPage, DownloadsQuery, EditComment, EnrollmentPoint, EnrollmentSeries, EnrollmentSeriesQuery, Entitlement, EntitlementIdParam, EntitlementStatus, EntitlementsPage, EntitlementsQuery, ErrorBody, GetInviteResult, GrantEntitlement, IntegrationActionInfo, Invite, InviteRole, InviteTokenParam, InvokeActionRequest, LearnCourseIdParam, LearnCourses, LearnDownload, LearnDownloads, LearnModules, LearnOrg, LearnViewer, ListQuery, Member, MemberIdParam, MemberStatus, MembersPage, MembersQuery, Module, ModuleList, ModulePathParam, OrgRole, OrgUserProfileSchema, OrgUserStatus, Organization, OverviewStats, PatchComment, PatchCourseSettings, PatchSettings, PostComment, ProgressReportItem, ProgressStatus, ReactionCounts, ReactionEmoji, ReconnectRequest, RedeemInvite, RedeemInviteResult, RenameDownloadAsset, ReorderDownloadAssets, ReorderInput, ReplyToComment, ReportComment, ReportProgress, RequestDownload, RequestUpload, Role, SaveActivity, ScopeSettings, SetCommentReaction, SetEntitlementStatus, SettingsNamespaceParam, SettingsScopeParam, SettingsValue, Student, StudentAnalytics, StudentCourseProgress, StudentIdParam, StudentsPage, StudentsQuery, UpdateAutomationBody, UpdateBundle, UpdateCourse, UpdateDownload, UpdateMemberRole, UpdateModule, UpdateOrganization, UpdateStudentBody, UpdateWebhookBody, UploadTicket, UserProfileSchema, Webhook, WebhookSecret, paginated };
@@ -35,22 +35,22 @@ declare const AvailableIntegrationsList: z.ZodArray<z.ZodObject<{
35
35
  type AvailableIntegrationsList = z.infer<typeof AvailableIntegrationsList>;
36
36
  /** The connection row minus credentialRef — not even the reference leaks. */
37
37
  declare const Connection: z.ZodObject<{
38
- active: z.ZodBoolean;
39
- id: z.ZodString;
40
38
  orgId: z.ZodString;
39
+ id: z.ZodString;
41
40
  createdAt: z.ZodCoercedDate<unknown>;
42
41
  updatedAt: z.ZodCoercedDate<unknown>;
43
42
  config: z.ZodRecord<z.ZodString, z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>>;
43
+ active: z.ZodBoolean;
44
44
  integrationId: z.ZodString;
45
45
  }, z.core.$strict>;
46
46
  type Connection = z.infer<typeof Connection>;
47
47
  declare const ConnectionsList: z.ZodArray<z.ZodObject<{
48
- active: z.ZodBoolean;
49
- id: z.ZodString;
50
48
  orgId: z.ZodString;
49
+ id: z.ZodString;
51
50
  createdAt: z.ZodCoercedDate<unknown>;
52
51
  updatedAt: z.ZodCoercedDate<unknown>;
53
52
  config: z.ZodRecord<z.ZodString, z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>>;
53
+ active: z.ZodBoolean;
54
54
  integrationId: z.ZodString;
55
55
  }, z.core.$strict>>;
56
56
  type ConnectionsList = z.infer<typeof ConnectionsList>;
@@ -1 +1 @@
1
- {"version":3,"file":"integrations.js","names":[],"sources":["../../../src/http/schemas/integrations.ts"],"sourcesContent":["// Integrations resource schemas. A Connection is an org's link to one external\n// service (Stripe, Slack, …). Secrets are WRITE-ONLY: accepted on\n// connect/reconnect, stored encrypted server-side, and never appear in any\n// response — responses carry configuration and state only.\nimport { z } from \"zod\";\nimport { connectionSchema, jsonRecordSchema } from \"@headless-lms/core/schemas\";\n\n/** An action an integration can be invoked with; schemas are JSON Schema. */\nexport const IntegrationActionInfo = z.object({\n id: z.string(),\n description: z.string(),\n inputSchema: z.record(z.string(), z.unknown()),\n outputSchema: z.record(z.string(), z.unknown()),\n});\nexport type IntegrationActionInfo = z.infer<typeof IntegrationActionInfo>;\n\n/** An integration this deployment supports; configSchema is JSON Schema for its config. */\nexport const AvailableIntegration = z.object({\n id: z.string(),\n configSchema: z.record(z.string(), z.unknown()),\n /** JSON Schema of the secrets the integration needs (form rendering only). */\n secretsSchema: z.record(z.string(), z.unknown()),\n actions: z.array(IntegrationActionInfo),\n});\nexport type AvailableIntegration = z.infer<typeof AvailableIntegration>;\n\nexport const AvailableIntegrationsList = z.array(AvailableIntegration);\nexport type AvailableIntegrationsList = z.infer<typeof AvailableIntegrationsList>;\n\n/** The connection row minus credentialRef — not even the reference leaks. */\nexport const Connection = connectionSchema.omit({ credentialRef: true });\nexport type Connection = z.infer<typeof Connection>;\n\nexport const ConnectionsList = z.array(Connection);\nexport type ConnectionsList = z.infer<typeof ConnectionsList>;\n\nexport const ConnectionIdParam = z.object({ id: z.string() });\nexport type ConnectionIdParam = z.infer<typeof ConnectionIdParam>;\n\nexport const ConnectRequest = z.object({\n integrationId: z.string().min(1),\n /** The connection's secrets (API keys, tokens, …). Write-only, never returned;\n * stored as one encrypted JSON document. */\n secrets: jsonRecordSchema,\n config: jsonRecordSchema.optional(),\n});\nexport type ConnectRequest = z.infer<typeof ConnectRequest>;\n\nexport const ReconnectRequest = z.object({\n secrets: jsonRecordSchema,\n});\nexport type ReconnectRequest = z.infer<typeof ReconnectRequest>;\n\nexport const ConfigureRequest = z.object({\n config: jsonRecordSchema.optional(),\n active: z.boolean().optional(),\n});\nexport type ConfigureRequest = z.infer<typeof ConfigureRequest>;\n\nexport const ConnectionActionParams = z.object({ id: z.string(), actionId: z.string() });\nexport type ConnectionActionParams = z.infer<typeof ConnectionActionParams>;\n\n/** The action's input, per its declared inputSchema. */\nexport const InvokeActionRequest = z.object({\n input: z.record(z.string(), z.unknown()).optional(),\n});\nexport type InvokeActionRequest = z.infer<typeof InvokeActionRequest>;\n\n/** Whatever the action resolved with, per its declared outputSchema. */\nexport const ActionInvocationResult = z.object({\n output: z.record(z.string(), z.unknown()),\n});\nexport type ActionInvocationResult = z.infer<typeof ActionInvocationResult>;\n"],"mappings":";;;;AAQA,MAAa,wBAAwB,EAAE,OAAO;CAC5C,IAAI,EAAE,OAAO;CACb,aAAa,EAAE,OAAO;CACtB,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;CAC7C,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAChD,CAAC;;AAID,MAAa,uBAAuB,EAAE,OAAO;CAC3C,IAAI,EAAE,OAAO;CACb,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;;CAE9C,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;CAC/C,SAAS,EAAE,MAAM,qBAAqB;AACxC,CAAC;AAGD,MAAa,4BAA4B,EAAE,MAAM,oBAAoB;;AAIrE,MAAa,aAAa,iBAAiB,KAAK,EAAE,eAAe,KAAK,CAAC;AAGvE,MAAa,kBAAkB,EAAE,MAAM,UAAU;AAGjD,MAAa,oBAAoB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAG5D,MAAa,iBAAiB,EAAE,OAAO;CACrC,eAAe,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;;;CAG/B,SAAS;CACT,QAAQ,iBAAiB,SAAS;AACpC,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO,EACvC,SAAS,iBACX,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO;CACvC,QAAQ,iBAAiB,SAAS;CAClC,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS;AAC/B,CAAC;AAGD,MAAa,yBAAyB,EAAE,OAAO;CAAE,IAAI,EAAE,OAAO;CAAG,UAAU,EAAE,OAAO;AAAE,CAAC;;AAIvF,MAAa,sBAAsB,EAAE,OAAO,EAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EACpD,CAAC;;AAID,MAAa,yBAAyB,EAAE,OAAO,EAC7C,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAC1C,CAAC"}
1
+ {"version":3,"file":"integrations.js","names":[],"sources":["../../../src/http/schemas/integrations.ts"],"sourcesContent":["// Integrations resource schemas. A Connection is an org's link to one external\n// service (Stripe, Slack, …). Secrets are WRITE-ONLY: accepted on\n// connect/reconnect, stored encrypted server-side, and never appear in any\n// response — responses carry configuration and state only.\nimport { z } from 'zod';\nimport { connectionSchema, jsonRecordSchema } from '@headless-lms/core/schemas';\n\n/** An action an integration can be invoked with; schemas are JSON Schema. */\nexport const IntegrationActionInfo = z.object({\n id: z.string(),\n description: z.string(),\n inputSchema: z.record(z.string(), z.unknown()),\n outputSchema: z.record(z.string(), z.unknown()),\n});\nexport type IntegrationActionInfo = z.infer<typeof IntegrationActionInfo>;\n\n/** An integration this deployment supports; configSchema is JSON Schema for its config. */\nexport const AvailableIntegration = z.object({\n id: z.string(),\n configSchema: z.record(z.string(), z.unknown()),\n /** JSON Schema of the secrets the integration needs (form rendering only). */\n secretsSchema: z.record(z.string(), z.unknown()),\n actions: z.array(IntegrationActionInfo),\n});\nexport type AvailableIntegration = z.infer<typeof AvailableIntegration>;\n\nexport const AvailableIntegrationsList = z.array(AvailableIntegration);\nexport type AvailableIntegrationsList = z.infer<typeof AvailableIntegrationsList>;\n\n/** The connection row minus credentialRef — not even the reference leaks. */\nexport const Connection = connectionSchema.omit({ credentialRef: true });\nexport type Connection = z.infer<typeof Connection>;\n\nexport const ConnectionsList = z.array(Connection);\nexport type ConnectionsList = z.infer<typeof ConnectionsList>;\n\nexport const ConnectionIdParam = z.object({ id: z.string() });\nexport type ConnectionIdParam = z.infer<typeof ConnectionIdParam>;\n\nexport const ConnectRequest = z.object({\n integrationId: z.string().min(1),\n /** The connection's secrets (API keys, tokens, …). Write-only, never returned;\n * stored as one encrypted JSON document. */\n secrets: jsonRecordSchema,\n config: jsonRecordSchema.optional(),\n});\nexport type ConnectRequest = z.infer<typeof ConnectRequest>;\n\nexport const ReconnectRequest = z.object({\n secrets: jsonRecordSchema,\n});\nexport type ReconnectRequest = z.infer<typeof ReconnectRequest>;\n\nexport const ConfigureRequest = z.object({\n config: jsonRecordSchema.optional(),\n active: z.boolean().optional(),\n});\nexport type ConfigureRequest = z.infer<typeof ConfigureRequest>;\n\nexport const ConnectionActionParams = z.object({ id: z.string(), actionId: z.string() });\nexport type ConnectionActionParams = z.infer<typeof ConnectionActionParams>;\n\n/** The action's input, per its declared inputSchema. */\nexport const InvokeActionRequest = z.object({\n input: z.record(z.string(), z.unknown()).optional(),\n});\nexport type InvokeActionRequest = z.infer<typeof InvokeActionRequest>;\n\n/** Whatever the action resolved with, per its declared outputSchema. */\nexport const ActionInvocationResult = z.object({\n output: z.record(z.string(), z.unknown()),\n});\nexport type ActionInvocationResult = z.infer<typeof ActionInvocationResult>;\n"],"mappings":";;;;AAQA,MAAa,wBAAwB,EAAE,OAAO;CAC5C,IAAI,EAAE,OAAO;CACb,aAAa,EAAE,OAAO;CACtB,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;CAC7C,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAChD,CAAC;;AAID,MAAa,uBAAuB,EAAE,OAAO;CAC3C,IAAI,EAAE,OAAO;CACb,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;;CAE9C,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;CAC/C,SAAS,EAAE,MAAM,qBAAqB;AACxC,CAAC;AAGD,MAAa,4BAA4B,EAAE,MAAM,oBAAoB;;AAIrE,MAAa,aAAa,iBAAiB,KAAK,EAAE,eAAe,KAAK,CAAC;AAGvE,MAAa,kBAAkB,EAAE,MAAM,UAAU;AAGjD,MAAa,oBAAoB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAG5D,MAAa,iBAAiB,EAAE,OAAO;CACrC,eAAe,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;;;CAG/B,SAAS;CACT,QAAQ,iBAAiB,SAAS;AACpC,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO,EACvC,SAAS,iBACX,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO;CACvC,QAAQ,iBAAiB,SAAS;CAClC,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS;AAC/B,CAAC;AAGD,MAAa,yBAAyB,EAAE,OAAO;CAAE,IAAI,EAAE,OAAO;CAAG,UAAU,EAAE,OAAO;AAAE,CAAC;;AAIvF,MAAa,sBAAsB,EAAE,OAAO,EAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EACpD,CAAC;;AAID,MAAa,yBAAyB,EAAE,OAAO,EAC7C,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAC1C,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { emailSchema } from "@headless-lms/core/schemas";
2
3
  //#region src/http/schemas/invites.ts
3
4
  /** Roles an invitation can carry. Never owner. */
4
5
  const InviteRole = z.enum([
@@ -19,7 +20,7 @@ const Invite = z.object({
19
20
  * only delivery is skipped. Both are ignored for staff roles, whose org user
20
21
  * is mirrored from the auth provider when they join. */
21
22
  const CreateInvite = z.object({
22
- email: z.email(),
23
+ email: emailSchema,
23
24
  role: InviteRole,
24
25
  firstName: z.string().trim().min(1).optional(),
25
26
  lastName: z.string().trim().min(1).optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"invites.js","names":[],"sources":["../../../src/http/schemas/invites.ts"],"sourcesContent":["// Invites resource schemas — domain-owned invites (staff + student).\nimport { z } from \"zod\";\n\n/** Roles an invitation can carry. Never owner. */\nexport const InviteRole = z.enum([\"admin\", \"instructor\", \"student\"]);\nexport type InviteRole = z.infer<typeof InviteRole>;\n\nexport const Invite = z.object({\n id: z.string(),\n email: z.string(),\n role: InviteRole,\n status: z.string(),\n expiresAt: z.date().nullable(),\n createdAt: z.date(),\n});\nexport type Invite = z.infer<typeof Invite>;\n\n/** A student is created by this call, not by the acceptance that follows it, so\n * the admin names them here. `sendEmail: false` still creates everything —\n * only delivery is skipped. Both are ignored for staff roles, whose org user\n * is mirrored from the auth provider when they join. */\nexport const CreateInvite = z.object({\n email: z.email(),\n role: InviteRole,\n firstName: z.string().trim().min(1).optional(),\n lastName: z.string().trim().min(1).optional(),\n sendEmail: z.boolean().default(true),\n});\nexport type CreateInvite = z.infer<typeof CreateInvite>;\n\nexport const ActivateInvite = z.object({ token: z.string().min(1) });\nexport type ActivateInvite = z.infer<typeof ActivateInvite>;\n\n/** accepted → consumed for the current session; auth-required → sign up/in first.\n * accountExists says which of the two: the invitee's email already has an\n * account (sign in to link it) or it does not (create one). */\nexport const ActivateInviteResult = z.object({\n status: z.enum([\"accepted\", \"auth-required\"]),\n email: z.string(),\n role: InviteRole,\n accountExists: z.boolean(),\n});\nexport type ActivateInviteResult = z.infer<typeof ActivateInviteResult>;\n\nexport const InviteTokenParam = z.object({ token: z.string().min(1) });\nexport type InviteTokenParam = z.infer<typeof InviteTokenParam>;\n\n/** Everything the invite landing page needs to render: who the invitation is\n * for, and the names the admin entered, which prefill sign-up. Whether the\n * address already has a login is not reported — the sign-up form discovers\n * that from a duplicate-signup rejection and switches to sign-in. */\nexport const GetInviteResult = z.object({\n email: z.string(),\n firstName: z.string().nullable(),\n lastName: z.string().nullable(),\n});\nexport type GetInviteResult = z.infer<typeof GetInviteResult>;\n\n/** Redeem: mints the session and accepts the invite in one request. `name` is\n * required only when no account exists yet (the sign-up branch). The email is\n * never sent — it is read from the invitation row, so it cannot be steered. */\nexport const RedeemInvite = z.object({\n token: z.string().min(1),\n password: z.string().min(1),\n name: z.string().min(1).optional(),\n});\nexport type RedeemInvite = z.infer<typeof RedeemInvite>;\n\nexport const RedeemInviteResult = z.object({ status: z.literal(\"accepted\") });\nexport type RedeemInviteResult = z.infer<typeof RedeemInviteResult>;\n\nexport const AcceptInvite = z.object({ token: z.string().min(1) });\nexport type AcceptInvite = z.infer<typeof AcceptInvite>;\n\nexport const AcceptInviteResult = z.object({\n\n});\nexport type AcceptInviteResult = z.infer<typeof AcceptInviteResult>;\n"],"mappings":";;;AAIA,MAAa,aAAa,EAAE,KAAK;CAAC;CAAS;CAAc;AAAS,CAAC;AAGnE,MAAa,SAAS,EAAE,OAAO;CAC7B,IAAI,EAAE,OAAO;CACb,OAAO,EAAE,OAAO;CAChB,MAAM;CACN,QAAQ,EAAE,OAAO;CACjB,WAAW,EAAE,KAAK,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,KAAK;AACpB,CAAC;;;;;AAOD,MAAa,eAAe,EAAE,OAAO;CACnC,OAAO,EAAE,MAAM;CACf,MAAM;CACN,WAAW,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC7C,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC5C,WAAW,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI;AACrC,CAAC;AAGD,MAAa,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;;AAMnE,MAAa,uBAAuB,EAAE,OAAO;CAC3C,QAAQ,EAAE,KAAK,CAAC,YAAY,eAAe,CAAC;CAC5C,OAAO,EAAE,OAAO;CAChB,MAAM;CACN,eAAe,EAAE,QAAQ;AAC3B,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;;;AAOrE,MAAa,kBAAkB,EAAE,OAAO;CACtC,OAAO,EAAE,OAAO;CAChB,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;AAChC,CAAC;;;;AAMD,MAAa,eAAe,EAAE,OAAO;CACnC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CAC1B,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;AACnC,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,UAAU,EAAE,CAAC;AAG5E,MAAa,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAGjE,MAAa,qBAAqB,EAAE,OAAO,CAE3C,CAAC"}
1
+ {"version":3,"file":"invites.js","names":[],"sources":["../../../src/http/schemas/invites.ts"],"sourcesContent":["// Invites resource schemas — domain-owned invites (staff + student).\nimport { z } from 'zod';\nimport { emailSchema } from '@headless-lms/core/schemas';\n\n/** Roles an invitation can carry. Never owner. */\nexport const InviteRole = z.enum(['admin', 'instructor', 'student']);\nexport type InviteRole = z.infer<typeof InviteRole>;\n\nexport const Invite = z.object({\n id: z.string(),\n email: z.string(),\n role: InviteRole,\n status: z.string(),\n expiresAt: z.date().nullable(),\n createdAt: z.date(),\n});\nexport type Invite = z.infer<typeof Invite>;\n\n/** A student is created by this call, not by the acceptance that follows it, so\n * the admin names them here. `sendEmail: false` still creates everything —\n * only delivery is skipped. Both are ignored for staff roles, whose org user\n * is mirrored from the auth provider when they join. */\nexport const CreateInvite = z.object({\n email: emailSchema,\n role: InviteRole,\n firstName: z.string().trim().min(1).optional(),\n lastName: z.string().trim().min(1).optional(),\n sendEmail: z.boolean().default(true),\n});\nexport type CreateInvite = z.infer<typeof CreateInvite>;\n\nexport const ActivateInvite = z.object({ token: z.string().min(1) });\nexport type ActivateInvite = z.infer<typeof ActivateInvite>;\n\n/** accepted → consumed for the current session; auth-required → sign up/in first.\n * accountExists says which of the two: the invitee's email already has an\n * account (sign in to link it) or it does not (create one). */\nexport const ActivateInviteResult = z.object({\n status: z.enum(['accepted', 'auth-required']),\n email: z.string(),\n role: InviteRole,\n accountExists: z.boolean(),\n});\nexport type ActivateInviteResult = z.infer<typeof ActivateInviteResult>;\n\nexport const InviteTokenParam = z.object({ token: z.string().min(1) });\nexport type InviteTokenParam = z.infer<typeof InviteTokenParam>;\n\n/** Everything the invite landing page needs to render: who the invitation is\n * for, and the names the admin entered, which prefill sign-up. Whether the\n * address already has a login is not reported — the sign-up form discovers\n * that from a duplicate-signup rejection and switches to sign-in. */\nexport const GetInviteResult = z.object({\n email: z.string(),\n firstName: z.string().nullable(),\n lastName: z.string().nullable(),\n});\nexport type GetInviteResult = z.infer<typeof GetInviteResult>;\n\n/** Redeem: mints the session and accepts the invite in one request. `name` is\n * required only when no account exists yet (the sign-up branch). The email is\n * never sent — it is read from the invitation row, so it cannot be steered. */\nexport const RedeemInvite = z.object({\n token: z.string().min(1),\n password: z.string().min(1),\n name: z.string().min(1).optional(),\n});\nexport type RedeemInvite = z.infer<typeof RedeemInvite>;\n\nexport const RedeemInviteResult = z.object({ status: z.literal('accepted') });\nexport type RedeemInviteResult = z.infer<typeof RedeemInviteResult>;\n\nexport const AcceptInvite = z.object({ token: z.string().min(1) });\nexport type AcceptInvite = z.infer<typeof AcceptInvite>;\n\nexport const AcceptInviteResult = z.object({});\nexport type AcceptInviteResult = z.infer<typeof AcceptInviteResult>;\n"],"mappings":";;;;AAKA,MAAa,aAAa,EAAE,KAAK;CAAC;CAAS;CAAc;AAAS,CAAC;AAGnE,MAAa,SAAS,EAAE,OAAO;CAC7B,IAAI,EAAE,OAAO;CACb,OAAO,EAAE,OAAO;CAChB,MAAM;CACN,QAAQ,EAAE,OAAO;CACjB,WAAW,EAAE,KAAK,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,KAAK;AACpB,CAAC;;;;;AAOD,MAAa,eAAe,EAAE,OAAO;CACnC,OAAO;CACP,MAAM;CACN,WAAW,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC7C,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC5C,WAAW,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI;AACrC,CAAC;AAGD,MAAa,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;;AAMnE,MAAa,uBAAuB,EAAE,OAAO;CAC3C,QAAQ,EAAE,KAAK,CAAC,YAAY,eAAe,CAAC;CAC5C,OAAO,EAAE,OAAO;CAChB,MAAM;CACN,eAAe,EAAE,QAAQ;AAC3B,CAAC;AAGD,MAAa,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;;;AAOrE,MAAa,kBAAkB,EAAE,OAAO;CACtC,OAAO,EAAE,OAAO;CAChB,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;AAChC,CAAC;;;;AAMD,MAAa,eAAe,EAAE,OAAO;CACnC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACvB,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CAC1B,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;AACnC,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,UAAU,EAAE,CAAC;AAG5E,MAAa,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAGjE,MAAa,qBAAqB,EAAE,OAAO,CAAC,CAAC"}
@@ -14,7 +14,15 @@ declare const LearnCourses: z.ZodArray<z.ZodObject<{
14
14
  }>;
15
15
  category: z.ZodString;
16
16
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
17
- settings: z.ZodType<import("@headless-lms/core/types").JsonValue, unknown, z.core.$ZodTypeInternals<import("@headless-lms/core/types").JsonValue, unknown>>;
17
+ settings: z.ZodObject<{
18
+ transcriptDownloads: z.ZodBoolean;
19
+ comments: z.ZodOptional<z.ZodObject<{
20
+ enabled: z.ZodBoolean;
21
+ threaded: z.ZodBoolean;
22
+ requireReview: z.ZodBoolean;
23
+ reactions: z.ZodBoolean;
24
+ }, z.core.$strict>>;
25
+ }, z.core.$strict>;
18
26
  createdAt: z.ZodCoercedDate<unknown>;
19
27
  updatedAt: z.ZodCoercedDate<unknown>;
20
28
  }, z.core.$strict>>;
@@ -77,6 +85,8 @@ declare const LearnDownload: z.ZodObject<{
77
85
  assetId: z.ZodString;
78
86
  seq: z.ZodNumber;
79
87
  displayName: z.ZodNullable<z.ZodString>;
88
+ createdAt: z.ZodCoercedDate<unknown>;
89
+ updatedAt: z.ZodCoercedDate<unknown>;
80
90
  }, z.core.$strict>>;
81
91
  }, z.core.$strip>;
82
92
  type LearnDownload = z.infer<typeof LearnDownload>;
@@ -1 +1 @@
1
- {"version":3,"file":"learn.js","names":[],"sources":["../../../src/http/schemas/learn.ts"],"sourcesContent":["// Learn resource schemas — the student-facing read surface. Reuses the Course\n// and Module payloads (identical wire shape to the back-office API, including\n// the opaque activity `settings` blob) so one renderer path serves both.\nimport { z } from \"zod\";\nimport { progressReportItemSchema } from \"@headless-lms/core/schemas\";\nimport { Course } from \"./content.js\";\nimport { Module } from \"./activities.js\";\nimport { Download, DownloadAsset } from \"./downloads.js\";\nimport { OrgRole } from \"./shared.js\";\n\n/** Courses the authenticated student is actively enrolled in (published only). */\nexport const LearnCourses = z.array(Course);\nexport type LearnCourses = z.infer<typeof LearnCourses>;\n\n/** One enrolled course's module→activity tree (published activities only). */\nexport const LearnModules = z.array(Module);\nexport type LearnModules = z.infer<typeof LearnModules>;\n\nexport const LearnCourseIdParam = z.object({ courseId: z.string() });\nexport type LearnCourseIdParam = z.infer<typeof LearnCourseIdParam>;\n\n/** Downloads the authenticated student is actively entitled to (published only). */\nexport const LearnDownloads = z.array(Download);\nexport type LearnDownloads = z.infer<typeof LearnDownloads>;\n\n/** One entitled download plus its ordered assets. */\nexport const LearnDownload = z.object({\n download: Download,\n assets: z.array(DownloadAsset),\n});\nexport type LearnDownload = z.infer<typeof LearnDownload>;\n\n/** The portal org's public identity — the student surface themes against it. */\nexport const LearnOrg = z.object({\n id: z.string(),\n name: z.string(),\n slug: z.string(),\n});\nexport type LearnOrg = z.infer<typeof LearnOrg>;\n\n/** Who the caller is within the session's org. The session cookie identifies\n * an auth user; the learner surface is keyed on `org_users.id`. */\nexport const LearnViewer = z.object({\n orgUserId: z.string(),\n role: OrgRole,\n});\nexport type LearnViewer = z.infer<typeof LearnViewer>;\n\n/** One reported fact — never a decision. `asset` names the subject within the\n * activity (absent = the activity itself); `completed` is the learner's\n * activity-level claim. Every other field is the asset type's own vocabulary,\n * passed through opaquely. */\nexport const ProgressReportItem = progressReportItemSchema;\nexport type ProgressReportItem = z.infer<typeof ProgressReportItem>;\n\n/** The report envelope: the target (key names the content type) and a batch of\n * items. `[]` is a bare touch — it creates the record. */\nexport const ReportProgress = z.object({\n activity: z.string(),\n reports: z.array(ProgressReportItem),\n});\nexport type ReportProgress = z.infer<typeof ReportProgress>;\n\n/** The reported target's state after the service decided. */\nexport const ProgressStatus = z.object({\n status: z.enum([\"in-progress\", \"completed\"]),\n});\nexport type ProgressStatus = z.infer<typeof ProgressStatus>;\n\n/** Per-course progress, derived on read against current structure. */\nexport const CourseProgress = z.object({\n /** Keyed by activity id; absent key = not started. */\n activities: z.record(z.string(), z.enum([\"in-progress\", \"completed\"])),\n /** Integer 0–100, completed ÷ current activities, rounded. */\n percent: z.int().min(0).max(100),\n completed: z.boolean(),\n /** Keyed by activity id: the per-asset reported state map (opaque). */\n positions: z.record(z.string(), z.unknown()),\n});\nexport type CourseProgress = z.infer<typeof CourseProgress>;\n\n"],"mappings":";;;;;;;;AAWA,MAAa,eAAe,EAAE,MAAM,MAAM;;AAI1C,MAAa,eAAe,EAAE,MAAM,MAAM;AAG1C,MAAa,qBAAqB,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;;AAInE,MAAa,iBAAiB,EAAE,MAAM,QAAQ;;AAI9C,MAAa,gBAAgB,EAAE,OAAO;CACpC,UAAU;CACV,QAAQ,EAAE,MAAM,aAAa;AAC/B,CAAC;;AAID,MAAa,WAAW,EAAE,OAAO;CAC/B,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,OAAO;AACjB,CAAC;;;AAKD,MAAa,cAAc,EAAE,OAAO;CAClC,WAAW,EAAE,OAAO;CACpB,MAAM;AACR,CAAC;;;;;AAOD,MAAa,qBAAqB;;;AAKlC,MAAa,iBAAiB,EAAE,OAAO;CACrC,UAAU,EAAE,OAAO;CACnB,SAAS,EAAE,MAAM,kBAAkB;AACrC,CAAC;;AAID,MAAa,iBAAiB,EAAE,OAAO,EACrC,QAAQ,EAAE,KAAK,CAAC,eAAe,WAAW,CAAC,EAC7C,CAAC;;AAID,MAAa,iBAAiB,EAAE,OAAO;;CAErC,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,KAAK,CAAC,eAAe,WAAW,CAAC,CAAC;;CAErE,SAAS,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG;CAC/B,WAAW,EAAE,QAAQ;;CAErB,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"learn.js","names":[],"sources":["../../../src/http/schemas/learn.ts"],"sourcesContent":["// Learn resource schemas — the student-facing read surface. Reuses the Course\n// and Module payloads (identical wire shape to the back-office API, including\n// the opaque activity `settings` blob) so one renderer path serves both.\nimport { z } from 'zod';\nimport { progressReportItemSchema } from '@headless-lms/core/schemas';\nimport { Course } from './content.js';\nimport { Module } from './activities.js';\nimport { Download, DownloadAsset } from './downloads.js';\nimport { OrgRole } from './shared.js';\n\n/** Courses the authenticated student is actively enrolled in (published only). */\nexport const LearnCourses = z.array(Course);\nexport type LearnCourses = z.infer<typeof LearnCourses>;\n\n/** One enrolled course's module→activity tree (published activities only). */\nexport const LearnModules = z.array(Module);\nexport type LearnModules = z.infer<typeof LearnModules>;\n\nexport const LearnCourseIdParam = z.object({ courseId: z.string() });\nexport type LearnCourseIdParam = z.infer<typeof LearnCourseIdParam>;\n\n/** Downloads the authenticated student is actively entitled to (published only). */\nexport const LearnDownloads = z.array(Download);\nexport type LearnDownloads = z.infer<typeof LearnDownloads>;\n\n/** One entitled download plus its ordered assets. */\nexport const LearnDownload = z.object({\n download: Download,\n assets: z.array(DownloadAsset),\n});\nexport type LearnDownload = z.infer<typeof LearnDownload>;\n\n/** The portal org's public identity — the student surface themes against it. */\nexport const LearnOrg = z.object({\n id: z.string(),\n name: z.string(),\n slug: z.string(),\n});\nexport type LearnOrg = z.infer<typeof LearnOrg>;\n\n/** Who the caller is within the session's org. The session cookie identifies\n * an auth user; the learner surface is keyed on `org_users.id`. */\nexport const LearnViewer = z.object({\n orgUserId: z.string(),\n role: OrgRole,\n});\nexport type LearnViewer = z.infer<typeof LearnViewer>;\n\n/** One reported fact — never a decision. `asset` names the subject within the\n * activity (absent = the activity itself); `completed` is the learner's\n * activity-level claim. Every other field is the asset type's own vocabulary,\n * passed through opaquely. */\nexport const ProgressReportItem = progressReportItemSchema;\nexport type ProgressReportItem = z.infer<typeof ProgressReportItem>;\n\n/** The report envelope: the target (key names the content type) and a batch of\n * items. `[]` is a bare touch — it creates the record. */\nexport const ReportProgress = z.object({\n activity: z.string(),\n reports: z.array(ProgressReportItem),\n});\nexport type ReportProgress = z.infer<typeof ReportProgress>;\n\n/** The reported target's state after the service decided. */\nexport const ProgressStatus = z.object({\n status: z.enum(['in-progress', 'completed']),\n});\nexport type ProgressStatus = z.infer<typeof ProgressStatus>;\n\n/** Per-course progress, derived on read against current structure. */\nexport const CourseProgress = z.object({\n /** Keyed by activity id; absent key = not started. */\n activities: z.record(z.string(), z.enum(['in-progress', 'completed'])),\n /** Integer 0–100, completed ÷ current activities, rounded. */\n percent: z.int().min(0).max(100),\n completed: z.boolean(),\n /** Keyed by activity id: the per-asset reported state map (opaque). */\n positions: z.record(z.string(), z.unknown()),\n});\nexport type CourseProgress = z.infer<typeof CourseProgress>;\n"],"mappings":";;;;;;;;AAWA,MAAa,eAAe,EAAE,MAAM,MAAM;;AAI1C,MAAa,eAAe,EAAE,MAAM,MAAM;AAG1C,MAAa,qBAAqB,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;;AAInE,MAAa,iBAAiB,EAAE,MAAM,QAAQ;;AAI9C,MAAa,gBAAgB,EAAE,OAAO;CACpC,UAAU;CACV,QAAQ,EAAE,MAAM,aAAa;AAC/B,CAAC;;AAID,MAAa,WAAW,EAAE,OAAO;CAC/B,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,OAAO;AACjB,CAAC;;;AAKD,MAAa,cAAc,EAAE,OAAO;CAClC,WAAW,EAAE,OAAO;CACpB,MAAM;AACR,CAAC;;;;;AAOD,MAAa,qBAAqB;;;AAKlC,MAAa,iBAAiB,EAAE,OAAO;CACrC,UAAU,EAAE,OAAO;CACnB,SAAS,EAAE,MAAM,kBAAkB;AACrC,CAAC;;AAID,MAAa,iBAAiB,EAAE,OAAO,EACrC,QAAQ,EAAE,KAAK,CAAC,eAAe,WAAW,CAAC,EAC7C,CAAC;;AAID,MAAa,iBAAiB,EAAE,OAAO;;CAErC,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,KAAK,CAAC,eAAe,WAAW,CAAC,CAAC;;CAErE,SAAS,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG;CAC/B,WAAW,EAAE,QAAQ;;CAErB,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"members.js","names":[],"sources":["../../../src/http/schemas/members.ts"],"sourcesContent":["// Team (org members) resource schemas.\nimport { z } from \"zod\";\nimport { ListQuery, paginated, OrgUserProfileSchema } from \"./shared.js\";\n\n/** Org-scoped roles, mirrored from better-auth's organization plugin. */\nexport const Role = z.enum([\"owner\", \"admin\", \"instructor\"]);\nexport type Role = z.infer<typeof Role>;\n\nexport const MemberStatus = z.enum([\"active\", \"invited\"]);\nexport type MemberStatus = z.infer<typeof MemberStatus>;\n\nexport const Member = OrgUserProfileSchema.extend({\n role: Role,\n status: MemberStatus,\n joinedAt: z.string().nullable(),\n invitedAt: z.string().nullable(),\n});\nexport type Member = z.infer<typeof Member>;\n\nexport const MembersQuery = ListQuery.extend({\n role: Role.optional(),\n status: MemberStatus.optional(),\n});\nexport type MembersQuery = z.infer<typeof MembersQuery>;\n\nexport const MembersPage = paginated(Member);\nexport type MembersPage = z.infer<typeof MembersPage>;\n\nexport const UpdateMemberRole = z.object({ role: Role });\nexport type UpdateMemberRole = z.infer<typeof UpdateMemberRole>;\n\nexport const MemberIdParam = z.object({ id: z.string() });\nexport type MemberIdParam = z.infer<typeof MemberIdParam>;\n"],"mappings":";;;;AAKA,MAAa,OAAO,EAAE,KAAK;CAAC;CAAS;CAAS;AAAY,CAAC;AAG3D,MAAa,eAAe,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC;AAGxD,MAAa,SAAS,qBAAqB,OAAO;CAChD,MAAM;CACN,QAAQ;CACR,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AAGD,MAAa,eAAe,UAAU,OAAO;CAC3C,MAAM,KAAK,SAAS;CACpB,QAAQ,aAAa,SAAS;AAChC,CAAC;AAGD,MAAa,cAAc,UAAU,MAAM;AAG3C,MAAa,mBAAmB,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGvD,MAAa,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"members.js","names":[],"sources":["../../../src/http/schemas/members.ts"],"sourcesContent":["// Team (org members) resource schemas.\nimport { z } from 'zod';\nimport { ListQuery, paginated, OrgUserProfileSchema } from './shared.js';\n\n/** Org-scoped roles, mirrored from better-auth's organization plugin. */\nexport const Role = z.enum(['owner', 'admin', 'instructor']);\nexport type Role = z.infer<typeof Role>;\n\nexport const MemberStatus = z.enum(['active', 'invited']);\nexport type MemberStatus = z.infer<typeof MemberStatus>;\n\nexport const Member = OrgUserProfileSchema.extend({\n role: Role,\n status: MemberStatus,\n joinedAt: z.string().nullable(),\n invitedAt: z.string().nullable(),\n});\nexport type Member = z.infer<typeof Member>;\n\nexport const MembersQuery = ListQuery.extend({\n role: Role.optional(),\n status: MemberStatus.optional(),\n});\nexport type MembersQuery = z.infer<typeof MembersQuery>;\n\nexport const MembersPage = paginated(Member);\nexport type MembersPage = z.infer<typeof MembersPage>;\n\nexport const UpdateMemberRole = z.object({ role: Role });\nexport type UpdateMemberRole = z.infer<typeof UpdateMemberRole>;\n\nexport const MemberIdParam = z.object({ id: z.string() });\nexport type MemberIdParam = z.infer<typeof MemberIdParam>;\n"],"mappings":";;;;AAKA,MAAa,OAAO,EAAE,KAAK;CAAC;CAAS;CAAS;AAAY,CAAC;AAG3D,MAAa,eAAe,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC;AAGxD,MAAa,SAAS,qBAAqB,OAAO;CAChD,MAAM;CACN,QAAQ;CACR,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;AAGD,MAAa,eAAe,UAAU,OAAO;CAC3C,MAAM,KAAK,SAAS;CACpB,QAAQ,aAAa,SAAS;AAChC,CAAC;AAGD,MAAa,cAAc,UAAU,MAAM;AAG3C,MAAa,mBAAmB,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGvD,MAAa,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"organizations.js","names":[],"sources":["../../../src/http/schemas/organizations.ts"],"sourcesContent":["// Organization resource schemas. Org creation is served by the API's own\n// `/api/organizations` route (which drives Better Auth under the hood), so the\n// created org is part of the typed contract and SDK — not the auth namespace.\nimport { z } from \"zod\";\n\nexport const Organization = z.object({\n id: z.string(),\n name: z.string(),\n slug: z.string(),\n createdAt: z.string(),\n});\nexport type Organization = z.infer<typeof Organization>;\n\nexport const CreateOrganization = z.object({\n name: z.string().min(1),\n slug: z.string().min(1),\n});\nexport type CreateOrganization = z.infer<typeof CreateOrganization>;\n\n// Update the active organization's profile. Slug must stay URL-safe (Better Auth\n// enforces uniqueness); both fields are sent together from the settings form.\nexport const UpdateOrganization = z.object({\n name: z.string().min(1).max(100),\n slug: z\n .string()\n .min(1)\n .max(50)\n .regex(/^[a-z0-9-]+$/, \"Use lowercase letters, numbers, and hyphens only\"),\n});\nexport type UpdateOrganization = z.infer<typeof UpdateOrganization>;\n"],"mappings":";;AAKA,MAAa,eAAe,EAAE,OAAO;CACnC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,OAAO;CACf,WAAW,EAAE,OAAO;AACtB,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO;CACzC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC;AAKD,MAAa,qBAAqB,EAAE,OAAO;CACzC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG;CAC/B,MAAM,EACH,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,IAAI,EAAE,CAAC,CACP,MAAM,gBAAgB,kDAAkD;AAC7E,CAAC"}
1
+ {"version":3,"file":"organizations.js","names":[],"sources":["../../../src/http/schemas/organizations.ts"],"sourcesContent":["// Organization resource schemas. Org creation is served by the API's own\n// `/api/organizations` route (which drives Better Auth under the hood), so the\n// created org is part of the typed contract and SDK — not the auth namespace.\nimport { z } from 'zod';\n\nexport const Organization = z.object({\n id: z.string(),\n name: z.string(),\n slug: z.string(),\n createdAt: z.string(),\n});\nexport type Organization = z.infer<typeof Organization>;\n\nexport const CreateOrganization = z.object({\n name: z.string().min(1),\n slug: z.string().min(1),\n});\nexport type CreateOrganization = z.infer<typeof CreateOrganization>;\n\n// Update the active organization's profile. Slug must stay URL-safe (Better Auth\n// enforces uniqueness); both fields are sent together from the settings form.\nexport const UpdateOrganization = z.object({\n name: z.string().min(1).max(100),\n slug: z\n .string()\n .min(1)\n .max(50)\n .regex(/^[a-z0-9-]+$/, 'Use lowercase letters, numbers, and hyphens only'),\n});\nexport type UpdateOrganization = z.infer<typeof UpdateOrganization>;\n"],"mappings":";;AAKA,MAAa,eAAe,EAAE,OAAO;CACnC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,OAAO;CACf,WAAW,EAAE,OAAO;AACtB,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO;CACzC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC;AAKD,MAAa,qBAAqB,EAAE,OAAO;CACzC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG;CAC/B,MAAM,EACH,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,IAAI,EAAE,CAAC,CACP,MAAM,gBAAgB,kDAAkD;AAC7E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","names":[],"sources":["../../../src/http/schemas/settings.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/** A namespace's values. The owning domain defines the shape; the contract\n * carries it opaquely so a new namespace needs no contract change. */\nexport const SettingsValue = z.record(z.string(), z.unknown());\nexport type SettingsValue = z.infer<typeof SettingsValue>;\n\n\nexport const ScopeSettings = z.object({\n scopeId: z.string(),\n namespaces: z.record(z.string(), z.any()),\n});\nexport type ScopeSettings = z.infer<typeof ScopeSettings>;\n\nexport const SettingsScopeParam = z.object({ scopeId: z.string() });\nexport const SettingsNamespaceParam = z.object({\n scopeId: z.string(),\n namespace: z.string(),\n});\n\n/** Partial by definition — the server shallow-merges it into the stored value. */\nexport const PatchSettings = SettingsValue;\n"],"mappings":";;;;AAIA,MAAa,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAI7D,MAAa,gBAAgB,EAAE,OAAO;CACpC,SAAS,EAAE,OAAO;CAClB,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC;AAC1C,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAClE,MAAa,yBAAyB,EAAE,OAAO;CAC7C,SAAS,EAAE,OAAO;CAClB,WAAW,EAAE,OAAO;AACtB,CAAC;;AAGD,MAAa,gBAAgB"}
1
+ {"version":3,"file":"settings.js","names":[],"sources":["../../../src/http/schemas/settings.ts"],"sourcesContent":["import { z } from 'zod';\n\n/** A namespace's values. The owning domain defines the shape; the contract\n * carries it opaquely so a new namespace needs no contract change. */\nexport const SettingsValue = z.record(z.string(), z.unknown());\nexport type SettingsValue = z.infer<typeof SettingsValue>;\n\nexport const ScopeSettings = z.object({\n scopeId: z.string(),\n namespaces: z.record(z.string(), z.any()),\n});\nexport type ScopeSettings = z.infer<typeof ScopeSettings>;\n\nexport const SettingsScopeParam = z.object({ scopeId: z.string() });\nexport const SettingsNamespaceParam = z.object({\n scopeId: z.string(),\n namespace: z.string(),\n});\n\n/** Partial by definition — the server shallow-merges it into the stored value. */\nexport const PatchSettings = SettingsValue;\n"],"mappings":";;;;AAIA,MAAa,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAG7D,MAAa,gBAAgB,EAAE,OAAO;CACpC,SAAS,EAAE,OAAO;CAClB,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC;AAC1C,CAAC;AAGD,MAAa,qBAAqB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAClE,MAAa,yBAAyB,EAAE,OAAO;CAC7C,SAAS,EAAE,OAAO;CAClB,WAAW,EAAE,OAAO;AACtB,CAAC;;AAGD,MAAa,gBAAgB"}
@@ -6,6 +6,7 @@ type Matches<A, _B extends A> = true;
6
6
  declare const ErrorBody: z.ZodObject<{
7
7
  error: z.ZodString;
8
8
  message: z.ZodOptional<z.ZodString>;
9
+ requestId: z.ZodOptional<z.ZodString>;
9
10
  }, z.core.$strip>;
10
11
  type ErrorBody = z.infer<typeof ErrorBody>;
11
12
  /**
@@ -3,7 +3,9 @@ import { z } from "zod";
3
3
  /** Uniform error envelope returned by every non-2xx response. */
4
4
  const ErrorBody = z.object({
5
5
  error: z.string(),
6
- message: z.string().optional()
6
+ message: z.string().optional(),
7
+ /** Server-side correlation id — quote it to find the matching API log line. */
8
+ requestId: z.string().optional()
7
9
  });
8
10
  /**
9
11
  * Common list query for page-based collections. `z.coerce` because query-string
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","names":[],"sources":["../../../src/http/schemas/shared.ts"],"sourcesContent":["// Shared contract primitives reused across resource contracts.\nimport { z } from \"zod\";\n\n/** Fails typecheck when a schema and its domain type drift apart. */\nexport type Matches<A, _B extends A> = true;\n\n/** Uniform error envelope returned by every non-2xx response. */\nexport const ErrorBody = z.object({\n error: z.string(),\n message: z.string().optional(),\n});\nexport type ErrorBody = z.infer<typeof ErrorBody>;\n\n/**\n * Common list query for page-based collections. `z.coerce` because query-string\n * values arrive as strings; defaults make the params optional for callers.\n */\nexport const ListQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().trim().optional(),\n /** Sort field, optionally prefixed with `-` for descending (e.g. `-updatedAt`). */\n sort: z.string().optional(),\n});\nexport type ListQuery = z.infer<typeof ListQuery>;\n\n/** Wrap a row schema into the standard paginated envelope. */\nexport function paginated<T extends z.ZodTypeAny>(row: T) {\n return z.object({\n rows: z.array(row),\n total: z.number().int(),\n page: z.number().int(),\n pageSize: z.number().int(),\n });\n}\n\n/** All four org roles. `members.ts` exports a staff-only three-value `Role`;\n * this is the full set, used wherever a learner can also appear. */\nexport const OrgRole = z.enum([\"owner\", \"admin\", \"instructor\", \"student\"]);\nexport type OrgRole = z.infer<typeof OrgRole>;\n\n/** Mirrors UserProfile in @headless-lms/core/types — keyed on the auth user id. */\nexport const UserProfileSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type UserProfileSchema = z.infer<typeof UserProfileSchema>;\n\n/** Mirrors OrgUserProfile in @headless-lms/core/types — keyed on org_users.id. */\nexport const OrgUserProfileSchema = z.object({\n id: z.string(),\n firstName: z.string().nullable(),\n lastName: z.string().nullable(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type OrgUserProfileSchema = z.infer<typeof OrgUserProfileSchema>;\n"],"mappings":";;;AAOA,MAAa,YAAY,EAAE,OAAO;CAChC,OAAO,EAAE,OAAO;CAChB,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;AAC/B,CAAC;;;;;AAOD,MAAa,YAAY,EAAE,OAAO;CAChC,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;CAC9C,UAAU,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE;CAC5D,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS;;CAEnC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;AAC5B,CAAC;;AAID,SAAgB,UAAkC,KAAQ;CACxD,OAAO,EAAE,OAAO;EACd,MAAM,EAAE,MAAM,GAAG;EACjB,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI;EACtB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI;EACrB,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CAC3B,CAAC;AACH;;;AAIA,MAAa,UAAU,EAAE,KAAK;CAAC;CAAS;CAAS;CAAc;AAAS,CAAC;;AAIzE,MAAa,oBAAoB,EAAE,OAAO;CACxC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC;;AAID,MAAa,uBAAuB,EAAE,OAAO;CAC3C,IAAI,EAAE,OAAO;CACb,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC"}
1
+ {"version":3,"file":"shared.js","names":[],"sources":["../../../src/http/schemas/shared.ts"],"sourcesContent":["// Shared contract primitives reused across resource contracts.\nimport { z } from 'zod';\n\n/** Fails typecheck when a schema and its domain type drift apart. */\nexport type Matches<A, _B extends A> = true;\n\n/** Uniform error envelope returned by every non-2xx response. */\nexport const ErrorBody = z.object({\n error: z.string(),\n message: z.string().optional(),\n /** Server-side correlation id — quote it to find the matching API log line. */\n requestId: z.string().optional(),\n});\nexport type ErrorBody = z.infer<typeof ErrorBody>;\n\n/**\n * Common list query for page-based collections. `z.coerce` because query-string\n * values arrive as strings; defaults make the params optional for callers.\n */\nexport const ListQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().trim().optional(),\n /** Sort field, optionally prefixed with `-` for descending (e.g. `-updatedAt`). */\n sort: z.string().optional(),\n});\nexport type ListQuery = z.infer<typeof ListQuery>;\n\n/** Wrap a row schema into the standard paginated envelope. */\nexport function paginated<T extends z.ZodTypeAny>(row: T) {\n return z.object({\n rows: z.array(row),\n total: z.number().int(),\n page: z.number().int(),\n pageSize: z.number().int(),\n });\n}\n\n/** All four org roles. `members.ts` exports a staff-only three-value `Role`;\n * this is the full set, used wherever a learner can also appear. */\nexport const OrgRole = z.enum(['owner', 'admin', 'instructor', 'student']);\nexport type OrgRole = z.infer<typeof OrgRole>;\n\n/** Mirrors UserProfile in @headless-lms/core/types — keyed on the auth user id. */\nexport const UserProfileSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type UserProfileSchema = z.infer<typeof UserProfileSchema>;\n\n/** Mirrors OrgUserProfile in @headless-lms/core/types — keyed on org_users.id. */\nexport const OrgUserProfileSchema = z.object({\n id: z.string(),\n firstName: z.string().nullable(),\n lastName: z.string().nullable(),\n email: z.string(),\n image: z.string().nullable(),\n});\nexport type OrgUserProfileSchema = z.infer<typeof OrgUserProfileSchema>;\n"],"mappings":";;;AAOA,MAAa,YAAY,EAAE,OAAO;CAChC,OAAO,EAAE,OAAO;CAChB,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;;AAOD,MAAa,YAAY,EAAE,OAAO;CAChC,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;CAC9C,UAAU,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE;CAC5D,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS;;CAEnC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;AAC5B,CAAC;;AAID,SAAgB,UAAkC,KAAQ;CACxD,OAAO,EAAE,OAAO;EACd,MAAM,EAAE,MAAM,GAAG;EACjB,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI;EACtB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI;EACrB,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CAC3B,CAAC;AACH;;;AAIA,MAAa,UAAU,EAAE,KAAK;CAAC;CAAS;CAAS;CAAc;AAAS,CAAC;;AAIzE,MAAa,oBAAoB,EAAE,OAAO;CACxC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC;;AAID,MAAa,uBAAuB,EAAE,OAAO;CAC3C,IAAI,EAAE,OAAO;CACb,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,OAAO,EAAE,OAAO;CAChB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC"}