scorm-again 1.7.0 → 2.0.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.
Files changed (85) hide show
  1. package/.babelrc +18 -7
  2. package/.github/dependabot.yml +5 -0
  3. package/.github/workflows/main.yml +79 -0
  4. package/.jsdoc.json +4 -5
  5. package/.mocharc.json +8 -0
  6. package/.run/Mocha Unit Tests.run.xml +5 -2
  7. package/CONTRIBUTING.md +1 -1
  8. package/README.md +14 -1
  9. package/dist/aicc.js +3661 -7170
  10. package/dist/aicc.js.map +1 -1
  11. package/dist/aicc.min.js +2 -40
  12. package/dist/aicc.min.js.map +1 -0
  13. package/dist/scorm-again.js +5671 -10695
  14. package/dist/scorm-again.js.map +1 -1
  15. package/dist/scorm-again.min.js +2 -52
  16. package/dist/scorm-again.min.js.map +1 -0
  17. package/dist/scorm12.js +2871 -5433
  18. package/dist/scorm12.js.map +1 -1
  19. package/dist/scorm12.min.js +2 -34
  20. package/dist/scorm12.min.js.map +1 -0
  21. package/dist/scorm2004.js +3868 -6797
  22. package/dist/scorm2004.js.map +1 -1
  23. package/dist/scorm2004.min.js +2 -40
  24. package/dist/scorm2004.min.js.map +1 -0
  25. package/eslint.config.js +21 -0
  26. package/package.json +73 -35
  27. package/results.json +34254 -0
  28. package/src/{AICC.js → AICC.ts} +27 -21
  29. package/src/BaseAPI.ts +1449 -0
  30. package/src/Scorm12API.ts +360 -0
  31. package/src/{Scorm2004API.js → Scorm2004API.ts} +245 -163
  32. package/src/cmi/aicc_cmi.ts +1248 -0
  33. package/src/cmi/common.ts +411 -0
  34. package/src/cmi/scorm12_cmi.ts +1426 -0
  35. package/src/cmi/scorm2004_cmi.ts +1874 -0
  36. package/src/constants/api_constants.ts +318 -0
  37. package/src/constants/error_codes.ts +88 -0
  38. package/src/constants/language_constants.ts +394 -0
  39. package/src/constants/regex.ts +97 -0
  40. package/src/constants/{response_constants.js → response_constants.ts} +67 -62
  41. package/src/exceptions.ts +133 -0
  42. package/src/exports/aicc.js +1 -1
  43. package/src/exports/scorm-again.js +3 -3
  44. package/src/exports/scorm12.js +1 -1
  45. package/src/exports/scorm2004.js +1 -1
  46. package/src/{utilities.js → utilities.ts} +114 -74
  47. package/tea.yaml +6 -0
  48. package/test/{AICC.spec.js → AICC.spec.ts} +70 -72
  49. package/test/Scorm12API.spec.ts +580 -0
  50. package/test/Scorm2004API.spec.ts +812 -0
  51. package/test/api_helpers.ts +176 -0
  52. package/test/cmi/{aicc_cmi.spec.js → aicc_cmi.spec.ts} +193 -209
  53. package/test/cmi/{scorm12_cmi.spec.js → scorm12_cmi.spec.ts} +251 -269
  54. package/test/cmi/scorm2004_cmi.spec.ts +1031 -0
  55. package/test/cmi_helpers.ts +207 -0
  56. package/test/exceptions.spec.ts +79 -0
  57. package/test/field_values.ts +202 -0
  58. package/test/utilities.spec.ts +322 -0
  59. package/tsconfig.json +18 -0
  60. package/webpack.config.js +65 -0
  61. package/.circleci/config.yml +0 -99
  62. package/.codeclimate.yml +0 -7
  63. package/.eslintrc.js +0 -36
  64. package/src/.flowconfig +0 -11
  65. package/src/BaseAPI.js +0 -1275
  66. package/src/Scorm12API.js +0 -308
  67. package/src/cmi/aicc_cmi.js +0 -1141
  68. package/src/cmi/common.js +0 -328
  69. package/src/cmi/scorm12_cmi.js +0 -1312
  70. package/src/cmi/scorm2004_cmi.js +0 -1692
  71. package/src/constants/api_constants.js +0 -218
  72. package/src/constants/error_codes.js +0 -87
  73. package/src/constants/language_constants.js +0 -76
  74. package/src/constants/regex.js +0 -84
  75. package/src/exceptions.js +0 -104
  76. package/test/Scorm12API.spec.js +0 -528
  77. package/test/Scorm2004API.spec.js +0 -775
  78. package/test/abstract_classes.spec.js +0 -17
  79. package/test/api_helpers.js +0 -128
  80. package/test/cmi/scorm2004_cmi.spec.js +0 -1066
  81. package/test/cmi_helpers.js +0 -161
  82. package/test/exceptions.spec.js +0 -71
  83. package/test/field_values.js +0 -353
  84. package/test/utilities.spec.js +0 -339
  85. package/webpack.js +0 -78
@@ -1,5 +1,4 @@
1
- // @flow
2
- import BaseAPI from './BaseAPI';
1
+ import BaseAPI, { RefObject, ResultObject, Settings } from "./BaseAPI";
3
2
  import {
4
3
  ADL,
5
4
  CMI,
@@ -8,45 +7,46 @@ import {
8
7
  CMIInteractionsObject,
9
8
  CMIInteractionsObjectivesObject,
10
9
  CMIObjectivesObject,
11
- } from './cmi/scorm2004_cmi';
12
- import * as Utilities from './utilities';
13
- import APIConstants from './constants/api_constants';
14
- import ErrorCodes from './constants/error_codes';
15
- import Responses from './constants/response_constants';
16
- import ValidLanguages from './constants/language_constants';
17
- import Regex from './constants/regex';
10
+ } from "./cmi/scorm2004_cmi";
11
+ import * as Utilities from "./utilities";
12
+ import APIConstants from "./constants/api_constants";
13
+ import ErrorCodes from "./constants/error_codes";
14
+ import { CorrectResponses, ResponseType } from "./constants/response_constants";
15
+ import ValidLanguages from "./constants/language_constants";
16
+ import Regex from "./constants/regex";
17
+ import { BaseCMI, CMIArray } from "./cmi/common";
18
18
 
19
19
  const scorm2004_constants = APIConstants.scorm2004;
20
20
  const global_constants = APIConstants.global;
21
21
  const scorm2004_error_codes = ErrorCodes.scorm2004;
22
- const correct_responses = Responses.correct;
22
+ const correct_responses = CorrectResponses;
23
23
  const scorm2004_regex = Regex.scorm2004;
24
24
 
25
25
  /**
26
26
  * API class for SCORM 2004
27
27
  */
28
28
  export default class Scorm2004API extends BaseAPI {
29
- #version: '1.0';
29
+ private _version: string = "1.0";
30
30
 
31
31
  /**
32
32
  * Constructor for SCORM 2004 API
33
- * @param {object} settings
33
+ * @param {Settings} settings
34
34
  */
35
- constructor(settings: {}) {
36
- const finalSettings = {
37
- ...{
38
- mastery_override: false,
39
- }, ...settings,
40
- };
35
+ constructor(settings?: Settings) {
36
+ if (settings) {
37
+ if (settings.mastery_override === undefined) {
38
+ settings.mastery_override = false;
39
+ }
40
+ }
41
41
 
42
- super(scorm2004_error_codes, finalSettings);
42
+ super(scorm2004_error_codes, settings);
43
43
 
44
44
  this.cmi = new CMI();
45
45
  this.adl = new ADL();
46
46
 
47
47
  // Rename functions to match 2004 Spec and expose to modules
48
48
  this.Initialize = this.lmsInitialize;
49
- this.Terminate = this.lmsTerminate;
49
+ this.Terminate = this.lmsFinish;
50
50
  this.GetValue = this.lmsGetValue;
51
51
  this.SetValue = this.lmsSetValue;
52
52
  this.Commit = this.lmsCommit;
@@ -55,55 +55,67 @@ export default class Scorm2004API extends BaseAPI {
55
55
  this.GetDiagnostic = this.lmsGetDiagnostic;
56
56
  }
57
57
 
58
+ public cmi: CMI;
59
+ public adl: ADL;
60
+
61
+ public Initialize: () => string;
62
+ public Terminate: () => string;
63
+ public GetValue: (CMIElement: string) => string;
64
+ public SetValue: (CMIElement: string, value: any) => string;
65
+ public Commit: () => string;
66
+ public GetLastError: () => string;
67
+ public GetErrorString: (CMIErrorCode: string | number) => string;
68
+ public GetDiagnostic: (CMIErrorCode: string | number) => string;
69
+
58
70
  /**
59
- * Getter for #version
71
+ * Getter for _version
60
72
  * @return {string}
61
73
  */
62
- get version() {
63
- return this.#version;
74
+ get version(): string {
75
+ return this._version;
64
76
  }
65
77
 
66
78
  /**
67
79
  * @return {string} bool
68
80
  */
69
- lmsInitialize() {
81
+ lmsInitialize(): string {
70
82
  this.cmi.initialize();
71
- return this.initialize('Initialize');
83
+ return this.initialize("Initialize");
72
84
  }
73
85
 
74
86
  /**
75
87
  * @return {string} bool
76
88
  */
77
- lmsTerminate() {
78
- const result = this.terminate('Terminate', true);
89
+ lmsFinish(): string {
90
+ const result = this.terminate("Terminate", true);
79
91
 
80
92
  if (result === global_constants.SCORM_TRUE) {
81
- if (this.adl.nav.request !== '_none_') {
93
+ if (this.adl.nav.request !== "_none_") {
82
94
  switch (this.adl.nav.request) {
83
- case 'continue':
84
- this.processListeners('SequenceNext');
95
+ case "continue":
96
+ this.processListeners("SequenceNext");
85
97
  break;
86
- case 'previous':
87
- this.processListeners('SequencePrevious');
98
+ case "previous":
99
+ this.processListeners("SequencePrevious");
88
100
  break;
89
- case 'choice':
90
- this.processListeners('SequenceChoice');
101
+ case "choice":
102
+ this.processListeners("SequenceChoice");
91
103
  break;
92
- case 'exit':
93
- this.processListeners('SequenceExit');
104
+ case "exit":
105
+ this.processListeners("SequenceExit");
94
106
  break;
95
- case 'exitAll':
96
- this.processListeners('SequenceExitAll');
107
+ case "exitAll":
108
+ this.processListeners("SequenceExitAll");
97
109
  break;
98
- case 'abandon':
99
- this.processListeners('SequenceAbandon');
110
+ case "abandon":
111
+ this.processListeners("SequenceAbandon");
100
112
  break;
101
- case 'abandonAll':
102
- this.processListeners('SequenceAbandonAll');
113
+ case "abandonAll":
114
+ this.processListeners("SequenceAbandonAll");
103
115
  break;
104
116
  }
105
117
  } else if (this.settings.autoProgress) {
106
- this.processListeners('SequenceNext');
118
+ this.processListeners("SequenceNext");
107
119
  }
108
120
  }
109
121
 
@@ -114,8 +126,8 @@ export default class Scorm2004API extends BaseAPI {
114
126
  * @param {string} CMIElement
115
127
  * @return {string}
116
128
  */
117
- lmsGetValue(CMIElement) {
118
- return this.getValue('GetValue', true, CMIElement);
129
+ lmsGetValue(CMIElement: string): string {
130
+ return this.getValue("GetValue", true, CMIElement);
119
131
  }
120
132
 
121
133
  /**
@@ -123,8 +135,8 @@ export default class Scorm2004API extends BaseAPI {
123
135
  * @param {any} value
124
136
  * @return {string}
125
137
  */
126
- lmsSetValue(CMIElement, value) {
127
- return this.setValue('SetValue', 'Commit', true, CMIElement, value);
138
+ lmsSetValue(CMIElement: string, value: any): string {
139
+ return this.setValue("SetValue", "Commit", true, CMIElement, value);
128
140
  }
129
141
 
130
142
  /**
@@ -132,8 +144,8 @@ export default class Scorm2004API extends BaseAPI {
132
144
  *
133
145
  * @return {string} bool
134
146
  */
135
- lmsCommit() {
136
- return this.commit('Commit');
147
+ lmsCommit(): string {
148
+ return this.commit("Commit");
137
149
  }
138
150
 
139
151
  /**
@@ -141,8 +153,8 @@ export default class Scorm2004API extends BaseAPI {
141
153
  *
142
154
  * @return {string}
143
155
  */
144
- lmsGetLastError() {
145
- return this.getLastError('GetLastError');
156
+ lmsGetLastError(): string {
157
+ return this.getLastError("GetLastError");
146
158
  }
147
159
 
148
160
  /**
@@ -151,8 +163,8 @@ export default class Scorm2004API extends BaseAPI {
151
163
  * @param {(string|number)} CMIErrorCode
152
164
  * @return {string}
153
165
  */
154
- lmsGetErrorString(CMIErrorCode) {
155
- return this.getErrorString('GetErrorString', CMIErrorCode);
166
+ lmsGetErrorString(CMIErrorCode: string | number): string {
167
+ return this.getErrorString("GetErrorString", CMIErrorCode);
156
168
  }
157
169
 
158
170
  /**
@@ -161,8 +173,8 @@ export default class Scorm2004API extends BaseAPI {
161
173
  * @param {(string|number)} CMIErrorCode
162
174
  * @return {string}
163
175
  */
164
- lmsGetDiagnostic(CMIErrorCode) {
165
- return this.getDiagnostic('GetDiagnostic', CMIErrorCode);
176
+ lmsGetDiagnostic(CMIErrorCode: string | number): string {
177
+ return this.getDiagnostic("GetDiagnostic", CMIErrorCode);
166
178
  }
167
179
 
168
180
  /**
@@ -172,8 +184,8 @@ export default class Scorm2004API extends BaseAPI {
172
184
  * @param {any} value
173
185
  * @return {string}
174
186
  */
175
- setCMIValue(CMIElement, value) {
176
- return this._commonSetCMIValue('SetValue', true, CMIElement, value);
187
+ setCMIValue(CMIElement: string, value: any): string {
188
+ return this._commonSetCMIValue("SetValue", true, CMIElement, value);
177
189
  }
178
190
 
179
191
  /**
@@ -182,22 +194,30 @@ export default class Scorm2004API extends BaseAPI {
182
194
  * @param {string} CMIElement
183
195
  * @param {any} value
184
196
  * @param {boolean} foundFirstIndex
185
- * @return {any}
197
+ * @return {BaseCMI|null}
186
198
  */
187
- getChildElement(CMIElement, value, foundFirstIndex) {
188
- let newChild;
189
-
190
- if (this.stringMatches(CMIElement, 'cmi\\.objectives\\.\\d+')) {
191
- newChild = new CMIObjectivesObject();
192
- } else if (foundFirstIndex && this.stringMatches(CMIElement,
193
- 'cmi\\.interactions\\.\\d+\\.correct_responses\\.\\d+')) {
194
- const parts = CMIElement.split('.');
199
+ getChildElement(
200
+ CMIElement: string,
201
+ value: any,
202
+ foundFirstIndex: boolean,
203
+ ): BaseCMI | null {
204
+ if (this.stringMatches(CMIElement, "cmi\\.objectives\\.\\d+")) {
205
+ return new CMIObjectivesObject();
206
+ } else if (
207
+ foundFirstIndex &&
208
+ this.stringMatches(
209
+ CMIElement,
210
+ "cmi\\.interactions\\.\\d+\\.correct_responses\\.\\d+",
211
+ )
212
+ ) {
213
+ const parts = CMIElement.split(".");
195
214
  const index = Number(parts[2]);
196
215
  const interaction = this.cmi.interactions.childArray[index];
197
216
  if (this.isInitialized()) {
198
217
  if (!interaction.type) {
199
218
  this.throwSCORMError(
200
- scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
219
+ scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED,
220
+ );
201
221
  } else {
202
222
  this.checkDuplicateChoiceResponse(interaction, value);
203
223
 
@@ -205,29 +225,40 @@ export default class Scorm2004API extends BaseAPI {
205
225
  if (response_type) {
206
226
  this.checkValidResponseType(response_type, value, interaction.type);
207
227
  } else {
208
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
209
- 'Incorrect Response Type: ' + interaction.type);
228
+ this.throwSCORMError(
229
+ scorm2004_error_codes.GENERAL_SET_FAILURE,
230
+ "Incorrect Response Type: " + interaction.type,
231
+ );
210
232
  }
211
233
  }
212
234
  }
213
- if (this.lastErrorCode === 0) {
214
- newChild = new CMIInteractionsCorrectResponsesObject();
235
+ if (this.lastErrorCode === "0") {
236
+ return new CMIInteractionsCorrectResponsesObject();
215
237
  }
216
- } else if (foundFirstIndex && this.stringMatches(CMIElement,
217
- 'cmi\\.interactions\\.\\d+\\.objectives\\.\\d+')) {
218
- newChild = new CMIInteractionsObjectivesObject();
219
- } else if (!foundFirstIndex &&
220
- this.stringMatches(CMIElement, 'cmi\\.interactions\\.\\d+')) {
221
- newChild = new CMIInteractionsObject();
222
- } else if (this.stringMatches(CMIElement,
223
- 'cmi\\.comments_from_learner\\.\\d+')) {
224
- newChild = new CMICommentsObject();
225
- } else if (this.stringMatches(CMIElement,
226
- 'cmi\\.comments_from_lms\\.\\d+')) {
227
- newChild = new CMICommentsObject(true);
238
+ } else if (
239
+ foundFirstIndex &&
240
+ this.stringMatches(
241
+ CMIElement,
242
+ "cmi\\.interactions\\.\\d+\\.objectives\\.\\d+",
243
+ )
244
+ ) {
245
+ return new CMIInteractionsObjectivesObject();
246
+ } else if (
247
+ !foundFirstIndex &&
248
+ this.stringMatches(CMIElement, "cmi\\.interactions\\.\\d+")
249
+ ) {
250
+ return new CMIInteractionsObject();
251
+ } else if (
252
+ this.stringMatches(CMIElement, "cmi\\.comments_from_learner\\.\\d+")
253
+ ) {
254
+ return new CMICommentsObject();
255
+ } else if (
256
+ this.stringMatches(CMIElement, "cmi\\.comments_from_lms\\.\\d+")
257
+ ) {
258
+ return new CMICommentsObject(true);
228
259
  }
229
260
 
230
- return newChild;
261
+ return null;
231
262
  }
232
263
 
233
264
  /**
@@ -236,7 +267,11 @@ export default class Scorm2004API extends BaseAPI {
236
267
  * @param {any} value
237
268
  * @param {string} interaction_type
238
269
  */
239
- checkValidResponseType(response_type, value, interaction_type) {
270
+ checkValidResponseType(
271
+ response_type: ResponseType,
272
+ value: any,
273
+ interaction_type: string,
274
+ ) {
240
275
  let nodes = [];
241
276
  if (response_type?.delimiter) {
242
277
  nodes = String(value).split(response_type.delimiter);
@@ -247,8 +282,10 @@ export default class Scorm2004API extends BaseAPI {
247
282
  if (nodes.length > 0 && nodes.length <= response_type.max) {
248
283
  this.checkCorrectResponseValue(interaction_type, nodes, value);
249
284
  } else if (nodes.length > response_type.max) {
250
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
251
- 'Data Model Element Pattern Too Long');
285
+ this.throwSCORMError(
286
+ scorm2004_error_codes.GENERAL_SET_FAILURE,
287
+ "Data Model Element Pattern Too Long",
288
+ );
252
289
  }
253
290
  }
254
291
 
@@ -257,11 +294,14 @@ export default class Scorm2004API extends BaseAPI {
257
294
  * @param {CMIInteractionsObject} interaction
258
295
  * @param {any} value
259
296
  */
260
- checkDuplicateChoiceResponse(interaction, value) {
297
+ checkDuplicateChoiceResponse(interaction: CMIInteractionsObject, value: any) {
261
298
  const interaction_count = interaction.correct_responses._count;
262
- if (interaction.type === 'choice') {
263
- for (let i = 0; i < interaction_count && this.lastErrorCode ===
264
- 0; i++) {
299
+ if (interaction.type === "choice") {
300
+ for (
301
+ let i = 0;
302
+ i < interaction_count && this.lastErrorCode === "0";
303
+ i++
304
+ ) {
265
305
  const response = interaction.correct_responses.childArray[i];
266
306
  if (response.pattern === value) {
267
307
  this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE);
@@ -275,8 +315,8 @@ export default class Scorm2004API extends BaseAPI {
275
315
  * @param {string} CMIElement
276
316
  * @param {*} value
277
317
  */
278
- validateCorrectResponse(CMIElement, value) {
279
- const parts = CMIElement.split('.');
318
+ validateCorrectResponse(CMIElement: string, value: any) {
319
+ const parts = CMIElement.split(".");
280
320
  const index = Number(parts[2]);
281
321
  const pattern_index = Number(parts[4]);
282
322
  const interaction = this.cmi.interactions.childArray[index];
@@ -285,25 +325,36 @@ export default class Scorm2004API extends BaseAPI {
285
325
  this.checkDuplicateChoiceResponse(interaction, value);
286
326
 
287
327
  const response_type = correct_responses[interaction.type];
288
- if (typeof response_type.limit === 'undefined' || interaction_count <=
289
- response_type.limit) {
328
+ if (
329
+ typeof response_type.limit === "undefined" ||
330
+ interaction_count <= response_type.limit
331
+ ) {
290
332
  this.checkValidResponseType(response_type, value, interaction.type);
291
333
 
292
- if (this.lastErrorCode === 0 &&
334
+ if (
335
+ (this.lastErrorCode === "0" &&
293
336
  (!response_type.duplicate ||
294
- !this.checkDuplicatedPattern(interaction.correct_responses,
295
- pattern_index, value)) ||
296
- (this.lastErrorCode === 0 && value === '')) {
337
+ !this.checkDuplicatedPattern(
338
+ interaction.correct_responses,
339
+ pattern_index,
340
+ value,
341
+ ))) ||
342
+ (this.lastErrorCode === "0" && value === "")
343
+ ) {
297
344
  // do nothing, we want the inverse
298
345
  } else {
299
- if (this.lastErrorCode === 0) {
300
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
301
- 'Data Model Element Pattern Already Exists');
346
+ if (this.lastErrorCode === "0") {
347
+ this.throwSCORMError(
348
+ scorm2004_error_codes.GENERAL_SET_FAILURE,
349
+ "Data Model Element Pattern Already Exists",
350
+ );
302
351
  }
303
352
  }
304
353
  } else {
305
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
306
- 'Data Model Element Collection Limit Reached');
354
+ this.throwSCORMError(
355
+ scorm2004_error_codes.GENERAL_SET_FAILURE,
356
+ "Data Model Element Collection Limit Reached",
357
+ );
307
358
  }
308
359
  }
309
360
 
@@ -313,8 +364,8 @@ export default class Scorm2004API extends BaseAPI {
313
364
  * @param {string} CMIElement
314
365
  * @return {*}
315
366
  */
316
- getCMIValue(CMIElement) {
317
- return this._commonGetCMIValue('GetValue', true, CMIElement);
367
+ getCMIValue(CMIElement: string): any {
368
+ return this._commonGetCMIValue("GetValue", true, CMIElement);
318
369
  }
319
370
 
320
371
  /**
@@ -324,15 +375,20 @@ export default class Scorm2004API extends BaseAPI {
324
375
  * @param {boolean} detail
325
376
  * @return {string}
326
377
  */
327
- getLmsErrorMessageDetails(errorNumber, detail) {
328
- let basicMessage = '';
329
- let detailMessage = '';
378
+ getLmsErrorMessageDetails(
379
+ errorNumber: string | number,
380
+ detail: boolean,
381
+ ): string {
382
+ let basicMessage = "";
383
+ let detailMessage = "";
330
384
 
331
385
  // Set error number to string since inconsistent from modules if string or number
332
386
  errorNumber = String(errorNumber);
333
387
  if (scorm2004_constants.error_descriptions[errorNumber]) {
334
- basicMessage = scorm2004_constants.error_descriptions[errorNumber].basicMessage;
335
- detailMessage = scorm2004_constants.error_descriptions[errorNumber].detailMessage;
388
+ basicMessage =
389
+ scorm2004_constants.error_descriptions[errorNumber].basicMessage;
390
+ detailMessage =
391
+ scorm2004_constants.error_descriptions[errorNumber].detailMessage;
336
392
  }
337
393
 
338
394
  return detail ? detailMessage : basicMessage;
@@ -345,7 +401,11 @@ export default class Scorm2004API extends BaseAPI {
345
401
  * @param {*} value
346
402
  * @return {boolean}
347
403
  */
348
- checkDuplicatedPattern = (correct_response, current_index, value) => {
404
+ checkDuplicatedPattern(
405
+ correct_response: CMIArray,
406
+ current_index: number,
407
+ value: any,
408
+ ): boolean {
349
409
  let found = false;
350
410
  const count = correct_response._count;
351
411
  for (let i = 0; i < count && !found; i++) {
@@ -354,7 +414,7 @@ export default class Scorm2004API extends BaseAPI {
354
414
  }
355
415
  }
356
416
  return found;
357
- };
417
+ }
358
418
 
359
419
  /**
360
420
  * Checks for a valid correct_response value
@@ -362,12 +422,19 @@ export default class Scorm2004API extends BaseAPI {
362
422
  * @param {Array} nodes
363
423
  * @param {*} value
364
424
  */
365
- checkCorrectResponseValue(interaction_type, nodes, value) {
425
+ checkCorrectResponseValue(
426
+ interaction_type: string,
427
+ nodes: Array<any>,
428
+ value: any,
429
+ ) {
366
430
  const response = correct_responses[interaction_type];
367
431
  const formatRegex = new RegExp(response.format);
368
- for (let i = 0; i < nodes.length && this.lastErrorCode === 0; i++) {
369
- if (interaction_type.match(
370
- '^(fill-in|long-fill-in|matching|performance|sequencing)$')) {
432
+ for (let i = 0; i < nodes.length && this.lastErrorCode === "0"; i++) {
433
+ if (
434
+ interaction_type.match(
435
+ "^(fill-in|long-fill-in|matching|performance|sequencing)$",
436
+ )
437
+ ) {
371
438
  nodes[i] = this.removeCorrectResponsePrefixes(nodes[i]);
372
439
  }
373
440
 
@@ -378,7 +445,10 @@ export default class Scorm2004API extends BaseAPI {
378
445
  if (!matches) {
379
446
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
380
447
  } else {
381
- if (!values[1].match(new RegExp(response.format2))) {
448
+ if (
449
+ !response.format2 ||
450
+ !values[1].match(new RegExp(response.format2))
451
+ ) {
382
452
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
383
453
  }
384
454
  }
@@ -387,17 +457,19 @@ export default class Scorm2004API extends BaseAPI {
387
457
  }
388
458
  } else {
389
459
  const matches = nodes[i].match(formatRegex);
390
- if ((!matches && value !== '') ||
391
- (!matches && interaction_type === 'true-false')) {
460
+ if (
461
+ (!matches && value !== "") ||
462
+ (!matches && interaction_type === "true-false")
463
+ ) {
392
464
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
393
465
  } else {
394
- if (interaction_type === 'numeric' && nodes.length > 1) {
466
+ if (interaction_type === "numeric" && nodes.length > 1) {
395
467
  if (Number(nodes[0]) > Number(nodes[1])) {
396
468
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
397
469
  }
398
470
  } else {
399
- if (nodes[i] !== '' && response.unique) {
400
- for (let j = 0; j < i && this.lastErrorCode === 0; j++) {
471
+ if (nodes[i] !== "" && response.unique) {
472
+ for (let j = 0; j < i && this.lastErrorCode === "0"; j++) {
401
473
  if (nodes[i] === nodes[j]) {
402
474
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
403
475
  }
@@ -414,41 +486,42 @@ export default class Scorm2004API extends BaseAPI {
414
486
  * @param {string} node
415
487
  * @return {*}
416
488
  */
417
- removeCorrectResponsePrefixes(node) {
489
+ removeCorrectResponsePrefixes(node: string): any {
418
490
  let seenOrder = false;
419
491
  let seenCase = false;
420
492
  let seenLang = false;
421
493
 
422
494
  const prefixRegex = new RegExp(
423
- '^({(lang|case_matters|order_matters)=([^}]+)})');
495
+ "^({(lang|case_matters|order_matters)=([^}]+)})",
496
+ );
424
497
  let matches = node.match(prefixRegex);
425
498
  let langMatches = null;
426
499
  while (matches) {
427
500
  switch (matches[2]) {
428
- case 'lang':
501
+ case "lang":
429
502
  langMatches = node.match(scorm2004_regex.CMILangcr);
430
503
  if (langMatches) {
431
504
  const lang = langMatches[3];
432
505
  if (lang !== undefined && lang.length > 0) {
433
- if (ValidLanguages[lang.toLowerCase()] === undefined) {
506
+ if (!ValidLanguages.includes(lang.toLowerCase())) {
434
507
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
435
508
  }
436
509
  }
437
510
  }
438
511
  seenLang = true;
439
512
  break;
440
- case 'case_matters':
513
+ case "case_matters":
441
514
  if (!seenLang && !seenOrder && !seenCase) {
442
- if (matches[3] !== 'true' && matches[3] !== 'false') {
515
+ if (matches[3] !== "true" && matches[3] !== "false") {
443
516
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
444
517
  }
445
518
  }
446
519
 
447
520
  seenCase = true;
448
521
  break;
449
- case 'order_matters':
522
+ case "order_matters":
450
523
  if (!seenCase && !seenLang && !seenOrder) {
451
- if (matches[3] !== 'true' && matches[3] !== 'false') {
524
+ if (matches[3] !== "true" && matches[3] !== "false") {
452
525
  this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
453
526
  }
454
527
  }
@@ -458,7 +531,7 @@ export default class Scorm2004API extends BaseAPI {
458
531
  default:
459
532
  break;
460
533
  }
461
- node = node.substr(matches[1].length);
534
+ node = node.substring(matches[1].length);
462
535
  matches = node.match(prefixRegex);
463
536
  }
464
537
 
@@ -469,7 +542,7 @@ export default class Scorm2004API extends BaseAPI {
469
542
  * Replace the whole API with another
470
543
  * @param {Scorm2004API} newAPI
471
544
  */
472
- replaceWithAnotherScormAPI(newAPI) {
545
+ replaceWithAnotherScormAPI(newAPI: Scorm2004API) {
473
546
  // Data Model
474
547
  this.cmi = newAPI.cmi;
475
548
  this.adl = newAPI.adl;
@@ -481,26 +554,26 @@ export default class Scorm2004API extends BaseAPI {
481
554
  * @param {boolean} terminateCommit
482
555
  * @return {object|Array}
483
556
  */
484
- renderCommitCMI(terminateCommit: boolean) {
485
- const cmiExport = this.renderCMIToJSONObject();
557
+ renderCommitCMI(terminateCommit: boolean): object | Array<any> {
558
+ const cmiExport: RefObject = this.renderCMIToJSONObject();
486
559
 
487
560
  if (terminateCommit) {
488
561
  cmiExport.cmi.total_time = this.cmi.getCurrentTotalTime();
489
562
  }
490
563
 
491
564
  const result = [];
492
- const flattened = Utilities.flatten(cmiExport);
565
+ const flattened: RefObject = Utilities.flatten(cmiExport);
493
566
  switch (this.settings.dataCommitFormat) {
494
- case 'flattened':
567
+ case "flattened":
495
568
  return Utilities.flatten(cmiExport);
496
- case 'params':
569
+ case "params":
497
570
  for (const item in flattened) {
498
571
  if ({}.hasOwnProperty.call(flattened, item)) {
499
572
  result.push(`${item}=${flattened[item]}`);
500
573
  }
501
574
  }
502
575
  return result;
503
- case 'json':
576
+ case "json":
504
577
  default:
505
578
  return cmiExport;
506
579
  }
@@ -510,28 +583,24 @@ export default class Scorm2004API extends BaseAPI {
510
583
  * Attempts to store the data to the LMS
511
584
  *
512
585
  * @param {boolean} terminateCommit
513
- * @return {string}
586
+ * @return {ResultObject}
514
587
  */
515
- storeData(terminateCommit: boolean) {
588
+ storeData(terminateCommit: boolean): ResultObject {
516
589
  if (terminateCommit) {
517
- if (this.cmi.mode === 'normal') {
518
- if (this.cmi.credit === 'credit') {
590
+ if (this.cmi.mode === "normal") {
591
+ if (this.cmi.credit === "credit") {
519
592
  if (this.cmi.completion_threshold && this.cmi.progress_measure) {
520
593
  if (this.cmi.progress_measure >= this.cmi.completion_threshold) {
521
- console.debug('Setting Completion Status: Completed');
522
- this.cmi.completion_status = 'completed';
594
+ this.cmi.completion_status = "completed";
523
595
  } else {
524
- console.debug('Setting Completion Status: Incomplete');
525
- this.cmi.completion_status = 'incomplete';
596
+ this.cmi.completion_status = "incomplete";
526
597
  }
527
598
  }
528
599
  if (this.cmi.scaled_passing_score && this.cmi.score.scaled) {
529
600
  if (this.cmi.score.scaled >= this.cmi.scaled_passing_score) {
530
- console.debug('Setting Success Status: Passed');
531
- this.cmi.success_status = 'passed';
601
+ this.cmi.success_status = "passed";
532
602
  } else {
533
- console.debug('Setting Success Status: Failed');
534
- this.cmi.success_status = 'failed';
603
+ this.cmi.success_status = "failed";
535
604
  }
536
605
  }
537
606
  }
@@ -539,34 +608,47 @@ export default class Scorm2004API extends BaseAPI {
539
608
  }
540
609
 
541
610
  let navRequest = false;
542
- if (this.adl.nav.request !== (this.startingData?.adl?.nav?.request) &&
543
- this.adl.nav.request !== '_none_') {
611
+ if (
612
+ this.adl.nav.request !== this.startingData?.adl?.nav?.request &&
613
+ this.adl.nav.request !== "_none_"
614
+ ) {
544
615
  this.adl.nav.request = encodeURIComponent(this.adl.nav.request);
545
616
  navRequest = true;
546
617
  }
547
618
 
548
- const commitObject = this.renderCommitCMI(terminateCommit ||
549
- this.settings.alwaysSendTotalTime);
619
+ const commitObject = this.renderCommitCMI(
620
+ terminateCommit || this.settings.alwaysSendTotalTime,
621
+ );
550
622
 
551
623
  if (this.apiLogLevel === global_constants.LOG_LEVEL_DEBUG) {
552
- console.debug('Commit (terminated: ' +
553
- (terminateCommit ? 'yes' : 'no') + '): ');
624
+ console.debug(
625
+ "Commit (terminated: " + (terminateCommit ? "yes" : "no") + "): ",
626
+ );
554
627
  console.debug(commitObject);
555
628
  }
556
- if (this.settings.lmsCommitUrl) {
557
- const result = this.processHttpRequest(this.settings.lmsCommitUrl,
558
- commitObject, terminateCommit);
629
+ if (typeof this.settings.lmsCommitUrl === "string") {
630
+ const result = this.processHttpRequest(
631
+ this.settings.lmsCommitUrl,
632
+ commitObject,
633
+ terminateCommit,
634
+ );
559
635
 
560
636
  // check if this is a sequencing call, and then call the necessary JS
561
637
  {
562
- if (navRequest && result.navRequest !== undefined &&
563
- result.navRequest !== '') {
638
+ if (
639
+ navRequest &&
640
+ result.navRequest !== undefined &&
641
+ result.navRequest !== ""
642
+ ) {
564
643
  Function(`"use strict";(() => { ${result.navRequest} })()`)();
565
644
  }
566
645
  }
567
646
  return result;
568
647
  } else {
569
- return global_constants.SCORM_TRUE;
648
+ return {
649
+ result: global_constants.SCORM_TRUE,
650
+ errorCode: 0,
651
+ };
570
652
  }
571
653
  }
572
654
  }