scorm-again 2.6.3 → 2.6.5

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 (73) hide show
  1. package/.claude/.claude/settings.local.json +13 -0
  2. package/.claude/settings.local.json +33 -0
  3. package/dist/aicc.js +38 -22
  4. package/dist/aicc.js.map +1 -1
  5. package/dist/aicc.min.js +1 -1
  6. package/dist/aicc.min.js.map +1 -1
  7. package/dist/esm/aicc.js +38 -22
  8. package/dist/esm/aicc.js.map +1 -1
  9. package/dist/esm/aicc.min.js +1 -1
  10. package/dist/esm/aicc.min.js.map +1 -1
  11. package/dist/esm/scorm-again.js +79 -47
  12. package/dist/esm/scorm-again.js.map +1 -1
  13. package/dist/esm/scorm-again.min.js +1 -1
  14. package/dist/esm/scorm-again.min.js.map +1 -1
  15. package/dist/esm/scorm12.js +35 -20
  16. package/dist/esm/scorm12.js.map +1 -1
  17. package/dist/esm/scorm12.min.js +1 -1
  18. package/dist/esm/scorm12.min.js.map +1 -1
  19. package/dist/esm/scorm2004.js +69 -41
  20. package/dist/esm/scorm2004.js.map +1 -1
  21. package/dist/esm/scorm2004.min.js +1 -1
  22. package/dist/esm/scorm2004.min.js.map +1 -1
  23. package/dist/scorm-again.js +79 -47
  24. package/dist/scorm-again.js.map +1 -1
  25. package/dist/scorm-again.min.js +1 -1
  26. package/dist/scorm-again.min.js.map +1 -1
  27. package/dist/scorm12.js +35 -20
  28. package/dist/scorm12.js.map +1 -1
  29. package/dist/scorm12.min.js +1 -1
  30. package/dist/scorm12.min.js.map +1 -1
  31. package/dist/scorm2004.js +69 -41
  32. package/dist/scorm2004.js.map +1 -1
  33. package/dist/scorm2004.min.js +1 -1
  34. package/dist/scorm2004.min.js.map +1 -1
  35. package/dist/types/cmi/scorm2004/adl.d.ts +8 -2
  36. package/dist/types/cmi/scorm2004/cmi.d.ts +1 -1
  37. package/package.json +1 -1
  38. package/src/BaseAPI.ts +56 -33
  39. package/src/Scorm12API.ts +3 -2
  40. package/src/Scorm2004API.ts +31 -24
  41. package/src/cmi/aicc/attempts.ts +3 -3
  42. package/src/cmi/aicc/core.ts +30 -12
  43. package/src/cmi/aicc/evaluation.ts +1 -1
  44. package/src/cmi/aicc/student_data.ts +1 -1
  45. package/src/cmi/aicc/student_demographics.ts +13 -13
  46. package/src/cmi/aicc/student_preferences.ts +1 -1
  47. package/src/cmi/aicc/tries.ts +3 -3
  48. package/src/cmi/aicc/validation.ts +1 -1
  49. package/src/cmi/common/array.ts +1 -1
  50. package/src/cmi/common/score.ts +3 -3
  51. package/src/cmi/common/validation.ts +2 -2
  52. package/src/cmi/scorm12/cmi.ts +12 -4
  53. package/src/cmi/scorm12/interactions.ts +27 -11
  54. package/src/cmi/scorm12/objectives.ts +4 -4
  55. package/src/cmi/scorm12/student_data.ts +12 -4
  56. package/src/cmi/scorm12/student_preference.ts +3 -1
  57. package/src/cmi/scorm12/validation.ts +5 -3
  58. package/src/cmi/scorm2004/adl.ts +39 -22
  59. package/src/cmi/scorm2004/cmi.ts +47 -17
  60. package/src/cmi/scorm2004/comments.ts +11 -5
  61. package/src/cmi/scorm2004/interactions.ts +25 -23
  62. package/src/cmi/scorm2004/learner_preference.ts +3 -1
  63. package/src/cmi/scorm2004/objectives.ts +5 -5
  64. package/src/cmi/scorm2004/score.ts +3 -3
  65. package/src/cmi/scorm2004/validation.ts +2 -2
  66. package/src/exceptions/aicc_exceptions.ts +4 -4
  67. package/src/exceptions/scorm12_exceptions.ts +4 -4
  68. package/src/exceptions/scorm2004_exceptions.ts +4 -4
  69. package/src/utilities.ts +3 -3
  70. package/test/BaseAPI.requestHandler.spec.ts +126 -0
  71. package/test/Scorm12API.spec.ts +45 -0
  72. package/test/Scorm2004API.spec.ts +43 -0
  73. package/tsconfig.json +1 -0
package/dist/scorm2004.js CHANGED
@@ -417,6 +417,10 @@ var BaseAPI = (function () {
417
417
  : this._error_codes.GENERAL;
418
418
  for (var idx = 0; idx < structure.length; idx++) {
419
419
  var attribute = structure[idx];
420
+ if (!attribute) {
421
+ this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
422
+ return api_constants.global_constants.SCORM_FALSE;
423
+ }
420
424
  if (idx === structure.length - 1) {
421
425
  if (scorm2004 && attribute.substring(0, 8) === "{target=") {
422
426
  if (this.isInitialized()) {
@@ -447,7 +451,7 @@ var BaseAPI = (function () {
447
451
  break;
448
452
  }
449
453
  if (refObject instanceof array.CMIArray) {
450
- var index = parseInt(structure[idx + 1], 10);
454
+ var index = parseInt(structure[idx + 1] || "0", 10);
451
455
  if (!isNaN(index)) {
452
456
  var item = refObject.childArray[index];
453
457
  if (item) {
@@ -491,6 +495,10 @@ var BaseAPI = (function () {
491
495
  : this._error_codes.GENERAL;
492
496
  for (var idx = 0; idx < structure.length; idx++) {
493
497
  attribute = structure[idx];
498
+ if (!attribute) {
499
+ this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
500
+ return;
501
+ }
494
502
  if (!scorm2004) {
495
503
  if (idx === structure.length - 1) {
496
504
  if (!this._checkObjectHasProperty(refObject, attribute)) {
@@ -516,7 +524,7 @@ var BaseAPI = (function () {
516
524
  break;
517
525
  }
518
526
  if (refObject instanceof array.CMIArray) {
519
- var index = parseInt(structure[idx + 1], 10);
527
+ var index = parseInt(structure[idx + 1] || "", 10);
520
528
  if (!isNaN(index)) {
521
529
  var item = refObject.childArray[index];
522
530
  if (item) {
@@ -554,17 +562,18 @@ var BaseAPI = (function () {
554
562
  return this.currentState === api_constants.global_constants.STATE_TERMINATED;
555
563
  };
556
564
  BaseAPI.prototype.on = function (listenerName, callback) {
565
+ var _a, _c;
557
566
  if (!callback)
558
567
  return;
559
568
  var listenerFunctions = listenerName.split(" ");
560
569
  for (var i = 0; i < listenerFunctions.length; i++) {
561
- var listenerSplit = listenerFunctions[i].split(".");
562
- if (listenerSplit.length === 0)
570
+ var listenerSplit = (_a = listenerFunctions[i]) === null || _a === void 0 ? void 0 : _a.split(".");
571
+ if (!listenerSplit || listenerSplit.length === 0)
563
572
  return;
564
573
  var functionName = listenerSplit[0];
565
574
  var CMIElement = null;
566
575
  if (listenerSplit.length > 1) {
567
- CMIElement = listenerName.replace(functionName + ".", "");
576
+ CMIElement = (_c = listenerFunctions[i]) === null || _c === void 0 ? void 0 : _c.replace(functionName + ".", "");
568
577
  }
569
578
  this.listenerArray.push({
570
579
  functionName: functionName,
@@ -575,17 +584,18 @@ var BaseAPI = (function () {
575
584
  }
576
585
  };
577
586
  BaseAPI.prototype.off = function (listenerName, callback) {
587
+ var _a, _c;
578
588
  if (!callback)
579
589
  return;
580
590
  var listenerFunctions = listenerName.split(" ");
581
591
  var _loop_1 = function (i) {
582
- var listenerSplit = listenerFunctions[i].split(".");
583
- if (listenerSplit.length === 0)
592
+ var listenerSplit = (_a = listenerFunctions[i]) === null || _a === void 0 ? void 0 : _a.split(".");
593
+ if (!listenerSplit || listenerSplit.length === 0)
584
594
  return { value: void 0 };
585
595
  var functionName = listenerSplit[0];
586
596
  var CMIElement = null;
587
597
  if (listenerSplit.length > 1) {
588
- CMIElement = listenerName.replace(functionName + ".", "");
598
+ CMIElement = (_c = listenerFunctions[i]) === null || _c === void 0 ? void 0 : _c.replace(functionName + ".", "");
589
599
  }
590
600
  var removeIndex = this_1.listenerArray.findIndex(function (obj) {
591
601
  return obj.functionName === functionName &&
@@ -605,15 +615,16 @@ var BaseAPI = (function () {
605
615
  }
606
616
  };
607
617
  BaseAPI.prototype.clear = function (listenerName) {
618
+ var _a, _c;
608
619
  var listenerFunctions = listenerName.split(" ");
609
620
  var _loop_2 = function (i) {
610
- var listenerSplit = listenerFunctions[i].split(".");
611
- if (listenerSplit.length === 0)
621
+ var listenerSplit = (_a = listenerFunctions[i]) === null || _a === void 0 ? void 0 : _a.split(".");
622
+ if (!listenerSplit || (listenerSplit === null || listenerSplit === void 0 ? void 0 : listenerSplit.length) === 0)
612
623
  return { value: void 0 };
613
624
  var functionName = listenerSplit[0];
614
625
  var CMIElement = null;
615
626
  if (listenerSplit.length > 1) {
616
- CMIElement = listenerName.replace(functionName + ".", "");
627
+ CMIElement = (_c = listenerFunctions[i]) === null || _c === void 0 ? void 0 : _c.replace(functionName + ".", "");
617
628
  }
618
629
  this_2.listenerArray = this_2.listenerArray.filter(function (obj) {
619
630
  return obj.functionName !== functionName && obj.CMIElement !== CMIElement;
@@ -780,6 +791,7 @@ var BaseAPI = (function () {
780
791
  errorCode: this.error_codes.GENERAL,
781
792
  };
782
793
  if (immediate) {
794
+ params = this.settings.requestHandler(params);
783
795
  this.performFetch(url, params).then(function (response) { return (0,tslib_es6.__awaiter)(_this, void 0, void 0, function () {
784
796
  return (0,tslib_es6.__generator)(this, function (_a) {
785
797
  switch (_a.label) {
@@ -1182,8 +1194,8 @@ function checkValidFormat(value, regexPattern, errorCode, errorClass, allowEmpty
1182
1194
  function checkValidRange(value, rangePattern, errorCode, errorClass) {
1183
1195
  var ranges = rangePattern.split("#");
1184
1196
  value = value * 1.0;
1185
- if (value >= ranges[0]) {
1186
- if (ranges[1] === "*" || value <= ranges[1]) {
1197
+ if (ranges[0] && value >= ranges[0]) {
1198
+ if (ranges[1] && (ranges[1] === "*" || value <= ranges[1])) {
1187
1199
  return true;
1188
1200
  }
1189
1201
  else {
@@ -1693,7 +1705,7 @@ function getSecondsAsISODuration(seconds) {
1693
1705
  var duration = "P";
1694
1706
  var remainder = seconds;
1695
1707
  for (var designationsKey in designations) {
1696
- var current_seconds = designations[designationsKey];
1708
+ var current_seconds = designations[designationsKey] || 1;
1697
1709
  var value = Math.floor(remainder / current_seconds);
1698
1710
  remainder = remainder % current_seconds;
1699
1711
  if (countDecimals(remainder) > 2) {
@@ -1800,7 +1812,7 @@ function unflatten(data) {
1800
1812
  var m = regex.exec(p);
1801
1813
  while (m) {
1802
1814
  cur = cur[prop] || (cur[prop] = m[2] ? [] : {});
1803
- prop = m[2] || m[1];
1815
+ prop = m[2] || m[1] || "";
1804
1816
  m = regex.exec(p);
1805
1817
  }
1806
1818
  cur[prop] = data[p];
@@ -1812,7 +1824,7 @@ function countDecimals(num) {
1812
1824
  if (Math.floor(num) === num || String(num).indexOf(".") < 0)
1813
1825
  return 0;
1814
1826
  var parts = num.toString().split(".")[1];
1815
- return parts.length || 0;
1827
+ return (parts === null || parts === void 0 ? void 0 : parts.length) || 0;
1816
1828
  }
1817
1829
  function formatMessage(functionName, message, CMIElement) {
1818
1830
  var baseLength = 20;
@@ -2348,11 +2360,12 @@ var Scorm2004ValidationError = (function (_super) {
2348
2360
  (0,tslib_es6.__extends)(Scorm2004ValidationError, _super);
2349
2361
  function Scorm2004ValidationError(errorCode) {
2350
2362
  var _this = this;
2363
+ var _a, _b, _c, _d;
2351
2364
  if ({}.hasOwnProperty.call(scorm2004_errors, String(errorCode))) {
2352
- _this = _super.call(this, errorCode, scorm2004_errors[String(errorCode)].basicMessage, scorm2004_errors[String(errorCode)].detailMessage) || this;
2365
+ _this = _super.call(this, errorCode, ((_a = scorm2004_errors[String(errorCode)]) === null || _a === void 0 ? void 0 : _a.basicMessage) || "Unknown error", (_b = scorm2004_errors[String(errorCode)]) === null || _b === void 0 ? void 0 : _b.detailMessage) || this;
2353
2366
  }
2354
2367
  else {
2355
- _this = _super.call(this, 101, scorm2004_errors["101"].basicMessage, scorm2004_errors["101"].detailMessage) || this;
2368
+ _this = _super.call(this, 101, ((_c = scorm2004_errors["101"]) === null || _c === void 0 ? void 0 : _c.basicMessage) || "General error", (_d = scorm2004_errors["101"]) === null || _d === void 0 ? void 0 : _d.detailMessage) || this;
2356
2369
  }
2357
2370
  return _this;
2358
2371
  }
@@ -2768,6 +2781,7 @@ var CMIInteractionsObject = (function (_super) {
2768
2781
  return this._learner_response;
2769
2782
  },
2770
2783
  set: function (learner_response) {
2784
+ var _a, _b, _c, _d;
2771
2785
  if (this.initialized && (this._type === "" || this._id === "")) {
2772
2786
  throw new Scorm2004ValidationError(error_codes.scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED);
2773
2787
  }
@@ -2785,14 +2799,14 @@ var CMIInteractionsObject = (function (_super) {
2785
2799
  var formatRegex = new RegExp(response_type.format);
2786
2800
  for (var i = 0; i < nodes.length; i++) {
2787
2801
  if (response_type === null || response_type === void 0 ? void 0 : response_type.delimiter2) {
2788
- var values = nodes[i].split(response_type.delimiter2);
2789
- if (values.length === 2) {
2790
- if (!values[0].match(formatRegex)) {
2802
+ var values = (_a = nodes[i]) === null || _a === void 0 ? void 0 : _a.split(response_type.delimiter2);
2803
+ if ((values === null || values === void 0 ? void 0 : values.length) === 2) {
2804
+ if (!((_b = values[0]) === null || _b === void 0 ? void 0 : _b.match(formatRegex))) {
2791
2805
  throw new Scorm2004ValidationError(error_codes.scorm2004_errors.TYPE_MISMATCH);
2792
2806
  }
2793
2807
  else {
2794
2808
  if (!response_type.format2 ||
2795
- !values[1].match(new RegExp(response_type.format2))) {
2809
+ !((_c = values[1]) === null || _c === void 0 ? void 0 : _c.match(new RegExp(response_type.format2)))) {
2796
2810
  throw new Scorm2004ValidationError(error_codes.scorm2004_errors.TYPE_MISMATCH);
2797
2811
  }
2798
2812
  }
@@ -2802,7 +2816,7 @@ var CMIInteractionsObject = (function (_super) {
2802
2816
  }
2803
2817
  }
2804
2818
  else {
2805
- if (!nodes[i].match(formatRegex)) {
2819
+ if (!((_d = nodes[i]) === null || _d === void 0 ? void 0 : _d.match(formatRegex))) {
2806
2820
  throw new Scorm2004ValidationError(error_codes.scorm2004_errors.TYPE_MISMATCH);
2807
2821
  }
2808
2822
  else {
@@ -4280,10 +4294,14 @@ var ADLNavRequestValid = (function (_super) {
4280
4294
  }
4281
4295
  for (var key in choice) {
4282
4296
  if ({}.hasOwnProperty.call(choice, key)) {
4283
- if (check2004ValidFormat(choice[key], regex.scorm2004_regex.NAVBoolean) &&
4284
- check2004ValidFormat(key, regex.scorm2004_regex.NAVTarget)) {
4285
- this._choice[key] =
4286
- enums.NAVBoolean[choice[key]];
4297
+ if (choice[key] !== undefined && check2004ValidFormat(key, regex.scorm2004_regex.NAVTarget)) {
4298
+ var value = choice[key];
4299
+ if (typeof value === 'string' && check2004ValidFormat(value, regex.scorm2004_regex.NAVBoolean)) {
4300
+ this._choice[key] = enums.NAVBoolean[value];
4301
+ }
4302
+ else if (Object.values(enums.NAVBoolean).includes(value)) {
4303
+ this._choice[key] = value;
4304
+ }
4287
4305
  }
4288
4306
  }
4289
4307
  }
@@ -4304,9 +4322,14 @@ var ADLNavRequestValid = (function (_super) {
4304
4322
  }
4305
4323
  for (var key in jump) {
4306
4324
  if ({}.hasOwnProperty.call(jump, key)) {
4307
- if (check2004ValidFormat(jump[key], regex.scorm2004_regex.NAVBoolean) &&
4308
- check2004ValidFormat(key, regex.scorm2004_regex.NAVTarget)) {
4309
- this._jump[key] = enums.NAVBoolean[jump[key]];
4325
+ if (jump[key] !== undefined && check2004ValidFormat(key, regex.scorm2004_regex.NAVTarget)) {
4326
+ var value = jump[key];
4327
+ if (typeof value === 'string' && check2004ValidFormat(value, regex.scorm2004_regex.NAVBoolean)) {
4328
+ this._jump[key] = enums.NAVBoolean[value];
4329
+ }
4330
+ else if (Object.values(enums.NAVBoolean).includes(value)) {
4331
+ this._jump[key] = value;
4332
+ }
4310
4333
  }
4311
4334
  }
4312
4335
  }
@@ -4457,19 +4480,19 @@ var Scorm2004Impl = (function (_super) {
4457
4480
  });
4458
4481
  };
4459
4482
  Scorm2004Impl.prototype.lmsGetValue = function (CMIElement) {
4460
- var _a;
4483
+ var _a, _b;
4461
4484
  var adlNavRequestRegex = "^adl\\.nav\\.request_valid\\.(choice|jump)\\.{target=\\S{0,}([a-zA-Z0-9-_]+)}$";
4462
4485
  if ((0,utilities.stringMatches)(CMIElement, adlNavRequestRegex)) {
4463
4486
  var matches = CMIElement.match(adlNavRequestRegex);
4464
4487
  if (matches) {
4465
4488
  var request = matches[1];
4466
- var target = matches[2].replace("{target=", "").replace("}", "");
4467
- if (request === "choice" || request === "jump") {
4489
+ var target = (_a = matches[2]) === null || _a === void 0 ? void 0 : _a.replace("{target=", "").replace("}", "");
4490
+ if (target && (request === "choice" || request === "jump")) {
4468
4491
  if (this.settings.scoItemIdValidator) {
4469
4492
  return String(this.settings.scoItemIdValidator(target));
4470
4493
  }
4471
4494
  if (this.settings.scoItemIds) {
4472
- return String((_a = this.settings.scoItemIds) === null || _a === void 0 ? void 0 : _a.includes(target));
4495
+ return String((_b = this.settings.scoItemIds) === null || _b === void 0 ? void 0 : _b.includes(target));
4473
4496
  }
4474
4497
  return String(request);
4475
4498
  }
@@ -4623,8 +4646,9 @@ var Scorm2004Impl = (function (_super) {
4623
4646
  var interaction_count = interaction.correct_responses._count;
4624
4647
  this.checkDuplicateChoiceResponse(interaction, value);
4625
4648
  var response_type = CorrectResponses[interaction.type];
4626
- if (typeof response_type.limit === "undefined" ||
4627
- interaction_count <= response_type.limit) {
4649
+ if (typeof response_type !== "undefined" &&
4650
+ (typeof response_type.limit === "undefined" ||
4651
+ interaction_count <= response_type.limit)) {
4628
4652
  this.checkValidResponseType(response_type, value, interaction.type);
4629
4653
  if ((this.lastErrorCode === "0" &&
4630
4654
  (!response_type.duplicate ||
@@ -4645,14 +4669,17 @@ var Scorm2004Impl = (function (_super) {
4645
4669
  return this._commonGetCMIValue("GetValue", true, CMIElement);
4646
4670
  };
4647
4671
  Scorm2004Impl.prototype.getLmsErrorMessageDetails = function (errorNumber, detail) {
4672
+ var _a, _b;
4648
4673
  var basicMessage = "";
4649
4674
  var detailMessage = "";
4650
4675
  errorNumber = String(errorNumber);
4651
4676
  if (api_constants.scorm2004_constants.error_descriptions[errorNumber]) {
4652
4677
  basicMessage =
4653
- api_constants.scorm2004_constants.error_descriptions[errorNumber].basicMessage;
4678
+ ((_a = api_constants.scorm2004_constants.error_descriptions[errorNumber]) === null || _a === void 0 ? void 0 : _a.basicMessage) ||
4679
+ "Unknown Error";
4654
4680
  detailMessage =
4655
- api_constants.scorm2004_constants.error_descriptions[errorNumber].detailMessage;
4681
+ ((_b = api_constants.scorm2004_constants.error_descriptions[errorNumber]) === null || _b === void 0 ? void 0 : _b.detailMessage) ||
4682
+ "";
4656
4683
  }
4657
4684
  return detail ? detailMessage : basicMessage;
4658
4685
  };
@@ -4668,7 +4695,7 @@ var Scorm2004Impl = (function (_super) {
4668
4695
  };
4669
4696
  Scorm2004Impl.prototype.checkCorrectResponseValue = function (interaction_type, nodes, value) {
4670
4697
  var response = CorrectResponses[interaction_type];
4671
- var formatRegex = new RegExp(response.format);
4698
+ var formatRegex = new RegExp((response === null || response === void 0 ? void 0 : response.format) || ".*");
4672
4699
  for (var i = 0; i < nodes.length && this.lastErrorCode === "0"; i++) {
4673
4700
  if (interaction_type.match("^(fill-in|long-fill-in|matching|performance|sequencing)$")) {
4674
4701
  nodes[i] = this.removeCorrectResponsePrefixes(nodes[i]);
@@ -4704,7 +4731,7 @@ var Scorm2004Impl = (function (_super) {
4704
4731
  }
4705
4732
  }
4706
4733
  else {
4707
- if (nodes[i] !== "" && response.unique) {
4734
+ if (nodes[i] !== "" && (response === null || response === void 0 ? void 0 : response.unique)) {
4708
4735
  for (var j = 0; j < i && this.lastErrorCode === "0"; j++) {
4709
4736
  if (nodes[i] === nodes[j]) {
4710
4737
  this.throwSCORMError(error_codes.scorm2004_errors.TYPE_MISMATCH);
@@ -4717,6 +4744,7 @@ var Scorm2004Impl = (function (_super) {
4717
4744
  }
4718
4745
  };
4719
4746
  Scorm2004Impl.prototype.removeCorrectResponsePrefixes = function (node) {
4747
+ var _a;
4720
4748
  var seenOrder = false;
4721
4749
  var seenCase = false;
4722
4750
  var seenLang = false;
@@ -4754,7 +4782,7 @@ var Scorm2004Impl = (function (_super) {
4754
4782
  seenOrder = true;
4755
4783
  break;
4756
4784
  }
4757
- node = node.substring(matches[1].length);
4785
+ node = node.substring(((_a = matches[1]) === null || _a === void 0 ? void 0 : _a.length) || 0);
4758
4786
  matches = node.match(prefixRegex);
4759
4787
  }
4760
4788
  return node;