scorm-again 2.6.2 → 2.6.4

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 (70) hide show
  1. package/dist/aicc.js +41 -25
  2. package/dist/aicc.js.map +1 -1
  3. package/dist/aicc.min.js +1 -1
  4. package/dist/aicc.min.js.map +1 -1
  5. package/dist/esm/aicc.js +41 -25
  6. package/dist/esm/aicc.js.map +1 -1
  7. package/dist/esm/aicc.min.js +1 -1
  8. package/dist/esm/aicc.min.js.map +1 -1
  9. package/dist/esm/scorm-again.js +70 -45
  10. package/dist/esm/scorm-again.js.map +1 -1
  11. package/dist/esm/scorm-again.min.js +1 -1
  12. package/dist/esm/scorm-again.min.js.map +1 -1
  13. package/dist/esm/scorm12.js +38 -23
  14. package/dist/esm/scorm12.js.map +1 -1
  15. package/dist/esm/scorm12.min.js +1 -1
  16. package/dist/esm/scorm12.min.js.map +1 -1
  17. package/dist/esm/scorm2004.js +60 -39
  18. package/dist/esm/scorm2004.js.map +1 -1
  19. package/dist/esm/scorm2004.min.js +1 -1
  20. package/dist/esm/scorm2004.min.js.map +1 -1
  21. package/dist/scorm-again.js +70 -45
  22. package/dist/scorm-again.js.map +1 -1
  23. package/dist/scorm-again.min.js +1 -1
  24. package/dist/scorm-again.min.js.map +1 -1
  25. package/dist/scorm12.js +38 -23
  26. package/dist/scorm12.js.map +1 -1
  27. package/dist/scorm12.min.js +1 -1
  28. package/dist/scorm12.min.js.map +1 -1
  29. package/dist/scorm2004.js +60 -39
  30. package/dist/scorm2004.js.map +1 -1
  31. package/dist/scorm2004.min.js +1 -1
  32. package/dist/scorm2004.min.js.map +1 -1
  33. package/index.d.ts +24 -3
  34. package/package.json +1 -1
  35. package/src/BaseAPI.ts +57 -35
  36. package/src/Scorm12API.ts +3 -2
  37. package/src/Scorm2004API.ts +31 -24
  38. package/src/cmi/aicc/attempts.ts +3 -3
  39. package/src/cmi/aicc/core.ts +30 -12
  40. package/src/cmi/aicc/evaluation.ts +1 -1
  41. package/src/cmi/aicc/student_data.ts +1 -1
  42. package/src/cmi/aicc/student_demographics.ts +13 -13
  43. package/src/cmi/aicc/student_preferences.ts +1 -1
  44. package/src/cmi/aicc/tries.ts +3 -3
  45. package/src/cmi/aicc/validation.ts +1 -1
  46. package/src/cmi/common/array.ts +1 -1
  47. package/src/cmi/common/score.ts +3 -3
  48. package/src/cmi/common/validation.ts +2 -2
  49. package/src/cmi/scorm12/cmi.ts +12 -4
  50. package/src/cmi/scorm12/interactions.ts +27 -11
  51. package/src/cmi/scorm12/objectives.ts +4 -4
  52. package/src/cmi/scorm12/student_data.ts +12 -4
  53. package/src/cmi/scorm12/student_preference.ts +3 -1
  54. package/src/cmi/scorm12/validation.ts +5 -3
  55. package/src/cmi/scorm2004/adl.ts +21 -7
  56. package/src/cmi/scorm2004/cmi.ts +45 -15
  57. package/src/cmi/scorm2004/comments.ts +11 -5
  58. package/src/cmi/scorm2004/interactions.ts +25 -23
  59. package/src/cmi/scorm2004/learner_preference.ts +3 -1
  60. package/src/cmi/scorm2004/objectives.ts +5 -5
  61. package/src/cmi/scorm2004/score.ts +3 -3
  62. package/src/cmi/scorm2004/validation.ts +2 -2
  63. package/src/constants/regex.ts +8 -1
  64. package/src/exceptions/aicc_exceptions.ts +4 -4
  65. package/src/exceptions/scorm12_exceptions.ts +4 -4
  66. package/src/exceptions/scorm2004_exceptions.ts +4 -4
  67. package/src/utilities.ts +3 -3
  68. package/test/Scorm12API.spec.ts +45 -0
  69. package/test/Scorm2004API.spec.ts +43 -0
  70. package/tsconfig.json +1 -0
package/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { Scorm12Impl } from "./src/Scorm12API";
1
+ import { Scorm12API as Scorm12Impl } from "./src/Scorm12API";
2
2
  import { CMI as Scorm12CMI } from "./src/cmi/scorm12/cmi";
3
3
  import { NAV as Scorm12NAV } from "./src/cmi/scorm12/nav";
4
4
  import { CMI as Scorm2004CMI } from "./src/cmi/scorm2004/cmi";
5
5
  import { ADL as Scorm2004ADL } from "./src/cmi/scorm2004/adl";
6
6
  import { Settings } from "./src/types/api_types";
7
- import { Scorm2004Impl } from "./src/Scorm2004API";
8
- import { AICCImpl } from "./src/AICC";
7
+ import { Scorm2004API as Scorm2004Impl } from "./src/Scorm2004API";
8
+ import { AICC as AICCImpl } from "./src/AICC";
9
9
 
10
10
  declare class Scorm12API extends Scorm12Impl {
11
11
  constructor(settings?: Settings);
@@ -21,6 +21,13 @@ declare class Scorm12API extends Scorm12Impl {
21
21
  LMSGetErrorString: (CMIErrorCode: string) => string;
22
22
  LMSGetDiagnostic: (CMIErrorCode: string) => string;
23
23
 
24
+ loadFromJSON: (json: any, CMIElement?: string) => void;
25
+ loadFromFlattenedJSON: (json: any, CMIElement?: string) => void;
26
+ on: (listenerName: string, callback: Function) => void;
27
+ off: (listenerName: string, callback: Function) => void;
28
+ clear: (listenerName: string) => void;
29
+
30
+
24
31
  /**
25
32
  * Called when the API needs to be reset
26
33
  */
@@ -41,6 +48,13 @@ declare class Scorm2004API extends Scorm2004Impl {
41
48
  GetErrorString: (CMIErrorCode: string) => string;
42
49
  GetDiagnostic: (CMIErrorCode: string) => string;
43
50
 
51
+ loadFromJSON: (json: any, CMIElement?: string) => void;
52
+ loadFromFlattenedJSON: (json: any, CMIElement?: string) => void;
53
+ on: (listenerName: string, callback: Function) => void;
54
+ off: (listenerName: string, callback: Function) => void;
55
+ clear: (listenerName: string) => void;
56
+
57
+
44
58
  /**
45
59
  * Called when the API needs to be reset
46
60
  */
@@ -61,6 +75,13 @@ declare class AICC extends AICCImpl {
61
75
  LMSGetErrorString: (CMIErrorCode: string) => string;
62
76
  LMSGetDiagnostic: (CMIErrorCode: string) => string;
63
77
 
78
+ loadFromJSON: (json: any, CMIElement?: string) => void;
79
+ loadFromFlattenedJSON: (json: any, CMIElement?: string) => void;
80
+ on: (listenerName: string, callback: Function) => void;
81
+ off: (listenerName: string, callback: Function) => void;
82
+ clear: (listenerName: string) => void;
83
+
84
+
64
85
  /**
65
86
  * Called when the API needs to be reset
66
87
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scorm-again",
3
- "version": "2.6.2",
3
+ "version": "2.6.4",
4
4
  "description": "A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004",
5
5
  "main": "dist/scorm-again.js",
6
6
  "types": "index.d.ts",
package/src/BaseAPI.ts CHANGED
@@ -88,9 +88,15 @@ export default abstract class BaseAPI implements IBaseAPI {
88
88
  let returnValue = global_constants.SCORM_FALSE;
89
89
 
90
90
  if (this.isInitialized()) {
91
- this.throwSCORMError(this._error_codes.INITIALIZED, initializeMessage);
91
+ this.throwSCORMError(
92
+ this._error_codes.INITIALIZED as number,
93
+ initializeMessage,
94
+ );
92
95
  } else if (this.isTerminated()) {
93
- this.throwSCORMError(this._error_codes.TERMINATED, terminationMessage);
96
+ this.throwSCORMError(
97
+ this._error_codes.TERMINATED as number,
98
+ terminationMessage,
99
+ );
94
100
  } else {
95
101
  if (this.selfReportSessionTime) {
96
102
  this.cmi.setStartTime();
@@ -235,8 +241,8 @@ export default abstract class BaseAPI implements IBaseAPI {
235
241
  if (
236
242
  this.checkState(
237
243
  checkTerminated,
238
- this._error_codes.TERMINATION_BEFORE_INIT,
239
- this._error_codes.MULTIPLE_TERMINATION,
244
+ this._error_codes.TERMINATION_BEFORE_INIT as number,
245
+ this._error_codes.MULTIPLE_TERMINATION as number,
240
246
  )
241
247
  ) {
242
248
  this.currentState = global_constants.STATE_TERMINATED;
@@ -280,8 +286,8 @@ export default abstract class BaseAPI implements IBaseAPI {
280
286
  if (
281
287
  this.checkState(
282
288
  checkTerminated,
283
- this._error_codes.RETRIEVE_BEFORE_INIT,
284
- this._error_codes.RETRIEVE_AFTER_TERM,
289
+ this._error_codes.RETRIEVE_BEFORE_INIT as number,
290
+ this._error_codes.RETRIEVE_AFTER_TERM as number,
285
291
  )
286
292
  ) {
287
293
  if (checkTerminated) this.lastErrorCode = "0";
@@ -334,8 +340,8 @@ export default abstract class BaseAPI implements IBaseAPI {
334
340
  if (
335
341
  this.checkState(
336
342
  checkTerminated,
337
- this._error_codes.STORE_BEFORE_INIT,
338
- this._error_codes.STORE_AFTER_TERM,
343
+ this._error_codes.STORE_BEFORE_INIT as number,
344
+ this._error_codes.STORE_AFTER_TERM as number,
339
345
  )
340
346
  ) {
341
347
  if (checkTerminated) this.lastErrorCode = "0";
@@ -390,8 +396,8 @@ export default abstract class BaseAPI implements IBaseAPI {
390
396
  if (
391
397
  this.checkState(
392
398
  checkTerminated,
393
- this._error_codes.COMMIT_BEFORE_INIT,
394
- this._error_codes.COMMIT_AFTER_TERM,
399
+ this._error_codes.COMMIT_BEFORE_INIT as number,
400
+ this._error_codes.COMMIT_AFTER_TERM as number,
395
401
  )
396
402
  ) {
397
403
  const result = await this.storeData(false);
@@ -574,11 +580,15 @@ export default abstract class BaseAPI implements IBaseAPI {
574
580
 
575
581
  for (let idx = 0; idx < structure.length; idx++) {
576
582
  const attribute = structure[idx];
583
+ if (!attribute) {
584
+ this.throwSCORMError(invalidErrorCode as number, invalidErrorMessage);
585
+ return global_constants.SCORM_FALSE;
586
+ }
577
587
 
578
588
  if (idx === structure.length - 1) {
579
589
  if (scorm2004 && attribute.substring(0, 8) === "{target=") {
580
590
  if (this.isInitialized()) {
581
- this.throwSCORMError(this._error_codes.READ_ONLY_ELEMENT);
591
+ this.throwSCORMError(this._error_codes.READ_ONLY_ELEMENT as number);
582
592
  } else {
583
593
  refObject = {
584
594
  ...refObject,
@@ -586,7 +596,7 @@ export default abstract class BaseAPI implements IBaseAPI {
586
596
  };
587
597
  }
588
598
  } else if (!this._checkObjectHasProperty(refObject, attribute)) {
589
- this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
599
+ this.throwSCORMError(invalidErrorCode as number, invalidErrorMessage);
590
600
  } else {
591
601
  if (
592
602
  stringMatches(CMIElement, "\\.correct_responses\\.\\d+") &&
@@ -603,12 +613,12 @@ export default abstract class BaseAPI implements IBaseAPI {
603
613
  } else {
604
614
  refObject = refObject[attribute];
605
615
  if (!refObject) {
606
- this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
616
+ this.throwSCORMError(invalidErrorCode as number, invalidErrorMessage);
607
617
  break;
608
618
  }
609
619
 
610
620
  if (refObject instanceof CMIArray) {
611
- const index = parseInt(structure[idx + 1], 10);
621
+ const index = parseInt(structure[idx + 1] || "0", 10);
612
622
 
613
623
  // SCO is trying to set an item on an array
614
624
  if (!isNaN(index)) {
@@ -626,7 +636,10 @@ export default abstract class BaseAPI implements IBaseAPI {
626
636
  foundFirstIndex = true;
627
637
 
628
638
  if (!newChild) {
629
- this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
639
+ this.throwSCORMError(
640
+ invalidErrorCode as number,
641
+ invalidErrorMessage,
642
+ );
630
643
  } else {
631
644
  if (refObject.initialized) newChild.initialize();
632
645
 
@@ -683,10 +696,18 @@ export default abstract class BaseAPI implements IBaseAPI {
683
696
  for (let idx = 0; idx < structure.length; idx++) {
684
697
  attribute = structure[idx];
685
698
 
699
+ if (!attribute) {
700
+ this.throwSCORMError(invalidErrorCode as number, invalidErrorMessage);
701
+ return;
702
+ }
703
+
686
704
  if (!scorm2004) {
687
705
  if (idx === structure.length - 1) {
688
706
  if (!this._checkObjectHasProperty(refObject, attribute)) {
689
- this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
707
+ this.throwSCORMError(
708
+ invalidErrorCode as number,
709
+ invalidErrorMessage,
710
+ );
690
711
  return;
691
712
  }
692
713
  }
@@ -701,19 +722,19 @@ export default abstract class BaseAPI implements IBaseAPI {
701
722
  );
702
723
  return refObject._isTargetValid(target);
703
724
  } else if (!this._checkObjectHasProperty(refObject, attribute)) {
704
- this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
725
+ this.throwSCORMError(invalidErrorCode as number, invalidErrorMessage);
705
726
  return;
706
727
  }
707
728
  }
708
729
 
709
730
  refObject = refObject[attribute];
710
731
  if (refObject === undefined) {
711
- this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
732
+ this.throwSCORMError(invalidErrorCode as number, invalidErrorMessage);
712
733
  break;
713
734
  }
714
735
 
715
736
  if (refObject instanceof CMIArray) {
716
- const index = parseInt(structure[idx + 1], 10);
737
+ const index = parseInt(structure[idx + 1] || "", 10);
717
738
 
718
739
  // SCO is trying to set an item on an array
719
740
  if (!isNaN(index)) {
@@ -723,7 +744,7 @@ export default abstract class BaseAPI implements IBaseAPI {
723
744
  refObject = item;
724
745
  } else {
725
746
  this.throwSCORMError(
726
- this._error_codes.VALUE_NOT_INITIALIZED,
747
+ this._error_codes.VALUE_NOT_INITIALIZED as number,
727
748
  uninitializedErrorMessage,
728
749
  );
729
750
  break;
@@ -738,9 +759,9 @@ export default abstract class BaseAPI implements IBaseAPI {
738
759
  if (refObject === null || refObject === undefined) {
739
760
  if (!scorm2004) {
740
761
  if (attribute === "_children") {
741
- this.throwSCORMError(this._error_codes.CHILDREN_ERROR);
762
+ this.throwSCORMError(this._error_codes.CHILDREN_ERROR as number);
742
763
  } else if (attribute === "_count") {
743
- this.throwSCORMError(this._error_codes.COUNT_ERROR);
764
+ this.throwSCORMError(this._error_codes.COUNT_ERROR as number);
744
765
  }
745
766
  }
746
767
  } else {
@@ -786,14 +807,14 @@ export default abstract class BaseAPI implements IBaseAPI {
786
807
 
787
808
  const listenerFunctions = listenerName.split(" ");
788
809
  for (let i = 0; i < listenerFunctions.length; i++) {
789
- const listenerSplit = listenerFunctions[i].split(".");
790
- if (listenerSplit.length === 0) return;
810
+ const listenerSplit = listenerFunctions[i]?.split(".");
811
+ if (!listenerSplit || listenerSplit.length === 0) return;
791
812
 
792
813
  const functionName = listenerSplit[0];
793
814
 
794
815
  let CMIElement = null;
795
816
  if (listenerSplit.length > 1) {
796
- CMIElement = listenerName.replace(functionName + ".", "");
817
+ CMIElement = listenerFunctions[i]?.replace(functionName + ".", "");
797
818
  }
798
819
 
799
820
  this.listenerArray.push({
@@ -822,14 +843,14 @@ export default abstract class BaseAPI implements IBaseAPI {
822
843
 
823
844
  const listenerFunctions = listenerName.split(" ");
824
845
  for (let i = 0; i < listenerFunctions.length; i++) {
825
- const listenerSplit = listenerFunctions[i].split(".");
826
- if (listenerSplit.length === 0) return;
846
+ const listenerSplit = listenerFunctions[i]?.split(".");
847
+ if (!listenerSplit || listenerSplit.length === 0) return;
827
848
 
828
849
  const functionName = listenerSplit[0];
829
850
 
830
851
  let CMIElement = null;
831
852
  if (listenerSplit.length > 1) {
832
- CMIElement = listenerName.replace(functionName + ".", "");
853
+ CMIElement = listenerFunctions[i]?.replace(functionName + ".", "");
833
854
  }
834
855
 
835
856
  const removeIndex = this.listenerArray.findIndex(
@@ -858,14 +879,14 @@ export default abstract class BaseAPI implements IBaseAPI {
858
879
  clear(listenerName: string) {
859
880
  const listenerFunctions = listenerName.split(" ");
860
881
  for (let i = 0; i < listenerFunctions.length; i++) {
861
- const listenerSplit = listenerFunctions[i].split(".");
862
- if (listenerSplit.length === 0) return;
882
+ const listenerSplit = listenerFunctions[i]?.split(".");
883
+ if (!listenerSplit || listenerSplit?.length === 0) return;
863
884
 
864
885
  const functionName = listenerSplit[0];
865
886
 
866
887
  let CMIElement = null;
867
888
  if (listenerSplit.length > 1) {
868
- CMIElement = listenerName.replace(functionName + ".", "");
889
+ CMIElement = listenerFunctions[i]?.replace(functionName + ".", "");
869
890
  }
870
891
 
871
892
  this.listenerArray = this.listenerArray.filter(
@@ -1120,7 +1141,7 @@ export default abstract class BaseAPI implements IBaseAPI {
1120
1141
  const api = this;
1121
1142
  const genericError: ResultObject = {
1122
1143
  result: global_constants.SCORM_FALSE,
1123
- errorCode: this.error_codes.GENERAL,
1144
+ errorCode: this.error_codes.GENERAL as number,
1124
1145
  };
1125
1146
 
1126
1147
  // if we are terminating the module or closing the browser window/tab, we need to make this fetch ASAP.
@@ -1145,8 +1166,9 @@ export default abstract class BaseAPI implements IBaseAPI {
1145
1166
  const response = await this.performFetch(url, params);
1146
1167
 
1147
1168
  return this.transformResponse(response);
1148
- } catch (e) {
1149
- this.apiLog("processHttpRequest", e, LogLevelEnum.ERROR);
1169
+ } catch (e: unknown) {
1170
+ const message = e instanceof Error ? e.message : String(e);
1171
+ this.apiLog("processHttpRequest", message, LogLevelEnum.ERROR);
1150
1172
  api.processListeners("CommitError");
1151
1173
  return genericError;
1152
1174
  }
@@ -1217,7 +1239,7 @@ export default abstract class BaseAPI implements IBaseAPI {
1217
1239
  } else {
1218
1240
  console.error(e);
1219
1241
  }
1220
- this.throwSCORMError(this._error_codes.GENERAL);
1242
+ this.throwSCORMError(this._error_codes.GENERAL as number);
1221
1243
  }
1222
1244
  return returnValue;
1223
1245
  }
package/src/Scorm12API.ts CHANGED
@@ -277,9 +277,10 @@ class Scorm12Impl extends BaseAPI {
277
277
  errorNumber = String(errorNumber);
278
278
  if (scorm12_constants.error_descriptions[errorNumber]) {
279
279
  basicMessage =
280
- scorm12_constants.error_descriptions[errorNumber].basicMessage;
280
+ scorm12_constants.error_descriptions[errorNumber]?.basicMessage ||
281
+ "General Error";
281
282
  detailMessage =
282
- scorm12_constants.error_descriptions[errorNumber].detailMessage;
283
+ scorm12_constants.error_descriptions[errorNumber]?.detailMessage || "";
283
284
  }
284
285
 
285
286
  return detail ? detailMessage : basicMessage;
@@ -161,8 +161,8 @@ class Scorm2004Impl extends BaseAPI {
161
161
  const matches = CMIElement.match(adlNavRequestRegex);
162
162
  if (matches) {
163
163
  const request = matches[1];
164
- const target = matches[2].replace("{target=", "").replace("}", "");
165
- if (request === "choice" || request === "jump") {
164
+ const target = matches[2]?.replace("{target=", "").replace("}", "");
165
+ if (target && (request === "choice" || request === "jump")) {
166
166
  if (this.settings.scoItemIdValidator) {
167
167
  return String(this.settings.scoItemIdValidator(target));
168
168
  }
@@ -354,7 +354,9 @@ class Scorm2004Impl extends BaseAPI {
354
354
 
355
355
  if (this.isInitialized()) {
356
356
  if (!interaction.type) {
357
- this.throwSCORMError(scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED);
357
+ this.throwSCORMError(
358
+ scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED as number,
359
+ );
358
360
  } else {
359
361
  this.checkDuplicateChoiceResponse(interaction, value);
360
362
  const response_type = CorrectResponses[interaction.type];
@@ -362,7 +364,7 @@ class Scorm2004Impl extends BaseAPI {
362
364
  this.checkValidResponseType(response_type, value, interaction.type);
363
365
  } else {
364
366
  this.throwSCORMError(
365
- scorm2004_errors.GENERAL_SET_FAILURE,
367
+ scorm2004_errors.GENERAL_SET_FAILURE as number,
366
368
  "Incorrect Response Type: " + interaction.type,
367
369
  );
368
370
  }
@@ -398,7 +400,7 @@ class Scorm2004Impl extends BaseAPI {
398
400
  this.checkCorrectResponseValue(interaction_type, nodes, value);
399
401
  } else if (nodes.length > response_type.max) {
400
402
  this.throwSCORMError(
401
- scorm2004_errors.GENERAL_SET_FAILURE,
403
+ scorm2004_errors.GENERAL_SET_FAILURE as number,
402
404
  "Data Model Element Pattern Too Long",
403
405
  );
404
406
  }
@@ -419,7 +421,7 @@ class Scorm2004Impl extends BaseAPI {
419
421
  ) {
420
422
  const response = interaction.correct_responses.childArray[i];
421
423
  if (response.pattern === value) {
422
- this.throwSCORMError(scorm2004_errors.GENERAL_SET_FAILURE);
424
+ this.throwSCORMError(scorm2004_errors.GENERAL_SET_FAILURE as number);
423
425
  }
424
426
  }
425
427
  }
@@ -441,8 +443,9 @@ class Scorm2004Impl extends BaseAPI {
441
443
 
442
444
  const response_type = CorrectResponses[interaction.type];
443
445
  if (
444
- typeof response_type.limit === "undefined" ||
445
- interaction_count <= response_type.limit
446
+ typeof response_type !== "undefined" &&
447
+ (typeof response_type.limit === "undefined" ||
448
+ interaction_count <= response_type.limit)
446
449
  ) {
447
450
  this.checkValidResponseType(response_type, value, interaction.type);
448
451
 
@@ -460,14 +463,14 @@ class Scorm2004Impl extends BaseAPI {
460
463
  } else {
461
464
  if (this.lastErrorCode === "0") {
462
465
  this.throwSCORMError(
463
- scorm2004_errors.GENERAL_SET_FAILURE,
466
+ scorm2004_errors.GENERAL_SET_FAILURE as number,
464
467
  "Data Model Element Pattern Already Exists",
465
468
  );
466
469
  }
467
470
  }
468
471
  } else {
469
472
  this.throwSCORMError(
470
- scorm2004_errors.GENERAL_SET_FAILURE,
473
+ scorm2004_errors.GENERAL_SET_FAILURE as number,
471
474
  "Data Model Element Collection Limit Reached",
472
475
  );
473
476
  }
@@ -501,9 +504,11 @@ class Scorm2004Impl extends BaseAPI {
501
504
  errorNumber = String(errorNumber);
502
505
  if (scorm2004_constants.error_descriptions[errorNumber]) {
503
506
  basicMessage =
504
- scorm2004_constants.error_descriptions[errorNumber].basicMessage;
507
+ scorm2004_constants.error_descriptions[errorNumber]?.basicMessage ||
508
+ "Unknown Error";
505
509
  detailMessage =
506
- scorm2004_constants.error_descriptions[errorNumber].detailMessage;
510
+ scorm2004_constants.error_descriptions[errorNumber]?.detailMessage ||
511
+ "";
507
512
  }
508
513
 
509
514
  return detail ? detailMessage : basicMessage;
@@ -543,7 +548,7 @@ class Scorm2004Impl extends BaseAPI {
543
548
  value: any,
544
549
  ) {
545
550
  const response = CorrectResponses[interaction_type];
546
- const formatRegex = new RegExp(response.format);
551
+ const formatRegex = new RegExp(response?.format || ".*");
547
552
  for (let i = 0; i < nodes.length && this.lastErrorCode === "0"; i++) {
548
553
  if (
549
554
  interaction_type.match(
@@ -558,17 +563,17 @@ class Scorm2004Impl extends BaseAPI {
558
563
  if (values.length === 2) {
559
564
  const matches = values[0].match(formatRegex);
560
565
  if (!matches) {
561
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
566
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
562
567
  } else {
563
568
  if (
564
569
  !response.format2 ||
565
570
  !values[1].match(new RegExp(response.format2))
566
571
  ) {
567
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
572
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
568
573
  }
569
574
  }
570
575
  } else {
571
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
576
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
572
577
  }
573
578
  } else {
574
579
  const matches = nodes[i].match(formatRegex);
@@ -576,17 +581,19 @@ class Scorm2004Impl extends BaseAPI {
576
581
  (!matches && value !== "") ||
577
582
  (!matches && interaction_type === "true-false")
578
583
  ) {
579
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
584
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
580
585
  } else {
581
586
  if (interaction_type === "numeric" && nodes.length > 1) {
582
587
  if (Number(nodes[0]) > Number(nodes[1])) {
583
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
588
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
584
589
  }
585
590
  } else {
586
- if (nodes[i] !== "" && response.unique) {
591
+ if (nodes[i] !== "" && response?.unique) {
587
592
  for (let j = 0; j < i && this.lastErrorCode === "0"; j++) {
588
593
  if (nodes[i] === nodes[j]) {
589
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
594
+ this.throwSCORMError(
595
+ scorm2004_errors.TYPE_MISMATCH as number,
596
+ );
590
597
  }
591
598
  }
592
599
  }
@@ -619,7 +626,7 @@ class Scorm2004Impl extends BaseAPI {
619
626
  const lang = langMatches[3];
620
627
  if (lang !== undefined && lang.length > 0) {
621
628
  if (!ValidLanguages.includes(lang.toLowerCase())) {
622
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
629
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
623
630
  }
624
631
  }
625
632
  }
@@ -628,7 +635,7 @@ class Scorm2004Impl extends BaseAPI {
628
635
  case "case_matters":
629
636
  if (!seenLang && !seenOrder && !seenCase) {
630
637
  if (matches[3] !== "true" && matches[3] !== "false") {
631
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
638
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
632
639
  }
633
640
  }
634
641
 
@@ -637,14 +644,14 @@ class Scorm2004Impl extends BaseAPI {
637
644
  case "order_matters":
638
645
  if (!seenCase && !seenLang && !seenOrder) {
639
646
  if (matches[3] !== "true" && matches[3] !== "false") {
640
- this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
647
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH as number);
641
648
  }
642
649
  }
643
650
 
644
651
  seenOrder = true;
645
652
  break;
646
653
  }
647
- node = node.substring(matches[1].length);
654
+ node = node.substring(matches[1]?.length || 0);
648
655
  matches = node.match(prefixRegex);
649
656
  }
650
657
 
@@ -35,9 +35,9 @@ export class CMIAttemptRecordsObject extends BaseCMI {
35
35
  this.score = new CMIScore({
36
36
  score_children: aicc_constants.score_children,
37
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,
38
+ invalidErrorCode: scorm12_errors.INVALID_SET_VALUE as number,
39
+ invalidTypeCode: scorm12_errors.TYPE_MISMATCH as number,
40
+ invalidRangeCode: scorm12_errors.VALUE_OUT_OF_RANGE as number,
41
41
  errorClass: AICCValidationError,
42
42
  });
43
43
  }
@@ -20,9 +20,9 @@ export class CMICore extends BaseCMI {
20
20
  this.score = new CMIScore({
21
21
  score_children: scorm12_constants.score_children,
22
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,
23
+ invalidErrorCode: scorm12_errors.INVALID_SET_VALUE as number,
24
+ invalidTypeCode: scorm12_errors.TYPE_MISMATCH as number,
25
+ invalidRangeCode: scorm12_errors.VALUE_OUT_OF_RANGE as number,
26
26
  errorClass: Scorm12ValidationError,
27
27
  });
28
28
  }
@@ -83,7 +83,9 @@ export class CMICore extends BaseCMI {
83
83
  * @private
84
84
  */
85
85
  set _children(_children: string) {
86
- throw new Scorm12ValidationError(scorm12_errors.INVALID_SET_VALUE);
86
+ throw new Scorm12ValidationError(
87
+ scorm12_errors.INVALID_SET_VALUE as number,
88
+ );
87
89
  }
88
90
 
89
91
  /**
@@ -100,7 +102,9 @@ export class CMICore extends BaseCMI {
100
102
  */
101
103
  set student_id(student_id: string) {
102
104
  if (this.initialized) {
103
- throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
105
+ throw new Scorm12ValidationError(
106
+ scorm12_errors.READ_ONLY_ELEMENT as number,
107
+ );
104
108
  } else {
105
109
  this._student_id = student_id;
106
110
  }
@@ -120,7 +124,9 @@ export class CMICore extends BaseCMI {
120
124
  */
121
125
  set student_name(student_name: string) {
122
126
  if (this.initialized) {
123
- throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
127
+ throw new Scorm12ValidationError(
128
+ scorm12_errors.READ_ONLY_ELEMENT as number,
129
+ );
124
130
  } else {
125
131
  this._student_name = student_name;
126
132
  }
@@ -158,7 +164,9 @@ export class CMICore extends BaseCMI {
158
164
  */
159
165
  set credit(credit: string) {
160
166
  if (this.initialized) {
161
- throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
167
+ throw new Scorm12ValidationError(
168
+ scorm12_errors.READ_ONLY_ELEMENT as number,
169
+ );
162
170
  } else {
163
171
  this._credit = credit;
164
172
  }
@@ -202,7 +210,9 @@ export class CMICore extends BaseCMI {
202
210
  */
203
211
  set entry(entry: string) {
204
212
  if (this.initialized) {
205
- throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
213
+ throw new Scorm12ValidationError(
214
+ scorm12_errors.READ_ONLY_ELEMENT as number,
215
+ );
206
216
  } else {
207
217
  this._entry = entry;
208
218
  }
@@ -222,7 +232,9 @@ export class CMICore extends BaseCMI {
222
232
  */
223
233
  set total_time(total_time: string) {
224
234
  if (this.initialized) {
225
- throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
235
+ throw new Scorm12ValidationError(
236
+ scorm12_errors.READ_ONLY_ELEMENT as number,
237
+ );
226
238
  } else {
227
239
  this._total_time = total_time;
228
240
  }
@@ -242,7 +254,9 @@ export class CMICore extends BaseCMI {
242
254
  */
243
255
  set lesson_mode(lesson_mode: string) {
244
256
  if (this.initialized) {
245
- throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
257
+ throw new Scorm12ValidationError(
258
+ scorm12_errors.READ_ONLY_ELEMENT as number,
259
+ );
246
260
  } else {
247
261
  this._lesson_mode = lesson_mode;
248
262
  }
@@ -254,7 +268,9 @@ export class CMICore extends BaseCMI {
254
268
  */
255
269
  get exit(): string {
256
270
  if (!this.jsonString) {
257
- throw new Scorm12ValidationError(scorm12_errors.WRITE_ONLY_ELEMENT);
271
+ throw new Scorm12ValidationError(
272
+ scorm12_errors.WRITE_ONLY_ELEMENT as number,
273
+ );
258
274
  }
259
275
  return this._exit;
260
276
  }
@@ -275,7 +291,9 @@ export class CMICore extends BaseCMI {
275
291
  */
276
292
  get session_time(): string {
277
293
  if (!this.jsonString) {
278
- throw new Scorm12ValidationError(scorm12_errors.WRITE_ONLY_ELEMENT);
294
+ throw new Scorm12ValidationError(
295
+ scorm12_errors.WRITE_ONLY_ELEMENT as number,
296
+ );
279
297
  }
280
298
  return this._session_time;
281
299
  }
@@ -63,7 +63,7 @@ class CMIEvaluationComments extends CMIArray {
63
63
  constructor() {
64
64
  super({
65
65
  children: aicc_constants.comments_children,
66
- errorCode: scorm12_errors.INVALID_SET_VALUE,
66
+ errorCode: scorm12_errors.INVALID_SET_VALUE as number,
67
67
  errorClass: AICCValidationError,
68
68
  });
69
69
  }
@@ -56,7 +56,7 @@ export class AICCCMIStudentData extends CMIStudentData {
56
56
  */
57
57
  set tries_during_lesson(tries_during_lesson: string) {
58
58
  if (this.initialized) {
59
- throw new AICCValidationError(scorm12_errors.READ_ONLY_ELEMENT);
59
+ throw new AICCValidationError(scorm12_errors.READ_ONLY_ELEMENT as number);
60
60
  } else {
61
61
  this._tries_during_lesson = tries_during_lesson;
62
62
  }