@classroomio/mcp 0.0.4 → 0.0.6

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 (3) hide show
  1. package/README.md +57 -9
  2. package/dist/index.js +674 -289
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -41,7 +41,9 @@ ClassroomIO DB
41
41
 
42
42
  Current tools:
43
43
 
44
+ - `list_org_courses`
44
45
  - `get_course_structure`
46
+ - `update_course_landing_page`
45
47
  - `create_course_draft`
46
48
  - `create_course_draft_from_course`
47
49
  - `get_course_draft`
@@ -214,7 +216,37 @@ Result:
214
216
  - publish returns the live `courseId` and public `courseUrl`
215
217
  - publish can optionally set a random Unsplash-derived course cover
216
218
 
217
- ### Flow 2: Create a draft from a PDF
219
+ ### Flow 2: Update a landing page with AI-generated copy and media
220
+
221
+ User says:
222
+
223
+ ```text
224
+ Rewrite this course landing page to feel more premium, generate a new cover image, and add three believable reviews.
225
+ ```
226
+
227
+ Expected tool sequence:
228
+
229
+ 1. Agent calls `list_org_courses` if it needs to resolve the course ID by name first.
230
+ 2. Agent calls `update_course_landing_page`.
231
+
232
+ What the landing-page tool can update:
233
+
234
+ - title
235
+ - short description
236
+ - overview
237
+ - requirements
238
+ - goals
239
+ - pricing fields
240
+ - instructor section
241
+ - reviews
242
+ - landing page image
243
+
244
+ The tool can either:
245
+
246
+ - use an explicit `imageUrl`
247
+ - or generate a random Unsplash-based image with `generateImage` and `imageQuery`
248
+
249
+ ### Flow 3: Create a draft from a PDF
218
250
 
219
251
  User says:
220
252
 
@@ -237,7 +269,7 @@ Important:
237
269
  - the PDF does not need to be uploaded to MCP
238
270
  - the MCP package only receives structured JSON
239
271
 
240
- ### Flow 3: Tag a draft before publish
272
+ ### Flow 4: Tag a draft before publish
241
273
 
242
274
  User says:
243
275
 
@@ -257,7 +289,7 @@ Result:
257
289
  - publish ensures the tags exist in ClassroomIO
258
290
  - publish assigns those tags to the live course
259
291
 
260
- ### Flow 4: Update an existing course safely
292
+ ### Flow 5: Update an existing course safely
261
293
 
262
294
  User says:
263
295
 
@@ -267,11 +299,12 @@ Take my existing Algebra course, reorganize it, and rewrite the lesson content f
267
299
 
268
300
  Expected tool sequence:
269
301
 
270
- 1. Agent calls `get_course_structure` with the existing `courseId`.
271
- 2. Agent optionally calls `create_course_draft_from_course` to persist a seeded draft.
272
- 3. Agent updates the draft with the new structure and content using `update_course_draft`.
273
- 4. User reviews the changes.
274
- 5. Agent calls `publish_course_draft_to_existing_course`.
302
+ 1. Agent calls `list_org_courses` if it needs to resolve the course ID from the course name first.
303
+ 2. Agent calls `get_course_structure` with the existing `courseId`.
304
+ 3. Agent optionally calls `create_course_draft_from_course` to persist a seeded draft.
305
+ 4. Agent updates the draft with the new structure and content using `update_course_draft`.
306
+ 5. User reviews the changes.
307
+ 6. Agent calls `publish_course_draft_to_existing_course`.
275
308
 
276
309
  What this publish does today:
277
310
 
@@ -284,7 +317,7 @@ What this publish does today:
284
317
  - upserts lesson language content
285
318
  - merges draft tags into the existing course
286
319
 
287
- ### Flow 5: Add exercises to a live course
320
+ ### Flow 6: Add exercises to a live course
288
321
 
289
322
  User says:
290
323
 
@@ -349,6 +382,21 @@ Exercise tools use the live course directly:
349
382
  - `create_course_exercise_from_template`
350
383
  - `update_course_exercise`
351
384
 
385
+ Supported `questionTypeId` values for exercise payloads:
386
+
387
+ - `1` `RADIO` - Single answer
388
+ - `2` `CHECKBOX` - Multiple answers
389
+ - `3` `TEXTAREA` - Paragraph
390
+ - `4` `TRUE_FALSE` - True/False
391
+ - `5` `SHORT_ANSWER` - Short answer
392
+ - `6` `NUMERIC` - Numeric answer
393
+ - `7` `FILL_BLANK` - Fill in the blank
394
+ - `8` `FILE_UPLOAD` - File upload
395
+ - `9` `MATCHING` - Matching
396
+ - `10` `ORDERING` - Ordering
397
+ - `11` `HOTSPOT` - Hotspot
398
+ - `12` `LINK` - Links
399
+
352
400
  ## Operational Notes
353
401
 
354
402
  - `create_course_draft_from_course` may add warnings if a live course uses legacy lesson notes instead of localized lesson content
package/dist/index.js CHANGED
@@ -35,11 +35,25 @@ var ClassroomIoApiClient = class {
35
35
  method: "GET"
36
36
  });
37
37
  }
38
+ async updateCourseLandingPage(courseId, payload) {
39
+ return this.request(`/course/${courseId}/landing-page`, {
40
+ method: "PUT",
41
+ body: payload
42
+ });
43
+ }
38
44
  async getCourseDraft(draftId) {
39
45
  return this.request(`/organization/course-import/drafts/${draftId}`, {
40
46
  method: "GET"
41
47
  });
42
48
  }
49
+ async listOrganizationCourses(query = {}) {
50
+ const searchParams = new URLSearchParams();
51
+ if (query.tags) searchParams.set("tags", query.tags);
52
+ const querySuffix = searchParams.toString() ? `?${searchParams.toString()}` : "";
53
+ return this.request(`/organization/courses${querySuffix}`, {
54
+ method: "GET"
55
+ });
56
+ }
43
57
  async listCourseExercises(courseId, query = {}) {
44
58
  const searchParams = new URLSearchParams();
45
59
  if (query.lessonId) searchParams.set("lessonId", query.lessonId);
@@ -209,9 +223,257 @@ var ZAutomationCourseTagAssignment = ZAutomationDraftTagAssignment.extend({
209
223
  courseIds: z2.array(z2.string().uuid()).min(1).max(100)
210
224
  });
211
225
 
212
- // ../utils/dist/validation/exercise/exercise.js
226
+ // ../utils/dist/validation/organization/organization.js
213
227
  import * as z3 from "zod";
214
228
 
229
+ // ../utils/dist/constants/org.js
230
+ var blockedSubdomain = [
231
+ "academy",
232
+ "app",
233
+ "apps",
234
+ "blog",
235
+ "build",
236
+ "campaign",
237
+ "church",
238
+ "cloud",
239
+ "community",
240
+ "conference",
241
+ "course",
242
+ "courses",
243
+ "demo",
244
+ "dev",
245
+ "forum",
246
+ "group",
247
+ "groups",
248
+ "help",
249
+ "launch",
250
+ "launchweek",
251
+ "mobile",
252
+ "play",
253
+ "prod",
254
+ "production",
255
+ "schools",
256
+ "stage",
257
+ "staging",
258
+ "support",
259
+ "teacher",
260
+ "teachers",
261
+ "tech",
262
+ "training"
263
+ ];
264
+
265
+ // ../utils/dist/constants/content.js
266
+ var ContentType;
267
+ (function(ContentType2) {
268
+ ContentType2["Section"] = "SECTION";
269
+ ContentType2["Lesson"] = "LESSON";
270
+ ContentType2["Exercise"] = "EXERCISE";
271
+ })(ContentType || (ContentType = {}));
272
+
273
+ // ../utils/dist/validation/organization/organization.js
274
+ var ZGetOrganizations = z3.object({
275
+ siteName: z3.string().min(1).optional(),
276
+ customDomain: z3.string().min(1).optional(),
277
+ isCustomDomainVerified: z3.boolean().optional()
278
+ });
279
+ var ZGetCoursesBySiteName = z3.object({
280
+ siteName: z3.string().min(1),
281
+ tags: z3.string().optional()
282
+ });
283
+ var ZGetOrganizationCoursesQuery = z3.object({
284
+ tags: z3.string().optional()
285
+ });
286
+ var ZGetOrgSetup = z3.object({
287
+ siteName: z3.string().min(1)
288
+ });
289
+ var ZCreateOrgPlan = z3.object({
290
+ orgId: z3.uuid(),
291
+ planName: z3.enum(["EARLY_ADOPTER", "ENTERPRISE", "BASIC"]),
292
+ subscriptionId: z3.string().min(1),
293
+ triggeredBy: z3.number().int().positive(),
294
+ payload: z3.record(z3.string(), z3.unknown())
295
+ });
296
+ var ZUpdateOrgPlan = z3.object({
297
+ subscriptionId: z3.string().min(1),
298
+ payload: z3.record(z3.string(), z3.unknown())
299
+ });
300
+ var ZCancelOrgPlan = z3.object({
301
+ subscriptionId: z3.string().min(1),
302
+ payload: z3.record(z3.string(), z3.unknown())
303
+ });
304
+ var ZCreateOrganization = z3.object({
305
+ name: z3.string().min(5).refine((val) => !/^[-]|[-]$/.test(val), {
306
+ message: "Organization name cannot start or end with a hyphen"
307
+ }),
308
+ siteName: z3.string().min(5).refine((val) => !/^[-]|[-]$/.test(val), {
309
+ message: "Site name cannot start or end with a hyphen"
310
+ }).refine((val) => !blockedSubdomain.includes(val), {
311
+ message: "Sitename already exists."
312
+ })
313
+ });
314
+ var ZUpdateOrganization = z3.object({
315
+ name: z3.string().min(5).refine((val) => !/^[-]|[-]$/.test(val), {
316
+ message: "Organization name cannot start or end with a hyphen"
317
+ }).optional(),
318
+ avatarUrl: z3.url().optional(),
319
+ theme: z3.string().optional(),
320
+ landingpage: z3.record(z3.string(), z3.unknown()).optional(),
321
+ siteName: z3.string().min(1).optional(),
322
+ customDomain: z3.string().nullable().optional(),
323
+ isCustomDomainVerified: z3.boolean().optional(),
324
+ customization: z3.record(z3.string(), z3.unknown()).optional(),
325
+ disableSignup: z3.boolean().optional(),
326
+ disableSignupMessage: z3.string().optional(),
327
+ disableEmailPassword: z3.boolean().optional(),
328
+ disableGoogleAuth: z3.boolean().optional(),
329
+ /** Nested settings (stored in organization.settings JSONB). signup.inviteOnly = true means invite-only signup. */
330
+ settings: z3.object({
331
+ signup: z3.object({
332
+ inviteOnly: z3.boolean().optional()
333
+ }).optional()
334
+ }).optional()
335
+ });
336
+ var ZInviteTeamMembers = z3.object({
337
+ emails: z3.array(z3.string().email()).min(1).max(50),
338
+ roleId: z3.number().int().positive()
339
+ });
340
+ var ZRemoveTeamMember = z3.object({
341
+ memberId: z3.coerce.number().int().positive()
342
+ });
343
+ var ZGetUserAnalytics = z3.object({
344
+ userId: z3.uuid()
345
+ });
346
+
347
+ // ../utils/dist/validation/organization/quiz.js
348
+ import * as z4 from "zod";
349
+ var ZQuizGetParam = z4.object({
350
+ orgId: z4.uuid(),
351
+ quizId: z4.uuid()
352
+ });
353
+ var ZQuizListParam = z4.object({
354
+ orgId: z4.uuid()
355
+ });
356
+ var ZQuizCreate = z4.object({
357
+ title: z4.string().min(1),
358
+ questions: z4.array(z4.any()).optional(),
359
+ timelimit: z4.string().optional(),
360
+ theme: z4.string().optional()
361
+ });
362
+ var ZQuizUpdate = z4.object({
363
+ title: z4.string().min(1).optional(),
364
+ questions: z4.array(z4.any()).optional(),
365
+ timelimit: z4.string().optional(),
366
+ theme: z4.string().optional()
367
+ });
368
+
369
+ // ../utils/dist/validation/organization/exercise.js
370
+ import * as z5 from "zod";
371
+ var ZLMSExercisesParam = z5.object({
372
+ orgId: z5.uuid()
373
+ });
374
+
375
+ // ../utils/dist/validation/organization/invite.js
376
+ import * as z6 from "zod";
377
+ var ZOrganizationInviteTokenParam = z6.object({
378
+ token: z6.string().min(10).max(512)
379
+ });
380
+
381
+ // ../utils/dist/validation/organization/sso.js
382
+ import * as z7 from "zod";
383
+ var SSO_PROVIDERS = ["OKTA", "GOOGLE_WORKSPACE", "AUTH0"];
384
+ var ZCreateSsoConnection = z7.object({
385
+ provider: z7.enum(SSO_PROVIDERS),
386
+ displayName: z7.string().min(1, "Display name is required"),
387
+ issuer: z7.url("Must be a valid URL"),
388
+ domain: z7.string().min(1, "Domain is required").regex(/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/, "Invalid domain format"),
389
+ clientId: z7.string().min(1, "Client ID is required"),
390
+ clientSecret: z7.string().min(1, "Client secret is required"),
391
+ scopes: z7.string().default("openid profile email")
392
+ });
393
+ var ZUpdateSsoConnection = z7.object({
394
+ displayName: z7.string().min(1).optional(),
395
+ issuer: z7.url().optional(),
396
+ domain: z7.string().optional(),
397
+ clientId: z7.string().optional(),
398
+ clientSecret: z7.string().optional(),
399
+ scopes: z7.string().optional(),
400
+ isActive: z7.boolean().optional()
401
+ });
402
+ var ZUpdateSsoPolicy = z7.object({
403
+ forceSso: z7.boolean().optional(),
404
+ autoJoinSsoDomains: z7.boolean().optional(),
405
+ breakGlassEnabled: z7.boolean().optional(),
406
+ defaultRoleId: z7.number().int().positive().optional(),
407
+ roleMapping: z7.record(z7.string(), z7.number()).optional()
408
+ });
409
+ var ZSsoDiscoveryQuery = z7.object({
410
+ email: z7.email("Valid email is required")
411
+ });
412
+ var ZGetSsoConfig = z7.object({
413
+ orgId: z7.uuid()
414
+ });
415
+
416
+ // ../utils/dist/validation/organization/login-link.js
417
+ import { z as z8 } from "zod";
418
+ var ZLoginLinkQuery = z8.object({
419
+ token: z8.string().min(1),
420
+ redirect: z8.string().optional()
421
+ });
422
+ var ZLoginLinkPayload = z8.object({
423
+ sub: z8.uuid(),
424
+ email: z8.email(),
425
+ type: z8.literal("login-link")
426
+ });
427
+
428
+ // ../utils/dist/validation/organization/token-auth.js
429
+ import { z as z9 } from "zod";
430
+ var ZTokenExchangeQuery = z9.object({
431
+ token: z9.string().min(1),
432
+ redirect: z9.string().optional()
433
+ });
434
+ var ZTokenExchangePayload = z9.object({
435
+ sub: z9.string(),
436
+ email: z9.email(),
437
+ name: z9.string().optional(),
438
+ avatar: z9.url().optional(),
439
+ iat: z9.number(),
440
+ exp: z9.number()
441
+ });
442
+
443
+ // ../utils/dist/validation/organization/automation-key.js
444
+ import { z as z10 } from "zod";
445
+ var ZOrganizationApiKeyType = z10.enum(["mcp", "api", "zapier"]);
446
+ var ZOrganizationApiKeyScope = z10.enum([
447
+ "course_import:draft:create",
448
+ "course_import:draft:read",
449
+ "course_import:draft:update",
450
+ "course_import:draft:publish",
451
+ "course:read",
452
+ "course:write",
453
+ "course:tag:write",
454
+ "course:exercise:read",
455
+ "course:exercise:write",
456
+ "public_api:*"
457
+ ]);
458
+ var ZListOrganizationApiKeysQuery = z10.object({
459
+ type: ZOrganizationApiKeyType.optional()
460
+ });
461
+ var ZOrganizationAutomationUsageQuery = z10.object({
462
+ type: ZOrganizationApiKeyType.default("mcp")
463
+ });
464
+ var ZCreateOrganizationApiKey = z10.object({
465
+ type: ZOrganizationApiKeyType,
466
+ label: z10.string().min(1).max(120).optional(),
467
+ expiresAt: z10.string().datetime().optional(),
468
+ scopes: z10.array(ZOrganizationApiKeyScope).min(1).optional()
469
+ });
470
+ var ZOrganizationApiKeyParam = z10.object({
471
+ keyId: z10.string().uuid()
472
+ });
473
+
474
+ // ../utils/dist/validation/exercise/exercise.js
475
+ import * as z11 from "zod";
476
+
215
477
  // ../question-types/dist/question-type-keys.js
216
478
  var QUESTION_TYPE_KEY = {
217
479
  RADIO: "RADIO",
@@ -608,22 +870,22 @@ var QUESTION_VALIDATION_RULES = {
608
870
  ],
609
871
  [QUESTION_TYPE.TEXTAREA]: []
610
872
  };
611
- var ZExerciseUpdateQuestionBase = z3.object({
612
- id: z3.number().int().optional(),
613
- question: z3.string().min(1),
614
- questionTypeId: z3.number().int().min(1).optional(),
873
+ var ZExerciseUpdateQuestionBase = z11.object({
874
+ id: z11.number().int().optional(),
875
+ question: z11.string().min(1),
876
+ questionTypeId: z11.number().int().min(1).optional(),
615
877
  // Added to support question type updates
616
- points: z3.number().int().min(0).optional(),
617
- order: z3.number().int().min(0).optional(),
618
- settings: z3.record(z3.string(), z3.unknown()).optional(),
619
- deletedAt: z3.string().optional(),
878
+ points: z11.number().int().min(0).optional(),
879
+ order: z11.number().int().min(0).optional(),
880
+ settings: z11.record(z11.string(), z11.unknown()).optional(),
881
+ deletedAt: z11.string().optional(),
620
882
  // Marks question as deleted
621
- options: z3.array(z3.object({
622
- id: z3.number().int().optional(),
623
- label: z3.string().min(1),
624
- isCorrect: z3.boolean(),
625
- settings: z3.record(z3.string(), z3.unknown()).optional(),
626
- deletedAt: z3.string().optional()
883
+ options: z11.array(z11.object({
884
+ id: z11.number().int().optional(),
885
+ label: z11.string().min(1),
886
+ isCorrect: z11.boolean(),
887
+ settings: z11.record(z11.string(), z11.unknown()).optional(),
888
+ deletedAt: z11.string().optional()
627
889
  // Marks option as deleted
628
890
  })).optional()
629
891
  });
@@ -643,284 +905,321 @@ function validateQuestionOptions(question, ctx) {
643
905
  }
644
906
  }
645
907
  var ZExerciseUpdateQuestion = ZExerciseUpdateQuestionBase.superRefine(validateQuestionOptions);
646
- var ZExerciseCreate = z3.object({
647
- title: z3.string().min(1),
648
- description: z3.string().optional(),
649
- lessonId: z3.string().optional(),
650
- sectionId: z3.string().optional(),
651
- order: z3.number().int().optional(),
652
- courseId: z3.string().min(1),
653
- dueBy: z3.string().optional(),
654
- questions: z3.array(z3.object({
655
- question: z3.string().min(1),
656
- questionTypeId: z3.number().int().min(1).optional(),
657
- points: z3.number().int().min(0).optional(),
658
- settings: z3.record(z3.string(), z3.unknown()).optional(),
659
- options: z3.array(z3.object({
660
- label: z3.string().min(1),
661
- isCorrect: z3.boolean(),
662
- settings: z3.record(z3.string(), z3.unknown()).optional()
908
+ var ZExerciseCreate = z11.object({
909
+ title: z11.string().min(1),
910
+ description: z11.string().optional(),
911
+ lessonId: z11.string().optional(),
912
+ sectionId: z11.string().optional(),
913
+ order: z11.number().int().optional(),
914
+ courseId: z11.string().min(1),
915
+ dueBy: z11.string().optional(),
916
+ questions: z11.array(z11.object({
917
+ question: z11.string().min(1),
918
+ questionTypeId: z11.number().int().min(1).optional(),
919
+ points: z11.number().int().min(0).optional(),
920
+ settings: z11.record(z11.string(), z11.unknown()).optional(),
921
+ options: z11.array(z11.object({
922
+ label: z11.string().min(1),
923
+ isCorrect: z11.boolean(),
924
+ settings: z11.record(z11.string(), z11.unknown()).optional()
663
925
  })).min(2)
664
926
  })).optional()
665
927
  });
666
- var ZExerciseUpdate = z3.object({
667
- title: z3.string().min(1).optional(),
668
- description: z3.string().optional(),
669
- lessonId: z3.string().optional(),
670
- sectionId: z3.string().optional(),
671
- order: z3.number().int().optional(),
672
- isUnlocked: z3.boolean().optional(),
673
- dueBy: z3.string().optional(),
928
+ var ZExerciseUpdate = z11.object({
929
+ title: z11.string().min(1).optional(),
930
+ description: z11.string().optional(),
931
+ lessonId: z11.string().optional(),
932
+ sectionId: z11.string().optional(),
933
+ order: z11.number().int().optional(),
934
+ isUnlocked: z11.boolean().optional(),
935
+ dueBy: z11.string().optional(),
674
936
  // Changed from iso.datetime() to string to match frontend format
675
- questions: z3.array(ZExerciseUpdateQuestion).optional()
937
+ questions: z11.array(ZExerciseUpdateQuestion).optional()
676
938
  });
677
- var ZExerciseGetParam = z3.object({
678
- exerciseId: z3.string().min(1)
939
+ var ZExerciseGetParam = z11.object({
940
+ exerciseId: z11.string().min(1)
679
941
  });
680
- var ZExerciseListQuery = z3.object({
681
- lessonId: z3.string().optional(),
682
- sectionId: z3.string().optional()
942
+ var ZExerciseListQuery = z11.object({
943
+ lessonId: z11.string().optional(),
944
+ sectionId: z11.string().optional()
683
945
  });
684
- var ZExerciseSubmissionCreate = z3.object({
685
- exerciseId: z3.string().min(1),
686
- answers: z3.array(z3.object({
687
- questionId: z3.number().int(),
688
- optionId: z3.number().int().optional(),
689
- answer: z3.string().optional()
946
+ var ZExerciseSubmissionCreate = z11.object({
947
+ exerciseId: z11.string().min(1),
948
+ answers: z11.array(z11.object({
949
+ questionId: z11.number().int(),
950
+ optionId: z11.number().int().optional(),
951
+ answer: z11.string().optional()
690
952
  })).min(1)
691
953
  });
692
- var ZExerciseFromTemplate = z3.object({
693
- lessonId: z3.string().optional(),
694
- sectionId: z3.string().optional(),
695
- order: z3.number().int().optional(),
696
- templateId: z3.number().int().min(1)
954
+ var ZExerciseFromTemplate = z11.object({
955
+ lessonId: z11.string().optional(),
956
+ sectionId: z11.string().optional(),
957
+ order: z11.number().int().optional(),
958
+ templateId: z11.number().int().min(1)
697
959
  });
698
960
 
699
961
  // ../utils/dist/validation/course-import/course-import.js
700
- import * as z5 from "zod";
962
+ import * as z13 from "zod";
701
963
 
702
964
  // ../utils/dist/validation/course/course.js
703
- import * as z4 from "zod";
704
- var ZCourseClone = z4.object({
705
- title: z4.string().min(1),
706
- description: z4.string().optional(),
707
- slug: z4.string().min(1),
708
- organizationId: z4.string().min(1)
709
- });
710
- var ZCourseCloneParam = z4.object({
711
- courseId: z4.string().min(1)
712
- });
713
- var ZCourseGetParam = z4.object({
714
- courseId: z4.string().min(1)
715
- });
716
- var ZCourseGetQuery = z4.object({
717
- slug: z4.string().optional()
718
- });
719
- var ZCourseGetBySlugParam = z4.object({
720
- slug: z4.string().min(1)
721
- });
722
- var ZCourseEnrollParam = z4.object({
723
- courseId: z4.string().min(1)
724
- });
725
- var ZCourseEnrollBody = z4.object({
726
- inviteToken: z4.string().min(1).optional()
727
- });
728
- var ZCourseDownloadParam = z4.object({
729
- courseId: z4.string().min(1)
730
- });
731
- var ZCertificateDownload = z4.object({
732
- theme: z4.string().min(1),
733
- studentName: z4.string().min(1),
734
- courseName: z4.string().min(1),
735
- courseDescription: z4.string().min(1),
736
- orgName: z4.string().min(1),
737
- orgLogoUrl: z4.string().url().optional(),
738
- facilitator: z4.string().optional()
739
- });
740
- var ZCourseDownloadContent = z4.object({
741
- courseTitle: z4.string().min(1),
742
- orgName: z4.string().min(1),
743
- orgTheme: z4.string().min(1),
744
- lessons: z4.array(z4.object({
745
- lessonTitle: z4.string().min(1),
746
- lessonNumber: z4.string().min(1),
747
- lessonNote: z4.string(),
748
- slideUrl: z4.string().url().optional(),
749
- video: z4.array(z4.string().url()).optional()
965
+ import * as z12 from "zod";
966
+ var ZCourseClone = z12.object({
967
+ title: z12.string().min(1),
968
+ description: z12.string().optional(),
969
+ slug: z12.string().min(1),
970
+ organizationId: z12.string().min(1)
971
+ });
972
+ var ZCourseCloneParam = z12.object({
973
+ courseId: z12.string().min(1)
974
+ });
975
+ var ZCourseGetParam = z12.object({
976
+ courseId: z12.string().min(1)
977
+ });
978
+ var ZCourseGetQuery = z12.object({
979
+ slug: z12.string().optional()
980
+ });
981
+ var ZCourseGetBySlugParam = z12.object({
982
+ slug: z12.string().min(1)
983
+ });
984
+ var ZCourseEnrollParam = z12.object({
985
+ courseId: z12.string().min(1)
986
+ });
987
+ var ZCourseEnrollBody = z12.object({
988
+ inviteToken: z12.string().min(1).optional()
989
+ });
990
+ var ZCourseDownloadParam = z12.object({
991
+ courseId: z12.string().min(1)
992
+ });
993
+ var ZCertificateDownload = z12.object({
994
+ theme: z12.string().min(1),
995
+ studentName: z12.string().min(1),
996
+ courseName: z12.string().min(1),
997
+ courseDescription: z12.string().min(1),
998
+ orgName: z12.string().min(1),
999
+ orgLogoUrl: z12.string().url().optional(),
1000
+ facilitator: z12.string().optional()
1001
+ });
1002
+ var ZCourseDownloadContent = z12.object({
1003
+ courseTitle: z12.string().min(1),
1004
+ orgName: z12.string().min(1),
1005
+ orgTheme: z12.string().min(1),
1006
+ lessons: z12.array(z12.object({
1007
+ lessonTitle: z12.string().min(1),
1008
+ lessonNumber: z12.string().min(1),
1009
+ lessonNote: z12.string(),
1010
+ slideUrl: z12.string().url().optional(),
1011
+ video: z12.array(z12.string().url()).optional()
750
1012
  }))
751
1013
  });
752
- var ZLessonDownloadContent = z4.object({
753
- title: z4.string().min(1),
754
- number: z4.string().min(1),
755
- orgName: z4.string().min(1),
756
- note: z4.string(),
757
- slideUrl: z4.string().url().optional(),
758
- video: z4.array(z4.string().url()).optional(),
759
- courseTitle: z4.string().min(1)
760
- });
761
- var ZCoursePresignUrlUpload = z4.object({
762
- fileName: z4.string().min(1),
763
- fileType: z4.enum(ALLOWED_CONTENT_TYPES)
764
- });
765
- var ZCourseDocumentPresignUrlUpload = z4.object({
766
- fileName: z4.string().min(1),
767
- fileType: z4.enum(ALLOWED_DOCUMENT_TYPES)
768
- });
769
- var ZCourseDownloadPresignedUrl = z4.object({
770
- keys: z4.array(z4.string().min(1)).min(1)
771
- });
772
- var ZCourseContentUpdateItem = z4.object({
773
- id: z4.string().min(1),
774
- type: z4.enum(["LESSON", "EXERCISE"]),
775
- isUnlocked: z4.boolean().optional(),
776
- order: z4.number().int().min(0).optional(),
777
- sectionId: z4.string().nullable().optional()
778
- });
779
- var ZCourseContentUpdate = z4.object({
780
- items: z4.array(ZCourseContentUpdateItem).min(1)
781
- });
782
- var ZCourseContentDeleteItem = z4.object({
783
- id: z4.string().min(1),
784
- type: z4.enum(["LESSON", "EXERCISE"])
785
- });
786
- var ZCourseContentDelete = z4.object({
787
- sectionId: z4.string().min(1).optional(),
788
- items: z4.array(ZCourseContentDeleteItem).min(1).optional()
1014
+ var ZLessonDownloadContent = z12.object({
1015
+ title: z12.string().min(1),
1016
+ number: z12.string().min(1),
1017
+ orgName: z12.string().min(1),
1018
+ note: z12.string(),
1019
+ slideUrl: z12.string().url().optional(),
1020
+ video: z12.array(z12.string().url()).optional(),
1021
+ courseTitle: z12.string().min(1)
1022
+ });
1023
+ var ZCoursePresignUrlUpload = z12.object({
1024
+ fileName: z12.string().min(1),
1025
+ fileType: z12.enum(ALLOWED_CONTENT_TYPES)
1026
+ });
1027
+ var ZCourseDocumentPresignUrlUpload = z12.object({
1028
+ fileName: z12.string().min(1),
1029
+ fileType: z12.enum(ALLOWED_DOCUMENT_TYPES)
1030
+ });
1031
+ var ZCourseDownloadPresignedUrl = z12.object({
1032
+ keys: z12.array(z12.string().min(1)).min(1)
1033
+ });
1034
+ var ZCourseContentUpdateItem = z12.object({
1035
+ id: z12.string().min(1),
1036
+ type: z12.enum(["LESSON", "EXERCISE"]),
1037
+ isUnlocked: z12.boolean().optional(),
1038
+ order: z12.number().int().min(0).optional(),
1039
+ sectionId: z12.string().nullable().optional()
1040
+ });
1041
+ var ZCourseContentUpdate = z12.object({
1042
+ items: z12.array(ZCourseContentUpdateItem).min(1)
1043
+ });
1044
+ var ZCourseContentDeleteItem = z12.object({
1045
+ id: z12.string().min(1),
1046
+ type: z12.enum(["LESSON", "EXERCISE"])
1047
+ });
1048
+ var ZCourseContentDelete = z12.object({
1049
+ sectionId: z12.string().min(1).optional(),
1050
+ items: z12.array(ZCourseContentDeleteItem).min(1).optional()
789
1051
  }).refine((data) => Boolean(data.sectionId) !== Boolean(data.items), {
790
1052
  message: "Provide either sectionId or items",
791
1053
  path: ["sectionId"]
792
1054
  });
793
- var ZCourseCreate = z4.object({
794
- title: z4.string().min(1),
795
- description: z4.string().min(1),
796
- type: z4.enum(["LIVE_CLASS", "SELF_PACED"]),
797
- organizationId: z4.string().min(1)
798
- });
799
- var ZCourseMetadata = z4.object({
800
- requirements: z4.string().optional(),
801
- description: z4.string().optional(),
802
- goals: z4.string().optional(),
803
- videoUrl: z4.string().optional(),
804
- showDiscount: z4.boolean().optional(),
805
- discount: z4.number().optional(),
806
- paymentLink: z4.string().optional(),
807
- reward: z4.object({
808
- show: z4.boolean(),
809
- description: z4.string()
810
- }).optional(),
811
- instructor: z4.object({
812
- name: z4.string(),
813
- role: z4.string(),
814
- coursesNo: z4.number(),
815
- description: z4.string(),
816
- imgUrl: z4.string()
817
- }).optional(),
818
- certificate: z4.object({
819
- templateUrl: z4.string()
820
- }).optional(),
821
- reviews: z4.array(z4.object({
822
- id: z4.number(),
823
- hide: z4.boolean(),
824
- name: z4.string(),
825
- avatar_url: z4.string(),
826
- rating: z4.number(),
827
- created_at: z4.number(),
828
- description: z4.string()
829
- })).optional(),
830
- lessonTabsOrder: z4.array(z4.object({
831
- id: z4.union([z4.literal(1), z4.literal(2), z4.literal(3), z4.literal(4)]),
832
- name: z4.string()
833
- })).optional(),
834
- grading: z4.boolean().optional(),
835
- lessonDownload: z4.boolean().optional(),
836
- allowNewStudent: z4.boolean(),
837
- sectionDisplay: z4.record(z4.string(), z4.boolean()).optional(),
838
- isContentGroupingEnabled: z4.boolean().optional()
839
- });
840
- var ZCourseUpdate = z4.object({
841
- title: z4.string().min(1).optional(),
842
- description: z4.string().min(1).optional(),
843
- type: z4.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
844
- logo: z4.string().optional(),
845
- slug: z4.string().optional(),
846
- isPublished: z4.boolean().optional(),
847
- overview: z4.string().optional(),
1055
+ var ZCourseCreate = z12.object({
1056
+ title: z12.string().min(1),
1057
+ description: z12.string().min(1),
1058
+ type: z12.enum(["LIVE_CLASS", "SELF_PACED"]),
1059
+ organizationId: z12.string().min(1)
1060
+ });
1061
+ var ZCourseReward = z12.object({
1062
+ show: z12.boolean(),
1063
+ description: z12.string()
1064
+ });
1065
+ var ZCourseInstructor = z12.object({
1066
+ name: z12.string(),
1067
+ role: z12.string(),
1068
+ coursesNo: z12.number(),
1069
+ description: z12.string(),
1070
+ imgUrl: z12.string()
1071
+ });
1072
+ var ZCourseCertificate = z12.object({
1073
+ templateUrl: z12.string()
1074
+ });
1075
+ var ZCourseReview = z12.object({
1076
+ id: z12.number(),
1077
+ hide: z12.boolean(),
1078
+ name: z12.string(),
1079
+ avatar_url: z12.string(),
1080
+ rating: z12.number(),
1081
+ created_at: z12.number(),
1082
+ description: z12.string()
1083
+ });
1084
+ var ZCourseLessonTabsOrder = z12.array(z12.object({
1085
+ id: z12.union([z12.literal(1), z12.literal(2), z12.literal(3), z12.literal(4)]),
1086
+ name: z12.string()
1087
+ }));
1088
+ var ZCourseMetadata = z12.object({
1089
+ requirements: z12.string().optional(),
1090
+ description: z12.string().optional(),
1091
+ goals: z12.string().optional(),
1092
+ videoUrl: z12.string().optional(),
1093
+ showDiscount: z12.boolean().optional(),
1094
+ discount: z12.number().optional(),
1095
+ paymentLink: z12.string().optional(),
1096
+ reward: ZCourseReward.optional(),
1097
+ instructor: ZCourseInstructor.optional(),
1098
+ certificate: ZCourseCertificate.optional(),
1099
+ reviews: z12.array(ZCourseReview).optional(),
1100
+ lessonTabsOrder: ZCourseLessonTabsOrder.optional(),
1101
+ grading: z12.boolean().optional(),
1102
+ lessonDownload: z12.boolean().optional(),
1103
+ allowNewStudent: z12.boolean(),
1104
+ sectionDisplay: z12.record(z12.string(), z12.boolean()).optional(),
1105
+ isContentGroupingEnabled: z12.boolean().optional()
1106
+ });
1107
+ var ZCourseLandingPageMetadataUpdate = z12.object({
1108
+ requirements: z12.string().optional(),
1109
+ description: z12.string().optional(),
1110
+ goals: z12.string().optional(),
1111
+ videoUrl: z12.string().optional(),
1112
+ showDiscount: z12.boolean().optional(),
1113
+ discount: z12.number().optional(),
1114
+ paymentLink: z12.string().optional(),
1115
+ reward: ZCourseReward.partial().optional(),
1116
+ instructor: ZCourseInstructor.partial().optional(),
1117
+ certificate: ZCourseCertificate.partial().optional(),
1118
+ reviews: z12.array(ZCourseReview).optional(),
1119
+ lessonTabsOrder: ZCourseLessonTabsOrder.optional(),
1120
+ grading: z12.boolean().optional(),
1121
+ lessonDownload: z12.boolean().optional(),
1122
+ allowNewStudent: z12.boolean().optional(),
1123
+ sectionDisplay: z12.record(z12.string(), z12.boolean()).optional(),
1124
+ isContentGroupingEnabled: z12.boolean().optional()
1125
+ });
1126
+ var ZCourseUpdate = z12.object({
1127
+ title: z12.string().min(1).optional(),
1128
+ description: z12.string().min(1).optional(),
1129
+ type: z12.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
1130
+ logo: z12.string().optional(),
1131
+ slug: z12.string().optional(),
1132
+ isPublished: z12.boolean().optional(),
1133
+ overview: z12.string().optional(),
848
1134
  metadata: ZCourseMetadata.optional(),
849
- isCertificateDownloadable: z4.boolean().optional(),
850
- certificateTheme: z4.string().optional(),
851
- tagIds: z4.array(z4.uuid()).max(100).optional()
852
- });
853
- var ZCourseUpdateParam = z4.object({
854
- courseId: z4.string().min(1)
855
- });
856
- var ZCourseDeleteParam = z4.object({
857
- courseId: z4.string().min(1)
858
- });
859
- var ZCourseProgressParam = z4.object({
860
- courseId: z4.string().min(1)
861
- });
862
- var ZCourseProgressQuery = z4.object({
863
- profileId: z4.string().uuid()
864
- });
865
- var ZCourseUserAnalyticsParam = z4.object({
866
- courseId: z4.string().min(1),
867
- userId: z4.string().uuid()
1135
+ cost: z12.number().int().min(0).optional(),
1136
+ currency: z12.enum(["NGN", "USD"]).optional(),
1137
+ isCertificateDownloadable: z12.boolean().optional(),
1138
+ certificateTheme: z12.string().optional(),
1139
+ tagIds: z12.array(z12.uuid()).max(100).optional()
1140
+ });
1141
+ var ZCourseUpdateParam = z12.object({
1142
+ courseId: z12.string().min(1)
1143
+ });
1144
+ var ZCourseLandingPageUpdate = z12.object({
1145
+ title: z12.string().min(1).optional(),
1146
+ description: z12.string().min(1).optional(),
1147
+ overview: z12.string().optional(),
1148
+ cost: z12.number().int().min(0).optional(),
1149
+ currency: z12.enum(["NGN", "USD"]).optional(),
1150
+ imageUrl: z12.string().url().optional(),
1151
+ generateImage: z12.boolean().optional(),
1152
+ imageQuery: z12.string().min(1).max(120).optional(),
1153
+ metadata: ZCourseLandingPageMetadataUpdate.optional()
1154
+ });
1155
+ var ZCourseDeleteParam = z12.object({
1156
+ courseId: z12.string().min(1)
1157
+ });
1158
+ var ZCourseProgressParam = z12.object({
1159
+ courseId: z12.string().min(1)
1160
+ });
1161
+ var ZCourseProgressQuery = z12.object({
1162
+ profileId: z12.string().uuid()
1163
+ });
1164
+ var ZCourseUserAnalyticsParam = z12.object({
1165
+ courseId: z12.string().min(1),
1166
+ userId: z12.string().uuid()
868
1167
  });
869
1168
 
870
1169
  // ../utils/dist/validation/course-import/course-import.js
871
- var ZSupportedLocale = z5.enum(["en", "hi", "fr", "pt", "de", "vi", "ru", "es", "pl", "da"]);
872
- var ZCourseImportWarning = z5.object({
873
- code: z5.string().min(1),
874
- message: z5.string().min(1),
875
- severity: z5.enum(["info", "warning", "error"])
876
- });
877
- var ZCourseImportSourceReference = z5.object({
878
- type: z5.enum(["prompt", "pdf", "course"]),
879
- label: z5.string().min(1),
880
- pageStart: z5.number().int().min(1).optional(),
881
- pageEnd: z5.number().int().min(1).optional()
882
- });
883
- var ZCourseImportDraftCourse = z5.object({
884
- title: z5.string().min(1),
885
- description: z5.string().min(1),
886
- type: z5.enum(["LIVE_CLASS", "SELF_PACED"]),
1170
+ var ZSupportedLocale = z13.enum(["en", "hi", "fr", "pt", "de", "vi", "ru", "es", "pl", "da"]);
1171
+ var ZCourseImportWarning = z13.object({
1172
+ code: z13.string().min(1),
1173
+ message: z13.string().min(1),
1174
+ severity: z13.enum(["info", "warning", "error"])
1175
+ });
1176
+ var ZCourseImportSourceReference = z13.object({
1177
+ type: z13.enum(["prompt", "pdf", "course"]),
1178
+ label: z13.string().min(1),
1179
+ pageStart: z13.number().int().min(1).optional(),
1180
+ pageEnd: z13.number().int().min(1).optional()
1181
+ });
1182
+ var ZCourseImportDraftCourse = z13.object({
1183
+ title: z13.string().min(1),
1184
+ description: z13.string().min(1),
1185
+ type: z13.enum(["LIVE_CLASS", "SELF_PACED"]),
887
1186
  locale: ZSupportedLocale.default("en"),
888
1187
  metadata: ZCourseMetadata.optional()
889
1188
  });
890
- var ZCourseImportDraftSection = z5.object({
891
- externalId: z5.string().min(1),
892
- title: z5.string().min(1),
893
- order: z5.number().int().min(0)
894
- });
895
- var ZCourseImportDraftLesson = z5.object({
896
- externalId: z5.string().min(1),
897
- sectionExternalId: z5.string().min(1),
898
- title: z5.string().min(1),
899
- order: z5.number().int().min(0),
900
- isUnlocked: z5.boolean().optional(),
901
- public: z5.boolean().optional()
902
- });
903
- var ZCourseImportDraftLessonLanguage = z5.object({
904
- lessonExternalId: z5.string().min(1),
1189
+ var ZCourseImportDraftSection = z13.object({
1190
+ externalId: z13.string().min(1),
1191
+ title: z13.string().min(1),
1192
+ order: z13.number().int().min(0)
1193
+ });
1194
+ var ZCourseImportDraftLesson = z13.object({
1195
+ externalId: z13.string().min(1),
1196
+ sectionExternalId: z13.string().min(1),
1197
+ title: z13.string().min(1),
1198
+ order: z13.number().int().min(0),
1199
+ isUnlocked: z13.boolean().optional(),
1200
+ public: z13.boolean().optional()
1201
+ });
1202
+ var ZCourseImportDraftLessonLanguage = z13.object({
1203
+ lessonExternalId: z13.string().min(1),
905
1204
  locale: ZSupportedLocale,
906
- content: z5.string().min(1)
1205
+ content: z13.string().min(1)
907
1206
  });
908
- var ZCourseImportDraftPayload = z5.object({
1207
+ var ZCourseImportDraftPayload = z13.object({
909
1208
  course: ZCourseImportDraftCourse,
910
- tags: z5.array(z5.string().trim().min(1).max(80)).max(100).default([]),
911
- sections: z5.array(ZCourseImportDraftSection).min(1),
912
- lessons: z5.array(ZCourseImportDraftLesson).min(1),
913
- lessonLanguages: z5.array(ZCourseImportDraftLessonLanguage).min(1),
914
- exercises: z5.array(z5.record(z5.string(), z5.unknown())).optional(),
915
- sourceReferences: z5.array(ZCourseImportSourceReference).optional(),
916
- warnings: z5.array(ZCourseImportWarning).default([])
1209
+ tags: z13.array(z13.string().trim().min(1).max(80)).max(100).default([]),
1210
+ sections: z13.array(ZCourseImportDraftSection).min(1),
1211
+ lessons: z13.array(ZCourseImportDraftLesson).min(1),
1212
+ lessonLanguages: z13.array(ZCourseImportDraftLessonLanguage).min(1),
1213
+ exercises: z13.array(z13.record(z13.string(), z13.unknown())).optional(),
1214
+ sourceReferences: z13.array(ZCourseImportSourceReference).optional(),
1215
+ warnings: z13.array(ZCourseImportWarning).default([])
917
1216
  }).superRefine((value, ctx) => {
918
1217
  const normalizedTags = /* @__PURE__ */ new Set();
919
1218
  value.tags.forEach((tag, index) => {
920
1219
  const tagKey = tag.trim().toLowerCase();
921
1220
  if (normalizedTags.has(tagKey)) {
922
1221
  ctx.addIssue({
923
- code: z5.ZodIssueCode.custom,
1222
+ code: z13.ZodIssueCode.custom,
924
1223
  path: ["tags", index],
925
1224
  message: "Draft tags must be unique"
926
1225
  });
@@ -931,7 +1230,7 @@ var ZCourseImportDraftPayload = z5.object({
931
1230
  value.sections.forEach((section, index) => {
932
1231
  if (sectionIds.has(section.externalId)) {
933
1232
  ctx.addIssue({
934
- code: z5.ZodIssueCode.custom,
1233
+ code: z13.ZodIssueCode.custom,
935
1234
  path: ["sections", index, "externalId"],
936
1235
  message: "Section externalId must be unique"
937
1236
  });
@@ -942,7 +1241,7 @@ var ZCourseImportDraftPayload = z5.object({
942
1241
  value.lessons.forEach((lesson, index) => {
943
1242
  if (lessonIds.has(lesson.externalId)) {
944
1243
  ctx.addIssue({
945
- code: z5.ZodIssueCode.custom,
1244
+ code: z13.ZodIssueCode.custom,
946
1245
  path: ["lessons", index, "externalId"],
947
1246
  message: "Lesson externalId must be unique"
948
1247
  });
@@ -950,7 +1249,7 @@ var ZCourseImportDraftPayload = z5.object({
950
1249
  lessonIds.add(lesson.externalId);
951
1250
  if (!sectionIds.has(lesson.sectionExternalId)) {
952
1251
  ctx.addIssue({
953
- code: z5.ZodIssueCode.custom,
1252
+ code: z13.ZodIssueCode.custom,
954
1253
  path: ["lessons", index, "sectionExternalId"],
955
1254
  message: "Lesson sectionExternalId must reference an existing section"
956
1255
  });
@@ -959,51 +1258,111 @@ var ZCourseImportDraftPayload = z5.object({
959
1258
  value.lessonLanguages.forEach((lessonLanguage, index) => {
960
1259
  if (!lessonIds.has(lessonLanguage.lessonExternalId)) {
961
1260
  ctx.addIssue({
962
- code: z5.ZodIssueCode.custom,
1261
+ code: z13.ZodIssueCode.custom,
963
1262
  path: ["lessonLanguages", index, "lessonExternalId"],
964
1263
  message: "Lesson language must reference an existing lesson"
965
1264
  });
966
1265
  }
967
1266
  });
968
1267
  });
969
- var ZCourseImportDraftCreate = z5.object({
970
- sourceType: z5.enum(["prompt", "pdf", "course"]),
971
- idempotencyKey: z5.string().min(1).optional(),
972
- summary: z5.record(z5.string(), z5.unknown()).optional(),
973
- sourceArtifacts: z5.array(z5.record(z5.string(), z5.unknown())).optional(),
1268
+ var ZCourseImportDraftCreate = z13.object({
1269
+ sourceType: z13.enum(["prompt", "pdf", "course"]),
1270
+ idempotencyKey: z13.string().min(1).optional(),
1271
+ summary: z13.record(z13.string(), z13.unknown()).optional(),
1272
+ sourceArtifacts: z13.array(z13.record(z13.string(), z13.unknown())).optional(),
974
1273
  draft: ZCourseImportDraftPayload
975
1274
  });
976
- var ZCourseImportCourseParam = z5.object({
977
- courseId: z5.string().min(1)
1275
+ var ZCourseImportCourseParam = z13.object({
1276
+ courseId: z13.string().min(1)
978
1277
  });
979
- var ZCourseImportDraftCreateFromCourse = z5.object({
980
- courseId: z5.string().min(1),
981
- idempotencyKey: z5.string().min(1).optional(),
982
- summary: z5.record(z5.string(), z5.unknown()).optional(),
983
- sourceArtifacts: z5.array(z5.record(z5.string(), z5.unknown())).optional()
1278
+ var ZCourseImportDraftCreateFromCourse = z13.object({
1279
+ courseId: z13.string().min(1),
1280
+ idempotencyKey: z13.string().min(1).optional(),
1281
+ summary: z13.record(z13.string(), z13.unknown()).optional(),
1282
+ sourceArtifacts: z13.array(z13.record(z13.string(), z13.unknown())).optional()
984
1283
  });
985
- var ZCourseImportDraftGetParam = z5.object({
986
- draftId: z5.string().uuid()
1284
+ var ZCourseImportDraftGetParam = z13.object({
1285
+ draftId: z13.string().uuid()
987
1286
  });
988
- var ZCourseImportDraftUpdate = z5.object({
989
- summary: z5.record(z5.string(), z5.unknown()).optional(),
990
- sourceArtifacts: z5.array(z5.record(z5.string(), z5.unknown())).optional(),
991
- warnings: z5.array(ZCourseImportWarning).optional(),
1287
+ var ZCourseImportDraftUpdate = z13.object({
1288
+ summary: z13.record(z13.string(), z13.unknown()).optional(),
1289
+ sourceArtifacts: z13.array(z13.record(z13.string(), z13.unknown())).optional(),
1290
+ warnings: z13.array(ZCourseImportWarning).optional(),
992
1291
  draft: ZCourseImportDraftPayload.optional()
993
1292
  });
994
- var ZCourseImportDraftPublish = z5.object({
995
- title: z5.string().min(1).optional(),
996
- description: z5.string().min(1).optional(),
997
- type: z5.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
1293
+ var ZCourseImportDraftPublish = z13.object({
1294
+ title: z13.string().min(1).optional(),
1295
+ description: z13.string().min(1).optional(),
1296
+ type: z13.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
998
1297
  metadata: ZCourseMetadata.optional(),
999
- bannerImageUrl: z5.string().url().optional(),
1000
- bannerImageQuery: z5.string().min(1).max(120).optional(),
1001
- generateBannerImage: z5.boolean().optional()
1298
+ bannerImageUrl: z13.string().url().optional(),
1299
+ bannerImageQuery: z13.string().min(1).max(120).optional(),
1300
+ generateBannerImage: z13.boolean().optional()
1002
1301
  });
1003
1302
  var ZCourseImportDraftPublishToCourse = ZCourseImportDraftPublish.extend({
1004
- courseId: z5.string().min(1)
1303
+ courseId: z13.string().min(1)
1005
1304
  });
1006
1305
 
1306
+ // ../utils/dist/validation/course/section.js
1307
+ import * as z14 from "zod";
1308
+ var ZCourseSectionCreate = z14.object({
1309
+ title: z14.string().min(1),
1310
+ courseId: z14.string().min(1),
1311
+ order: z14.number().int().min(0).optional()
1312
+ });
1313
+ var ZCourseSectionUpdate = z14.object({
1314
+ title: z14.string().min(1).optional(),
1315
+ order: z14.number().int().min(0).optional()
1316
+ });
1317
+ var ZCourseSectionPromoteUngrouped = z14.object({
1318
+ title: z14.string().min(1)
1319
+ });
1320
+ var ZCourseSectionGetParam = z14.object({
1321
+ sectionId: z14.string().min(1)
1322
+ });
1323
+ var ZCourseSectionReorder = z14.object({
1324
+ sections: z14.array(z14.object({
1325
+ id: z14.string().min(1),
1326
+ order: z14.number().int().min(0)
1327
+ })).min(1)
1328
+ });
1329
+
1330
+ // ../utils/dist/validation/course/invite.js
1331
+ import * as z15 from "zod";
1332
+ var ZCourseInviteParam = z15.object({
1333
+ courseId: z15.string().min(1)
1334
+ });
1335
+ var ZCourseInviteRevokeParam = z15.object({
1336
+ courseId: z15.string().min(1),
1337
+ inviteId: z15.string().uuid()
1338
+ });
1339
+ var ZCourseInviteAuditParam = z15.object({
1340
+ courseId: z15.string().min(1),
1341
+ inviteId: z15.string().uuid()
1342
+ });
1343
+ var ZCourseInviteTokenParam = z15.object({
1344
+ token: z15.string().min(1)
1345
+ });
1346
+ var ZCreatePublicCourseInviteLink = z15.object({
1347
+ courseId: z15.uuid()
1348
+ });
1349
+ var ZCourseInvitePreset = z15.enum(["ONE_TIME_24H", "MULTI_USE_7D", "MULTI_USE_30D", "CUSTOM"]);
1350
+ var ZCreateCourseInvite = z15.object({
1351
+ preset: ZCourseInvitePreset.default("MULTI_USE_30D"),
1352
+ expiresAt: z15.string().min(1).optional(),
1353
+ maxUses: z15.number().int().min(1).max(1e3).optional(),
1354
+ allowedEmails: z15.array(z15.string().email()).max(100).optional(),
1355
+ allowedDomains: z15.array(z15.string().min(1)).max(100).optional(),
1356
+ recipientEmails: z15.array(z15.string().email()).max(500).optional(),
1357
+ recipientCsv: z15.string().max(25e3).optional(),
1358
+ sendEmail: z15.boolean().default(false),
1359
+ metadata: z15.record(z15.string(), z15.unknown()).optional()
1360
+ }).refine((data) => {
1361
+ const hasEmails = (data.recipientEmails?.length ?? 0) > 0;
1362
+ const hasCsv = typeof data.recipientCsv === "string" && data.recipientCsv.trim().length > 0;
1363
+ return hasEmails || hasCsv;
1364
+ }, { message: "recipientEmails or recipientCsv is required", path: ["recipientEmails"] });
1365
+
1007
1366
  // src/tools/course-drafts.ts
1008
1367
  var ZUpdateCourseDraftToolInput = ZCourseImportDraftUpdate.extend({
1009
1368
  draftId: ZCourseImportDraftGetParam.shape.draftId
@@ -1029,6 +1388,9 @@ var ZUpdateCourseExerciseToolInput = ZExerciseUpdate.extend({
1029
1388
  courseId: ZCourseImportCourseParam.shape.courseId,
1030
1389
  exerciseId: ZExerciseGetParam.shape.exerciseId
1031
1390
  });
1391
+ var ZUpdateCourseLandingPageToolInput = ZCourseLandingPageUpdate.extend({
1392
+ courseId: ZCourseImportCourseParam.shape.courseId
1393
+ });
1032
1394
  var ZPublishCourseDraftToolInput = ZCourseImportDraftPublish.extend({
1033
1395
  draftId: ZCourseImportDraftGetParam.shape.draftId
1034
1396
  });
@@ -1037,6 +1399,7 @@ var ZPublishCourseDraftToExistingCourseToolInput = ZCourseImportDraftPublishToCo
1037
1399
  });
1038
1400
  var createCourseDraftShape = ZCourseImportDraftCreate.shape;
1039
1401
  var createCourseDraftFromCourseShape = ZCourseImportDraftCreateFromCourse.shape;
1402
+ var listOrganizationCoursesShape = ZGetOrganizationCoursesQuery.shape;
1040
1403
  var getCourseStructureShape = ZCourseImportCourseParam.shape;
1041
1404
  var getCourseDraftShape = ZCourseImportDraftGetParam.shape;
1042
1405
  var updateCourseDraftShape = ZUpdateCourseDraftToolInput.shape;
@@ -1046,10 +1409,22 @@ var getCourseExerciseShape = ZGetCourseExerciseToolInput.shape;
1046
1409
  var createCourseExerciseShape = ZCreateCourseExerciseToolInput.shape;
1047
1410
  var createCourseExerciseFromTemplateShape = ZCreateCourseExerciseFromTemplateToolInput.shape;
1048
1411
  var updateCourseExerciseShape = ZUpdateCourseExerciseToolInput.shape;
1412
+ var updateCourseLandingPageShape = ZUpdateCourseLandingPageToolInput.shape;
1049
1413
  var publishCourseDraftShape = ZPublishCourseDraftToolInput.shape;
1050
1414
  var publishCourseDraftToExistingCourseShape = ZPublishCourseDraftToExistingCourseToolInput.shape;
1051
1415
  var tagCoursesShape = ZAutomationCourseTagAssignment.shape;
1416
+ var SUPPORTED_QUESTION_TYPES_GUIDE = "Supported questionTypeId values: RADIO=1 (Single answer), CHECKBOX=2 (Multiple answers), TEXTAREA=3 (Paragraph), TRUE_FALSE=4 (True/False), SHORT_ANSWER=5 (Short answer), NUMERIC=6 (Numeric answer), FILL_BLANK=7 (Fill in the blank), FILE_UPLOAD=8 (File upload), MATCHING=9 (Matching), ORDERING=10 (Ordering), HOTSPOT=11 (Hotspot), LINK=12 (Links). Use the numeric ids in exercise payloads.";
1052
1417
  function registerCourseDraftTools(server, apiClient) {
1418
+ server.tool(
1419
+ "list_org_courses",
1420
+ "List all courses in the authenticated organization. Use this when the user refers to a course by name and you need to discover the available course IDs first.",
1421
+ listOrganizationCoursesShape,
1422
+ async (args) => {
1423
+ const query = ZGetOrganizationCoursesQuery.parse(args);
1424
+ const result = await apiClient.listOrganizationCourses(query);
1425
+ return jsonContent(result);
1426
+ }
1427
+ );
1053
1428
  server.tool(
1054
1429
  "get_course_structure",
1055
1430
  "Read the current live course structure. Use this before creating a fresh draft for post-publish edits.",
@@ -1060,6 +1435,16 @@ function registerCourseDraftTools(server, apiClient) {
1060
1435
  return jsonContent(result);
1061
1436
  }
1062
1437
  );
1438
+ server.tool(
1439
+ "update_course_landing_page",
1440
+ "Update landing-page-facing course fields on a live course, including headline copy, overview, requirements, goals, pricing, reviews, instructor information, and the course image. Use imageUrl to set an explicit cover image, or set generateImage/imageQuery to fetch a random Unsplash-based image.",
1441
+ updateCourseLandingPageShape,
1442
+ async (args) => {
1443
+ const { courseId, ...payload } = ZUpdateCourseLandingPageToolInput.parse(args);
1444
+ const result = await apiClient.updateCourseLandingPage(courseId, payload);
1445
+ return jsonContent(result);
1446
+ }
1447
+ );
1063
1448
  server.tool(
1064
1449
  "create_course_draft",
1065
1450
  "Create a new unpublished course draft from structured course JSON. Use this before the first publish.",
@@ -1112,7 +1497,7 @@ function registerCourseDraftTools(server, apiClient) {
1112
1497
  );
1113
1498
  server.tool(
1114
1499
  "create_course_exercise",
1115
- "Create a new exercise directly on a live course. Use this for adding exercises after a course has already been published.",
1500
+ `Create a new exercise directly on a live course. Use this for adding exercises after a course has already been published. ${SUPPORTED_QUESTION_TYPES_GUIDE}`,
1116
1501
  createCourseExerciseShape,
1117
1502
  async (args) => {
1118
1503
  const { courseId, ...payload } = ZCreateCourseExerciseToolInput.parse(args);
@@ -1132,7 +1517,7 @@ function registerCourseDraftTools(server, apiClient) {
1132
1517
  );
1133
1518
  server.tool(
1134
1519
  "update_course_exercise",
1135
- "Update an existing exercise on a live course, including questions and options.",
1520
+ `Update an existing exercise on a live course, including questions and options. ${SUPPORTED_QUESTION_TYPES_GUIDE}`,
1136
1521
  updateCourseExerciseShape,
1137
1522
  async (args) => {
1138
1523
  const { courseId, exerciseId, ...payload } = ZUpdateCourseExerciseToolInput.parse(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classroomio/mcp",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",