course-format-ts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/.idea/edu-format-ts.iml +10 -0
  2. package/.idea/inspectionProfiles/Project_Default.xml +28 -0
  3. package/.idea/misc.xml +4 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/AGENTS.md +1 -0
  7. package/dist/courseFormat/AnswerPlaceholder.d.ts +37 -0
  8. package/dist/courseFormat/AnswerPlaceholder.js +101 -0
  9. package/dist/courseFormat/AnswerPlaceholderComparator.d.ts +4 -0
  10. package/dist/courseFormat/AnswerPlaceholderComparator.js +8 -0
  11. package/dist/courseFormat/AnswerPlaceholderDependency.d.ts +19 -0
  12. package/dist/courseFormat/AnswerPlaceholderDependency.js +91 -0
  13. package/dist/courseFormat/CheckFeedback.d.ts +20 -0
  14. package/dist/courseFormat/CheckFeedback.js +58 -0
  15. package/dist/courseFormat/CheckResult.d.ts +33 -0
  16. package/dist/courseFormat/CheckResult.js +58 -0
  17. package/dist/courseFormat/CheckResultSeverity.d.ts +7 -0
  18. package/dist/courseFormat/CheckResultSeverity.js +17 -0
  19. package/dist/courseFormat/CheckStatus.d.ts +5 -0
  20. package/dist/courseFormat/CheckStatus.js +9 -0
  21. package/dist/courseFormat/Course.d.ts +68 -0
  22. package/dist/courseFormat/Course.js +165 -0
  23. package/dist/courseFormat/CourseMode.d.ts +4 -0
  24. package/dist/courseFormat/CourseMode.js +8 -0
  25. package/dist/courseFormat/CourseVisibility.d.ts +4 -0
  26. package/dist/courseFormat/CourseVisibility.js +8 -0
  27. package/dist/courseFormat/CourseraCourse.d.ts +5 -0
  28. package/dist/courseFormat/CourseraCourse.js +15 -0
  29. package/dist/courseFormat/DescriptionFormat.d.ts +5 -0
  30. package/dist/courseFormat/DescriptionFormat.js +9 -0
  31. package/dist/courseFormat/EduCourse.d.ts +17 -0
  32. package/dist/courseFormat/EduCourse.js +42 -0
  33. package/dist/courseFormat/EduFile.d.ts +22 -0
  34. package/dist/courseFormat/EduFile.js +110 -0
  35. package/dist/courseFormat/EduFileErrorHighlightLevel.d.ts +5 -0
  36. package/dist/courseFormat/EduFileErrorHighlightLevel.js +9 -0
  37. package/dist/courseFormat/EduFormatNames.d.ts +75 -0
  38. package/dist/courseFormat/EduFormatNames.js +80 -0
  39. package/dist/courseFormat/EduTestInfo.d.ts +28 -0
  40. package/dist/courseFormat/EduTestInfo.js +68 -0
  41. package/dist/courseFormat/EduVersions.d.ts +2 -0
  42. package/dist/courseFormat/EduVersions.js +5 -0
  43. package/dist/courseFormat/FileContents.d.ts +36 -0
  44. package/dist/courseFormat/FileContents.js +67 -0
  45. package/dist/courseFormat/FileContentsFactory.d.ts +17 -0
  46. package/dist/courseFormat/FileContentsFactory.js +2 -0
  47. package/dist/courseFormat/FrameworkLesson.d.ts +9 -0
  48. package/dist/courseFormat/FrameworkLesson.js +28 -0
  49. package/dist/courseFormat/ItemContainer.d.ts +13 -0
  50. package/dist/courseFormat/ItemContainer.js +45 -0
  51. package/dist/courseFormat/JBAccountUserInfo.d.ts +9 -0
  52. package/dist/courseFormat/JBAccountUserInfo.js +20 -0
  53. package/dist/courseFormat/Language.d.ts +4 -0
  54. package/dist/courseFormat/Language.js +33 -0
  55. package/dist/courseFormat/Lesson.d.ts +20 -0
  56. package/dist/courseFormat/Lesson.js +56 -0
  57. package/dist/courseFormat/LessonContainer.d.ts +16 -0
  58. package/dist/courseFormat/LessonContainer.js +54 -0
  59. package/dist/courseFormat/PluginInfo.d.ts +7 -0
  60. package/dist/courseFormat/PluginInfo.js +15 -0
  61. package/dist/courseFormat/Section.d.ts +8 -0
  62. package/dist/courseFormat/Section.js +27 -0
  63. package/dist/courseFormat/StudyItem.d.ts +20 -0
  64. package/dist/courseFormat/StudyItem.js +47 -0
  65. package/dist/courseFormat/Tags.d.ts +16 -0
  66. package/dist/courseFormat/Tags.js +42 -0
  67. package/dist/courseFormat/TaskFile.d.ts +26 -0
  68. package/dist/courseFormat/TaskFile.js +72 -0
  69. package/dist/courseFormat/UserInfo.d.ts +3 -0
  70. package/dist/courseFormat/UserInfo.js +2 -0
  71. package/dist/courseFormat/Vendor.d.ts +7 -0
  72. package/dist/courseFormat/Vendor.js +14 -0
  73. package/dist/courseFormat/attempts/Attempt.d.ts +12 -0
  74. package/dist/courseFormat/attempts/Attempt.js +25 -0
  75. package/dist/courseFormat/attempts/AttemptBase.d.ts +9 -0
  76. package/dist/courseFormat/attempts/AttemptBase.js +28 -0
  77. package/dist/courseFormat/attempts/DataTaskAttempt.d.ts +6 -0
  78. package/dist/courseFormat/attempts/DataTaskAttempt.js +24 -0
  79. package/dist/courseFormat/attempts/Dataset.d.ts +12 -0
  80. package/dist/courseFormat/attempts/Dataset.js +21 -0
  81. package/dist/courseFormat/fileUtils.d.ts +5 -0
  82. package/dist/courseFormat/fileUtils.js +32 -0
  83. package/dist/courseFormat/hyperskill/HyperskillCourse.d.ts +13 -0
  84. package/dist/courseFormat/hyperskill/HyperskillCourse.js +25 -0
  85. package/dist/courseFormat/hyperskill/HyperskillProject.d.ts +10 -0
  86. package/dist/courseFormat/hyperskill/HyperskillProject.js +16 -0
  87. package/dist/courseFormat/hyperskill/HyperskillStage.d.ts +8 -0
  88. package/dist/courseFormat/hyperskill/HyperskillStage.js +20 -0
  89. package/dist/courseFormat/hyperskill/HyperskillTaskType.d.ts +4 -0
  90. package/dist/courseFormat/hyperskill/HyperskillTaskType.js +26 -0
  91. package/dist/courseFormat/hyperskill/HyperskillTopic.d.ts +5 -0
  92. package/dist/courseFormat/hyperskill/HyperskillTopic.js +11 -0
  93. package/dist/courseFormat/loggerUtils.d.ts +1 -0
  94. package/dist/courseFormat/loggerUtils.js +6 -0
  95. package/dist/courseFormat/stepik/StepikCourse.d.ts +5 -0
  96. package/dist/courseFormat/stepik/StepikCourse.js +15 -0
  97. package/dist/courseFormat/stepik/StepikLesson.d.ts +6 -0
  98. package/dist/courseFormat/stepik/StepikLesson.js +16 -0
  99. package/dist/courseFormat/tasks/AnswerTask.d.ts +8 -0
  100. package/dist/courseFormat/tasks/AnswerTask.js +11 -0
  101. package/dist/courseFormat/tasks/CodeTask.d.ts +12 -0
  102. package/dist/courseFormat/tasks/CodeTask.js +21 -0
  103. package/dist/courseFormat/tasks/DataTask.d.ts +18 -0
  104. package/dist/courseFormat/tasks/DataTask.js +32 -0
  105. package/dist/courseFormat/tasks/EduTask.d.ts +12 -0
  106. package/dist/courseFormat/tasks/EduTask.js +22 -0
  107. package/dist/courseFormat/tasks/IdeTask.d.ts +9 -0
  108. package/dist/courseFormat/tasks/IdeTask.js +14 -0
  109. package/dist/courseFormat/tasks/NumberTask.d.ts +9 -0
  110. package/dist/courseFormat/tasks/NumberTask.js +14 -0
  111. package/dist/courseFormat/tasks/OutputTask.d.ts +10 -0
  112. package/dist/courseFormat/tasks/OutputTask.js +18 -0
  113. package/dist/courseFormat/tasks/OutputTaskBase.d.ts +14 -0
  114. package/dist/courseFormat/tasks/OutputTaskBase.js +19 -0
  115. package/dist/courseFormat/tasks/RemoteEduTask.d.ts +9 -0
  116. package/dist/courseFormat/tasks/RemoteEduTask.js +15 -0
  117. package/dist/courseFormat/tasks/StringTask.d.ts +9 -0
  118. package/dist/courseFormat/tasks/StringTask.js +14 -0
  119. package/dist/courseFormat/tasks/TableTask.d.ts +17 -0
  120. package/dist/courseFormat/tasks/TableTask.js +43 -0
  121. package/dist/courseFormat/tasks/Task.d.ts +45 -0
  122. package/dist/courseFormat/tasks/Task.js +155 -0
  123. package/dist/courseFormat/tasks/TheoryTask.d.ts +10 -0
  124. package/dist/courseFormat/tasks/TheoryTask.js +15 -0
  125. package/dist/courseFormat/tasks/UnsupportedTask.d.ts +9 -0
  126. package/dist/courseFormat/tasks/UnsupportedTask.js +14 -0
  127. package/dist/courseFormat/tasks/choice/ChoiceOption.d.ts +10 -0
  128. package/dist/courseFormat/tasks/choice/ChoiceOption.js +33 -0
  129. package/dist/courseFormat/tasks/choice/ChoiceOptionStatus.d.ts +5 -0
  130. package/dist/courseFormat/tasks/choice/ChoiceOptionStatus.js +9 -0
  131. package/dist/courseFormat/tasks/choice/ChoiceTask.d.ts +23 -0
  132. package/dist/courseFormat/tasks/choice/ChoiceTask.js +47 -0
  133. package/dist/courseFormat/tasks/matching/MatchingTask.d.ts +10 -0
  134. package/dist/courseFormat/tasks/matching/MatchingTask.js +15 -0
  135. package/dist/courseFormat/tasks/matching/SortingBasedTask.d.ts +16 -0
  136. package/dist/courseFormat/tasks/matching/SortingBasedTask.js +50 -0
  137. package/dist/courseFormat/tasks/matching/SortingTask.d.ts +9 -0
  138. package/dist/courseFormat/tasks/matching/SortingTask.js +14 -0
  139. package/dist/courseFormat/uiMessages.d.ts +3 -0
  140. package/dist/courseFormat/uiMessages.js +14 -0
  141. package/dist/disk-loader.d.ts +4 -0
  142. package/dist/disk-loader.js +389 -0
  143. package/dist/index.d.ts +31 -0
  144. package/dist/index.js +64 -0
  145. package/dist/loader.d.ts +7 -0
  146. package/dist/loader.js +435 -0
  147. package/dist/models.d.ts +49 -0
  148. package/dist/models.js +2 -0
  149. package/dist/zip-loader.d.ts +4 -0
  150. package/dist/zip-loader.js +431 -0
  151. package/example-course-project/course-info.yaml +15 -0
  152. package/example-course-project/lesson1/lesson-info.yaml +3 -0
  153. package/example-course-project/lesson1/lesson-remote-info.yaml +1 -0
  154. package/example-course-project/lesson1/task1/Task.txt +1 -0
  155. package/example-course-project/lesson1/task1/task-info.yaml +12 -0
  156. package/example-course-project/lesson1/task1/task-remote-info.yaml +1 -0
  157. package/example-course-project/lesson1/task1/task.md +47 -0
  158. package/example-course-project/lesson1/task1/tests/Tests.txt +0 -0
  159. package/example-course-project/lesson1/task2/Task.txt +1 -0
  160. package/example-course-project/lesson1/task2/task-info.yaml +12 -0
  161. package/example-course-project/lesson1/task2/task-remote-info.yaml +1 -0
  162. package/example-course-project/lesson1/task2/task.md +47 -0
  163. package/example-course-project/lesson1/task2/tests/Tests.txt +0 -0
  164. package/package.json +19 -0
  165. package/src/@types/mime-types.d.ts +3 -0
  166. package/src/courseFormat/AnswerPlaceholder.ts +121 -0
  167. package/src/courseFormat/AnswerPlaceholderComparator.ts +7 -0
  168. package/src/courseFormat/AnswerPlaceholderDependency.ts +122 -0
  169. package/src/courseFormat/CheckFeedback.ts +71 -0
  170. package/src/courseFormat/CheckResult.ts +92 -0
  171. package/src/courseFormat/CheckResultSeverity.ts +13 -0
  172. package/src/courseFormat/CheckStatus.ts +5 -0
  173. package/src/courseFormat/Course.ts +201 -0
  174. package/src/courseFormat/CourseMode.ts +4 -0
  175. package/src/courseFormat/CourseVisibility.ts +4 -0
  176. package/src/courseFormat/CourseraCourse.ts +10 -0
  177. package/src/courseFormat/DescriptionFormat.ts +5 -0
  178. package/src/courseFormat/EduCourse.ts +41 -0
  179. package/src/courseFormat/EduFile.ts +133 -0
  180. package/src/courseFormat/EduFileErrorHighlightLevel.ts +5 -0
  181. package/src/courseFormat/EduFormatNames.ts +95 -0
  182. package/src/courseFormat/EduTestInfo.ts +87 -0
  183. package/src/courseFormat/EduVersions.ts +2 -0
  184. package/src/courseFormat/FileContents.ts +97 -0
  185. package/src/courseFormat/FileContentsFactory.ts +19 -0
  186. package/src/courseFormat/FrameworkLesson.ts +29 -0
  187. package/src/courseFormat/ItemContainer.ts +47 -0
  188. package/src/courseFormat/JBAccountUserInfo.ts +21 -0
  189. package/src/courseFormat/Language.ts +31 -0
  190. package/src/courseFormat/Lesson.ts +69 -0
  191. package/src/courseFormat/LessonContainer.ts +65 -0
  192. package/src/courseFormat/PluginInfo.ts +15 -0
  193. package/src/courseFormat/Section.ts +29 -0
  194. package/src/courseFormat/StudyItem.ts +55 -0
  195. package/src/courseFormat/Tags.ts +45 -0
  196. package/src/courseFormat/TaskFile.ts +88 -0
  197. package/src/courseFormat/UserInfo.ts +3 -0
  198. package/src/courseFormat/Vendor.ts +15 -0
  199. package/src/courseFormat/attempts/Attempt.ts +28 -0
  200. package/src/courseFormat/attempts/AttemptBase.ts +24 -0
  201. package/src/courseFormat/attempts/DataTaskAttempt.ts +19 -0
  202. package/src/courseFormat/attempts/Dataset.ts +13 -0
  203. package/src/courseFormat/fileUtils.ts +31 -0
  204. package/src/courseFormat/hyperskill/HyperskillCourse.ts +24 -0
  205. package/src/courseFormat/hyperskill/HyperskillProject.ts +10 -0
  206. package/src/courseFormat/hyperskill/HyperskillStage.ts +15 -0
  207. package/src/courseFormat/hyperskill/HyperskillTaskType.ts +23 -0
  208. package/src/courseFormat/hyperskill/HyperskillTopic.ts +5 -0
  209. package/src/courseFormat/loggerUtils.ts +3 -0
  210. package/src/courseFormat/stepik/StepikCourse.ts +10 -0
  211. package/src/courseFormat/stepik/StepikLesson.ts +11 -0
  212. package/src/courseFormat/tasks/AnswerTask.ts +13 -0
  213. package/src/courseFormat/tasks/CodeTask.ts +42 -0
  214. package/src/courseFormat/tasks/DataTask.ts +37 -0
  215. package/src/courseFormat/tasks/EduTask.ts +26 -0
  216. package/src/courseFormat/tasks/IdeTask.ts +17 -0
  217. package/src/courseFormat/tasks/NumberTask.ts +17 -0
  218. package/src/courseFormat/tasks/OutputTask.ts +21 -0
  219. package/src/courseFormat/tasks/OutputTaskBase.ts +23 -0
  220. package/src/courseFormat/tasks/RemoteEduTask.ts +18 -0
  221. package/src/courseFormat/tasks/StringTask.ts +17 -0
  222. package/src/courseFormat/tasks/TableTask.ts +51 -0
  223. package/src/courseFormat/tasks/Task.ts +181 -0
  224. package/src/courseFormat/tasks/TheoryTask.ts +19 -0
  225. package/src/courseFormat/tasks/UnsupportedTask.ts +17 -0
  226. package/src/courseFormat/tasks/choice/ChoiceOption.ts +37 -0
  227. package/src/courseFormat/tasks/choice/ChoiceOptionStatus.ts +5 -0
  228. package/src/courseFormat/tasks/choice/ChoiceTask.ts +57 -0
  229. package/src/courseFormat/tasks/matching/MatchingTask.ts +19 -0
  230. package/src/courseFormat/tasks/matching/SortingBasedTask.ts +59 -0
  231. package/src/courseFormat/tasks/matching/SortingTask.ts +17 -0
  232. package/src/courseFormat/uiMessages.ts +12 -0
  233. package/src/disk-loader.ts +463 -0
  234. package/src/index.ts +33 -0
  235. package/src/models.ts +54 -0
  236. package/src/zip-loader.ts +583 -0
  237. package/test/load-course.test.js +279 -0
  238. package/test/load-zip-course.test.js +73 -0
  239. package/tsconfig.json +15 -0
package/dist/index.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CheckStatus = exports.SortingTask = exports.MatchingTask = exports.ChoiceTask = exports.RemoteEduTask = exports.UnsupportedTask = exports.IdeTask = exports.TheoryTask = exports.TableTask = exports.DataTask = exports.OutputTask = exports.StringTask = exports.NumberTask = exports.AnswerTask = exports.CodeTask = exports.EduTask = exports.Task = exports.TaskFile = exports.Section = exports.FrameworkLesson = exports.StepikLesson = exports.Lesson = exports.CourseMode = exports.Course = exports.StepikCourse = exports.HyperskillCourse = exports.CourseraCourse = exports.EduCourse = exports.loadCourseProjectFromZip = exports.loadCourseProject = void 0;
4
+ var disk_loader_1 = require("./disk-loader");
5
+ Object.defineProperty(exports, "loadCourseProject", { enumerable: true, get: function () { return disk_loader_1.loadCourseProject; } });
6
+ var zip_loader_1 = require("./zip-loader");
7
+ Object.defineProperty(exports, "loadCourseProjectFromZip", { enumerable: true, get: function () { return zip_loader_1.loadCourseProjectFromZip; } });
8
+ // Core models
9
+ var EduCourse_1 = require("./courseFormat/EduCourse");
10
+ Object.defineProperty(exports, "EduCourse", { enumerable: true, get: function () { return EduCourse_1.EduCourse; } });
11
+ var CourseraCourse_1 = require("./courseFormat/CourseraCourse");
12
+ Object.defineProperty(exports, "CourseraCourse", { enumerable: true, get: function () { return CourseraCourse_1.CourseraCourse; } });
13
+ var HyperskillCourse_1 = require("./courseFormat/hyperskill/HyperskillCourse");
14
+ Object.defineProperty(exports, "HyperskillCourse", { enumerable: true, get: function () { return HyperskillCourse_1.HyperskillCourse; } });
15
+ var StepikCourse_1 = require("./courseFormat/stepik/StepikCourse");
16
+ Object.defineProperty(exports, "StepikCourse", { enumerable: true, get: function () { return StepikCourse_1.StepikCourse; } });
17
+ var Course_1 = require("./courseFormat/Course");
18
+ Object.defineProperty(exports, "Course", { enumerable: true, get: function () { return Course_1.Course; } });
19
+ var CourseMode_1 = require("./courseFormat/CourseMode");
20
+ Object.defineProperty(exports, "CourseMode", { enumerable: true, get: function () { return CourseMode_1.CourseMode; } });
21
+ var Lesson_1 = require("./courseFormat/Lesson");
22
+ Object.defineProperty(exports, "Lesson", { enumerable: true, get: function () { return Lesson_1.Lesson; } });
23
+ var StepikLesson_1 = require("./courseFormat/stepik/StepikLesson");
24
+ Object.defineProperty(exports, "StepikLesson", { enumerable: true, get: function () { return StepikLesson_1.StepikLesson; } });
25
+ var FrameworkLesson_1 = require("./courseFormat/FrameworkLesson");
26
+ Object.defineProperty(exports, "FrameworkLesson", { enumerable: true, get: function () { return FrameworkLesson_1.FrameworkLesson; } });
27
+ var Section_1 = require("./courseFormat/Section");
28
+ Object.defineProperty(exports, "Section", { enumerable: true, get: function () { return Section_1.Section; } });
29
+ var TaskFile_1 = require("./courseFormat/TaskFile");
30
+ Object.defineProperty(exports, "TaskFile", { enumerable: true, get: function () { return TaskFile_1.TaskFile; } });
31
+ var Task_1 = require("./courseFormat/tasks/Task");
32
+ Object.defineProperty(exports, "Task", { enumerable: true, get: function () { return Task_1.Task; } });
33
+ var EduTask_1 = require("./courseFormat/tasks/EduTask");
34
+ Object.defineProperty(exports, "EduTask", { enumerable: true, get: function () { return EduTask_1.EduTask; } });
35
+ var CodeTask_1 = require("./courseFormat/tasks/CodeTask");
36
+ Object.defineProperty(exports, "CodeTask", { enumerable: true, get: function () { return CodeTask_1.CodeTask; } });
37
+ var AnswerTask_1 = require("./courseFormat/tasks/AnswerTask");
38
+ Object.defineProperty(exports, "AnswerTask", { enumerable: true, get: function () { return AnswerTask_1.AnswerTask; } });
39
+ var NumberTask_1 = require("./courseFormat/tasks/NumberTask");
40
+ Object.defineProperty(exports, "NumberTask", { enumerable: true, get: function () { return NumberTask_1.NumberTask; } });
41
+ var StringTask_1 = require("./courseFormat/tasks/StringTask");
42
+ Object.defineProperty(exports, "StringTask", { enumerable: true, get: function () { return StringTask_1.StringTask; } });
43
+ var OutputTask_1 = require("./courseFormat/tasks/OutputTask");
44
+ Object.defineProperty(exports, "OutputTask", { enumerable: true, get: function () { return OutputTask_1.OutputTask; } });
45
+ var DataTask_1 = require("./courseFormat/tasks/DataTask");
46
+ Object.defineProperty(exports, "DataTask", { enumerable: true, get: function () { return DataTask_1.DataTask; } });
47
+ var TableTask_1 = require("./courseFormat/tasks/TableTask");
48
+ Object.defineProperty(exports, "TableTask", { enumerable: true, get: function () { return TableTask_1.TableTask; } });
49
+ var TheoryTask_1 = require("./courseFormat/tasks/TheoryTask");
50
+ Object.defineProperty(exports, "TheoryTask", { enumerable: true, get: function () { return TheoryTask_1.TheoryTask; } });
51
+ var IdeTask_1 = require("./courseFormat/tasks/IdeTask");
52
+ Object.defineProperty(exports, "IdeTask", { enumerable: true, get: function () { return IdeTask_1.IdeTask; } });
53
+ var UnsupportedTask_1 = require("./courseFormat/tasks/UnsupportedTask");
54
+ Object.defineProperty(exports, "UnsupportedTask", { enumerable: true, get: function () { return UnsupportedTask_1.UnsupportedTask; } });
55
+ var RemoteEduTask_1 = require("./courseFormat/tasks/RemoteEduTask");
56
+ Object.defineProperty(exports, "RemoteEduTask", { enumerable: true, get: function () { return RemoteEduTask_1.RemoteEduTask; } });
57
+ var ChoiceTask_1 = require("./courseFormat/tasks/choice/ChoiceTask");
58
+ Object.defineProperty(exports, "ChoiceTask", { enumerable: true, get: function () { return ChoiceTask_1.ChoiceTask; } });
59
+ var MatchingTask_1 = require("./courseFormat/tasks/matching/MatchingTask");
60
+ Object.defineProperty(exports, "MatchingTask", { enumerable: true, get: function () { return MatchingTask_1.MatchingTask; } });
61
+ var SortingTask_1 = require("./courseFormat/tasks/matching/SortingTask");
62
+ Object.defineProperty(exports, "SortingTask", { enumerable: true, get: function () { return SortingTask_1.SortingTask; } });
63
+ var CheckStatus_1 = require("./courseFormat/CheckStatus");
64
+ Object.defineProperty(exports, "CheckStatus", { enumerable: true, get: function () { return CheckStatus_1.CheckStatus; } });
@@ -0,0 +1,7 @@
1
+ import { Course } from "./courseFormat/Course";
2
+ /**
3
+ * Load a course from an in-memory file map (used by zip loader).
4
+ * The map must contain the same directory structure as a course project
5
+ * on disk (with course-info.yaml at the root).
6
+ */
7
+ export declare function loadCourseFromZip(zipBuffer: Uint8Array, _options?: unknown): Promise<Course>;
package/dist/loader.js ADDED
@@ -0,0 +1,435 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.loadCourseFromZip = loadCourseFromZip;
46
+ const yaml_1 = require("yaml");
47
+ const CheckStatus_1 = require("./courseFormat/CheckStatus");
48
+ const CourseMode_1 = require("./courseFormat/CourseMode");
49
+ const Lesson_1 = require("./courseFormat/Lesson");
50
+ const EduCourse_1 = require("./courseFormat/EduCourse");
51
+ const CourseraCourse_1 = require("./courseFormat/CourseraCourse");
52
+ const HyperskillCourse_1 = require("./courseFormat/hyperskill/HyperskillCourse");
53
+ const StepikCourse_1 = require("./courseFormat/stepik/StepikCourse");
54
+ const StepikLesson_1 = require("./courseFormat/stepik/StepikLesson");
55
+ const EduTask_1 = require("./courseFormat/tasks/EduTask");
56
+ const CodeTask_1 = require("./courseFormat/tasks/CodeTask");
57
+ const NumberTask_1 = require("./courseFormat/tasks/NumberTask");
58
+ const StringTask_1 = require("./courseFormat/tasks/StringTask");
59
+ const OutputTask_1 = require("./courseFormat/tasks/OutputTask");
60
+ const DataTask_1 = require("./courseFormat/tasks/DataTask");
61
+ const TableTask_1 = require("./courseFormat/tasks/TableTask");
62
+ const TheoryTask_1 = require("./courseFormat/tasks/TheoryTask");
63
+ const IdeTask_1 = require("./courseFormat/tasks/IdeTask");
64
+ const UnsupportedTask_1 = require("./courseFormat/tasks/UnsupportedTask");
65
+ const RemoteEduTask_1 = require("./courseFormat/tasks/RemoteEduTask");
66
+ const ChoiceTask_1 = require("./courseFormat/tasks/choice/ChoiceTask");
67
+ const ChoiceOption_1 = require("./courseFormat/tasks/choice/ChoiceOption");
68
+ const ChoiceOptionStatus_1 = require("./courseFormat/tasks/choice/ChoiceOptionStatus");
69
+ const MatchingTask_1 = require("./courseFormat/tasks/matching/MatchingTask");
70
+ const SortingTask_1 = require("./courseFormat/tasks/matching/SortingTask");
71
+ const TaskFile_1 = require("./courseFormat/TaskFile");
72
+ /**
73
+ * Simple path joining (works in browser).
74
+ */
75
+ function pathJoin(...parts) {
76
+ return parts.filter(p => p.length > 0).join("/");
77
+ }
78
+ /**
79
+ * Cross-platform base64 encoding from Uint8Array.
80
+ * Uses btoa which is available in modern browsers and Node.js.
81
+ */
82
+ function uint8ArrayToBase64(data) {
83
+ let binary = "";
84
+ const bytes = new Uint8Array(data);
85
+ for (let i = 0; i < bytes.length; i++) {
86
+ binary += String.fromCharCode(bytes[i]);
87
+ }
88
+ return btoa(binary);
89
+ }
90
+ class MemoryFileSystem {
91
+ constructor(files) {
92
+ this.files = files;
93
+ }
94
+ readFile(filePath) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ const content = this.files.get(filePath);
97
+ if (content === undefined) {
98
+ throw new Error(`File not found: ${filePath}`);
99
+ }
100
+ return content;
101
+ });
102
+ }
103
+ readFileSync(filePath) {
104
+ var _a;
105
+ return (_a = this.files.get(filePath)) !== null && _a !== void 0 ? _a : null;
106
+ }
107
+ }
108
+ const COURSE_CONFIG = "course-info.yaml";
109
+ const LESSON_CONFIG = "lesson-info.yaml";
110
+ const TASK_CONFIG = "task-info.yaml";
111
+ function createCourse(type) {
112
+ switch (type) {
113
+ case "hyperskill":
114
+ return new HyperskillCourse_1.HyperskillCourse();
115
+ case "coursera":
116
+ return new CourseraCourse_1.CourseraCourse();
117
+ case "stepik":
118
+ return new StepikCourse_1.StepikCourse();
119
+ default:
120
+ const course = new EduCourse_1.EduCourse();
121
+ return course;
122
+ }
123
+ }
124
+ function hydrateCourse(course, yaml) {
125
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
126
+ course.name = (_a = yaml.title) !== null && _a !== void 0 ? _a : "";
127
+ course.description = (_b = yaml.summary) !== null && _b !== void 0 ? _b : "";
128
+ course.programmingLanguage = (_c = yaml.programming_language) !== null && _c !== void 0 ? _c : "";
129
+ course.languageVersion = yaml.programming_language_version;
130
+ course.environment = (_d = yaml.environment) !== null && _d !== void 0 ? _d : course.environment;
131
+ course.solutionsHidden = (_e = yaml.solutions_hidden) !== null && _e !== void 0 ? _e : course.solutionsHidden;
132
+ course.environmentSettings = (_f = yaml.environment_settings) !== null && _f !== void 0 ? _f : course.environmentSettings;
133
+ course.customContentPath = (_g = yaml.custom_content_path) !== null && _g !== void 0 ? _g : course.customContentPath;
134
+ course.disabledFeatures = (_h = yaml.disabled_features) !== null && _h !== void 0 ? _h : course.disabledFeatures;
135
+ course.vendor = (_j = yaml.vendor) !== null && _j !== void 0 ? _j : course.vendor;
136
+ if (yaml.is_private !== undefined)
137
+ course.isMarketplacePrivate = yaml.is_private;
138
+ if (yaml.mode) {
139
+ course.courseMode = CourseMode_1.CourseMode.STUDENT;
140
+ }
141
+ else {
142
+ course.courseMode = CourseMode_1.CourseMode.EDUCATOR;
143
+ }
144
+ }
145
+ /**
146
+ * Load a course from an in-memory file map (used by zip loader).
147
+ * The map must contain the same directory structure as a course project
148
+ * on disk (with course-info.yaml at the root).
149
+ */
150
+ function loadCourseFromZip(zipBuffer, _options) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ const zipFiles = yield parseZipToBufferMap(zipBuffer);
153
+ const memoryFs = new MemoryFileSystem(zipFiles);
154
+ return loadCourseProjectInternal("", memoryFs);
155
+ });
156
+ }
157
+ function loadCourseProjectInternal(projectPath, fileSystem) {
158
+ return __awaiter(this, void 0, void 0, function* () {
159
+ const courseConfigPath = pathJoin(projectPath, COURSE_CONFIG);
160
+ const courseYaml = yield readRawYamlFile(courseConfigPath, fileSystem);
161
+ if (!courseYaml.title) {
162
+ throw new Error(`Missing 'title' in ${courseConfigPath}`);
163
+ }
164
+ if (!courseYaml.language) {
165
+ throw new Error(`Missing 'language' in ${courseConfigPath}`);
166
+ }
167
+ if (!courseYaml.programming_language) {
168
+ throw new Error(`Missing 'programming_language' in ${courseConfigPath}`);
169
+ }
170
+ const contentNames = ensureNamedContent(courseYaml.content, courseConfigPath);
171
+ const course = createCourse(courseYaml.type);
172
+ hydrateCourse(course, courseYaml);
173
+ course.languageCode = courseYaml.language;
174
+ const lessons = yield Promise.all(contentNames.map((lessonName) => loadLesson(projectPath, lessonName, courseYaml.type, fileSystem)));
175
+ for (const lesson of lessons) {
176
+ course.addLesson(lesson);
177
+ }
178
+ return course;
179
+ });
180
+ }
181
+ function createLesson(courseType) {
182
+ if (courseType === "stepik") {
183
+ return new StepikLesson_1.StepikLesson();
184
+ }
185
+ return new Lesson_1.Lesson();
186
+ }
187
+ function hydrateLesson(lesson, lessonName, yaml) {
188
+ lesson.name = lessonName;
189
+ if (yaml.custom_name) {
190
+ lesson.customPresentableName = yaml.custom_name;
191
+ }
192
+ if (yaml.tags) {
193
+ lesson.contentTags = yaml.tags;
194
+ }
195
+ }
196
+ function loadLesson(coursePath, lessonName, courseType, fileSystem) {
197
+ return __awaiter(this, void 0, void 0, function* () {
198
+ const lessonPath = pathJoin(coursePath, lessonName);
199
+ const lessonConfigPath = pathJoin(lessonPath, LESSON_CONFIG);
200
+ const lessonYaml = yield readRawYamlFile(lessonConfigPath, fileSystem);
201
+ const taskNames = ensureNamedContent(lessonYaml.content, lessonConfigPath);
202
+ const tasks = yield Promise.all(taskNames.map((taskName) => loadTask(lessonPath, taskName, fileSystem)));
203
+ const lesson = createLesson(courseType);
204
+ hydrateLesson(lesson, lessonName, lessonYaml);
205
+ for (const task of tasks) {
206
+ lesson.addTask(task);
207
+ }
208
+ return lesson;
209
+ });
210
+ }
211
+ function createTask(taskType) {
212
+ switch (taskType) {
213
+ case "edu":
214
+ case "pycharm":
215
+ return new EduTask_1.EduTask();
216
+ case "code":
217
+ return new CodeTask_1.CodeTask();
218
+ case "number":
219
+ return new NumberTask_1.NumberTask();
220
+ case "string":
221
+ return new StringTask_1.StringTask();
222
+ case "output":
223
+ return new OutputTask_1.OutputTask();
224
+ case "dataset":
225
+ return new DataTask_1.DataTask();
226
+ case "table":
227
+ return new TableTask_1.TableTask();
228
+ case "theory":
229
+ return new TheoryTask_1.TheoryTask();
230
+ case "ide":
231
+ return new IdeTask_1.IdeTask();
232
+ case "unsupported":
233
+ return new UnsupportedTask_1.UnsupportedTask();
234
+ case "remote_edu":
235
+ return new RemoteEduTask_1.RemoteEduTask();
236
+ case "choice":
237
+ return new ChoiceTask_1.ChoiceTask();
238
+ case "matching":
239
+ return new MatchingTask_1.MatchingTask();
240
+ case "sorting":
241
+ return new SortingTask_1.SortingTask();
242
+ default:
243
+ return null;
244
+ }
245
+ }
246
+ function hydrateTask(task, taskName, yaml) {
247
+ var _a;
248
+ task.name = taskName;
249
+ if (yaml.status !== undefined && yaml.status !== null) {
250
+ const statusStr = String(yaml.status);
251
+ const statusMap = {
252
+ Unchecked: CheckStatus_1.CheckStatus.Unchecked,
253
+ Solved: CheckStatus_1.CheckStatus.Solved,
254
+ Failed: CheckStatus_1.CheckStatus.Failed,
255
+ };
256
+ task.status = (_a = statusMap[statusStr]) !== null && _a !== void 0 ? _a : CheckStatus_1.CheckStatus.Unchecked;
257
+ }
258
+ if (typeof yaml.record === "number") {
259
+ task.record = yaml.record;
260
+ }
261
+ if (yaml.feedback_link !== undefined) {
262
+ task.feedbackLink = String(yaml.feedback_link);
263
+ }
264
+ if (yaml.solution_hidden !== undefined) {
265
+ task.solutionHidden = Boolean(yaml.solution_hidden);
266
+ }
267
+ if (Array.isArray(yaml.tags)) {
268
+ task.contentTags = yaml.tags.map(String);
269
+ }
270
+ }
271
+ function hydrateChoiceTask(task, yaml) {
272
+ if (yaml.is_multiple_choice !== undefined) {
273
+ task.isMultipleChoice = Boolean(yaml.is_multiple_choice);
274
+ }
275
+ if (Array.isArray(yaml.options)) {
276
+ task.choiceOptions = yaml.options.map((opt) => {
277
+ var _a;
278
+ const option = new ChoiceOption_1.ChoiceOption();
279
+ option.text = String((_a = opt.text) !== null && _a !== void 0 ? _a : "");
280
+ if (opt.is_correct === true) {
281
+ option.status = ChoiceOptionStatus_1.ChoiceOptionStatus.CORRECT;
282
+ }
283
+ else if (opt.is_correct === false) {
284
+ option.status = ChoiceOptionStatus_1.ChoiceOptionStatus.INCORRECT;
285
+ }
286
+ return option;
287
+ });
288
+ }
289
+ }
290
+ function hydrateMatchingTask(task, yaml) {
291
+ if (Array.isArray(yaml.captions)) {
292
+ const captions = yaml.captions;
293
+ task.captions = captions.map((c) => {
294
+ var _a, _b;
295
+ const first = String((_a = c.first) !== null && _a !== void 0 ? _a : "");
296
+ const second = String((_b = c.second) !== null && _b !== void 0 ? _b : "");
297
+ return `${first} : ${second}`;
298
+ });
299
+ }
300
+ if (Array.isArray(yaml.options)) {
301
+ const opts = yaml.options;
302
+ task.options = opts.map(String);
303
+ }
304
+ }
305
+ function hydrateSortingTask(task, yaml) {
306
+ if (Array.isArray(yaml.options)) {
307
+ const opts = yaml.options;
308
+ task.options = opts.map(String);
309
+ }
310
+ }
311
+ function hydrateTableTask(task, yaml) {
312
+ if (yaml.is_multiple_choice !== undefined) {
313
+ task.isMultipleChoice = Boolean(yaml.is_multiple_choice);
314
+ }
315
+ if (Array.isArray(yaml.rows)) {
316
+ task.rows = yaml.rows.map(String);
317
+ }
318
+ if (Array.isArray(yaml.columns)) {
319
+ task.columns = yaml.columns.map(String);
320
+ }
321
+ if (Array.isArray(yaml.selected)) {
322
+ const sel = yaml.selected;
323
+ task.selected = sel.map((row) => row.map(Boolean));
324
+ }
325
+ }
326
+ function loadTask(lessonPath, taskName, fileSystem) {
327
+ return __awaiter(this, void 0, void 0, function* () {
328
+ const taskPath = pathJoin(lessonPath, taskName);
329
+ const taskConfigPath = pathJoin(taskPath, TASK_CONFIG);
330
+ const rawYaml = yield readRawYamlFile(taskConfigPath, fileSystem);
331
+ if (!rawYaml.type) {
332
+ throw new Error(`Missing 'type' in ${taskConfigPath}`);
333
+ }
334
+ const task = createTask(rawYaml.type);
335
+ if (!task) {
336
+ throw new Error(`Unknown task type '${rawYaml.type}' in ${taskConfigPath}`);
337
+ }
338
+ hydrateTask(task, taskName, rawYaml);
339
+ const files = rawYaml.files
340
+ ? yield Promise.all(rawYaml.files.map((file) => loadTaskFile(taskPath, file, fileSystem)))
341
+ : [];
342
+ for (const taskFile of files) {
343
+ task.addTaskFileInstance(taskFile);
344
+ }
345
+ // Hydrate task-specific fields
346
+ if (task instanceof ChoiceTask_1.ChoiceTask) {
347
+ hydrateChoiceTask(task, rawYaml);
348
+ }
349
+ else if (task instanceof MatchingTask_1.MatchingTask) {
350
+ hydrateMatchingTask(task, rawYaml);
351
+ }
352
+ else if (task instanceof SortingTask_1.SortingTask) {
353
+ hydrateSortingTask(task, rawYaml);
354
+ }
355
+ else if (task instanceof TableTask_1.TableTask) {
356
+ hydrateTableTask(task, rawYaml);
357
+ }
358
+ return task;
359
+ });
360
+ }
361
+ function loadTaskFile(ownerPath, fileYaml, fileSystem) {
362
+ return __awaiter(this, void 0, void 0, function* () {
363
+ var _a, _b, _c, _d, _e;
364
+ if (!fileYaml.name) {
365
+ throw new Error(`Task file without name in ${ownerPath}`);
366
+ }
367
+ const isBinary = (_a = fileYaml.is_binary) !== null && _a !== void 0 ? _a : false;
368
+ const text = yield resolveTaskFileText(ownerPath, fileYaml, isBinary, fileSystem);
369
+ const taskFile = new TaskFile_1.TaskFile();
370
+ taskFile.name = fileYaml.name;
371
+ taskFile.text = text !== null && text !== void 0 ? text : "";
372
+ taskFile.isVisible = (_b = fileYaml.visible) !== null && _b !== void 0 ? _b : true;
373
+ taskFile.isEditable = (_c = fileYaml.editable) !== null && _c !== void 0 ? _c : true;
374
+ taskFile.isPropagatable = (_d = fileYaml.propagatable) !== null && _d !== void 0 ? _d : true;
375
+ taskFile.isLearnerCreated = (_e = fileYaml.learner_created) !== null && _e !== void 0 ? _e : false;
376
+ return taskFile;
377
+ });
378
+ }
379
+ function resolveTaskFileText(ownerPath, fileYaml, isBinary, fileSystem) {
380
+ return __awaiter(this, void 0, void 0, function* () {
381
+ if (fileYaml.text !== undefined) {
382
+ return fileYaml.text;
383
+ }
384
+ return readTaskFile(ownerPath, fileYaml.name, isBinary, fileSystem);
385
+ });
386
+ }
387
+ function readTaskFile(ownerPath, name, isBinary, fileSystem) {
388
+ return __awaiter(this, void 0, void 0, function* () {
389
+ if (!name)
390
+ return undefined;
391
+ const filePath = pathJoin(ownerPath, name);
392
+ try {
393
+ const data = yield fileSystem.readFile(filePath);
394
+ return isBinary ? uint8ArrayToBase64(data) : new TextDecoder().decode(data);
395
+ }
396
+ catch (_a) {
397
+ return undefined;
398
+ }
399
+ });
400
+ }
401
+ function ensureNamedContent(content, configPath) {
402
+ if (!content)
403
+ return [];
404
+ return content.map((name, index) => {
405
+ if (!name) {
406
+ throw new Error(`Unnamed item at position ${index + 1} in ${configPath}`);
407
+ }
408
+ return name;
409
+ });
410
+ }
411
+ function readRawYamlFile(filePath, fileSystem) {
412
+ return __awaiter(this, void 0, void 0, function* () {
413
+ const data = yield fileSystem.readFile(filePath);
414
+ return (0, yaml_1.parse)(new TextDecoder().decode(data));
415
+ });
416
+ }
417
+ /**
418
+ * Parse a zip buffer into a map of file paths to their contents.
419
+ * Uses fflate which is pure JS and works in both Node.js and browser environments.
420
+ */
421
+ function parseZipToBufferMap(zipBuffer) {
422
+ return __awaiter(this, void 0, void 0, function* () {
423
+ const { unzipSync } = yield Promise.resolve().then(() => __importStar(require("fflate")));
424
+ const unzipped = unzipSync(new Uint8Array(zipBuffer));
425
+ const files = new Map();
426
+ for (const [entryPath, data] of Object.entries(unzipped)) {
427
+ // Normalize path: strip leading "/" or "./", replace backslashes
428
+ const normalized = entryPath.replace(/^\.?[\\/]+/, "").replace(/\\/g, "/");
429
+ if (normalized) {
430
+ files.set(normalized, data);
431
+ }
432
+ }
433
+ return files;
434
+ });
435
+ }
@@ -0,0 +1,49 @@
1
+ export interface Vendor {
2
+ name: string;
3
+ url?: string;
4
+ email?: string;
5
+ }
6
+ export type CourseMode = "STUDENT" | "EDUCATOR";
7
+ export interface TaskFile {
8
+ name: string;
9
+ text?: string;
10
+ visible: boolean;
11
+ editable: boolean;
12
+ propagatable: boolean;
13
+ isBinary: boolean;
14
+ learnerCreated: boolean;
15
+ }
16
+ export interface Task {
17
+ name: string;
18
+ type: string;
19
+ status?: string;
20
+ record?: number;
21
+ files: TaskFile[];
22
+ feedbackLink?: string;
23
+ solutionHidden?: boolean;
24
+ tags?: string[];
25
+ }
26
+ export interface Lesson {
27
+ name: string;
28
+ customName?: string;
29
+ tags?: string[];
30
+ content: Task[];
31
+ }
32
+ export interface Course {
33
+ type: string;
34
+ title: string;
35
+ summary: string;
36
+ language: string;
37
+ programmingLanguage: string;
38
+ programmingLanguageVersion?: string;
39
+ environment?: string;
40
+ solutionsHidden?: boolean;
41
+ environmentSettings: Record<string, string>;
42
+ additionalFiles: TaskFile[];
43
+ customContentPath?: string;
44
+ disabledFeatures: string[];
45
+ vendor?: Vendor;
46
+ isPrivate?: boolean;
47
+ courseMode: CourseMode;
48
+ content: Lesson[];
49
+ }
package/dist/models.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ import { Course } from "./courseFormat/Course";
2
+ export declare function loadCourseProjectFromZip(data: Uint8Array, options?: {
3
+ aesKey?: string;
4
+ }): Promise<Course>;