scorm-again 2.4.1 → 2.6.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/README.md +23 -23
- package/dist/aicc.js +676 -493
- package/dist/aicc.js.map +1 -1
- package/dist/aicc.min.js +1 -1
- package/dist/aicc.min.js.map +1 -1
- package/dist/esm/aicc.js +692 -496
- package/dist/esm/aicc.js.map +1 -1
- package/dist/esm/aicc.min.js +1 -1
- package/dist/esm/aicc.min.js.map +1 -1
- package/dist/esm/scorm-again.js +1151 -743
- package/dist/esm/scorm-again.js.map +1 -1
- package/dist/esm/scorm-again.min.js +1 -1
- package/dist/esm/scorm-again.min.js.map +1 -1
- package/dist/esm/scorm12.js +534 -401
- package/dist/esm/scorm12.js.map +1 -1
- package/dist/esm/scorm12.min.js +1 -1
- package/dist/esm/scorm12.min.js.map +1 -1
- package/dist/esm/scorm2004.js +712 -465
- package/dist/esm/scorm2004.js.map +1 -1
- package/dist/esm/scorm2004.min.js +1 -1
- package/dist/esm/scorm2004.min.js.map +1 -1
- package/dist/scorm-again.js +1127 -731
- package/dist/scorm-again.js.map +1 -1
- package/dist/scorm-again.min.js +1 -1
- package/dist/scorm-again.min.js.map +1 -1
- package/dist/scorm12.js +521 -400
- package/dist/scorm12.js.map +1 -1
- package/dist/scorm12.min.js +1 -1
- package/dist/scorm12.min.js.map +1 -1
- package/dist/scorm2004.js +698 -464
- package/dist/scorm2004.js.map +1 -1
- package/dist/scorm2004.min.js +1 -1
- package/dist/scorm2004.min.js.map +1 -1
- package/package.json +15 -15
- package/src/AICC.ts +3 -0
- package/src/BaseAPI.ts +60 -95
- package/src/Scorm12API.ts +14 -14
- package/src/Scorm2004API.ts +107 -37
- package/src/cmi/aicc/attempts.ts +22 -12
- package/src/cmi/aicc/cmi.ts +2 -2
- package/src/cmi/aicc/core.ts +44 -26
- package/src/cmi/aicc/evaluation.ts +31 -12
- package/src/cmi/aicc/paths.ts +29 -15
- package/src/cmi/aicc/student_data.ts +14 -5
- package/src/cmi/aicc/student_demographics.ts +31 -24
- package/src/cmi/aicc/student_preferences.ts +11 -11
- package/src/cmi/aicc/tries.ts +24 -14
- package/src/cmi/aicc/validation.ts +3 -4
- package/src/cmi/common/array.ts +17 -5
- package/src/cmi/common/base_cmi.ts +3 -1
- package/src/cmi/common/score.ts +16 -13
- package/src/cmi/scorm12/cmi.ts +25 -10
- package/src/cmi/scorm12/interactions.ts +62 -28
- package/src/cmi/scorm12/nav.ts +13 -5
- package/src/cmi/scorm12/objectives.ts +28 -18
- package/src/cmi/scorm12/student_data.ts +15 -8
- package/src/cmi/scorm12/student_preference.ts +20 -13
- package/src/cmi/scorm12/validation.ts +7 -7
- package/src/cmi/scorm2004/adl.ts +141 -25
- package/src/cmi/scorm2004/cmi.ts +50 -55
- package/src/cmi/scorm2004/comments.ts +21 -20
- package/src/cmi/scorm2004/interactions.ts +73 -32
- package/src/cmi/scorm2004/learner_preference.ts +20 -13
- package/src/cmi/scorm2004/objectives.ts +41 -16
- package/src/cmi/scorm2004/score.ts +22 -11
- package/src/cmi/scorm2004/validation.ts +4 -4
- package/src/constants/api_constants.ts +8 -29
- package/src/constants/default_settings.ts +26 -12
- package/src/constants/enums.ts +9 -0
- package/src/constants/error_codes.ts +5 -12
- package/src/constants/regex.ts +5 -11
- package/src/constants/response_constants.ts +1 -2
- package/src/exceptions/aicc_exceptions.ts +29 -0
- package/src/exceptions/scorm12_exceptions.ts +29 -0
- package/src/exceptions/scorm2004_exceptions.ts +29 -0
- package/src/exceptions.ts +1 -86
- package/src/types/api_types.ts +29 -5
- package/test/AICC.spec.ts +114 -43
- package/test/Scorm12API.spec.ts +37 -39
- package/test/Scorm2004API.spec.ts +165 -80
- package/test/cmi/aicc_cmi.spec.ts +6 -9
- package/test/cmi/scorm12_cmi.spec.ts +8 -8
- package/test/cmi/scorm2004_cmi.spec.ts +8 -9
- package/test/exceptions.spec.ts +11 -9
- package/test/types/api_types.spec.ts +40 -47
- package/test/utilities.spec.ts +1 -4
- package/webpack.config.js +4 -0
package/src/Scorm2004API.ts
CHANGED
|
@@ -2,12 +2,13 @@ import BaseAPI from "./BaseAPI";
|
|
|
2
2
|
import { CMI } from "./cmi/scorm2004/cmi";
|
|
3
3
|
import * as Utilities from "./utilities";
|
|
4
4
|
import { stringMatches } from "./utilities";
|
|
5
|
-
import
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
global_constants,
|
|
7
|
+
scorm2004_constants,
|
|
8
|
+
} from "./constants/api_constants";
|
|
9
|
+
import { scorm2004_errors } from "./constants/error_codes";
|
|
7
10
|
import { CorrectResponses, ResponseType } from "./constants/response_constants";
|
|
8
11
|
import ValidLanguages from "./constants/language_constants";
|
|
9
|
-
import Regex from "./constants/regex";
|
|
10
|
-
import regex from "./constants/regex";
|
|
11
12
|
import { CMIArray } from "./cmi/common/array";
|
|
12
13
|
import { BaseCMI } from "./cmi/common/base_cmi";
|
|
13
14
|
import {
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
} from "./cmi/scorm2004/interactions";
|
|
18
19
|
import { CMICommentsObject } from "./cmi/scorm2004/comments";
|
|
19
20
|
import { CMIObjectivesObject } from "./cmi/scorm2004/objectives";
|
|
20
|
-
import { ADL } from "./cmi/scorm2004/adl";
|
|
21
|
+
import { ADL, ADLDataObject } from "./cmi/scorm2004/adl";
|
|
21
22
|
import {
|
|
22
23
|
CommitObject,
|
|
23
24
|
RefObject,
|
|
@@ -26,12 +27,14 @@ import {
|
|
|
26
27
|
Settings,
|
|
27
28
|
} from "./types/api_types";
|
|
28
29
|
import { CompletionStatus, SuccessStatus } from "./constants/enums";
|
|
30
|
+
import { scorm2004_regex } from "./constants/regex";
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* API class for SCORM 2004
|
|
32
34
|
*/
|
|
33
35
|
class Scorm2004Impl extends BaseAPI {
|
|
34
36
|
private _version: string = "1.0";
|
|
37
|
+
private _globalObjectives: CMIObjectivesObject[] = [];
|
|
35
38
|
|
|
36
39
|
/**
|
|
37
40
|
* Constructor for SCORM 2004 API
|
|
@@ -44,7 +47,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
super(
|
|
50
|
+
super(scorm2004_errors, settings);
|
|
48
51
|
|
|
49
52
|
this.cmi = new CMI();
|
|
50
53
|
this.adl = new ADL();
|
|
@@ -78,8 +81,8 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
78
81
|
reset(settings?: Settings) {
|
|
79
82
|
this.commonReset(settings);
|
|
80
83
|
|
|
81
|
-
this.cmi
|
|
82
|
-
this.adl
|
|
84
|
+
this.cmi?.reset();
|
|
85
|
+
this.adl?.reset();
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
/**
|
|
@@ -90,6 +93,13 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
90
93
|
return this._version;
|
|
91
94
|
}
|
|
92
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Getter for _globalObjectives
|
|
98
|
+
*/
|
|
99
|
+
get globalObjectives(): CMIObjectivesObject[] {
|
|
100
|
+
return this._globalObjectives;
|
|
101
|
+
}
|
|
102
|
+
|
|
93
103
|
/**
|
|
94
104
|
* @return {string} bool
|
|
95
105
|
*/
|
|
@@ -105,13 +115,13 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
105
115
|
(async () => {
|
|
106
116
|
await this.internalFinish();
|
|
107
117
|
})();
|
|
108
|
-
return
|
|
118
|
+
return global_constants.SCORM_TRUE;
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
async internalFinish(): Promise<string> {
|
|
112
122
|
const result = await this.terminate("Terminate", true);
|
|
113
123
|
|
|
114
|
-
if (result ===
|
|
124
|
+
if (result === global_constants.SCORM_TRUE) {
|
|
115
125
|
if (this.adl.nav.request !== "_none_") {
|
|
116
126
|
const navActions: { [key: string]: string } = {
|
|
117
127
|
continue: "SequenceNext",
|
|
@@ -125,12 +135,17 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
125
135
|
};
|
|
126
136
|
|
|
127
137
|
let request = this.adl.nav.request;
|
|
128
|
-
const choiceJumpRegex = new RegExp(
|
|
138
|
+
const choiceJumpRegex = new RegExp(scorm2004_regex.NAVEvent);
|
|
129
139
|
const matches = request.match(choiceJumpRegex);
|
|
130
140
|
let target = "";
|
|
131
|
-
if (matches
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
if (matches) {
|
|
142
|
+
if (matches.groups?.choice_target) {
|
|
143
|
+
target = matches.groups?.choice_target;
|
|
144
|
+
request = "choice";
|
|
145
|
+
} else if (matches.groups?.jump_target) {
|
|
146
|
+
target = matches.groups?.jump_target;
|
|
147
|
+
request = "jump";
|
|
148
|
+
}
|
|
134
149
|
}
|
|
135
150
|
const action = navActions[request];
|
|
136
151
|
if (action) {
|
|
@@ -171,6 +186,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
171
186
|
* @return {string}
|
|
172
187
|
*/
|
|
173
188
|
lmsSetValue(CMIElement: string, value: any): string {
|
|
189
|
+
// Proceed with regular setting for non-objective elements or fallback behavior
|
|
174
190
|
return this.setValue("SetValue", "Commit", true, CMIElement, value);
|
|
175
191
|
}
|
|
176
192
|
|
|
@@ -187,7 +203,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
187
203
|
await this.commit("LMSCommit", false);
|
|
188
204
|
})();
|
|
189
205
|
}
|
|
190
|
-
return
|
|
206
|
+
return global_constants.SCORM_TRUE;
|
|
191
207
|
}
|
|
192
208
|
|
|
193
209
|
/**
|
|
@@ -227,6 +243,57 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
227
243
|
* @return {string}
|
|
228
244
|
*/
|
|
229
245
|
override setCMIValue(CMIElement: string, value: any): string {
|
|
246
|
+
// Check if we're updating a global or local objective
|
|
247
|
+
if (stringMatches(CMIElement, "cmi\\.objectives\\.\\d+")) {
|
|
248
|
+
const parts = CMIElement.split(".");
|
|
249
|
+
const index = Number(parts[2]);
|
|
250
|
+
const element_base = `cmi.objectives.${index}`;
|
|
251
|
+
|
|
252
|
+
let objective_id;
|
|
253
|
+
const setting_id = stringMatches(
|
|
254
|
+
CMIElement,
|
|
255
|
+
"cmi\\.objectives\\.\\d+\\.id",
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
if (setting_id) {
|
|
259
|
+
// If we're setting the objective ID, capture it directly
|
|
260
|
+
objective_id = value;
|
|
261
|
+
} else {
|
|
262
|
+
// Find existing objective ID if available
|
|
263
|
+
const objective = this.cmi.objectives.findObjectiveByIndex(index);
|
|
264
|
+
objective_id = objective ? objective.id : undefined;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Check if the objective ID matches a global objective
|
|
268
|
+
const is_global =
|
|
269
|
+
objective_id && this.settings.globalObjectiveIds.includes(objective_id);
|
|
270
|
+
|
|
271
|
+
if (is_global) {
|
|
272
|
+
// Locate or create an entry in _globalObjectives for the global objective
|
|
273
|
+
let global_index = this._globalObjectives.findIndex(
|
|
274
|
+
(obj) => obj.id === objective_id,
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
if (global_index === -1) {
|
|
278
|
+
global_index = this._globalObjectives.length;
|
|
279
|
+
const newGlobalObjective = new CMIObjectivesObject();
|
|
280
|
+
newGlobalObjective.id = objective_id;
|
|
281
|
+
this._globalObjectives.push(newGlobalObjective);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Update the global objective
|
|
285
|
+
const global_element = CMIElement.replace(
|
|
286
|
+
element_base,
|
|
287
|
+
`_globalObjectives.${global_index}`,
|
|
288
|
+
);
|
|
289
|
+
this._commonSetCMIValue(
|
|
290
|
+
"SetGlobalObjectiveValue",
|
|
291
|
+
true,
|
|
292
|
+
global_element,
|
|
293
|
+
value,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
230
297
|
return this._commonSetCMIValue("SetValue", true, CMIElement, value);
|
|
231
298
|
}
|
|
232
299
|
|
|
@@ -273,6 +340,10 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
273
340
|
return new CMICommentsObject(true);
|
|
274
341
|
}
|
|
275
342
|
|
|
343
|
+
if (stringMatches(CMIElement, "adl\\.data\\.\\d+")) {
|
|
344
|
+
return new ADLDataObject();
|
|
345
|
+
}
|
|
346
|
+
|
|
276
347
|
return null;
|
|
277
348
|
}
|
|
278
349
|
|
|
@@ -286,7 +357,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
286
357
|
|
|
287
358
|
if (this.isInitialized()) {
|
|
288
359
|
if (!interaction.type) {
|
|
289
|
-
this.throwSCORMError(
|
|
360
|
+
this.throwSCORMError(scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED);
|
|
290
361
|
} else {
|
|
291
362
|
this.checkDuplicateChoiceResponse(interaction, value);
|
|
292
363
|
const response_type = CorrectResponses[interaction.type];
|
|
@@ -294,7 +365,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
294
365
|
this.checkValidResponseType(response_type, value, interaction.type);
|
|
295
366
|
} else {
|
|
296
367
|
this.throwSCORMError(
|
|
297
|
-
|
|
368
|
+
scorm2004_errors.GENERAL_SET_FAILURE,
|
|
298
369
|
"Incorrect Response Type: " + interaction.type,
|
|
299
370
|
);
|
|
300
371
|
}
|
|
@@ -330,7 +401,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
330
401
|
this.checkCorrectResponseValue(interaction_type, nodes, value);
|
|
331
402
|
} else if (nodes.length > response_type.max) {
|
|
332
403
|
this.throwSCORMError(
|
|
333
|
-
|
|
404
|
+
scorm2004_errors.GENERAL_SET_FAILURE,
|
|
334
405
|
"Data Model Element Pattern Too Long",
|
|
335
406
|
);
|
|
336
407
|
}
|
|
@@ -351,7 +422,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
351
422
|
) {
|
|
352
423
|
const response = interaction.correct_responses.childArray[i];
|
|
353
424
|
if (response.pattern === value) {
|
|
354
|
-
this.throwSCORMError(
|
|
425
|
+
this.throwSCORMError(scorm2004_errors.GENERAL_SET_FAILURE);
|
|
355
426
|
}
|
|
356
427
|
}
|
|
357
428
|
}
|
|
@@ -392,14 +463,14 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
392
463
|
} else {
|
|
393
464
|
if (this.lastErrorCode === "0") {
|
|
394
465
|
this.throwSCORMError(
|
|
395
|
-
|
|
466
|
+
scorm2004_errors.GENERAL_SET_FAILURE,
|
|
396
467
|
"Data Model Element Pattern Already Exists",
|
|
397
468
|
);
|
|
398
469
|
}
|
|
399
470
|
}
|
|
400
471
|
} else {
|
|
401
472
|
this.throwSCORMError(
|
|
402
|
-
|
|
473
|
+
scorm2004_errors.GENERAL_SET_FAILURE,
|
|
403
474
|
"Data Model Element Collection Limit Reached",
|
|
404
475
|
);
|
|
405
476
|
}
|
|
@@ -431,11 +502,11 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
431
502
|
|
|
432
503
|
// Set error number to string since inconsistent from modules if string or number
|
|
433
504
|
errorNumber = String(errorNumber);
|
|
434
|
-
if (
|
|
505
|
+
if (scorm2004_constants.error_descriptions[errorNumber]) {
|
|
435
506
|
basicMessage =
|
|
436
|
-
|
|
507
|
+
scorm2004_constants.error_descriptions[errorNumber].basicMessage;
|
|
437
508
|
detailMessage =
|
|
438
|
-
|
|
509
|
+
scorm2004_constants.error_descriptions[errorNumber].detailMessage;
|
|
439
510
|
}
|
|
440
511
|
|
|
441
512
|
return detail ? detailMessage : basicMessage;
|
|
@@ -490,17 +561,17 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
490
561
|
if (values.length === 2) {
|
|
491
562
|
const matches = values[0].match(formatRegex);
|
|
492
563
|
if (!matches) {
|
|
493
|
-
this.throwSCORMError(
|
|
564
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
494
565
|
} else {
|
|
495
566
|
if (
|
|
496
567
|
!response.format2 ||
|
|
497
568
|
!values[1].match(new RegExp(response.format2))
|
|
498
569
|
) {
|
|
499
|
-
this.throwSCORMError(
|
|
570
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
500
571
|
}
|
|
501
572
|
}
|
|
502
573
|
} else {
|
|
503
|
-
this.throwSCORMError(
|
|
574
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
504
575
|
}
|
|
505
576
|
} else {
|
|
506
577
|
const matches = nodes[i].match(formatRegex);
|
|
@@ -508,17 +579,17 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
508
579
|
(!matches && value !== "") ||
|
|
509
580
|
(!matches && interaction_type === "true-false")
|
|
510
581
|
) {
|
|
511
|
-
this.throwSCORMError(
|
|
582
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
512
583
|
} else {
|
|
513
584
|
if (interaction_type === "numeric" && nodes.length > 1) {
|
|
514
585
|
if (Number(nodes[0]) > Number(nodes[1])) {
|
|
515
|
-
this.throwSCORMError(
|
|
586
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
516
587
|
}
|
|
517
588
|
} else {
|
|
518
589
|
if (nodes[i] !== "" && response.unique) {
|
|
519
590
|
for (let j = 0; j < i && this.lastErrorCode === "0"; j++) {
|
|
520
591
|
if (nodes[i] === nodes[j]) {
|
|
521
|
-
this.throwSCORMError(
|
|
592
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
522
593
|
}
|
|
523
594
|
}
|
|
524
595
|
}
|
|
@@ -546,12 +617,12 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
546
617
|
while (matches) {
|
|
547
618
|
switch (matches[2]) {
|
|
548
619
|
case "lang":
|
|
549
|
-
langMatches = node.match(
|
|
620
|
+
langMatches = node.match(scorm2004_regex.CMILangcr);
|
|
550
621
|
if (langMatches) {
|
|
551
622
|
const lang = langMatches[3];
|
|
552
623
|
if (lang !== undefined && lang.length > 0) {
|
|
553
624
|
if (!ValidLanguages.includes(lang.toLowerCase())) {
|
|
554
|
-
this.throwSCORMError(
|
|
625
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
555
626
|
}
|
|
556
627
|
}
|
|
557
628
|
}
|
|
@@ -560,7 +631,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
560
631
|
case "case_matters":
|
|
561
632
|
if (!seenLang && !seenOrder && !seenCase) {
|
|
562
633
|
if (matches[3] !== "true" && matches[3] !== "false") {
|
|
563
|
-
this.throwSCORMError(
|
|
634
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
564
635
|
}
|
|
565
636
|
}
|
|
566
637
|
|
|
@@ -569,7 +640,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
569
640
|
case "order_matters":
|
|
570
641
|
if (!seenCase && !seenLang && !seenOrder) {
|
|
571
642
|
if (matches[3] !== "true" && matches[3] !== "false") {
|
|
572
|
-
this.throwSCORMError(
|
|
643
|
+
this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
|
|
573
644
|
}
|
|
574
645
|
}
|
|
575
646
|
|
|
@@ -634,7 +705,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
634
705
|
const totalTimeDuration = this.cmi.getCurrentTotalTime();
|
|
635
706
|
const totalTimeSeconds = Utilities.getDurationAsSeconds(
|
|
636
707
|
totalTimeDuration,
|
|
637
|
-
|
|
708
|
+
scorm2004_regex.CMITimespan,
|
|
638
709
|
);
|
|
639
710
|
|
|
640
711
|
let completionStatus = CompletionStatus.unknown;
|
|
@@ -718,7 +789,6 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
718
789
|
this.adl.nav.request !== this.startingData?.adl?.nav?.request &&
|
|
719
790
|
this.adl.nav.request !== "_none_"
|
|
720
791
|
) {
|
|
721
|
-
this.adl.nav.request = encodeURIComponent(this.adl.nav.request);
|
|
722
792
|
navRequest = true;
|
|
723
793
|
}
|
|
724
794
|
|
|
@@ -743,7 +813,7 @@ class Scorm2004Impl extends BaseAPI {
|
|
|
743
813
|
return result;
|
|
744
814
|
} else {
|
|
745
815
|
return {
|
|
746
|
-
result:
|
|
816
|
+
result: global_constants.SCORM_TRUE,
|
|
747
817
|
errorCode: 0,
|
|
748
818
|
};
|
|
749
819
|
}
|
package/src/cmi/aicc/attempts.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseCMI } from "../common/base_cmi";
|
|
2
2
|
import { CMIScore } from "../common/score";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { AICCValidationError } from "../../exceptions";
|
|
3
|
+
import { aicc_constants } from "../../constants/api_constants";
|
|
4
|
+
import { aicc_regex } from "../../constants/regex";
|
|
5
|
+
import { scorm12_errors } from "../../constants/error_codes";
|
|
6
|
+
import { AICCValidationError } from "../../exceptions/aicc_exceptions";
|
|
7
7
|
import { checkAICCValidFormat } from "./validation";
|
|
8
8
|
import { CMIArray } from "../common/array";
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ export class CMIAttemptRecords extends CMIArray {
|
|
|
16
16
|
*/
|
|
17
17
|
constructor() {
|
|
18
18
|
super({
|
|
19
|
-
children:
|
|
19
|
+
children: aicc_constants.attempt_records_children,
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -25,17 +25,19 @@ export class CMIAttemptRecords extends CMIArray {
|
|
|
25
25
|
* Class for AICC Attempt Records
|
|
26
26
|
*/
|
|
27
27
|
export class CMIAttemptRecordsObject extends BaseCMI {
|
|
28
|
+
private _lesson_status = "";
|
|
29
|
+
|
|
28
30
|
/**
|
|
29
31
|
* Constructor for AICC Attempt Records object
|
|
30
32
|
*/
|
|
31
33
|
constructor() {
|
|
32
34
|
super();
|
|
33
35
|
this.score = new CMIScore({
|
|
34
|
-
score_children:
|
|
35
|
-
score_range:
|
|
36
|
-
invalidErrorCode:
|
|
37
|
-
invalidTypeCode:
|
|
38
|
-
invalidRangeCode:
|
|
36
|
+
score_children: aicc_constants.score_children,
|
|
37
|
+
score_range: aicc_regex.score_range,
|
|
38
|
+
invalidErrorCode: scorm12_errors.INVALID_SET_VALUE,
|
|
39
|
+
invalidTypeCode: scorm12_errors.TYPE_MISMATCH,
|
|
40
|
+
invalidRangeCode: scorm12_errors.VALUE_OUT_OF_RANGE,
|
|
39
41
|
errorClass: AICCValidationError,
|
|
40
42
|
});
|
|
41
43
|
}
|
|
@@ -47,10 +49,18 @@ export class CMIAttemptRecordsObject extends BaseCMI {
|
|
|
47
49
|
*/
|
|
48
50
|
override initialize() {
|
|
49
51
|
super.initialize();
|
|
52
|
+
|
|
53
|
+
this._lesson_status = "";
|
|
50
54
|
this.score?.initialize();
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Called when the API has been reset
|
|
59
|
+
*/
|
|
60
|
+
reset(): void {
|
|
61
|
+
this._initialized = false;
|
|
62
|
+
this.score?.reset();
|
|
63
|
+
}
|
|
54
64
|
|
|
55
65
|
/**
|
|
56
66
|
* Getter for _lesson_status
|
|
@@ -65,7 +75,7 @@ export class CMIAttemptRecordsObject extends BaseCMI {
|
|
|
65
75
|
* @param {string} lesson_status
|
|
66
76
|
*/
|
|
67
77
|
set lesson_status(lesson_status: string) {
|
|
68
|
-
if (checkAICCValidFormat(lesson_status,
|
|
78
|
+
if (checkAICCValidFormat(lesson_status, aicc_regex.CMIStatus2)) {
|
|
69
79
|
this._lesson_status = lesson_status;
|
|
70
80
|
}
|
|
71
81
|
}
|
package/src/cmi/aicc/cmi.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Scorm12CMI from "../scorm12/cmi";
|
|
2
|
-
import
|
|
2
|
+
import { aicc_constants } from "../../constants/api_constants";
|
|
3
3
|
import { CMIEvaluation } from "./evaluation";
|
|
4
4
|
import { AICCStudentPreferences } from "./student_preferences";
|
|
5
5
|
import { CMIStudentDemographics } from "./student_demographics";
|
|
@@ -20,7 +20,7 @@ export class CMI extends Scorm12CMI.CMI {
|
|
|
20
20
|
* @param {boolean} initialized
|
|
21
21
|
*/
|
|
22
22
|
constructor(initialized: boolean = false) {
|
|
23
|
-
super(
|
|
23
|
+
super(aicc_constants.cmi_children);
|
|
24
24
|
if (initialized) this.initialize();
|
|
25
25
|
this.student_preference = new AICCStudentPreferences();
|
|
26
26
|
this.student_data = new AICCCMIStudentData();
|
package/src/cmi/aicc/core.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseCMI } from "../common/base_cmi";
|
|
2
2
|
import { CMIScore } from "../common/score";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { Scorm12ValidationError } from "../../exceptions";
|
|
3
|
+
import { scorm12_constants } from "../../constants/api_constants";
|
|
4
|
+
import { scorm12_regex } from "../../constants/regex";
|
|
5
|
+
import { scorm12_errors } from "../../constants/error_codes";
|
|
6
|
+
import { Scorm12ValidationError } from "../../exceptions/scorm12_exceptions";
|
|
7
7
|
import { check12ValidFormat } from "../scorm12/validation";
|
|
8
8
|
import * as Util from "../../utilities";
|
|
9
9
|
|
|
@@ -18,11 +18,11 @@ export class CMICore extends BaseCMI {
|
|
|
18
18
|
constructor() {
|
|
19
19
|
super();
|
|
20
20
|
this.score = new CMIScore({
|
|
21
|
-
score_children:
|
|
22
|
-
score_range:
|
|
23
|
-
invalidErrorCode:
|
|
24
|
-
invalidTypeCode:
|
|
25
|
-
invalidRangeCode:
|
|
21
|
+
score_children: scorm12_constants.score_children,
|
|
22
|
+
score_range: scorm12_regex.score_range,
|
|
23
|
+
invalidErrorCode: scorm12_errors.INVALID_SET_VALUE,
|
|
24
|
+
invalidTypeCode: scorm12_errors.TYPE_MISMATCH,
|
|
25
|
+
invalidRangeCode: scorm12_errors.VALUE_OUT_OF_RANGE,
|
|
26
26
|
errorClass: Scorm12ValidationError,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
@@ -37,7 +37,7 @@ export class CMICore extends BaseCMI {
|
|
|
37
37
|
this.score?.initialize();
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
private __children =
|
|
40
|
+
private __children = scorm12_constants.core_children;
|
|
41
41
|
private _student_id = "";
|
|
42
42
|
private _student_name = "";
|
|
43
43
|
private _lesson_location = "";
|
|
@@ -50,6 +50,24 @@ export class CMICore extends BaseCMI {
|
|
|
50
50
|
private _session_time = "00:00:00";
|
|
51
51
|
private _suspend_data = "";
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Called when the API has been reset
|
|
55
|
+
*/
|
|
56
|
+
reset(): void {
|
|
57
|
+
this._initialized = false;
|
|
58
|
+
|
|
59
|
+
this._exit = "";
|
|
60
|
+
this._entry = "";
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resetting ensures we accurately track the time spent on each individual SCO session independently. Each new
|
|
64
|
+
* session should start from zero, so we can reset cmi.core.session_time at the beginning of each session.
|
|
65
|
+
*/
|
|
66
|
+
this._session_time = "00:00:00";
|
|
67
|
+
|
|
68
|
+
this.score?.reset();
|
|
69
|
+
}
|
|
70
|
+
|
|
53
71
|
/**
|
|
54
72
|
* Getter for __children
|
|
55
73
|
* @return {string}
|
|
@@ -65,7 +83,7 @@ export class CMICore extends BaseCMI {
|
|
|
65
83
|
* @private
|
|
66
84
|
*/
|
|
67
85
|
set _children(_children: string) {
|
|
68
|
-
throw new Scorm12ValidationError(
|
|
86
|
+
throw new Scorm12ValidationError(scorm12_errors.INVALID_SET_VALUE);
|
|
69
87
|
}
|
|
70
88
|
|
|
71
89
|
/**
|
|
@@ -82,7 +100,7 @@ export class CMICore extends BaseCMI {
|
|
|
82
100
|
*/
|
|
83
101
|
set student_id(student_id: string) {
|
|
84
102
|
if (this.initialized) {
|
|
85
|
-
throw new Scorm12ValidationError(
|
|
103
|
+
throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
|
|
86
104
|
} else {
|
|
87
105
|
this._student_id = student_id;
|
|
88
106
|
}
|
|
@@ -102,7 +120,7 @@ export class CMICore extends BaseCMI {
|
|
|
102
120
|
*/
|
|
103
121
|
set student_name(student_name: string) {
|
|
104
122
|
if (this.initialized) {
|
|
105
|
-
throw new Scorm12ValidationError(
|
|
123
|
+
throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
|
|
106
124
|
} else {
|
|
107
125
|
this._student_name = student_name;
|
|
108
126
|
}
|
|
@@ -121,7 +139,7 @@ export class CMICore extends BaseCMI {
|
|
|
121
139
|
* @param {string} lesson_location
|
|
122
140
|
*/
|
|
123
141
|
set lesson_location(lesson_location: string) {
|
|
124
|
-
if (check12ValidFormat(lesson_location,
|
|
142
|
+
if (check12ValidFormat(lesson_location, scorm12_regex.CMIString256, true)) {
|
|
125
143
|
this._lesson_location = lesson_location;
|
|
126
144
|
}
|
|
127
145
|
}
|
|
@@ -140,7 +158,7 @@ export class CMICore extends BaseCMI {
|
|
|
140
158
|
*/
|
|
141
159
|
set credit(credit: string) {
|
|
142
160
|
if (this.initialized) {
|
|
143
|
-
throw new Scorm12ValidationError(
|
|
161
|
+
throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
|
|
144
162
|
} else {
|
|
145
163
|
this._credit = credit;
|
|
146
164
|
}
|
|
@@ -160,11 +178,11 @@ export class CMICore extends BaseCMI {
|
|
|
160
178
|
*/
|
|
161
179
|
set lesson_status(lesson_status: string) {
|
|
162
180
|
if (this.initialized) {
|
|
163
|
-
if (check12ValidFormat(lesson_status,
|
|
181
|
+
if (check12ValidFormat(lesson_status, scorm12_regex.CMIStatus)) {
|
|
164
182
|
this._lesson_status = lesson_status;
|
|
165
183
|
}
|
|
166
184
|
} else {
|
|
167
|
-
if (check12ValidFormat(lesson_status,
|
|
185
|
+
if (check12ValidFormat(lesson_status, scorm12_regex.CMIStatus2)) {
|
|
168
186
|
this._lesson_status = lesson_status;
|
|
169
187
|
}
|
|
170
188
|
}
|
|
@@ -184,7 +202,7 @@ export class CMICore extends BaseCMI {
|
|
|
184
202
|
*/
|
|
185
203
|
set entry(entry: string) {
|
|
186
204
|
if (this.initialized) {
|
|
187
|
-
throw new Scorm12ValidationError(
|
|
205
|
+
throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
|
|
188
206
|
} else {
|
|
189
207
|
this._entry = entry;
|
|
190
208
|
}
|
|
@@ -204,7 +222,7 @@ export class CMICore extends BaseCMI {
|
|
|
204
222
|
*/
|
|
205
223
|
set total_time(total_time: string) {
|
|
206
224
|
if (this.initialized) {
|
|
207
|
-
throw new Scorm12ValidationError(
|
|
225
|
+
throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
|
|
208
226
|
} else {
|
|
209
227
|
this._total_time = total_time;
|
|
210
228
|
}
|
|
@@ -224,7 +242,7 @@ export class CMICore extends BaseCMI {
|
|
|
224
242
|
*/
|
|
225
243
|
set lesson_mode(lesson_mode: string) {
|
|
226
244
|
if (this.initialized) {
|
|
227
|
-
throw new Scorm12ValidationError(
|
|
245
|
+
throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
|
|
228
246
|
} else {
|
|
229
247
|
this._lesson_mode = lesson_mode;
|
|
230
248
|
}
|
|
@@ -236,7 +254,7 @@ export class CMICore extends BaseCMI {
|
|
|
236
254
|
*/
|
|
237
255
|
get exit(): string {
|
|
238
256
|
if (!this.jsonString) {
|
|
239
|
-
throw new Scorm12ValidationError(
|
|
257
|
+
throw new Scorm12ValidationError(scorm12_errors.WRITE_ONLY_ELEMENT);
|
|
240
258
|
}
|
|
241
259
|
return this._exit;
|
|
242
260
|
}
|
|
@@ -246,7 +264,7 @@ export class CMICore extends BaseCMI {
|
|
|
246
264
|
* @param {string} exit
|
|
247
265
|
*/
|
|
248
266
|
set exit(exit: string) {
|
|
249
|
-
if (check12ValidFormat(exit,
|
|
267
|
+
if (check12ValidFormat(exit, scorm12_regex.CMIExit, true)) {
|
|
250
268
|
this._exit = exit;
|
|
251
269
|
}
|
|
252
270
|
}
|
|
@@ -257,7 +275,7 @@ export class CMICore extends BaseCMI {
|
|
|
257
275
|
*/
|
|
258
276
|
get session_time(): string {
|
|
259
277
|
if (!this.jsonString) {
|
|
260
|
-
throw new Scorm12ValidationError(
|
|
278
|
+
throw new Scorm12ValidationError(scorm12_errors.WRITE_ONLY_ELEMENT);
|
|
261
279
|
}
|
|
262
280
|
return this._session_time;
|
|
263
281
|
}
|
|
@@ -267,7 +285,7 @@ export class CMICore extends BaseCMI {
|
|
|
267
285
|
* @param {string} session_time
|
|
268
286
|
*/
|
|
269
287
|
set session_time(session_time: string) {
|
|
270
|
-
if (check12ValidFormat(session_time,
|
|
288
|
+
if (check12ValidFormat(session_time, scorm12_regex.CMITimespan)) {
|
|
271
289
|
this._session_time = session_time;
|
|
272
290
|
}
|
|
273
291
|
}
|
|
@@ -285,7 +303,7 @@ export class CMICore extends BaseCMI {
|
|
|
285
303
|
* @param {string} suspend_data
|
|
286
304
|
*/
|
|
287
305
|
set suspend_data(suspend_data: string) {
|
|
288
|
-
if (check12ValidFormat(suspend_data,
|
|
306
|
+
if (check12ValidFormat(suspend_data, scorm12_regex.CMIString4096, true)) {
|
|
289
307
|
this._suspend_data = suspend_data;
|
|
290
308
|
}
|
|
291
309
|
}
|
|
@@ -307,7 +325,7 @@ export class CMICore extends BaseCMI {
|
|
|
307
325
|
return Util.addHHMMSSTimeStrings(
|
|
308
326
|
this._total_time,
|
|
309
327
|
sessionTime,
|
|
310
|
-
new RegExp(
|
|
328
|
+
new RegExp(scorm12_regex.CMITimespan),
|
|
311
329
|
);
|
|
312
330
|
}
|
|
313
331
|
|