@tinyweb_dev/oe-exam-sdk 0.2.9 → 0.2.11

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 (93) hide show
  1. package/dist/components/exams/take/ExamTakingPageContainer.js +6 -0
  2. package/dist/components/exams/take/components/QuestionRenderer.js +7 -3
  3. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingGroupRenderer.d.ts +13 -0
  4. package/dist/components/exams/take/components/question-renderers/MoversWordOrderingGroupRenderer.js +30 -0
  5. package/dist/components/exams/take/components/question-renderers/index.d.ts +1 -0
  6. package/dist/components/exams/take/components/question-renderers/index.js +1 -0
  7. package/dist/components/exams/take/utils/answer-transformers.js +8 -1
  8. package/dist/components/exams/take/utils/question-transformers.d.ts +16 -1
  9. package/dist/components/exams/take/utils/question-transformers.js +47 -2
  10. package/dist/components/questions/_shared/config/question-types.config.js +18 -0
  11. package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.d.ts +1 -0
  12. package/dist/components/questions/_shared/types/index.d.ts +1 -0
  13. package/dist/components/questions/_shared/types/index.js +1 -0
  14. package/dist/components/questions/_shared/types/match-columns-to-make-sentences.type.d.ts +56 -0
  15. package/dist/components/questions/_shared/types/match-columns-to-make-sentences.type.js +2 -0
  16. package/dist/components/questions/_shared/types/match-word-to-picture-group.type.d.ts +35 -0
  17. package/dist/components/questions/_shared/types/match-word-to-picture-group.type.js +2 -0
  18. package/dist/components/questions/_shared/types/word-ordering-group.type.d.ts +34 -0
  19. package/dist/components/questions/_shared/types/word-ordering-group.type.js +2 -0
  20. package/dist/components/questions/components/QuestionSearchDropdown.js +3 -0
  21. package/dist/components/questions/components/QuestionTypeSelector.js +3 -0
  22. package/dist/components/questions/creator/question-type-registry.js +6 -0
  23. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.js +1 -1
  24. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.js +5 -3
  25. package/dist/components/questions/types/choose-the-correct-answer-group/map-choose-the-correct-answer-group-data.js +16 -2
  26. package/dist/components/questions/types/choose-the-correct-answer-group/transform.js +4 -0
  27. package/dist/components/questions/types/fill-in-blank-group/transform.js +21 -2
  28. package/dist/components/questions/types/match-columns-to-make-sentences/MatchColumnsToMakeSentencesClient.d.ts +2 -0
  29. package/dist/components/questions/types/match-columns-to-make-sentences/MatchColumnsToMakeSentencesClient.js +74 -0
  30. package/dist/components/questions/types/match-columns-to-make-sentences/MatchColumnsToMakeSentencesCreator.d.ts +2 -0
  31. package/dist/components/questions/types/match-columns-to-make-sentences/MatchColumnsToMakeSentencesCreator.js +222 -0
  32. package/dist/components/questions/types/match-columns-to-make-sentences/index.d.ts +5 -0
  33. package/dist/components/questions/types/match-columns-to-make-sentences/index.js +5 -0
  34. package/dist/components/questions/types/match-columns-to-make-sentences/map-match-columns-to-make-sentences-data.d.ts +8 -0
  35. package/dist/components/questions/types/match-columns-to-make-sentences/map-match-columns-to-make-sentences-data.js +199 -0
  36. package/dist/components/questions/types/match-columns-to-make-sentences/register.d.ts +2 -0
  37. package/dist/components/questions/types/match-columns-to-make-sentences/register.js +36 -0
  38. package/dist/components/questions/types/match-columns-to-make-sentences/transform.d.ts +2 -0
  39. package/dist/components/questions/types/match-columns-to-make-sentences/transform.js +66 -0
  40. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupClient.d.ts +2 -0
  41. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupClient.js +65 -0
  42. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupCreator.d.ts +2 -0
  43. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupCreator.js +95 -0
  44. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupImageField.d.ts +6 -0
  45. package/dist/components/questions/types/match-word-to-picture-group/MatchWordToPictureGroupImageField.js +16 -0
  46. package/dist/components/questions/types/match-word-to-picture-group/index.d.ts +5 -0
  47. package/dist/components/questions/types/match-word-to-picture-group/index.js +5 -0
  48. package/dist/components/questions/types/match-word-to-picture-group/map-match-word-to-picture-group-data.d.ts +4 -0
  49. package/dist/components/questions/types/match-word-to-picture-group/map-match-word-to-picture-group-data.js +77 -0
  50. package/dist/components/questions/types/match-word-to-picture-group/register.d.ts +2 -0
  51. package/dist/components/questions/types/match-word-to-picture-group/register.js +36 -0
  52. package/dist/components/questions/types/match-word-to-picture-group/transform.d.ts +2 -0
  53. package/dist/components/questions/types/match-word-to-picture-group/transform.js +36 -0
  54. package/dist/components/questions/types/word-ordering-group/WordOrderingGroupClient.d.ts +2 -0
  55. package/dist/components/questions/types/word-ordering-group/WordOrderingGroupClient.js +25 -0
  56. package/dist/components/questions/types/word-ordering-group/WordOrderingGroupCreator.d.ts +2 -0
  57. package/dist/components/questions/types/word-ordering-group/WordOrderingGroupCreator.js +121 -0
  58. package/dist/components/questions/types/word-ordering-group/index.d.ts +5 -0
  59. package/dist/components/questions/types/word-ordering-group/index.js +5 -0
  60. package/dist/components/questions/types/word-ordering-group/map-word-ordering-group-data.d.ts +4 -0
  61. package/dist/components/questions/types/word-ordering-group/map-word-ordering-group-data.js +74 -0
  62. package/dist/components/questions/types/word-ordering-group/register.d.ts +2 -0
  63. package/dist/components/questions/types/word-ordering-group/register.js +36 -0
  64. package/dist/components/questions/types/word-ordering-group/transform.d.ts +2 -0
  65. package/dist/components/questions/types/word-ordering-group/transform.js +33 -0
  66. package/dist/components/questions/types/write-a-short-letter/WriteAShortLetterCreator.js +5 -5
  67. package/dist/components/questions/viewer/MatchColumnsToMakeSentencesViewer.d.ts +8 -0
  68. package/dist/components/questions/viewer/MatchColumnsToMakeSentencesViewer.js +49 -0
  69. package/dist/components/questions/viewer/MatchWordToPictureGroupViewer.js +2 -2
  70. package/dist/components/questions/viewer/QuestionViewer.js +6 -0
  71. package/dist/components/questions/viewer/WordOrderingGroupViewer.d.ts +7 -0
  72. package/dist/components/questions/viewer/WordOrderingGroupViewer.js +29 -0
  73. package/dist/components/questions/viewer/index.d.ts +2 -0
  74. package/dist/components/questions/viewer/index.js +2 -0
  75. package/dist/components/results/renderers/review-question-body-dedicated.js +1 -1
  76. package/dist/components/results/renderers/review-question-body-movers.js +6 -2
  77. package/dist/components/results/review-data.js +13 -0
  78. package/dist/index.d.ts +1 -1
  79. package/dist/index.js +1 -1
  80. package/dist/shared/constants/question-skills.js +6 -0
  81. package/dist/shared/lib/utils/question-reverse-transform.js +111 -2
  82. package/dist/shared/lib/utils/question-transform.js +6 -0
  83. package/dist/shared/types/common.types.d.ts +1 -1
  84. package/dist/shared/types/questions/choose-the-correct-answer-group.d.ts +1 -0
  85. package/dist/shared/types/questions/index.d.ts +3 -0
  86. package/dist/shared/types/questions/index.js +6 -0
  87. package/dist/shared/types/questions/match-columns-to-make-sentences.d.ts +50 -0
  88. package/dist/shared/types/questions/match-columns-to-make-sentences.js +1 -0
  89. package/dist/shared/types/questions/match-word-to-picture-group.d.ts +31 -0
  90. package/dist/shared/types/questions/match-word-to-picture-group.js +1 -0
  91. package/dist/shared/types/questions/word-ordering-group.d.ts +28 -0
  92. package/dist/shared/types/questions/word-ordering-group.js +1 -0
  93. package/package.json +1 -1
@@ -226,7 +226,9 @@ function normalizeChooseAnswerGroupImageUrl(value) {
226
226
  const reverseChooseTheCorrectAnswerGroup = (apiQuestion) => {
227
227
  const content = asRecord(apiQuestion.content);
228
228
  const answer = readAnswer(apiQuestion);
229
- const fallbackAnswers = asArray(answer.answer).map((item) => asString(item));
229
+ const fallbackAnswers = asArray(answer.answer).map((item) => (asString(item) || (Array.isArray(item)
230
+ ? asString(item.find((token) => typeof token === 'string' && token.trim() !== ''))
231
+ : '')));
230
232
  const items = asArray(content.items).map((rawItem, index) => {
231
233
  const item = asRecord(rawItem);
232
234
  const itemContent = asRecord(item.content);
@@ -251,7 +253,13 @@ const reverseChooseTheCorrectAnswerGroup = (apiQuestion) => {
251
253
  { id: 'opt-2', text: '' },
252
254
  { id: 'opt-3', text: '' },
253
255
  ],
254
- correctAnswer: asString(itemAnswer.answer) || fallbackAnswers[index] || options[0]?.id || 'opt-1',
256
+ correctAnswer: asString(itemAnswer.answer)
257
+ || (Array.isArray(itemAnswer.answer)
258
+ ? asString(itemAnswer.answer.find((token) => typeof token === 'string' && token.trim() !== ''))
259
+ : '')
260
+ || fallbackAnswers[index]
261
+ || options[0]?.id
262
+ || 'opt-1',
255
263
  isExample,
256
264
  points: isExample ? 0 : asNumber(item.points, 1),
257
265
  questionNumber: asNumber(item.questionNumber, index + 1),
@@ -260,12 +268,14 @@ const reverseChooseTheCorrectAnswerGroup = (apiQuestion) => {
260
268
  };
261
269
  });
262
270
  const audioUrl = asString(asRecord(content.meta).audioUrl).trim();
271
+ const imageUrl = normalizeChooseAnswerGroupImageUrl(asRecord(content.meta).imageUrl);
263
272
  return {
264
273
  content: '',
265
274
  answer: {
266
275
  instruction: asString(asRecord(content.meta).instruction, 'Choose the correct answer.'),
267
276
  passage: asString(asRecord(content.meta).passage),
268
277
  ...(audioUrl ? { audioUrl } : {}),
278
+ ...(imageUrl !== undefined ? { imageUrl } : {}),
269
279
  items,
270
280
  explanation: asString(apiQuestion.explanation),
271
281
  points: items.reduce((total, item) => (item.isExample ? total : total + item.points), 0),
@@ -603,6 +613,102 @@ const reverseSimpleAnswer = (apiQuestion) => {
603
613
  },
604
614
  };
605
615
  };
616
+ const reverseWordOrderingGroup = (apiQuestion) => {
617
+ const content = asRecord(apiQuestion.content);
618
+ const answer = readAnswer(apiQuestion);
619
+ const fallbackAnswers = asArray(answer.answer);
620
+ const items = asArray(content.items);
621
+ const meta = asRecord(content.meta);
622
+ const mappedItems = items.map((rawItem, index) => {
623
+ const item = asRecord(rawItem);
624
+ const itemContent = asRecord(item.content);
625
+ const itemAnswer = asRecord(item.correctAnswer);
626
+ const isExample = item.isExample === true;
627
+ const words = asArray(itemContent.words).map((token) => asString(token)).filter(Boolean);
628
+ const itemTokens = asArray(itemAnswer.answer).map((token) => asString(token)).filter(Boolean);
629
+ const fallbackTokens = asArray(fallbackAnswers[index]).map((token) => asString(token)).filter(Boolean);
630
+ return {
631
+ words,
632
+ answer: itemTokens.length ? itemTokens : fallbackTokens,
633
+ isExample,
634
+ points: isExample ? 0 : (typeof item.points === 'number' ? item.points : 1),
635
+ questionNumber: typeof item.questionNumber === 'number' ? item.questionNumber : index + 1,
636
+ };
637
+ });
638
+ return {
639
+ content: '',
640
+ answer: {
641
+ instruction: asString(meta.instruction, 'Order the words.'),
642
+ items: mappedItems,
643
+ explanation: asString(apiQuestion.explanation),
644
+ points: mappedItems.reduce((total, item) => (item.isExample ? total : total + (item.points || 0)), 0),
645
+ },
646
+ };
647
+ };
648
+ const reverseMatchWordToPictureGroup = (apiQuestion) => {
649
+ const content = asRecord(apiQuestion.content);
650
+ const answer = readAnswer(apiQuestion);
651
+ const fallbackAnswers = asArray(answer.answer);
652
+ const items = asArray(content.items);
653
+ const meta = asRecord(content.meta);
654
+ const mappedItems = items.map((rawItem, index) => {
655
+ const item = asRecord(rawItem);
656
+ const itemContent = asRecord(item.content);
657
+ const itemAnswer = asRecord(item.correctAnswer);
658
+ const isExample = item.isExample === true;
659
+ return {
660
+ imageUrl: asString(itemContent.imageUrl),
661
+ correctAnswer: asString(itemAnswer.answer) || asString(fallbackAnswers[index]),
662
+ isExample,
663
+ points: isExample ? 0 : (typeof item.points === 'number' ? item.points : 1),
664
+ questionNumber: typeof item.questionNumber === 'number' ? item.questionNumber : index + 1,
665
+ };
666
+ });
667
+ return {
668
+ content: '',
669
+ answer: {
670
+ instruction: asString(meta.instruction, 'Look and complete.'),
671
+ wordBank: asArray(meta.wordBank).map((word) => asString(word)).filter(Boolean),
672
+ items: mappedItems,
673
+ explanation: asString(apiQuestion.explanation),
674
+ points: mappedItems.reduce((total, item) => (item.isExample ? total : total + (item.points || 0)), 0),
675
+ },
676
+ };
677
+ };
678
+ const reverseMatchColumnsToMakeSentences = (apiQuestion) => {
679
+ const content = asRecord(apiQuestion.content);
680
+ const answer = readAnswer(apiQuestion);
681
+ const fallbackAnswers = asArray(answer.answer);
682
+ const items = asArray(content.items);
683
+ const columns = asArray(content.columns);
684
+ const meta = asRecord(content.meta);
685
+ const mappedItems = items.map((rawItem, index) => {
686
+ const item = asRecord(rawItem);
687
+ const itemContent = asRecord(item.content);
688
+ const itemAnswer = asRecord(asRecord(item.correctAnswer).answer ?? fallbackAnswers[index]);
689
+ const fragmentIds = asArray(itemAnswer.fragmentIds).map((id) => asString(id)).filter(Boolean);
690
+ const isExample = item.isExample === true;
691
+ return {
692
+ stemFragmentId: asString(itemContent.stemFragmentId) || fragmentIds[0] || '',
693
+ fragmentIds,
694
+ sentence: asString(itemAnswer.sentence),
695
+ isExample,
696
+ points: isExample ? 0 : (typeof item.points === 'number' ? item.points : 1),
697
+ questionNumber: typeof item.questionNumber === 'number' ? item.questionNumber : index + 1,
698
+ };
699
+ });
700
+ return {
701
+ content: '',
702
+ answer: {
703
+ title: asString(meta.title),
704
+ instruction: asString(meta.instruction, 'Match the information to make sentences. You can use the same words more than once.'),
705
+ columns,
706
+ items: mappedItems,
707
+ explanation: asString(apiQuestion.explanation),
708
+ points: mappedItems.reduce((total, item) => (item.isExample ? total : total + (item.points || 0)), 0),
709
+ },
710
+ };
711
+ };
606
712
  const handlers = {
607
713
  CHOOSE_THE_CORRECT_ANSWER: reverseChooseTheCorrectAnswer,
608
714
  CHOOSE_THE_CORRECT_ANSWER_GROUP: reverseChooseTheCorrectAnswerGroup,
@@ -653,6 +759,9 @@ const handlers = {
653
759
  GN_SPEAKING_INTERVIEW: reverseGroupPayload,
654
760
  CROSSWORD_PUZZLE: reverseCrosswordPuzzle,
655
761
  FIND_WORDS_IN_MATRIX: reverseFindWordsInMatrix,
762
+ MATCH_COLUMNS_TO_MAKE_SENTENCES: reverseMatchColumnsToMakeSentences,
763
+ MATCH_WORD_TO_PICTURE_GROUP: reverseMatchWordToPictureGroup,
764
+ WORD_ORDERING_GROUP: reverseWordOrderingGroup,
656
765
  };
657
766
  function reverseWriteAShortLetter(apiQuestion) {
658
767
  const content = asRecord(apiQuestion.content);
@@ -47,6 +47,9 @@ import { transformGNSpeakingInterview } from '../../../components/questions/type
47
47
  import { transformWordFillStructuredForm } from '../../../components/questions/types/word-fill-structured-form/transform';
48
48
  import { transformCrosswordPuzzle } from '../../../components/questions/types/crossword-puzzle/transform';
49
49
  import { transformFindWordsInMatrix } from '../../../components/questions/types/find-words-in-matrix/transform';
50
+ import { transformMatchColumnsToMakeSentences } from '../../../components/questions/types/match-columns-to-make-sentences/transform';
51
+ import { transformMatchWordToPictureGroup } from '../../../components/questions/types/match-word-to-picture-group/transform';
52
+ import { transformWordOrderingGroup } from '../../../components/questions/types/word-ordering-group/transform';
50
53
  // ─── Handler map ────────────────────────────────────────────────────────────
51
54
  const questionTransformHandlers = {
52
55
  // Look picture
@@ -100,6 +103,9 @@ const questionTransformHandlers = {
100
103
  WORD_FILL_STRUCTURED_FORM: transformWordFillStructuredForm,
101
104
  CROSSWORD_PUZZLE: transformCrosswordPuzzle,
102
105
  FIND_WORDS_IN_MATRIX: transformFindWordsInMatrix,
106
+ MATCH_COLUMNS_TO_MAKE_SENTENCES: transformMatchColumnsToMakeSentences,
107
+ MATCH_WORD_TO_PICTURE_GROUP: transformMatchWordToPictureGroup,
108
+ WORD_ORDERING_GROUP: transformWordOrderingGroup,
103
109
  };
104
110
  /**
105
111
  * Transform frontend question format to API format.
@@ -29,7 +29,7 @@ export declare enum StudentSelectionType {
29
29
  }
30
30
  export type ResultStatus = 'PENDING' | 'PARTIAL_GRADED' | 'GRADED';
31
31
  export type StudentStatus = 'NOT_STARTED' | 'IN_PROGRESS' | 'SUBMITTED';
32
- export type QuestionType = 'FILL_IN_BLANK' | 'TRUE_FALSE' | 'MATCHING' | 'ORDERING' | 'LISTENING' | 'COLORING' | 'ESSAY' | 'LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE' | 'LISTEN_AND_TICK_ANSWER' | 'LISTEN_AND_FILL_NAME_NUMBER' | 'LISTENING_FILL_BLANK' | 'LISTENING_COLOR' | 'TICK_TRUE_OR_FALSE' | 'TICK_YES_OR_NO' | 'READING_TICK_CROSS' | 'ARRANGE_LETTERS_INTO_WORDS' | 'READ_PASSAGE_AND_COMPLETE_STORY' | 'CLOZE_TEST_WITH_TICK_BOX' | 'READ_AND_CHOOSE_APPROPRIATE_WORD' | 'WRITE_SHORT_PARAGRAPH' | 'LABEL_THE_PICTURE' | 'READING_LETTER_ARRANGE' | 'READING_PASSAGE_FILL' | 'FILL_BLANK' | 'FILL_MISSING_WORDS_IN_GRID' | 'LOOK_PICTURE_CHOOSE_CORRECT_ANSWER' | 'LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER' | 'LOOK_PICTURE_FILL_WORD_HINT' | 'LABEL_THE_PICTURE' | 'READ_AND_COLOR_OBJECTS' | 'IMAGE_OBJECT_MATCHING' | 'READ_PASSAGE_AND_ANSWER_QUESTIONS' | 'CHOOSE_THE_CORRECT_ANSWER' | 'CHOOSE_THE_CORRECT_ANSWER_GROUP' | 'TRUE_FALSE_GROUP' | 'TRUE_FALSE_CORRECT_GROUP' | 'FILL_IN_BLANK_GROUP' | 'MATCHING_WITH_LINES_GROUP' | 'CROSS_OUT_WORD_GROUP' | 'SPONTANEOUS_QA_GROUP' | 'WORD_ORDER_AND_MATCH_GROUP' | 'WRITE_A_SHORT_LETTER' | 'WRITE_CORRECT_VERB_FORM' | 'CHOOSE_CORRECT_ADJECTIVE' | 'ANSWER_THE_QUESTION' | 'ANSWER_THE_QUESTION_GROUP' | 'WORD_ORDERING' | 'WORD_FILL_PARAGRAPH' | 'MATCH_BY_WRITING_ANSWER' | 'MATCH_WORD_TO_PICTURE' | 'WRITE_SENTENCES' | 'LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP' | 'LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE' | 'LISTEN_AND_DRAG_OBJECTS_INTO_SCENE' | 'LISTEN_AND_SPEAK_ANSWER' | 'LISTEN_AND_SPEAK_IMAGE_GROUP' | 'LISTEN_AND_SPEAK_QUESTION_LIST' | 'LISTEN_AND_SPEAK_COMPARE_IMAGES' | 'LISTEN_AND_SPEAK_WITH_STORY_IMAGES' | 'LISTEN_AND_SPEAK_ODD_ONE_OUT' | 'LISTEN_AND_SPEAK_INFO_EXCHANGE' | 'READ_DISPLAYED_CONTENT' | 'SPEAKING_DESCRIBE_IMAGE' | 'SPONTANEOUS_QA' | 'SPEAKING_CONVERSATION' | 'GN_SPEAKING_INTERVIEW' | 'SPEAKING_CUE_CARD' | 'WORD_FILL_STRUCTURED_FORM' | 'CROSSWORD_PUZZLE' | 'FIND_WORDS_IN_MATRIX';
32
+ export type QuestionType = 'FILL_IN_BLANK' | 'TRUE_FALSE' | 'MATCHING' | 'ORDERING' | 'LISTENING' | 'COLORING' | 'ESSAY' | 'LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE' | 'LISTEN_AND_TICK_ANSWER' | 'LISTEN_AND_FILL_NAME_NUMBER' | 'LISTENING_FILL_BLANK' | 'LISTENING_COLOR' | 'TICK_TRUE_OR_FALSE' | 'TICK_YES_OR_NO' | 'READING_TICK_CROSS' | 'ARRANGE_LETTERS_INTO_WORDS' | 'READ_PASSAGE_AND_COMPLETE_STORY' | 'CLOZE_TEST_WITH_TICK_BOX' | 'READ_AND_CHOOSE_APPROPRIATE_WORD' | 'WRITE_SHORT_PARAGRAPH' | 'LABEL_THE_PICTURE' | 'READING_LETTER_ARRANGE' | 'READING_PASSAGE_FILL' | 'FILL_BLANK' | 'FILL_MISSING_WORDS_IN_GRID' | 'LOOK_PICTURE_CHOOSE_CORRECT_ANSWER' | 'LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER' | 'LOOK_PICTURE_FILL_WORD_HINT' | 'LABEL_THE_PICTURE' | 'READ_AND_COLOR_OBJECTS' | 'IMAGE_OBJECT_MATCHING' | 'READ_PASSAGE_AND_ANSWER_QUESTIONS' | 'CHOOSE_THE_CORRECT_ANSWER' | 'CHOOSE_THE_CORRECT_ANSWER_GROUP' | 'TRUE_FALSE_GROUP' | 'TRUE_FALSE_CORRECT_GROUP' | 'FILL_IN_BLANK_GROUP' | 'MATCHING_WITH_LINES_GROUP' | 'CROSS_OUT_WORD_GROUP' | 'SPONTANEOUS_QA_GROUP' | 'WORD_ORDER_AND_MATCH_GROUP' | 'WRITE_A_SHORT_LETTER' | 'WRITE_CORRECT_VERB_FORM' | 'CHOOSE_CORRECT_ADJECTIVE' | 'ANSWER_THE_QUESTION' | 'ANSWER_THE_QUESTION_GROUP' | 'WORD_ORDERING' | 'WORD_FILL_PARAGRAPH' | 'MATCH_BY_WRITING_ANSWER' | 'MATCH_WORD_TO_PICTURE' | 'WRITE_SENTENCES' | 'LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP' | 'LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE' | 'LISTEN_AND_DRAG_OBJECTS_INTO_SCENE' | 'LISTEN_AND_SPEAK_ANSWER' | 'LISTEN_AND_SPEAK_IMAGE_GROUP' | 'LISTEN_AND_SPEAK_QUESTION_LIST' | 'LISTEN_AND_SPEAK_COMPARE_IMAGES' | 'LISTEN_AND_SPEAK_WITH_STORY_IMAGES' | 'LISTEN_AND_SPEAK_ODD_ONE_OUT' | 'LISTEN_AND_SPEAK_INFO_EXCHANGE' | 'READ_DISPLAYED_CONTENT' | 'SPEAKING_DESCRIBE_IMAGE' | 'SPONTANEOUS_QA' | 'SPEAKING_CONVERSATION' | 'GN_SPEAKING_INTERVIEW' | 'SPEAKING_CUE_CARD' | 'WORD_FILL_STRUCTURED_FORM' | 'CROSSWORD_PUZZLE' | 'FIND_WORDS_IN_MATRIX' | 'MATCH_COLUMNS_TO_MAKE_SENTENCES' | 'MATCH_WORD_TO_PICTURE_GROUP' | 'WORD_ORDERING_GROUP';
33
33
  export type Level = 'Pre-A1' | 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2';
34
34
  export type Difficulty = 'EASY' | 'MEDIUM' | 'HARD';
35
35
  export type Skill = 'LISTENING' | 'READING' | 'WRITING' | 'SPEAKING';
@@ -25,6 +25,7 @@ export interface ChooseTheCorrectAnswerGroupContent {
25
25
  instruction?: string;
26
26
  passage?: string;
27
27
  audioUrl?: string;
28
+ imageUrl?: string | string[];
28
29
  };
29
30
  items: ChooseTheCorrectAnswerGroupItem[];
30
31
  }
@@ -34,5 +34,8 @@ export * from './crossword-puzzle';
34
34
  export * from './find-words-in-matrix';
35
35
  export * from './match-word-to-picture';
36
36
  export * from './matching-with-lines-group';
37
+ export * from './match-columns-to-make-sentences';
38
+ export * from './match-word-to-picture-group';
39
+ export * from './word-ordering-group';
37
40
  export * from './true-false-correct-group';
38
41
  export * from './fill-in-blank-group';
@@ -54,6 +54,12 @@ export * from './find-words-in-matrix';
54
54
  export * from './match-word-to-picture';
55
55
  // MATCHING_WITH_LINES_GROUP
56
56
  export * from './matching-with-lines-group';
57
+ // MATCH_COLUMNS_TO_MAKE_SENTENCES
58
+ export * from './match-columns-to-make-sentences';
59
+ // MATCH_WORD_TO_PICTURE_GROUP
60
+ export * from './match-word-to-picture-group';
61
+ // WORD_ORDERING_GROUP
62
+ export * from './word-ordering-group';
57
63
  // TRUE_FALSE_CORRECT_GROUP
58
64
  export * from './true-false-correct-group';
59
65
  // FILL_IN_BLANK_GROUP
@@ -0,0 +1,50 @@
1
+ export declare const MATCH_COLUMNS_TO_MAKE_SENTENCE_ITEM_TYPE: "MATCH_COLUMNS_TO_MAKE_SENTENCE";
2
+ export interface MatchColumnsFragment {
3
+ id: string;
4
+ text: string;
5
+ }
6
+ export interface MatchColumnsColumn {
7
+ id: string;
8
+ label?: string;
9
+ role: 'stem' | 'choice';
10
+ fragments: MatchColumnsFragment[];
11
+ }
12
+ export interface MatchColumnsItemAnswer {
13
+ fragmentIds: string[];
14
+ sentence: string;
15
+ }
16
+ export interface MatchColumnsGroupItemContent {
17
+ stemFragmentId: string;
18
+ }
19
+ export interface MatchColumnsGroupItem {
20
+ questionType?: typeof MATCH_COLUMNS_TO_MAKE_SENTENCE_ITEM_TYPE;
21
+ isExample?: boolean;
22
+ content: MatchColumnsGroupItemContent;
23
+ correctAnswer?: {
24
+ answer: MatchColumnsItemAnswer;
25
+ };
26
+ points?: number;
27
+ questionNumber?: number;
28
+ }
29
+ export interface MatchColumnsGroupContent {
30
+ meta?: {
31
+ title?: string;
32
+ instruction?: string;
33
+ };
34
+ columns: MatchColumnsColumn[];
35
+ items: MatchColumnsGroupItem[];
36
+ }
37
+ export interface MatchColumnsGroupCorrectAnswer {
38
+ answer: MatchColumnsItemAnswer[];
39
+ }
40
+ export interface MatchColumnsGroupAPIPayload {
41
+ id?: string;
42
+ questionType: 'MATCH_COLUMNS_TO_MAKE_SENTENCES';
43
+ content: MatchColumnsGroupContent;
44
+ correctAnswer: MatchColumnsGroupCorrectAnswer;
45
+ points: number;
46
+ explanation?: string;
47
+ questionNumber: number;
48
+ partId?: string;
49
+ partNo?: number;
50
+ }
@@ -0,0 +1 @@
1
+ export const MATCH_COLUMNS_TO_MAKE_SENTENCE_ITEM_TYPE = 'MATCH_COLUMNS_TO_MAKE_SENTENCE';
@@ -0,0 +1,31 @@
1
+ export declare const MATCH_WORD_TO_PICTURE_ITEM_TYPE: "MATCH_WORD_TO_PICTURE";
2
+ export interface MatchWordToPictureGroupItem {
3
+ questionType?: typeof MATCH_WORD_TO_PICTURE_ITEM_TYPE;
4
+ isExample?: boolean;
5
+ content: {
6
+ imageUrl: string;
7
+ };
8
+ correctAnswer?: {
9
+ answer: string;
10
+ };
11
+ points?: number;
12
+ questionNumber?: number;
13
+ }
14
+ export interface MatchWordToPictureGroupContent {
15
+ meta?: {
16
+ instruction?: string;
17
+ wordBank?: string[];
18
+ };
19
+ items: MatchWordToPictureGroupItem[];
20
+ }
21
+ export interface MatchWordToPictureGroupAPIPayload {
22
+ id?: string;
23
+ questionType: 'MATCH_WORD_TO_PICTURE_GROUP';
24
+ content: MatchWordToPictureGroupContent;
25
+ correctAnswer: {
26
+ answer: string[];
27
+ };
28
+ points: number;
29
+ explanation?: string;
30
+ questionNumber: number;
31
+ }
@@ -0,0 +1 @@
1
+ export const MATCH_WORD_TO_PICTURE_ITEM_TYPE = 'MATCH_WORD_TO_PICTURE';
@@ -0,0 +1,28 @@
1
+ export declare const WORD_ORDERING_ITEM_TYPE: "WORD_ORDERING";
2
+ export interface WordOrderingGroupItem {
3
+ questionType?: typeof WORD_ORDERING_ITEM_TYPE;
4
+ isExample?: boolean;
5
+ content: {
6
+ words: string[];
7
+ };
8
+ correctAnswer?: {
9
+ answer: string[];
10
+ };
11
+ points?: number;
12
+ questionNumber?: number;
13
+ }
14
+ export interface WordOrderingGroupAPIPayload {
15
+ questionType: 'WORD_ORDERING_GROUP';
16
+ content: {
17
+ meta?: {
18
+ instruction?: string;
19
+ };
20
+ items: WordOrderingGroupItem[];
21
+ };
22
+ correctAnswer: {
23
+ answer: string[][];
24
+ };
25
+ points: number;
26
+ explanation?: string;
27
+ questionNumber: number;
28
+ }
@@ -0,0 +1 @@
1
+ export const WORD_ORDERING_ITEM_TYPE = 'WORD_ORDERING';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinyweb_dev/oe-exam-sdk",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Reusable OceanEdu question components.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",