diff --git a/package.json b/package.json index 1d4a87e1f0e47a0f2e5d65ae31213aef7b858076..320b49b225c1ae978ad2e5a7b3c462de9930a11b 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "epoc-specs", - "version": "1.0.0", + "version": "2.0.0", "description": "ePoc (Electronic Pocket Open Course) types specifications", - "main": "dist/epoc.ts", - "types": "dist/epoc.d.ts", + "main": "dist/index.ts", + "types": "dist/index.d.ts", "scripts": { "prepublish": "tsc" }, @@ -17,7 +17,6 @@ "author": "Inria Learning Lab", "license": "CeCILL-B", "devDependencies": { - "typedoc": "^0.23.25", "typescript": "^4.9.5" } } diff --git a/src/contents/html.ts b/src/contents/html.ts deleted file mode 100644 index 64160119a8e10da004e7a3fd3adedaca3f54815a..0000000000000000000000000000000000000000 --- a/src/contents/html.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {Content} from './content'; -import {html} from '../types'; - -export interface Html extends Content { - html: html; -} diff --git a/src/contents/video.ts b/src/contents/video.ts deleted file mode 100644 index 692fdc57a28d97aebbc889f8a2ee9ab1563c76ef..0000000000000000000000000000000000000000 --- a/src/contents/video.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {Content} from './content'; -import {html} from '../types'; - -export interface Video extends Content { - source: string; - summary: html; - subtitles: {label: string, lang: string, src: string}[]; - transcript: string; - poster: string; -} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..8338723d23ddc578fb1e51b44124a05cd156bd21 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export * as v1 from './v1' +export * as v2 from './v2' \ No newline at end of file diff --git a/src/author.ts b/src/v1/author.ts similarity index 100% rename from src/author.ts rename to src/v1/author.ts diff --git a/src/contents/content.ts b/src/v1/content.ts similarity index 56% rename from src/contents/content.ts rename to src/v1/content.ts index 99abfe253749eeb6874e5a729557a369c5f219fd..e7a717a9e04278116e485066ea8c2f31b7949e0c 100644 --- a/src/contents/content.ts +++ b/src/v1/content.ts @@ -1,4 +1,4 @@ -import {uid} from '../types'; +import {html, uid} from './types'; export interface Content { id: uid; @@ -9,6 +9,28 @@ export interface Content { conditionResolver?: ScoreResolver | ChoiceResolver; } +export interface Video extends Content { + source: string; + summary: html; + subtitles: {label: string, lang: string, src: string}[]; + transcript: string; + poster: string; +} + +export interface Html extends Content { + html: html; +} + +export interface Assessment extends Content { + summary?: string; + questions?: uid[]; + time?: number; +} + +export interface SimpleQuestion extends Content { + question: uid; +} + interface Resolver { conditionalFlag: ConditionalFlag[]; } diff --git a/src/epoc.ts b/src/v1/epoc.ts similarity index 70% rename from src/epoc.ts rename to src/v1/epoc.ts index 7fb51e073fc6dde28ff440712dde4cff1b43f71c..a8c4088c01119a44a258fd579845c3a87593d44d 100644 --- a/src/epoc.ts +++ b/src/v1/epoc.ts @@ -1,7 +1,7 @@ import {Author} from './author'; -import {Content} from './contents/content'; +import {Content} from './content'; import {html, uid} from './types'; -import {Assessment, Question} from './contents/assessment'; +import {Question} from './question'; export interface EpocMetadata { lastModif : string; @@ -33,10 +33,6 @@ export interface Epoc extends EpocMetadata { questions: Record<uid, Question>; } -export interface EpocRuntime extends Epoc { - assessments: Assessment[]; -} - export interface Chapter { id: uid; title: string; @@ -45,16 +41,6 @@ export interface Chapter { contents: uid[]; } -export interface ChapterRuntime extends Chapter { - time: number; - videoCount: number; - assessmentCount: number; - initializedContents: Content[]; - assessments: uid[]; - chapterOpened: boolean; - assessmentDone: boolean; -} - export interface Parameters { chapterParameter?: string; easierScoring?: boolean; diff --git a/src/v1/index.ts b/src/v1/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd3593f612d963dde668f51c9536d310c5d39057 --- /dev/null +++ b/src/v1/index.ts @@ -0,0 +1,3 @@ +export * from './epoc' +export * from './types' +export * from './content' \ No newline at end of file diff --git a/src/contents/assessment.ts b/src/v1/question.ts similarity index 56% rename from src/contents/assessment.ts rename to src/v1/question.ts index 4a8215dc21a0902dd15dc8f8d2d91e207ead231a..d24cf2ddba759f25414e03fa0b03dc66cec58fcc 100644 --- a/src/contents/assessment.ts +++ b/src/v1/question.ts @@ -1,26 +1,4 @@ -import {Content} from './content'; -import {html, uid} from '../types'; - -export interface Assessment extends Content { - summary?: string; - questions?: uid[]; - time?: number; -} - -export interface AssessmentRuntime extends Assessment { - score?: number; - scoreTotal?: number; - chapterId?: uid; - easierScoring?: boolean; -} - -export interface SimpleQuestion extends Content { - question: uid; -} - -export interface SimpleQuestionRuntime extends SimpleQuestion { - chapterId?: number; -} +import {html} from './types'; export interface Question { type: string; @@ -55,14 +33,6 @@ export interface SwipeQuestion extends Question { correctResponse: Array<{label: string, values: string[]}>; } -export interface SwipeQuestionRuntime extends SwipeQuestion { - possibilities?: Array<string>; -} - export interface DropDownListQuestion extends Question { correctResponse: Array<{label: string, values: string[]}>; -} - -export interface DropDownListQuestionRuntime extends DragAndDropquestion { - categories?: Array<string>; } \ No newline at end of file diff --git a/src/types.ts b/src/v1/types.ts similarity index 100% rename from src/types.ts rename to src/v1/types.ts diff --git a/src/v2/achievement.ts b/src/v2/achievement.ts new file mode 100644 index 0000000000000000000000000000000000000000..c8884593a4458e05a417ce109f0cb201ba1bf6eb --- /dev/null +++ b/src/v2/achievement.ts @@ -0,0 +1,22 @@ +import {uid} from './types'; +import {Rule} from './rule' + +/** +* Describe a pedagogical achievement and conditions to unlock it +*/ +export interface Achievement { + /** + * Achievement unique id + */ + id: uid; + + /** + * Achievement title that will be shown in the course + */ + title: string; + + /** + * The rule to obtain the achievement + */ + rule: Rule +} diff --git a/src/v2/content.ts b/src/v2/content.ts new file mode 100644 index 0000000000000000000000000000000000000000..7cdeaaa11708f535bcf41aeba79771b1e19c5edd --- /dev/null +++ b/src/v2/content.ts @@ -0,0 +1,98 @@ +import {uid, html, uri, langcode} from './types'; + +/** +* Define the union type of all kind of screen content +*/ +export type Content = Html | Video | Assessment | SimpleQuestion; + +/** +* Define the base content properties +*/ +export interface BaseContent { + type: string; +} + +/** +* Define the html content properties +*/ +export interface Html extends BaseContent { + /** + * Specifies the type of content + */ + type: 'html'; + + /** + * Specifies the rich html text of the content + */ + html: html; +} + +/** +* Define the video content properties +*/ +export interface Video extends BaseContent { + /** + * Specifies the type of content + */ + type: 'video'; + + /** + * Specifies the video source uri + */ + src: uri; + + /** + * Specifies the list of available subtitles (label, lang, uri) + */ + subtitles: {label: string, lang: langcode, src: uri}[]; + + /** + * Specifies the text transcript of the video + */ + transcript: string; + + /** + * Specifies the video poster (thumbnail) uri + */ + poster: uri; +} + +/** +* Define the assessment content properties +*/ +export interface Assessment extends BaseContent { + /** + * Specifies the type of content + */ + type: 'assessment'; + + /** + * Quick summary of the assessment + */ + summary?: string; + + /** + * List of question ids attached to the assessment + */ + questions?: uid[]; + + /** + * Estimated time to do the assessment + */ + time?: number; +} + +/** +* Define the simple question content properties +*/ +export interface SimpleQuestion extends BaseContent { + /** + * Specifies the type of content + */ + type: 'simple-question'; + + /** + * Question id attached to the assessment + */ + question: uid; +} diff --git a/src/v2/epoc.ts b/src/v2/epoc.ts new file mode 100644 index 0000000000000000000000000000000000000000..41018f56233060849ddb3219710f65a8cc0dfc9a --- /dev/null +++ b/src/v2/epoc.ts @@ -0,0 +1,231 @@ +import {Content} from './content'; +import {html, uid, uri, langcode} from './types'; +import {Question} from './question'; +import {Achievement} from './achievement'; + +/** +* Contains all the ePoc metadata that can be retrieved from the library API +*/ +export interface EpocMetadata { + /** + * Specifies the ePoc data format version for backward compatibility + */ + version: number; + + /** + * Specifies the last modification date (YYYY-MM-DD HH:MM:SS) + */ + lastModif: string; + + /** + * Defines the unique id of the ePoc + */ + id: string; + + /** + * Defines the edition name of the ePoc + */ + edition: string; + + /** + * Defines the title of the ePoc + */ + title: string; + + /** + * Defines the path or URL of the ePoc illustration + */ + image: uri; + + /** + * Defines the path or URL of the ePoc video teaser + */ + teaser?: uri; + + /** + * Defines the path or URL of the video thumbnail + */ + thumbnail : uri; + + /** + * Defines the summary of the ePoc + */ + summary: html; + + /** + * List of all authors of the ePoc + */ + authors: Author[]; + + /** + * Defines the list of pedagogical objectives of the ePoc + */ + objectives: string[]; + + /** + * Specifies the total of chapters of the ePoc + */ + chaptersCount: number; + + /** + * Specifies the total of assessments of the ePoc + */ + assessmentsCount: number; + + /** + * Specifies the download URL + */ + download: uri; + + /** + * Map of translations available (lang code, ePoc id) + */ + translations?: Map<langcode, uid>; + +} + +/** + * Contains all the ePoc metadata and contents + */ +export interface Epoc extends EpocMetadata { + /** + * Map of all chapters (id, chapter) of the ePoc + */ + chapters: Map<uid, Chapter>; + + /** + * Map of all screens (id, screens) of the ePoc + */ + screens: Map<uid, Screen>; + + + /** + * Map of all contents (id, content) of the ePoc + */ + contents: Map<uid, Content>; + + /** + * Map of all questions (id, question) of the ePoc + */ + questions: Map<uid, Question>; + + /** + * Parameters of the ePoc + */ + parameters: Parameters; + + /** + * The score to obtain the certificate + * @deprecated Use pedagogical achievements instead + */ + certificateScore?: number; + + /** + * Map of all contents (id, content) of the ePoc + */ + achievements: Map<uid, Achievement> + + /** + * List of plugins of the ePoc + */ + plugins: uri[]; + +} + + +export interface Author { + + /** + * Specifies the author's full name (firstname and lastname) + */ + name: string; + + /** + * Specifies the author's profil picture + */ + image: string; + + /** + * Specifies the author's job title + */ + titre: string; + + /** + * Specifies the author's profil picture + */ + description: html; +} + +export interface Parameters { + + /** + * Specifies the chapter label globally + * @default 'Chapter' + */ + chapterLabel?: string; +} + +export interface Chapter { + + /** + * Specifies the chapter label + * @default 'Chapter' + */ + label?: string; + + /** + * Specifies the chapter title + */ + title: string; + + /** + * Specifies the chapter starting edges + */ + edges: Edge[]; +} + +export interface Screen { + + /** + * Specifies the screen card icon + */ + icon: string; + + /** + * Specifies the screen card title + */ + title: string; + + /** + * Specifies the screen card subtitle + */ + subtitle?: string; + + /** + * List the screen content ids + */ + contents: uid[]; + + /** + * Specifies the screen edges + */ + edges: Edge[]; +} + +export interface Edge { + + /** + * Specifies the source screen uid + */ + source: uid; + + /** + * Specifies the target screen uid + */ + target: uid; + + /** + * @Todo Define conditionnal behavior of edges + */ + data?: Object; +} diff --git a/src/v2/index.ts b/src/v2/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b7fb3c4193e3f61143f92abf588cc6fe74c75733 --- /dev/null +++ b/src/v2/index.ts @@ -0,0 +1,6 @@ +export * from './epoc' +export * from './types' +export * from './achievement' +export * from './content' +export * from './question' +export * from './rule' \ No newline at end of file diff --git a/src/v2/question.ts b/src/v2/question.ts new file mode 100644 index 0000000000000000000000000000000000000000..ec40df55716a4fb579d1173034f198a7d3877610 --- /dev/null +++ b/src/v2/question.ts @@ -0,0 +1,132 @@ +import {html} from './types'; + +/** +* Define the base question properties +*/ +export interface Question { + /** + * Specifies the type of question + */ + type: string; + + /** + * The score of this question + * @deprecated Use pedagogical achievements instead + */ + score: number; + + /** + * The statement of the question + */ + statement: string; + + /** + * The label of the question + */ + label: string; + + /** + * The list of possible responses of the question + */ + responses: Array<Response>; + + /** + * The correction of the question + */ + correctResponse: string|Array<string>|Array<{label: string, values: string[]}>; + + /** + * The explanation of the correction of the question + */ + explanation: html; +} + +/** +* Define the question response properties +*/ +export interface Response { + /** + * The label of the response + */ + label: string; + + /** + * The hidden value of the response + */ + value: string; +} + +/** +* Define the simple choice question properties +*/ +export interface SimpleChoiceQuestion extends Question { + /** + * Specifies the type of question + */ + type: 'choice'; + + /** + * The correction for question with single value expected + */ + correctResponse: string; +} + +/** +* Define the multiple choice question properties +*/ +export interface MultipleChoiceQuestion extends Question { + /** + * Specifies the type of question + */ + type: 'multiple-choice'; + + /** + * The correction for question with multiple values expected + */ + correctResponse: Array<string>; +} + +/** +* Define the drag and drop question properties +*/ +export interface DragAndDropquestion extends Question{ + /** + * Specifies the type of question + */ + type: 'drag-and-drop'; + + /** + * The correction for sortable question type (drag-and-drop, swipe, dropdown) + */ + correctResponse: Array<{label: string, values: string[]}>; +} + +/** +* Define the swipe question properties +*/ +export interface SwipeQuestion extends Question { + /** + * Specifies the type of question + */ + type: 'swipe'; + + /** + * The correction for sortable question type (drag-and-drop, swipe, dropdown) + */ + correctResponse: Array<{label: string, values: string[]}>; +} + +/** +* Define the dropdown question properties +*/ +export interface DropDownListQuestion extends Question { + /** + * Specifies the type of question + */ + type: 'dropdown-list'; + + /** + * The correction for sortable question type (drag-and-drop, swipe, dropdown) + */ + correctResponse: Array<{label: string, values: string[]}>; +} diff --git a/src/v2/rule.ts b/src/v2/rule.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac2fc0326f672314ae03b3e16e01f02709c3707b --- /dev/null +++ b/src/v2/rule.ts @@ -0,0 +1,8 @@ +// Types to represents jsonlogic rules https://jsonlogic.com/ +export type Operators = "var" | ">" | ">=" | "<" | "<=" | "===" | "!==" | "and" | "or"; +export type Operand = number | string | Rule; +export type Operands = [Operand, Operand?]; + +export type Rule = { + [key in Operators]?: Operands; +}; diff --git a/src/v2/types.ts b/src/v2/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..259c90eba557dfc70eeb25f51be6f819679e4a46 --- /dev/null +++ b/src/v2/types.ts @@ -0,0 +1,19 @@ +/** +* Unique identifier string +*/ +export type uid = string; + +/** +* Rich html content string +*/ +export type html = string; // + +/** +* Local filepath or URL of a file +*/ +export type uri = string; + +/** +* Language two-letter (639-1) lowercase abbreviation +*/ +export type langcode = string