@anantagnanam/lms 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.
- package/LICENSE +21 -21
- package/README.md +23 -2
- package/astro/client.ts +73 -151
- package/astro/components/CourseOverview.astro +25 -3
- package/astro/components/LearnerDashboard.astro +6 -0
- package/astro/components/LearningShell.astro +10 -1
- package/astro/components/LessonAvailabilityNote.astro +26 -0
- package/astro/components/LessonContent.astro +53 -0
- package/astro/components/LessonPlayer.astro +40 -61
- package/astro/components/MediaPlayer.astro +55 -4
- package/astro/media-player.ts +99 -0
- package/astro/pages/author-preview.astro +71 -0
- package/astro/pages/course.astro +10 -0
- package/astro/pages/lesson.astro +3 -0
- package/astro/pages/library.astro +173 -0
- package/astro/pages/paths.astro +73 -0
- package/astro/quiz-drafts.ts +87 -0
- package/astro/quiz-player.ts +362 -0
- package/astro/styles.css +12 -0
- package/dist/admin.d.ts +3 -1
- package/dist/admin.js +585 -116
- package/dist/admin.js.map +1 -1
- package/dist/astro.js +3 -0
- package/dist/astro.js.map +1 -1
- package/dist/{constants-C0kT94tc.js → constants-Cnx7k82Z.js} +25 -3
- package/dist/constants-Cnx7k82Z.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime.d.ts +104 -12
- package/dist/runtime.js +896 -116
- package/dist/runtime.js.map +1 -1
- package/dist/schemas.d.ts +68 -1
- package/dist/schemas.js +34 -2
- package/dist/schemas.js.map +1 -1
- package/dist/server.d.ts +11 -1
- package/dist/server.js +13 -2
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +107 -4
- package/package.json +1 -1
- package/dist/constants-C0kT94tc.js.map +0 -1
package/dist/schemas.d.ts
CHANGED
|
@@ -83,6 +83,12 @@ declare const lessonSchema: z.ZodObject<{
|
|
|
83
83
|
field: z.ZodDefault<z.ZodString>;
|
|
84
84
|
}, z.core.$strip>>>;
|
|
85
85
|
mediaUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
86
|
+
transcript: z.ZodDefault<z.ZodString>;
|
|
87
|
+
captions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
88
|
+
src: z.ZodString;
|
|
89
|
+
language: z.ZodString;
|
|
90
|
+
label: z.ZodString;
|
|
91
|
+
}, z.core.$strip>>>;
|
|
86
92
|
liveStartsAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
87
93
|
durationMinutes: z.ZodDefault<z.ZodNumber>;
|
|
88
94
|
minStudySeconds: z.ZodDefault<z.ZodNumber>;
|
|
@@ -157,6 +163,12 @@ declare const moduleSchema: z.ZodObject<{
|
|
|
157
163
|
field: z.ZodDefault<z.ZodString>;
|
|
158
164
|
}, z.core.$strip>>>;
|
|
159
165
|
mediaUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
166
|
+
transcript: z.ZodDefault<z.ZodString>;
|
|
167
|
+
captions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
168
|
+
src: z.ZodString;
|
|
169
|
+
language: z.ZodString;
|
|
170
|
+
label: z.ZodString;
|
|
171
|
+
}, z.core.$strip>>>;
|
|
160
172
|
liveStartsAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
161
173
|
durationMinutes: z.ZodDefault<z.ZodNumber>;
|
|
162
174
|
minStudySeconds: z.ZodDefault<z.ZodNumber>;
|
|
@@ -279,6 +291,12 @@ declare const courseDataSchema: z.ZodObject<{
|
|
|
279
291
|
field: z.ZodDefault<z.ZodString>;
|
|
280
292
|
}, z.core.$strip>>>;
|
|
281
293
|
mediaUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
294
|
+
transcript: z.ZodDefault<z.ZodString>;
|
|
295
|
+
captions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
296
|
+
src: z.ZodString;
|
|
297
|
+
language: z.ZodString;
|
|
298
|
+
label: z.ZodString;
|
|
299
|
+
}, z.core.$strip>>>;
|
|
282
300
|
liveStartsAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
283
301
|
durationMinutes: z.ZodDefault<z.ZodNumber>;
|
|
284
302
|
minStudySeconds: z.ZodDefault<z.ZodNumber>;
|
|
@@ -405,6 +423,12 @@ declare const courseSaveSchema: z.ZodObject<{
|
|
|
405
423
|
field: z.ZodDefault<z.ZodString>;
|
|
406
424
|
}, z.core.$strip>>>;
|
|
407
425
|
mediaUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
426
|
+
transcript: z.ZodDefault<z.ZodString>;
|
|
427
|
+
captions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
428
|
+
src: z.ZodString;
|
|
429
|
+
language: z.ZodString;
|
|
430
|
+
label: z.ZodString;
|
|
431
|
+
}, z.core.$strip>>>;
|
|
408
432
|
liveStartsAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
409
433
|
durationMinutes: z.ZodDefault<z.ZodNumber>;
|
|
410
434
|
minStudySeconds: z.ZodDefault<z.ZodNumber>;
|
|
@@ -486,6 +510,14 @@ declare const quizSubmitSchema: z.ZodObject<{
|
|
|
486
510
|
lessonId: z.ZodString;
|
|
487
511
|
attemptId: z.ZodString;
|
|
488
512
|
answers: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
513
|
+
expectedDraftRevision: z.ZodOptional<z.ZodNumber>;
|
|
514
|
+
}, z.core.$strip>;
|
|
515
|
+
declare const quizDraftSchema: z.ZodObject<{
|
|
516
|
+
courseId: z.ZodString;
|
|
517
|
+
lessonId: z.ZodString;
|
|
518
|
+
attemptId: z.ZodString;
|
|
519
|
+
answers: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
520
|
+
expectedDraftRevision: z.ZodDefault<z.ZodNumber>;
|
|
489
521
|
}, z.core.$strip>;
|
|
490
522
|
declare const assignmentSubmitSchema: z.ZodObject<{
|
|
491
523
|
courseId: z.ZodString;
|
|
@@ -579,6 +611,41 @@ declare const noteSchema: z.ZodObject<{
|
|
|
579
611
|
lessonId: z.ZodString;
|
|
580
612
|
note: z.ZodString;
|
|
581
613
|
}, z.core.$strip>;
|
|
614
|
+
declare const preferencesSchema: z.ZodObject<{
|
|
615
|
+
emailNotifications: z.ZodDefault<z.ZodBoolean>;
|
|
616
|
+
weeklyGoalLessons: z.ZodDefault<z.ZodNumber>;
|
|
617
|
+
}, z.core.$strip>;
|
|
618
|
+
declare const playbackSchema: z.ZodObject<{
|
|
619
|
+
courseId: z.ZodString;
|
|
620
|
+
lessonId: z.ZodString;
|
|
621
|
+
positionSeconds: z.ZodNumber;
|
|
622
|
+
playbackRate: z.ZodNumber;
|
|
623
|
+
expectedRevision: z.ZodNumber;
|
|
624
|
+
}, z.core.$strip>;
|
|
625
|
+
declare const pathDataSchema: z.ZodObject<{
|
|
626
|
+
title: z.ZodString;
|
|
627
|
+
description: z.ZodDefault<z.ZodString>;
|
|
628
|
+
courseIds: z.ZodArray<z.ZodString>;
|
|
629
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
630
|
+
draft: "draft";
|
|
631
|
+
published: "published";
|
|
632
|
+
archived: "archived";
|
|
633
|
+
}>>;
|
|
634
|
+
}, z.core.$strip>;
|
|
635
|
+
declare const pathSaveSchema: z.ZodObject<{
|
|
636
|
+
id: z.ZodOptional<z.ZodString>;
|
|
637
|
+
expectedRevision: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
638
|
+
data: z.ZodObject<{
|
|
639
|
+
title: z.ZodString;
|
|
640
|
+
description: z.ZodDefault<z.ZodString>;
|
|
641
|
+
courseIds: z.ZodArray<z.ZodString>;
|
|
642
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
643
|
+
draft: "draft";
|
|
644
|
+
published: "published";
|
|
645
|
+
archived: "archived";
|
|
646
|
+
}>>;
|
|
647
|
+
}, z.core.$strip>;
|
|
648
|
+
}, z.core.$strip>;
|
|
582
649
|
//#endregion
|
|
583
|
-
export { answersSchema, assignmentSchema, assignmentSubmitSchema, catalogSchema, certificateActionSchema, certificateRevokeSchema, cohortDataSchema, cohortSaveSchema, courseDataSchema, courseIdSchema, courseSaveSchema, discussionSchema, enrollmentAdminSchema, enrollmentRequestSchema, gradeSchema, idSchema, keySchema, lessonIdSchema, lessonSchema, moderateSchema, moduleSchema, noteSchema, pageSchema, questionSchema, quizSchema, quizSubmitSchema, resourceSchema, reviewSchema, safeUrlSchema, settingsSchema };
|
|
650
|
+
export { answersSchema, assignmentSchema, assignmentSubmitSchema, catalogSchema, certificateActionSchema, certificateRevokeSchema, cohortDataSchema, cohortSaveSchema, courseDataSchema, courseIdSchema, courseSaveSchema, discussionSchema, enrollmentAdminSchema, enrollmentRequestSchema, gradeSchema, idSchema, keySchema, lessonIdSchema, lessonSchema, moderateSchema, moduleSchema, noteSchema, pageSchema, pathDataSchema, pathSaveSchema, playbackSchema, preferencesSchema, questionSchema, quizDraftSchema, quizSchema, quizSubmitSchema, resourceSchema, reviewSchema, safeUrlSchema, settingsSchema };
|
|
584
651
|
//# sourceMappingURL=schemas.d.ts.map
|
package/dist/schemas.js
CHANGED
|
@@ -111,6 +111,12 @@ const lessonSchema = z.object({
|
|
|
111
111
|
field: idSchema.default("content")
|
|
112
112
|
}).nullable().default(null),
|
|
113
113
|
mediaUrl: safeUrlSchema.nullable().default(null),
|
|
114
|
+
transcript: text.default(""),
|
|
115
|
+
captions: z.array(z.object({
|
|
116
|
+
src: safeUrlSchema,
|
|
117
|
+
language: z.string().regex(/^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$/).max(35),
|
|
118
|
+
label: title
|
|
119
|
+
})).max(20).default([]),
|
|
114
120
|
liveStartsAt: timestamp.nullable().default(null),
|
|
115
121
|
durationMinutes: z.number().int().min(0).max(1440).default(10),
|
|
116
122
|
minStudySeconds: z.number().int().min(0).max(86400).default(0),
|
|
@@ -243,8 +249,10 @@ const lessonIdSchema = courseIdSchema.extend({ lessonId: idSchema });
|
|
|
243
249
|
const answersSchema = z.record(idSchema, z.union([z.string().max(2e3), z.array(z.string().max(500)).max(10)]));
|
|
244
250
|
const quizSubmitSchema = lessonIdSchema.extend({
|
|
245
251
|
attemptId: idSchema,
|
|
246
|
-
answers: answersSchema
|
|
252
|
+
answers: answersSchema,
|
|
253
|
+
expectedDraftRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
|
|
247
254
|
});
|
|
255
|
+
const quizDraftSchema = quizSubmitSchema.extend({ expectedDraftRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).default(0) });
|
|
248
256
|
const assignmentSubmitSchema = lessonIdSchema.extend({
|
|
249
257
|
body: z.string().trim().min(1).max(2e4),
|
|
250
258
|
attachmentUrl: safeUrlSchema.nullable().default(null)
|
|
@@ -309,7 +317,31 @@ const certificateRevokeSchema = courseIdSchema.extend({
|
|
|
309
317
|
reason: z.string().trim().min(1).max(1e3)
|
|
310
318
|
});
|
|
311
319
|
const noteSchema = lessonIdSchema.extend({ note: z.string().max(1e4) });
|
|
320
|
+
const preferencesSchema = z.object({
|
|
321
|
+
emailNotifications: z.boolean().default(true),
|
|
322
|
+
weeklyGoalLessons: z.number().int().min(0).max(100).default(3)
|
|
323
|
+
});
|
|
324
|
+
const playbackSchema = lessonIdSchema.extend({
|
|
325
|
+
positionSeconds: z.number().finite().min(0).max(86400),
|
|
326
|
+
playbackRate: z.number().min(.25).max(3),
|
|
327
|
+
expectedRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER)
|
|
328
|
+
});
|
|
329
|
+
const pathDataSchema = z.object({
|
|
330
|
+
title,
|
|
331
|
+
description: z.string().max(5e3).default(""),
|
|
332
|
+
courseIds: z.array(idSchema).min(1).max(30).refine((ids) => new Set(ids).size === ids.length, "Courses must be unique."),
|
|
333
|
+
status: z.enum([
|
|
334
|
+
"draft",
|
|
335
|
+
"published",
|
|
336
|
+
"archived"
|
|
337
|
+
]).default("draft")
|
|
338
|
+
});
|
|
339
|
+
const pathSaveSchema = z.object({
|
|
340
|
+
id: idSchema.optional(),
|
|
341
|
+
expectedRevision: z.string().max(128).nullable().default(null),
|
|
342
|
+
data: pathDataSchema
|
|
343
|
+
});
|
|
312
344
|
|
|
313
345
|
//#endregion
|
|
314
|
-
export { answersSchema, assignmentSchema, assignmentSubmitSchema, catalogSchema, certificateActionSchema, certificateRevokeSchema, cohortDataSchema, cohortSaveSchema, courseDataSchema, courseIdSchema, courseSaveSchema, discussionSchema, enrollmentAdminSchema, enrollmentRequestSchema, gradeSchema, idSchema, keySchema, lessonIdSchema, lessonSchema, moderateSchema, moduleSchema, noteSchema, pageSchema, questionSchema, quizSchema, quizSubmitSchema, resourceSchema, reviewSchema, safeUrlSchema, settingsSchema };
|
|
346
|
+
export { answersSchema, assignmentSchema, assignmentSubmitSchema, catalogSchema, certificateActionSchema, certificateRevokeSchema, cohortDataSchema, cohortSaveSchema, courseDataSchema, courseIdSchema, courseSaveSchema, discussionSchema, enrollmentAdminSchema, enrollmentRequestSchema, gradeSchema, idSchema, keySchema, lessonIdSchema, lessonSchema, moderateSchema, moduleSchema, noteSchema, pageSchema, pathDataSchema, pathSaveSchema, playbackSchema, preferencesSchema, questionSchema, quizDraftSchema, quizSchema, quizSubmitSchema, resourceSchema, reviewSchema, safeUrlSchema, settingsSchema };
|
|
315
347
|
//# sourceMappingURL=schemas.js.map
|
package/dist/schemas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","names":[],"sources":["../src/schemas.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const idSchema = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[a-zA-Z0-9_-]+$/, \"Use letters, numbers, underscores or hyphens.\")\n .refine(\n (value) => ![\"__proto__\", \"constructor\", \"prototype\"].includes(value),\n \"This identifier is reserved. Choose another ID.\",\n );\nexport const keySchema = z\n .string()\n .min(1)\n .max(1024)\n .regex(/^[a-zA-Z0-9_:.-]+$/);\nconst title = z.string().trim().min(1).max(200);\nconst text = z.string().max(50_000);\nconst timestamp = z.iso.datetime({ offset: true });\nexport const safeUrlSchema = z\n .string()\n .max(2048)\n .refine((value) => {\n if (/^\\/(?!\\/)[^\\s\\\\]*$/.test(value)) return true;\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" && !url.username && !url.password;\n } catch {\n return false;\n }\n }, \"Use an HTTPS URL or a path on this site.\");\n\nexport const resourceSchema = z.object({\n id: idSchema,\n title,\n url: safeUrlSchema,\n description: z.string().max(1000).default(\"\"),\n});\nconst optionSchema = z.object({ id: idSchema, text: z.string().trim().min(1).max(2000) });\nexport const questionSchema = z\n .object({\n id: idSchema,\n type: z.enum([\"single\", \"multiple\", \"true_false\", \"short\"]),\n prompt: z.string().trim().min(1).max(5000),\n options: z.array(optionSchema).max(10).default([]),\n correctAnswers: z.array(z.string().trim().min(1).max(500)).min(1).max(10),\n points: z.number().int().min(1).max(100).default(1),\n explanation: z.string().max(5000).default(\"\"),\n })\n .superRefine((question, ctx) => {\n const optionIds = question.options.map((option) => option.id);\n if (new Set(optionIds).size !== optionIds.length)\n ctx.addIssue({ code: \"custom\", message: \"Option IDs must be unique.\" });\n if (new Set(question.correctAnswers).size !== question.correctAnswers.length)\n ctx.addIssue({ code: \"custom\", message: \"Correct answers must be unique.\" });\n if (question.type !== \"short\") {\n if (question.options.length < 2)\n ctx.addIssue({ code: \"custom\", message: \"Choice questions need at least two options.\" });\n if (question.correctAnswers.some((answer) => !optionIds.includes(answer)))\n ctx.addIssue({ code: \"custom\", message: \"Correct answers must refer to option IDs.\" });\n if (question.type !== \"multiple\" && question.correctAnswers.length !== 1)\n ctx.addIssue({ code: \"custom\", message: \"This question requires one correct answer.\" });\n if (\n question.type === \"true_false\" &&\n (question.options.length !== 2 ||\n !optionIds.includes(\"true\") ||\n !optionIds.includes(\"false\"))\n )\n ctx.addIssue({\n code: \"custom\",\n message: \"True/false options must have the IDs true and false.\",\n });\n }\n });\nexport const quizSchema = z\n .object({\n questions: z.array(questionSchema).min(1).max(50),\n passingPercent: z.number().int().min(1).max(100).default(70),\n maxAttempts: z.number().int().min(1).max(20).default(3),\n timeLimitMinutes: z.number().int().min(0).max(180).default(30),\n randomizeQuestions: z.boolean().default(true),\n randomizeOptions: z.boolean().default(false),\n showFeedback: z.enum([\"after_pass\", \"after_submit\", \"never\"]).default(\"after_pass\"),\n })\n .refine(\n (quiz) => new Set(quiz.questions.map((question) => question.id)).size === quiz.questions.length,\n \"Question IDs must be unique.\",\n );\n\nexport const assignmentSchema = z\n .object({\n instructions: z.string().trim().min(1).max(20_000),\n maxPoints: z.number().int().min(1).max(1000).default(100),\n passingPoints: z.number().int().min(1).max(1000).default(60),\n dueAt: timestamp.nullable().default(null),\n allowResubmission: z.boolean().default(true),\n })\n .refine(\n (assignment) => assignment.passingPoints <= assignment.maxPoints,\n \"Passing points cannot exceed maximum points.\",\n );\n\nexport const lessonSchema = z\n .object({\n id: idSchema,\n title,\n summary: z.string().max(2000).default(\"\"),\n kind: z.enum([\"text\", \"video\", \"audio\", \"quiz\", \"assignment\", \"live\"]).default(\"text\"),\n body: text.default(\"\"),\n portableText: z.array(z.record(z.string(), z.unknown())).max(1000).default([]),\n contentSource: z\n .object({ collection: idSchema, id: idSchema, field: idSchema.default(\"content\") })\n .nullable()\n .default(null),\n mediaUrl: safeUrlSchema.nullable().default(null),\n liveStartsAt: timestamp.nullable().default(null),\n durationMinutes: z.number().int().min(0).max(1440).default(10),\n minStudySeconds: z.number().int().min(0).max(86400).default(0),\n preview: z.boolean().default(false),\n required: z.boolean().default(true),\n resources: z.array(resourceSchema).max(30).default([]),\n quiz: quizSchema.nullable().default(null),\n assignment: assignmentSchema.nullable().default(null),\n })\n .superRefine((lesson, ctx) => {\n if (lesson.kind === \"quiz\" && !lesson.quiz)\n ctx.addIssue({ code: \"custom\", message: \"Quiz lessons need a quiz.\" });\n if (lesson.kind === \"assignment\" && !lesson.assignment)\n ctx.addIssue({ code: \"custom\", message: \"Assignment lessons need an assignment.\" });\n if ([\"video\", \"audio\", \"live\"].includes(lesson.kind) && !lesson.mediaUrl)\n ctx.addIssue({ code: \"custom\", message: \"Media and live lessons need a URL.\" });\n if (lesson.kind === \"live\" && !lesson.liveStartsAt)\n ctx.addIssue({ code: \"custom\", message: \"Live lessons need a start time.\" });\n if (new Set(lesson.resources.map((resource) => resource.id)).size !== lesson.resources.length)\n ctx.addIssue({ code: \"custom\", message: \"Resource IDs must be unique.\" });\n });\n\nexport const moduleSchema = z.object({\n id: idSchema,\n title,\n description: z.string().max(2000).default(\"\"),\n releaseDays: z.number().int().min(0).max(3650).default(0),\n unlockAt: timestamp.nullable().default(null),\n lessons: z.array(lessonSchema).max(100).default([]),\n});\n\nexport const courseDataSchema = z\n .object({\n slug: z\n .string()\n .trim()\n .min(1)\n .max(100)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, \"Use lowercase words separated by hyphens.\"),\n title,\n summary: z.string().trim().max(1000).default(\"\"),\n description: text.default(\"\"),\n outcomes: z.array(z.string().trim().min(1).max(500)).max(30).default([]),\n requirements: z.array(z.string().trim().min(1).max(500)).max(30).default([]),\n category: z.string().trim().max(100).default(\"\"),\n tags: z.array(z.string().trim().min(1).max(60)).max(20).default([]),\n language: z.string().trim().min(2).max(35).default(\"en\"),\n level: z.enum([\"beginner\", \"intermediate\", \"advanced\", \"all\"]).default(\"all\"),\n featuredImage: z\n .object({\n id: z.string().max(128).default(\"\"),\n src: safeUrlSchema,\n alt: z.string().max(500).default(\"\"),\n })\n .nullable()\n .default(null),\n instructorName: z.string().trim().max(200).default(\"\"),\n instructorIds: z.array(idSchema).max(20).default([]),\n status: z.enum([\"draft\", \"published\", \"archived\"]).default(\"draft\"),\n enrollmentMode: z.enum([\"open\", \"approval\", \"invite\"]).default(\"open\"),\n commerce: z\n .object({\n accessModel: z.enum([\"free\", \"paid\"]).default(\"free\"),\n offerId: idSchema.nullable().default(null),\n priceMinor: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().default(null),\n currency: z\n .string()\n .regex(/^[A-Z]{3}$/)\n .default(\"INR\"),\n })\n .default({ accessModel: \"free\", offerId: null, priceMinor: null, currency: \"INR\" }),\n prerequisiteCourseIds: z.array(idSchema).max(20).default([]),\n sequential: z.boolean().default(true),\n enrollmentClosesAt: timestamp.nullable().default(null),\n accessDays: z.number().int().min(0).max(3650).default(0),\n certificateEnabled: z.boolean().default(true),\n modules: z.array(moduleSchema).max(50).default([]),\n })\n .superRefine((course, ctx) => {\n const allIds = course.modules.flatMap((module) => [\n module.id,\n ...module.lessons.map((lesson) => lesson.id),\n ]);\n if (new Set(allIds).size !== allIds.length)\n ctx.addIssue({\n code: \"custom\",\n message: \"Module and lesson IDs must be unique across the course.\",\n });\n if (course.modules.flatMap((module) => module.lessons).length > 150)\n ctx.addIssue({ code: \"custom\", message: \"A course supports up to 150 lessons.\" });\n if (\n course.status === \"published\" &&\n !course.modules.some((module) => module.lessons.some((lesson) => lesson.required))\n )\n ctx.addIssue({\n code: \"custom\",\n message: \"Publish a course with at least one required lesson.\",\n });\n });\n\nexport const courseSaveSchema = z.object({\n id: idSchema.optional(),\n expectedRevision: z.string().max(128).nullable().default(null),\n data: courseDataSchema,\n});\nexport const pageSchema = z.object({\n cursor: z.string().max(4000).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(24),\n});\nexport const catalogSchema = pageSchema.extend({\n q: z.string().max(100).default(\"\"),\n category: z.string().max(100).default(\"\"),\n level: z.enum([\"beginner\", \"intermediate\", \"advanced\", \"all\"]).optional(),\n language: z.string().max(35).optional(),\n});\nexport const courseIdSchema = z.object({ courseId: idSchema });\nexport const lessonIdSchema = courseIdSchema.extend({ lessonId: idSchema });\nexport const answersSchema = z.record(\n idSchema,\n z.union([z.string().max(2000), z.array(z.string().max(500)).max(10)]),\n);\nexport const quizSubmitSchema = lessonIdSchema.extend({\n attemptId: idSchema,\n answers: answersSchema,\n});\nexport const assignmentSubmitSchema = lessonIdSchema.extend({\n body: z.string().trim().min(1).max(20_000),\n attachmentUrl: safeUrlSchema.nullable().default(null),\n});\nexport const enrollmentRequestSchema = courseIdSchema.extend({ cohortId: idSchema.optional() });\nexport const enrollmentAdminSchema = courseIdSchema.extend({\n userId: idSchema,\n status: z.enum([\"active\", \"rejected\", \"suspended\", \"cancelled\"]),\n reason: z.string().max(1000).default(\"\"),\n cohortId: idSchema.nullable().optional(),\n accessStartsAt: timestamp.nullable().optional(),\n accessExpiresAt: timestamp.nullable().optional(),\n});\nexport const gradeSchema = lessonIdSchema.extend({\n userId: idSchema,\n submissionId: idSchema,\n points: z.number().int().min(0).max(1000),\n feedback: z.string().max(10_000).default(\"\"),\n});\nexport const discussionSchema = lessonIdSchema.extend({\n body: z.string().trim().min(1).max(5000),\n parentId: idSchema.nullable().default(null),\n});\nexport const reviewSchema = courseIdSchema.extend({\n rating: z.number().int().min(1).max(5),\n body: z.string().trim().min(1).max(3000),\n});\nexport const moderateSchema = z.object({\n id: keySchema,\n status: z.enum([\"published\", \"hidden\"]),\n expectedRevision: z.string().min(1).max(128),\n});\nexport const cohortDataSchema = z\n .object({\n title,\n courseIds: z.array(idSchema).min(1).max(20),\n memberIds: z.array(idSchema).max(1000).default([]),\n startsAt: timestamp.nullable().default(null),\n endsAt: timestamp.nullable().default(null),\n })\n .refine(\n (cohort) =>\n !cohort.startsAt || !cohort.endsAt || Date.parse(cohort.endsAt) > Date.parse(cohort.startsAt),\n \"Cohort end must follow its start.\",\n )\n .refine(\n (cohort) => new Set(cohort.memberIds).size === cohort.memberIds.length,\n \"Cohort members must be unique.\",\n )\n .refine(\n (cohort) => new Set(cohort.courseIds).size === cohort.courseIds.length,\n \"Cohort courses must be unique.\",\n );\nexport const cohortSaveSchema = z.object({\n id: idSchema.optional(),\n expectedRevision: z.string().max(128).nullable().default(null),\n data: cohortDataSchema,\n});\nexport const settingsSchema = z.object({\n academyTitle: title.default(\"Ananta Gnanam Academy\"),\n academyDescription: z.string().max(2000).default(\"Build knowledge, one lesson at a time.\"),\n issuerName: title.default(\"Ananta Gnanam\"),\n moderateDiscussions: z.boolean().default(true),\n moderateReviews: z.boolean().default(true),\n emailNotifications: z.boolean().default(false),\n reminderDays: z.number().int().min(0).max(90).default(7),\n});\nexport const certificateActionSchema = courseIdSchema.extend({ shared: z.boolean() });\nexport const certificateRevokeSchema = courseIdSchema.extend({\n userId: idSchema,\n reason: z.string().trim().min(1).max(1000),\n});\nexport const noteSchema = lessonIdSchema.extend({ note: z.string().max(10_000) });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schemas.js","names":[],"sources":["../src/schemas.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const idSchema = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[a-zA-Z0-9_-]+$/, \"Use letters, numbers, underscores or hyphens.\")\n .refine(\n (value) => ![\"__proto__\", \"constructor\", \"prototype\"].includes(value),\n \"This identifier is reserved. Choose another ID.\",\n );\nexport const keySchema = z\n .string()\n .min(1)\n .max(1024)\n .regex(/^[a-zA-Z0-9_:.-]+$/);\nconst title = z.string().trim().min(1).max(200);\nconst text = z.string().max(50_000);\nconst timestamp = z.iso.datetime({ offset: true });\nexport const safeUrlSchema = z\n .string()\n .max(2048)\n .refine((value) => {\n if (/^\\/(?!\\/)[^\\s\\\\]*$/.test(value)) return true;\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" && !url.username && !url.password;\n } catch {\n return false;\n }\n }, \"Use an HTTPS URL or a path on this site.\");\n\nexport const resourceSchema = z.object({\n id: idSchema,\n title,\n url: safeUrlSchema,\n description: z.string().max(1000).default(\"\"),\n});\nconst optionSchema = z.object({ id: idSchema, text: z.string().trim().min(1).max(2000) });\nexport const questionSchema = z\n .object({\n id: idSchema,\n type: z.enum([\"single\", \"multiple\", \"true_false\", \"short\"]),\n prompt: z.string().trim().min(1).max(5000),\n options: z.array(optionSchema).max(10).default([]),\n correctAnswers: z.array(z.string().trim().min(1).max(500)).min(1).max(10),\n points: z.number().int().min(1).max(100).default(1),\n explanation: z.string().max(5000).default(\"\"),\n })\n .superRefine((question, ctx) => {\n const optionIds = question.options.map((option) => option.id);\n if (new Set(optionIds).size !== optionIds.length)\n ctx.addIssue({ code: \"custom\", message: \"Option IDs must be unique.\" });\n if (new Set(question.correctAnswers).size !== question.correctAnswers.length)\n ctx.addIssue({ code: \"custom\", message: \"Correct answers must be unique.\" });\n if (question.type !== \"short\") {\n if (question.options.length < 2)\n ctx.addIssue({ code: \"custom\", message: \"Choice questions need at least two options.\" });\n if (question.correctAnswers.some((answer) => !optionIds.includes(answer)))\n ctx.addIssue({ code: \"custom\", message: \"Correct answers must refer to option IDs.\" });\n if (question.type !== \"multiple\" && question.correctAnswers.length !== 1)\n ctx.addIssue({ code: \"custom\", message: \"This question requires one correct answer.\" });\n if (\n question.type === \"true_false\" &&\n (question.options.length !== 2 ||\n !optionIds.includes(\"true\") ||\n !optionIds.includes(\"false\"))\n )\n ctx.addIssue({\n code: \"custom\",\n message: \"True/false options must have the IDs true and false.\",\n });\n }\n });\nexport const quizSchema = z\n .object({\n questions: z.array(questionSchema).min(1).max(50),\n passingPercent: z.number().int().min(1).max(100).default(70),\n maxAttempts: z.number().int().min(1).max(20).default(3),\n timeLimitMinutes: z.number().int().min(0).max(180).default(30),\n randomizeQuestions: z.boolean().default(true),\n randomizeOptions: z.boolean().default(false),\n showFeedback: z.enum([\"after_pass\", \"after_submit\", \"never\"]).default(\"after_pass\"),\n })\n .refine(\n (quiz) => new Set(quiz.questions.map((question) => question.id)).size === quiz.questions.length,\n \"Question IDs must be unique.\",\n );\n\nexport const assignmentSchema = z\n .object({\n instructions: z.string().trim().min(1).max(20_000),\n maxPoints: z.number().int().min(1).max(1000).default(100),\n passingPoints: z.number().int().min(1).max(1000).default(60),\n dueAt: timestamp.nullable().default(null),\n allowResubmission: z.boolean().default(true),\n })\n .refine(\n (assignment) => assignment.passingPoints <= assignment.maxPoints,\n \"Passing points cannot exceed maximum points.\",\n );\n\nexport const lessonSchema = z\n .object({\n id: idSchema,\n title,\n summary: z.string().max(2000).default(\"\"),\n kind: z.enum([\"text\", \"video\", \"audio\", \"quiz\", \"assignment\", \"live\"]).default(\"text\"),\n body: text.default(\"\"),\n portableText: z.array(z.record(z.string(), z.unknown())).max(1000).default([]),\n contentSource: z\n .object({ collection: idSchema, id: idSchema, field: idSchema.default(\"content\") })\n .nullable()\n .default(null),\n mediaUrl: safeUrlSchema.nullable().default(null),\n transcript: text.default(\"\"),\n captions: z\n .array(\n z.object({\n src: safeUrlSchema,\n language: z\n .string()\n .regex(/^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$/)\n .max(35),\n label: title,\n }),\n )\n .max(20)\n .default([]),\n liveStartsAt: timestamp.nullable().default(null),\n durationMinutes: z.number().int().min(0).max(1440).default(10),\n minStudySeconds: z.number().int().min(0).max(86400).default(0),\n preview: z.boolean().default(false),\n required: z.boolean().default(true),\n resources: z.array(resourceSchema).max(30).default([]),\n quiz: quizSchema.nullable().default(null),\n assignment: assignmentSchema.nullable().default(null),\n })\n .superRefine((lesson, ctx) => {\n if (lesson.kind === \"quiz\" && !lesson.quiz)\n ctx.addIssue({ code: \"custom\", message: \"Quiz lessons need a quiz.\" });\n if (lesson.kind === \"assignment\" && !lesson.assignment)\n ctx.addIssue({ code: \"custom\", message: \"Assignment lessons need an assignment.\" });\n if ([\"video\", \"audio\", \"live\"].includes(lesson.kind) && !lesson.mediaUrl)\n ctx.addIssue({ code: \"custom\", message: \"Media and live lessons need a URL.\" });\n if (lesson.kind === \"live\" && !lesson.liveStartsAt)\n ctx.addIssue({ code: \"custom\", message: \"Live lessons need a start time.\" });\n if (new Set(lesson.resources.map((resource) => resource.id)).size !== lesson.resources.length)\n ctx.addIssue({ code: \"custom\", message: \"Resource IDs must be unique.\" });\n });\n\nexport const moduleSchema = z.object({\n id: idSchema,\n title,\n description: z.string().max(2000).default(\"\"),\n releaseDays: z.number().int().min(0).max(3650).default(0),\n unlockAt: timestamp.nullable().default(null),\n lessons: z.array(lessonSchema).max(100).default([]),\n});\n\nexport const courseDataSchema = z\n .object({\n slug: z\n .string()\n .trim()\n .min(1)\n .max(100)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, \"Use lowercase words separated by hyphens.\"),\n title,\n summary: z.string().trim().max(1000).default(\"\"),\n description: text.default(\"\"),\n outcomes: z.array(z.string().trim().min(1).max(500)).max(30).default([]),\n requirements: z.array(z.string().trim().min(1).max(500)).max(30).default([]),\n category: z.string().trim().max(100).default(\"\"),\n tags: z.array(z.string().trim().min(1).max(60)).max(20).default([]),\n language: z.string().trim().min(2).max(35).default(\"en\"),\n level: z.enum([\"beginner\", \"intermediate\", \"advanced\", \"all\"]).default(\"all\"),\n featuredImage: z\n .object({\n id: z.string().max(128).default(\"\"),\n src: safeUrlSchema,\n alt: z.string().max(500).default(\"\"),\n })\n .nullable()\n .default(null),\n instructorName: z.string().trim().max(200).default(\"\"),\n instructorIds: z.array(idSchema).max(20).default([]),\n status: z.enum([\"draft\", \"published\", \"archived\"]).default(\"draft\"),\n enrollmentMode: z.enum([\"open\", \"approval\", \"invite\"]).default(\"open\"),\n commerce: z\n .object({\n accessModel: z.enum([\"free\", \"paid\"]).default(\"free\"),\n offerId: idSchema.nullable().default(null),\n priceMinor: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().default(null),\n currency: z\n .string()\n .regex(/^[A-Z]{3}$/)\n .default(\"INR\"),\n })\n .default({ accessModel: \"free\", offerId: null, priceMinor: null, currency: \"INR\" }),\n prerequisiteCourseIds: z.array(idSchema).max(20).default([]),\n sequential: z.boolean().default(true),\n enrollmentClosesAt: timestamp.nullable().default(null),\n accessDays: z.number().int().min(0).max(3650).default(0),\n certificateEnabled: z.boolean().default(true),\n modules: z.array(moduleSchema).max(50).default([]),\n })\n .superRefine((course, ctx) => {\n const allIds = course.modules.flatMap((module) => [\n module.id,\n ...module.lessons.map((lesson) => lesson.id),\n ]);\n if (new Set(allIds).size !== allIds.length)\n ctx.addIssue({\n code: \"custom\",\n message: \"Module and lesson IDs must be unique across the course.\",\n });\n if (course.modules.flatMap((module) => module.lessons).length > 150)\n ctx.addIssue({ code: \"custom\", message: \"A course supports up to 150 lessons.\" });\n if (\n course.status === \"published\" &&\n !course.modules.some((module) => module.lessons.some((lesson) => lesson.required))\n )\n ctx.addIssue({\n code: \"custom\",\n message: \"Publish a course with at least one required lesson.\",\n });\n });\n\nexport const courseSaveSchema = z.object({\n id: idSchema.optional(),\n expectedRevision: z.string().max(128).nullable().default(null),\n data: courseDataSchema,\n});\nexport const pageSchema = z.object({\n cursor: z.string().max(4000).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(24),\n});\nexport const catalogSchema = pageSchema.extend({\n q: z.string().max(100).default(\"\"),\n category: z.string().max(100).default(\"\"),\n level: z.enum([\"beginner\", \"intermediate\", \"advanced\", \"all\"]).optional(),\n language: z.string().max(35).optional(),\n});\nexport const courseIdSchema = z.object({ courseId: idSchema });\nexport const lessonIdSchema = courseIdSchema.extend({ lessonId: idSchema });\nexport const answersSchema = z.record(\n idSchema,\n z.union([z.string().max(2000), z.array(z.string().max(500)).max(10)]),\n);\nexport const quizSubmitSchema = lessonIdSchema.extend({\n attemptId: idSchema,\n answers: answersSchema,\n expectedDraftRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),\n});\nexport const quizDraftSchema = quizSubmitSchema.extend({\n expectedDraftRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).default(0),\n});\nexport const assignmentSubmitSchema = lessonIdSchema.extend({\n body: z.string().trim().min(1).max(20_000),\n attachmentUrl: safeUrlSchema.nullable().default(null),\n});\nexport const enrollmentRequestSchema = courseIdSchema.extend({ cohortId: idSchema.optional() });\nexport const enrollmentAdminSchema = courseIdSchema.extend({\n userId: idSchema,\n status: z.enum([\"active\", \"rejected\", \"suspended\", \"cancelled\"]),\n reason: z.string().max(1000).default(\"\"),\n cohortId: idSchema.nullable().optional(),\n accessStartsAt: timestamp.nullable().optional(),\n accessExpiresAt: timestamp.nullable().optional(),\n});\nexport const gradeSchema = lessonIdSchema.extend({\n userId: idSchema,\n submissionId: idSchema,\n points: z.number().int().min(0).max(1000),\n feedback: z.string().max(10_000).default(\"\"),\n});\nexport const discussionSchema = lessonIdSchema.extend({\n body: z.string().trim().min(1).max(5000),\n parentId: idSchema.nullable().default(null),\n});\nexport const reviewSchema = courseIdSchema.extend({\n rating: z.number().int().min(1).max(5),\n body: z.string().trim().min(1).max(3000),\n});\nexport const moderateSchema = z.object({\n id: keySchema,\n status: z.enum([\"published\", \"hidden\"]),\n expectedRevision: z.string().min(1).max(128),\n});\nexport const cohortDataSchema = z\n .object({\n title,\n courseIds: z.array(idSchema).min(1).max(20),\n memberIds: z.array(idSchema).max(1000).default([]),\n startsAt: timestamp.nullable().default(null),\n endsAt: timestamp.nullable().default(null),\n })\n .refine(\n (cohort) =>\n !cohort.startsAt || !cohort.endsAt || Date.parse(cohort.endsAt) > Date.parse(cohort.startsAt),\n \"Cohort end must follow its start.\",\n )\n .refine(\n (cohort) => new Set(cohort.memberIds).size === cohort.memberIds.length,\n \"Cohort members must be unique.\",\n )\n .refine(\n (cohort) => new Set(cohort.courseIds).size === cohort.courseIds.length,\n \"Cohort courses must be unique.\",\n );\nexport const cohortSaveSchema = z.object({\n id: idSchema.optional(),\n expectedRevision: z.string().max(128).nullable().default(null),\n data: cohortDataSchema,\n});\nexport const settingsSchema = z.object({\n academyTitle: title.default(\"Ananta Gnanam Academy\"),\n academyDescription: z.string().max(2000).default(\"Build knowledge, one lesson at a time.\"),\n issuerName: title.default(\"Ananta Gnanam\"),\n moderateDiscussions: z.boolean().default(true),\n moderateReviews: z.boolean().default(true),\n emailNotifications: z.boolean().default(false),\n reminderDays: z.number().int().min(0).max(90).default(7),\n});\nexport const certificateActionSchema = courseIdSchema.extend({ shared: z.boolean() });\nexport const certificateRevokeSchema = courseIdSchema.extend({\n userId: idSchema,\n reason: z.string().trim().min(1).max(1000),\n});\nexport const noteSchema = lessonIdSchema.extend({ note: z.string().max(10_000) });\n\nexport const preferencesSchema = z.object({\n emailNotifications: z.boolean().default(true),\n weeklyGoalLessons: z.number().int().min(0).max(100).default(3),\n});\nexport const playbackSchema = lessonIdSchema.extend({\n positionSeconds: z.number().finite().min(0).max(86_400),\n playbackRate: z.number().min(0.25).max(3),\n expectedRevision: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),\n});\nexport const pathDataSchema = z.object({\n title,\n description: z.string().max(5000).default(\"\"),\n courseIds: z\n .array(idSchema)\n .min(1)\n .max(30)\n .refine((ids) => new Set(ids).size === ids.length, \"Courses must be unique.\"),\n status: z.enum([\"draft\", \"published\", \"archived\"]).default(\"draft\"),\n});\nexport const pathSaveSchema = z.object({\n id: idSchema.optional(),\n expectedRevision: z.string().max(128).nullable().default(null),\n data: pathDataSchema,\n});\n"],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { CourseDetail, PublicLesson } from "./types.js";
|
|
2
|
+
|
|
1
3
|
//#region src/errors.d.ts
|
|
2
4
|
declare class LmsError extends Error {
|
|
3
5
|
readonly code: string;
|
|
@@ -22,9 +24,17 @@ interface RuntimeLocals {
|
|
|
22
24
|
declare function lmsPublic<T>(locals: RuntimeLocals, route: string, input: Record<string, unknown>, origin: string): Promise<T>;
|
|
23
25
|
declare function lmsLearner<T>(locals: RuntimeLocals, route: string, input: Record<string, unknown>, origin: string): Promise<T>;
|
|
24
26
|
declare function loginUrl(loginPath: string, returnTo: string): string;
|
|
27
|
+
/** A fixed private read route; authorization remains at the EmDash runtime boundary. */
|
|
28
|
+
declare function lmsAuthorLessonPreview(locals: RuntimeLocals, input: {
|
|
29
|
+
courseId: string;
|
|
30
|
+
lessonId: string;
|
|
31
|
+
}, origin: string): Promise<{
|
|
32
|
+
course: CourseDetail;
|
|
33
|
+
lesson: PublicLesson;
|
|
34
|
+
}>;
|
|
25
35
|
declare function courseUrl(basePath: string, slug: string): string;
|
|
26
36
|
declare function lessonUrl(basePath: string, slug: string, lessonId: string): string;
|
|
27
37
|
declare function certificateUrl(basePath: string, id: string): string;
|
|
28
38
|
//#endregion
|
|
29
|
-
export { LmsError, certificateUrl, courseUrl, lessonUrl, lmsLearner, lmsPublic, loginUrl };
|
|
39
|
+
export { LmsError, certificateUrl, courseUrl, lessonUrl, lmsAuthorLessonPreview, lmsLearner, lmsPublic, loginUrl };
|
|
30
40
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as PLUGIN_ID } from "./constants-
|
|
1
|
+
import { r as PLUGIN_ID } from "./constants-Cnx7k82Z.js";
|
|
2
2
|
import { t as LmsError } from "./errors-ChzJS9al.js";
|
|
3
3
|
|
|
4
4
|
//#region src/server.ts
|
|
@@ -18,6 +18,9 @@ async function lmsPublic(locals, route, input, origin) {
|
|
|
18
18
|
return unwrap(await dispatch(PLUGIN_ID, "GET", route, new Request(requestUrl(route, input, origin))));
|
|
19
19
|
}
|
|
20
20
|
const READ_ROUTES = new Set([
|
|
21
|
+
"learner/paths",
|
|
22
|
+
"learner/saved",
|
|
23
|
+
"learner/preferences",
|
|
21
24
|
"learner/dashboard",
|
|
22
25
|
"learner/course",
|
|
23
26
|
"learner/course-by-slug",
|
|
@@ -39,6 +42,14 @@ function loginUrl(loginPath, returnTo) {
|
|
|
39
42
|
url.searchParams.set("redirect", returnTo);
|
|
40
43
|
return `${url.pathname}${url.search}${url.hash}`;
|
|
41
44
|
}
|
|
45
|
+
/** A fixed private read route; authorization remains at the EmDash runtime boundary. */
|
|
46
|
+
async function lmsAuthorLessonPreview(locals, input, origin) {
|
|
47
|
+
if (!locals.user) throw new LmsError("UNAUTHORIZED", "Sign in to preview this lesson.", 401);
|
|
48
|
+
const dispatch = locals.emdash?.handlePluginApiRoute;
|
|
49
|
+
if (!dispatch) throw new LmsError("LMS_UNAVAILABLE", "The learning service is unavailable.", 503);
|
|
50
|
+
const route = "admin/lesson/preview";
|
|
51
|
+
return unwrap(await dispatch(PLUGIN_ID, "GET", route, new Request(requestUrl(route, input, origin)), locals.user));
|
|
52
|
+
}
|
|
42
53
|
function courseUrl(basePath, slug) {
|
|
43
54
|
return `${basePath}/courses/${encodeURIComponent(slug)}`;
|
|
44
55
|
}
|
|
@@ -50,5 +61,5 @@ function certificateUrl(basePath, id) {
|
|
|
50
61
|
}
|
|
51
62
|
|
|
52
63
|
//#endregion
|
|
53
|
-
export { LmsError, certificateUrl, courseUrl, lessonUrl, lmsLearner, lmsPublic, loginUrl };
|
|
64
|
+
export { LmsError, certificateUrl, courseUrl, lessonUrl, lmsAuthorLessonPreview, lmsLearner, lmsPublic, loginUrl };
|
|
54
65
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","names":[],"sources":["../src/server.ts"],"sourcesContent":["import { PLUGIN_ID } from \"./constants.js\";\nimport { LmsError } from \"./errors.js\";\nimport type { RouteEnvelope } from \"./types.js\";\n\ninterface RuntimeLocals {\n user?: { id: string; email: string; name: string | null; role: number; createdAt: Date | string };\n emdash?: {\n handlePublicPluginApiRoute?: (\n pluginId: string,\n method: string,\n path: string,\n request: Request,\n ) => Promise<unknown>;\n handlePluginApiRoute?: (\n pluginId: string,\n method: string,\n path: string,\n request: Request,\n user?: RuntimeLocals[\"user\"] | null,\n ) => Promise<unknown>;\n };\n}\n\nfunction requestUrl(route: string, input: Record<string, unknown>, origin: string): URL {\n const url = new URL(`/_emdash/api/plugins/${PLUGIN_ID}/${route}`, origin);\n for (const [key, value] of Object.entries(input))\n if (value !== undefined && value !== null && value !== \"\")\n url.searchParams.set(key, String(value));\n return url;\n}\nfunction unwrap<T>(input: unknown): T {\n const result = input as RouteEnvelope<T>;\n if (!result?.success)\n throw new LmsError(\n result?.error?.code ?? \"LMS_UNAVAILABLE\",\n result?.error?.message ?? \"The learning service is unavailable.\",\n result?.status ?? 503,\n );\n return result.data as T;\n}\nexport async function lmsPublic<T>(\n locals: RuntimeLocals,\n route: string,\n input: Record<string, unknown>,\n origin: string,\n): Promise<T> {\n const dispatch = locals.emdash?.handlePublicPluginApiRoute;\n if (!dispatch) throw new LmsError(\"LMS_UNAVAILABLE\", \"The learning service is unavailable.\", 503);\n return unwrap<T>(\n await dispatch(PLUGIN_ID, \"GET\", route, new Request(requestUrl(route, input, origin))),\n );\n}\nconst READ_ROUTES = new Set([\n \"learner/dashboard\",\n \"learner/course\",\n \"learner/course-by-slug\",\n \"learner/lesson\",\n \"learner/certificate\",\n \"learner/certificate-by-id\",\n \"learner/cohort\",\n \"learner/notifications\",\n]);\nexport async function lmsLearner<T>(\n locals: RuntimeLocals,\n route: string,\n input: Record<string, unknown>,\n origin: string,\n): Promise<T> {\n if (!locals.user || locals.user.role < 10)\n throw new LmsError(\"UNAUTHORIZED\", \"Sign in to continue.\", 401);\n if (!READ_ROUTES.has(route))\n throw new LmsError(\"FORBIDDEN\", \"This route is not available to the learner renderer.\", 403);\n const dispatch = locals.emdash?.handlePluginApiRoute;\n if (!dispatch) throw new LmsError(\"LMS_UNAVAILABLE\", \"The learning service is unavailable.\", 503);\n return unwrap<T>(\n await dispatch(\n PLUGIN_ID,\n \"GET\",\n route,\n new Request(requestUrl(route, input, origin)),\n locals.user,\n ),\n );\n}\nexport function loginUrl(loginPath: string, returnTo: string): string {\n const url = new URL(loginPath, \"https://lms.invalid\");\n url.searchParams.set(\"redirect\", returnTo);\n return `${url.pathname}${url.search}${url.hash}`;\n}\nexport function courseUrl(basePath: string, slug: string): string {\n return `${basePath}/courses/${encodeURIComponent(slug)}`;\n}\nexport function lessonUrl(basePath: string, slug: string, lessonId: string): string {\n return `${courseUrl(basePath, slug)}/lessons/${encodeURIComponent(lessonId)}`;\n}\nexport function certificateUrl(basePath: string, id: string): string {\n return `${basePath}/certificates/${encodeURIComponent(id)}`;\n}\nexport { LmsError } from \"./errors.js\";\n"],"mappings":";;;;AAuBA,SAAS,WAAW,OAAe,OAAgC,QAAqB;CACtF,MAAM,MAAM,IAAI,IAAI,wBAAwB,UAAU,GAAG,SAAS,OAAO;AACzE,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,KAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,GACrD,KAAI,aAAa,IAAI,KAAK,OAAO,MAAM,CAAC;AAC5C,QAAO;;AAET,SAAS,OAAU,OAAmB;CACpC,MAAM,SAAS;AACf,KAAI,CAAC,QAAQ,QACX,OAAM,IAAI,SACR,QAAQ,OAAO,QAAQ,mBACvB,QAAQ,OAAO,WAAW,wCAC1B,QAAQ,UAAU,IACnB;AACH,QAAO,OAAO;;AAEhB,eAAsB,UACpB,QACA,OACA,OACA,QACY;CACZ,MAAM,WAAW,OAAO,QAAQ;AAChC,KAAI,CAAC,SAAU,OAAM,IAAI,SAAS,mBAAmB,wCAAwC,IAAI;AACjG,QAAO,OACL,MAAM,SAAS,WAAW,OAAO,OAAO,IAAI,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,CAAC,CACvF;;AAEH,MAAM,cAAc,IAAI,IAAI;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AACF,eAAsB,WACpB,QACA,OACA,OACA,QACY;AACZ,KAAI,CAAC,OAAO,QAAQ,OAAO,KAAK,OAAO,GACrC,OAAM,IAAI,SAAS,gBAAgB,wBAAwB,IAAI;AACjE,KAAI,CAAC,YAAY,IAAI,MAAM,CACzB,OAAM,IAAI,SAAS,aAAa,wDAAwD,IAAI;CAC9F,MAAM,WAAW,OAAO,QAAQ;AAChC,KAAI,CAAC,SAAU,OAAM,IAAI,SAAS,mBAAmB,wCAAwC,IAAI;AACjG,QAAO,OACL,MAAM,SACJ,WACA,OACA,OACA,IAAI,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,EAC7C,OAAO,KACR,CACF;;AAEH,SAAgB,SAAS,WAAmB,UAA0B;CACpE,MAAM,MAAM,IAAI,IAAI,WAAW,sBAAsB;AACrD,KAAI,aAAa,IAAI,YAAY,SAAS;AAC1C,QAAO,GAAG,IAAI,WAAW,IAAI,SAAS,IAAI;;
|
|
1
|
+
{"version":3,"file":"server.js","names":[],"sources":["../src/server.ts"],"sourcesContent":["import { PLUGIN_ID } from \"./constants.js\";\nimport { LmsError } from \"./errors.js\";\nimport type { CourseDetail, PublicLesson, RouteEnvelope } from \"./types.js\";\n\ninterface RuntimeLocals {\n user?: { id: string; email: string; name: string | null; role: number; createdAt: Date | string };\n emdash?: {\n handlePublicPluginApiRoute?: (\n pluginId: string,\n method: string,\n path: string,\n request: Request,\n ) => Promise<unknown>;\n handlePluginApiRoute?: (\n pluginId: string,\n method: string,\n path: string,\n request: Request,\n user?: RuntimeLocals[\"user\"] | null,\n ) => Promise<unknown>;\n };\n}\n\nfunction requestUrl(route: string, input: Record<string, unknown>, origin: string): URL {\n const url = new URL(`/_emdash/api/plugins/${PLUGIN_ID}/${route}`, origin);\n for (const [key, value] of Object.entries(input))\n if (value !== undefined && value !== null && value !== \"\")\n url.searchParams.set(key, String(value));\n return url;\n}\nfunction unwrap<T>(input: unknown): T {\n const result = input as RouteEnvelope<T>;\n if (!result?.success)\n throw new LmsError(\n result?.error?.code ?? \"LMS_UNAVAILABLE\",\n result?.error?.message ?? \"The learning service is unavailable.\",\n result?.status ?? 503,\n );\n return result.data as T;\n}\nexport async function lmsPublic<T>(\n locals: RuntimeLocals,\n route: string,\n input: Record<string, unknown>,\n origin: string,\n): Promise<T> {\n const dispatch = locals.emdash?.handlePublicPluginApiRoute;\n if (!dispatch) throw new LmsError(\"LMS_UNAVAILABLE\", \"The learning service is unavailable.\", 503);\n return unwrap<T>(\n await dispatch(PLUGIN_ID, \"GET\", route, new Request(requestUrl(route, input, origin))),\n );\n}\nconst READ_ROUTES = new Set([\n \"learner/paths\",\n \"learner/saved\",\n \"learner/preferences\",\n \"learner/dashboard\",\n \"learner/course\",\n \"learner/course-by-slug\",\n \"learner/lesson\",\n \"learner/certificate\",\n \"learner/certificate-by-id\",\n \"learner/cohort\",\n \"learner/notifications\",\n]);\nexport async function lmsLearner<T>(\n locals: RuntimeLocals,\n route: string,\n input: Record<string, unknown>,\n origin: string,\n): Promise<T> {\n if (!locals.user || locals.user.role < 10)\n throw new LmsError(\"UNAUTHORIZED\", \"Sign in to continue.\", 401);\n if (!READ_ROUTES.has(route))\n throw new LmsError(\"FORBIDDEN\", \"This route is not available to the learner renderer.\", 403);\n const dispatch = locals.emdash?.handlePluginApiRoute;\n if (!dispatch) throw new LmsError(\"LMS_UNAVAILABLE\", \"The learning service is unavailable.\", 503);\n return unwrap<T>(\n await dispatch(\n PLUGIN_ID,\n \"GET\",\n route,\n new Request(requestUrl(route, input, origin)),\n locals.user,\n ),\n );\n}\nexport function loginUrl(loginPath: string, returnTo: string): string {\n const url = new URL(loginPath, \"https://lms.invalid\");\n url.searchParams.set(\"redirect\", returnTo);\n return `${url.pathname}${url.search}${url.hash}`;\n}\n/** A fixed private read route; authorization remains at the EmDash runtime boundary. */\nexport async function lmsAuthorLessonPreview(\n locals: RuntimeLocals,\n input: { courseId: string; lessonId: string },\n origin: string,\n): Promise<{ course: CourseDetail; lesson: PublicLesson }> {\n if (!locals.user) throw new LmsError(\"UNAUTHORIZED\", \"Sign in to preview this lesson.\", 401);\n const dispatch = locals.emdash?.handlePluginApiRoute;\n if (!dispatch) throw new LmsError(\"LMS_UNAVAILABLE\", \"The learning service is unavailable.\", 503);\n const route = \"admin/lesson/preview\";\n return unwrap(\n await dispatch(\n PLUGIN_ID,\n \"GET\",\n route,\n new Request(requestUrl(route, input, origin)),\n locals.user,\n ),\n );\n}\nexport function courseUrl(basePath: string, slug: string): string {\n return `${basePath}/courses/${encodeURIComponent(slug)}`;\n}\nexport function lessonUrl(basePath: string, slug: string, lessonId: string): string {\n return `${courseUrl(basePath, slug)}/lessons/${encodeURIComponent(lessonId)}`;\n}\nexport function certificateUrl(basePath: string, id: string): string {\n return `${basePath}/certificates/${encodeURIComponent(id)}`;\n}\nexport { LmsError } from \"./errors.js\";\n"],"mappings":";;;;AAuBA,SAAS,WAAW,OAAe,OAAgC,QAAqB;CACtF,MAAM,MAAM,IAAI,IAAI,wBAAwB,UAAU,GAAG,SAAS,OAAO;AACzE,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,KAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,GACrD,KAAI,aAAa,IAAI,KAAK,OAAO,MAAM,CAAC;AAC5C,QAAO;;AAET,SAAS,OAAU,OAAmB;CACpC,MAAM,SAAS;AACf,KAAI,CAAC,QAAQ,QACX,OAAM,IAAI,SACR,QAAQ,OAAO,QAAQ,mBACvB,QAAQ,OAAO,WAAW,wCAC1B,QAAQ,UAAU,IACnB;AACH,QAAO,OAAO;;AAEhB,eAAsB,UACpB,QACA,OACA,OACA,QACY;CACZ,MAAM,WAAW,OAAO,QAAQ;AAChC,KAAI,CAAC,SAAU,OAAM,IAAI,SAAS,mBAAmB,wCAAwC,IAAI;AACjG,QAAO,OACL,MAAM,SAAS,WAAW,OAAO,OAAO,IAAI,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,CAAC,CACvF;;AAEH,MAAM,cAAc,IAAI,IAAI;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AACF,eAAsB,WACpB,QACA,OACA,OACA,QACY;AACZ,KAAI,CAAC,OAAO,QAAQ,OAAO,KAAK,OAAO,GACrC,OAAM,IAAI,SAAS,gBAAgB,wBAAwB,IAAI;AACjE,KAAI,CAAC,YAAY,IAAI,MAAM,CACzB,OAAM,IAAI,SAAS,aAAa,wDAAwD,IAAI;CAC9F,MAAM,WAAW,OAAO,QAAQ;AAChC,KAAI,CAAC,SAAU,OAAM,IAAI,SAAS,mBAAmB,wCAAwC,IAAI;AACjG,QAAO,OACL,MAAM,SACJ,WACA,OACA,OACA,IAAI,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,EAC7C,OAAO,KACR,CACF;;AAEH,SAAgB,SAAS,WAAmB,UAA0B;CACpE,MAAM,MAAM,IAAI,IAAI,WAAW,sBAAsB;AACrD,KAAI,aAAa,IAAI,YAAY,SAAS;AAC1C,QAAO,GAAG,IAAI,WAAW,IAAI,SAAS,IAAI;;;AAG5C,eAAsB,uBACpB,QACA,OACA,QACyD;AACzD,KAAI,CAAC,OAAO,KAAM,OAAM,IAAI,SAAS,gBAAgB,mCAAmC,IAAI;CAC5F,MAAM,WAAW,OAAO,QAAQ;AAChC,KAAI,CAAC,SAAU,OAAM,IAAI,SAAS,mBAAmB,wCAAwC,IAAI;CACjG,MAAM,QAAQ;AACd,QAAO,OACL,MAAM,SACJ,WACA,OACA,OACA,IAAI,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,EAC7C,OAAO,KACR,CACF;;AAEH,SAAgB,UAAU,UAAkB,MAAsB;AAChE,QAAO,GAAG,SAAS,WAAW,mBAAmB,KAAK;;AAExD,SAAgB,UAAU,UAAkB,MAAc,UAA0B;AAClF,QAAO,GAAG,UAAU,UAAU,KAAK,CAAC,WAAW,mBAAmB,SAAS;;AAE7E,SAAgB,eAAe,UAAkB,IAAoB;AACnE,QAAO,GAAG,SAAS,gBAAgB,mBAAmB,GAAG"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cohortDataSchema, courseDataSchema, lessonSchema, moduleSchema, questionSchema, quizSchema, settingsSchema } from "./schemas.js";
|
|
1
|
+
import { cohortDataSchema, courseDataSchema, lessonSchema, moduleSchema, pathDataSchema, preferencesSchema, questionSchema, quizSchema, settingsSchema } from "./schemas.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
@@ -14,7 +14,39 @@ interface Course extends CourseData {
|
|
|
14
14
|
createdBy: string;
|
|
15
15
|
createdAt: string;
|
|
16
16
|
updatedAt: string;
|
|
17
|
-
schemaVersion: 1;
|
|
17
|
+
schemaVersion: 1 | 2;
|
|
18
|
+
draftRevisionId?: string;
|
|
19
|
+
publishedEditionId?: string;
|
|
20
|
+
publishedDraftRevisionId?: string;
|
|
21
|
+
legacyEditionId?: string;
|
|
22
|
+
}
|
|
23
|
+
interface CourseRevision {
|
|
24
|
+
id: string;
|
|
25
|
+
courseId: string;
|
|
26
|
+
parentId: string | null;
|
|
27
|
+
data: CourseData;
|
|
28
|
+
kind: "migration" | "draft" | "publish" | "restore" | "archive";
|
|
29
|
+
createdBy: string;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
editionId?: string;
|
|
32
|
+
restoredFrom?: string;
|
|
33
|
+
}
|
|
34
|
+
type RevisionSummary = Omit<CourseRevision, "data"> & {
|
|
35
|
+
title: string;
|
|
36
|
+
};
|
|
37
|
+
interface CourseEdition {
|
|
38
|
+
id: string;
|
|
39
|
+
courseId: string;
|
|
40
|
+
data: CourseData;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
}
|
|
43
|
+
interface MigrationState {
|
|
44
|
+
phase: "courses" | "enrollments" | "complete";
|
|
45
|
+
cursor?: string;
|
|
46
|
+
coursesProcessed: number;
|
|
47
|
+
enrollmentsProcessed: number;
|
|
48
|
+
updatedAt: string;
|
|
49
|
+
lastError: string | null;
|
|
18
50
|
}
|
|
19
51
|
interface Actor {
|
|
20
52
|
id: string;
|
|
@@ -49,8 +81,12 @@ interface QuizAttempt {
|
|
|
49
81
|
passed: boolean;
|
|
50
82
|
feedback: QuestionResult[];
|
|
51
83
|
answers: Answers;
|
|
84
|
+
/** Records created before draft fencing have revision zero. */
|
|
85
|
+
draftRevision?: number;
|
|
52
86
|
}
|
|
53
|
-
type PublicQuizAttempt = Omit<QuizAttempt, "quiz"
|
|
87
|
+
type PublicQuizAttempt = Omit<QuizAttempt, "quiz" | "draftRevision"> & {
|
|
88
|
+
draftRevision: number;
|
|
89
|
+
};
|
|
54
90
|
interface AssignmentSubmission {
|
|
55
91
|
id: string;
|
|
56
92
|
body: string;
|
|
@@ -70,6 +106,63 @@ interface LessonProgress {
|
|
|
70
106
|
note: string;
|
|
71
107
|
quizAttempts: QuizAttempt[];
|
|
72
108
|
assignments: AssignmentSubmission[];
|
|
109
|
+
playback?: Playback;
|
|
110
|
+
}
|
|
111
|
+
interface Playback {
|
|
112
|
+
positionSeconds: number;
|
|
113
|
+
playbackRate: number;
|
|
114
|
+
revision: number;
|
|
115
|
+
updatedAt: string;
|
|
116
|
+
}
|
|
117
|
+
type LearnerPreferences = z.infer<typeof preferencesSchema>;
|
|
118
|
+
interface SavedCourse {
|
|
119
|
+
userId: string;
|
|
120
|
+
courseId: string;
|
|
121
|
+
saved: boolean;
|
|
122
|
+
updatedAt: string;
|
|
123
|
+
}
|
|
124
|
+
interface LearningPath extends z.infer<typeof pathDataSchema> {
|
|
125
|
+
id: string;
|
|
126
|
+
createdAt: string;
|
|
127
|
+
updatedAt: string;
|
|
128
|
+
}
|
|
129
|
+
interface PathEnrollment {
|
|
130
|
+
pathId: string;
|
|
131
|
+
userId: string;
|
|
132
|
+
title: string;
|
|
133
|
+
courseIds: string[];
|
|
134
|
+
joinedAt: string;
|
|
135
|
+
}
|
|
136
|
+
interface PublicPath {
|
|
137
|
+
id: string;
|
|
138
|
+
title: string;
|
|
139
|
+
description: string;
|
|
140
|
+
courses: (CourseCard | null)[];
|
|
141
|
+
}
|
|
142
|
+
interface LearnerPath {
|
|
143
|
+
pathId: string;
|
|
144
|
+
title: string;
|
|
145
|
+
joinedAt: string;
|
|
146
|
+
completed: number;
|
|
147
|
+
total: number;
|
|
148
|
+
courses: {
|
|
149
|
+
course: CourseCard | null;
|
|
150
|
+
completed: boolean;
|
|
151
|
+
}[];
|
|
152
|
+
}
|
|
153
|
+
interface LmsHealth {
|
|
154
|
+
version: string;
|
|
155
|
+
maintenance: {
|
|
156
|
+
startedAt: string;
|
|
157
|
+
completedAt: string | null;
|
|
158
|
+
failed: boolean;
|
|
159
|
+
} | null;
|
|
160
|
+
maintenanceStale: boolean;
|
|
161
|
+
pendingEmails: number;
|
|
162
|
+
failedEmails: number;
|
|
163
|
+
oldestPendingAt: string | null;
|
|
164
|
+
emailEnabled: boolean;
|
|
165
|
+
migration: MigrationState | null;
|
|
73
166
|
}
|
|
74
167
|
interface Certificate {
|
|
75
168
|
id: string;
|
|
@@ -86,6 +179,8 @@ interface Certificate {
|
|
|
86
179
|
interface Enrollment {
|
|
87
180
|
id: string;
|
|
88
181
|
courseId: string;
|
|
182
|
+
/** Immutable curriculum selected at enrollment; v1 records use the course's legacy edition. */
|
|
183
|
+
courseEditionId?: string;
|
|
89
184
|
userId: string;
|
|
90
185
|
learnerName: string;
|
|
91
186
|
learnerEmail: string;
|
|
@@ -265,6 +360,14 @@ interface ProgressSummary {
|
|
|
265
360
|
total: number;
|
|
266
361
|
percent: number;
|
|
267
362
|
nextLessonId: string | null;
|
|
363
|
+
blockedLessonId: string | null;
|
|
364
|
+
availability: Record<string, LessonAvailability>;
|
|
365
|
+
}
|
|
366
|
+
interface LessonAvailability {
|
|
367
|
+
available: boolean;
|
|
368
|
+
code: string | null;
|
|
369
|
+
reason: string | null;
|
|
370
|
+
releaseAt: string | null;
|
|
268
371
|
}
|
|
269
372
|
interface LmsOptions {
|
|
270
373
|
basePath?: string;
|
|
@@ -280,5 +383,5 @@ interface RouteEnvelope<T> {
|
|
|
280
383
|
};
|
|
281
384
|
}
|
|
282
385
|
//#endregion
|
|
283
|
-
export { AccessGrant, Acquisition, Actor, Answers, AssignmentSubmission, AuditRecord, Certificate, CertificateIndex, Cohort, CohortMembership, Course, CourseCard, CourseData, CourseDetail, CourseModule, CurriculumLesson, CurriculumModule, Discussion, Enrollment, Lesson, LessonProgress, LmsOptions, LmsSettings, Notification, Page, ProgressSummary, PublicEnrollment, PublicLesson, PublicQuestion, PublicQuizAttempt, QuestionResult, Quiz, QuizAttempt, QuizQuestion, Review, RouteEnvelope, Versioned };
|
|
386
|
+
export { AccessGrant, Acquisition, Actor, Answers, AssignmentSubmission, AuditRecord, Certificate, CertificateIndex, Cohort, CohortMembership, Course, CourseCard, CourseData, CourseDetail, CourseEdition, CourseModule, CourseRevision, CurriculumLesson, CurriculumModule, Discussion, Enrollment, LearnerPath, LearnerPreferences, LearningPath, Lesson, LessonAvailability, LessonProgress, LmsHealth, LmsOptions, LmsSettings, MigrationState, Notification, Page, PathEnrollment, Playback, ProgressSummary, PublicEnrollment, PublicLesson, PublicPath, PublicQuestion, PublicQuizAttempt, QuestionResult, Quiz, QuizAttempt, QuizQuestion, Review, RevisionSummary, RouteEnvelope, SavedCourse, Versioned };
|
|
284
387
|
//# sourceMappingURL=types.d.ts.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants-C0kT94tc.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const PLUGIN_ID = \"anantagnanam-lms\";\nexport const PLUGIN_VERSION = \"0.1.0\";\nexport const API_BASE = `/_emdash/api/plugins/${PLUGIN_ID}`;\nexport const MAX_DOCUMENT_BYTES = 950_000;\n\nimport type { PluginStorageConfig } from \"emdash\";\n\nexport const storage = {\n courses: {\n indexes: [\n \"status\",\n \"title\",\n \"searchTitle\",\n \"category\",\n \"level\",\n \"language\",\n \"updatedAt\",\n \"createdBy\",\n ],\n uniqueIndexes: [\"slug\"],\n },\n enrollments: {\n indexes: [\n \"userId\",\n \"courseId\",\n \"status\",\n \"accessStatus\",\n \"accessSource\",\n \"enrolledAt\",\n \"completedAt\",\n \"lastActivityAt\",\n \"cohortId\",\n [\"courseId\", \"status\"],\n [\"userId\", \"status\"],\n ],\n },\n certificates: { indexes: [\"userId\", \"courseId\"] },\n discussions: {\n indexes: [\n \"courseId\",\n \"lessonId\",\n \"authorId\",\n \"status\",\n \"createdAt\",\n \"parentId\",\n [\"courseId\", \"createdAt\"],\n ],\n },\n reviews: { indexes: [\"courseId\", \"userId\", \"status\", \"createdAt\"] },\n cohorts: { indexes: [\"title\", \"createdAt\", \"createdBy\"] },\n cohort_enrollments: { indexes: [\"cohortId\", \"userId\", \"status\", \"requestedAt\"] },\n notifications: { indexes: [\"userId\", \"read\", \"createdAt\", \"emailStatus\", \"claimedAt\"] },\n audit: { indexes: [\"actorId\", \"action\", \"resourceId\", \"createdAt\"] },\n} satisfies PluginStorageConfig;\n\nexport const adminPages = [\n { path: \"/\", label: \"Learning overview\", icon: \"graduation-cap\", group: \"Learning\" },\n { path: \"/courses\", label: \"Courses\", icon: \"books\", group: \"Learning\" },\n { path: \"/learners\", label: \"Enrollments\", icon: \"users\", group: \"Learning\" },\n { path: \"/assignments\", label: \"Assignments\", icon: \"exam\", group: \"Learning\" },\n { path: \"/community\", label: \"Community\", icon: \"chats\", group: \"Learning\" },\n { path: \"/cohorts\", label: \"Cohorts\", icon: \"users-three\", group: \"Learning\" },\n { path: \"/reports\", label: \"Reports\", icon: \"chart-bar\", group: \"Learning\" },\n { path: \"/notifications\", label: \"Notifications\", icon: \"bell\", group: \"Learning\" },\n { path: \"/audit\", label: \"Audit history\", icon: \"clock-counter-clockwise\", group: \"Learning\" },\n { path: \"/settings\", label: \"LMS settings\", icon: \"gear\", group: \"Learning\" },\n];\n"],"mappings":";AAAA,MAAa,YAAY;AACzB,MAAa,iBAAiB;AAC9B,MAAa,WAAW,wBAAwB;AAChD,MAAa,qBAAqB;AAIlC,MAAa,UAAU;CACrB,SAAS;EACP,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACD,eAAe,CAAC,OAAO;EACxB;CACD,aAAa,EACX,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CAAC,YAAY,SAAS;EACtB,CAAC,UAAU,SAAS;EACrB,EACF;CACD,cAAc,EAAE,SAAS,CAAC,UAAU,WAAW,EAAE;CACjD,aAAa,EACX,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA,CAAC,YAAY,YAAY;EAC1B,EACF;CACD,SAAS,EAAE,SAAS;EAAC;EAAY;EAAU;EAAU;EAAY,EAAE;CACnE,SAAS,EAAE,SAAS;EAAC;EAAS;EAAa;EAAY,EAAE;CACzD,oBAAoB,EAAE,SAAS;EAAC;EAAY;EAAU;EAAU;EAAc,EAAE;CAChF,eAAe,EAAE,SAAS;EAAC;EAAU;EAAQ;EAAa;EAAe;EAAY,EAAE;CACvF,OAAO,EAAE,SAAS;EAAC;EAAW;EAAU;EAAc;EAAY,EAAE;CACrE;AAED,MAAa,aAAa;CACxB;EAAE,MAAM;EAAK,OAAO;EAAqB,MAAM;EAAkB,OAAO;EAAY;CACpF;EAAE,MAAM;EAAY,OAAO;EAAW,MAAM;EAAS,OAAO;EAAY;CACxE;EAAE,MAAM;EAAa,OAAO;EAAe,MAAM;EAAS,OAAO;EAAY;CAC7E;EAAE,MAAM;EAAgB,OAAO;EAAe,MAAM;EAAQ,OAAO;EAAY;CAC/E;EAAE,MAAM;EAAc,OAAO;EAAa,MAAM;EAAS,OAAO;EAAY;CAC5E;EAAE,MAAM;EAAY,OAAO;EAAW,MAAM;EAAe,OAAO;EAAY;CAC9E;EAAE,MAAM;EAAY,OAAO;EAAW,MAAM;EAAa,OAAO;EAAY;CAC5E;EAAE,MAAM;EAAkB,OAAO;EAAiB,MAAM;EAAQ,OAAO;EAAY;CACnF;EAAE,MAAM;EAAU,OAAO;EAAiB,MAAM;EAA2B,OAAO;EAAY;CAC9F;EAAE,MAAM;EAAa,OAAO;EAAgB,MAAM;EAAQ,OAAO;EAAY;CAC9E"}
|