scorm-again 1.7.1 → 2.1.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 (124) hide show
  1. package/.babelrc +18 -7
  2. package/.github/dependabot.yml +5 -0
  3. package/.github/workflows/main.yml +79 -0
  4. package/.github/workflows/stale.yml +14 -0
  5. package/.jsdoc.json +4 -5
  6. package/.mocharc.json +8 -0
  7. package/.run/{Mocha Unit Tests.run.xml → Mocha Unit Tests (watch).run.xml } +6 -3
  8. package/.run/Template Mocha.run.xml +17 -0
  9. package/CONTRIBUTING.md +1 -1
  10. package/README.md +183 -71
  11. package/dist/aicc.js +3822 -7030
  12. package/dist/aicc.js.map +1 -1
  13. package/dist/aicc.min.js +2 -40
  14. package/dist/aicc.min.js.map +1 -0
  15. package/dist/scorm-again.js +5965 -10498
  16. package/dist/scorm-again.js.map +1 -1
  17. package/dist/scorm-again.min.js +2 -52
  18. package/dist/scorm-again.min.js.map +1 -0
  19. package/dist/scorm12.js +3028 -5373
  20. package/dist/scorm12.js.map +1 -1
  21. package/dist/scorm12.min.js +2 -34
  22. package/dist/scorm12.min.js.map +1 -0
  23. package/dist/scorm2004.js +4054 -6693
  24. package/dist/scorm2004.js.map +1 -1
  25. package/dist/scorm2004.min.js +2 -40
  26. package/dist/scorm2004.min.js.map +1 -0
  27. package/eslint.config.js +21 -0
  28. package/package.json +76 -34
  29. package/results.json +34254 -0
  30. package/src/AICC.ts +72 -0
  31. package/src/BaseAPI.ts +1300 -0
  32. package/src/Scorm12API.ts +387 -0
  33. package/src/Scorm2004API.ts +688 -0
  34. package/src/cmi/aicc/attempts.ts +94 -0
  35. package/src/cmi/aicc/cmi.ts +100 -0
  36. package/src/cmi/aicc/core.ts +360 -0
  37. package/src/cmi/aicc/evaluation.ts +157 -0
  38. package/src/cmi/aicc/paths.ts +180 -0
  39. package/src/cmi/aicc/student_data.ts +86 -0
  40. package/src/cmi/aicc/student_demographics.ts +367 -0
  41. package/src/cmi/aicc/student_preferences.ts +176 -0
  42. package/src/cmi/aicc/tries.ts +116 -0
  43. package/src/cmi/aicc/validation.ts +25 -0
  44. package/src/cmi/common/array.ts +77 -0
  45. package/src/cmi/common/base_cmi.ts +46 -0
  46. package/src/cmi/common/score.ts +203 -0
  47. package/src/cmi/common/validation.ts +60 -0
  48. package/src/cmi/scorm12/cmi.ts +224 -0
  49. package/src/cmi/scorm12/interactions.ts +368 -0
  50. package/src/cmi/scorm12/nav.ts +54 -0
  51. package/src/cmi/scorm12/objectives.ts +112 -0
  52. package/src/cmi/scorm12/student_data.ts +130 -0
  53. package/src/cmi/scorm12/student_preference.ts +158 -0
  54. package/src/cmi/scorm12/validation.ts +48 -0
  55. package/src/cmi/scorm2004/adl.ts +272 -0
  56. package/src/cmi/scorm2004/cmi.ts +599 -0
  57. package/src/cmi/scorm2004/comments.ts +163 -0
  58. package/src/cmi/scorm2004/interactions.ts +466 -0
  59. package/src/cmi/scorm2004/learner_preference.ts +152 -0
  60. package/src/cmi/scorm2004/objectives.ts +212 -0
  61. package/src/cmi/scorm2004/score.ts +78 -0
  62. package/src/cmi/scorm2004/validation.ts +42 -0
  63. package/src/constants/api_constants.ts +318 -0
  64. package/src/constants/default_settings.ts +81 -0
  65. package/src/constants/enums.ts +5 -0
  66. package/src/constants/error_codes.ts +88 -0
  67. package/src/constants/language_constants.ts +394 -0
  68. package/src/constants/regex.ts +97 -0
  69. package/src/constants/{response_constants.js → response_constants.ts} +69 -62
  70. package/src/exceptions.ts +154 -0
  71. package/src/exports/aicc.js +1 -1
  72. package/src/exports/scorm-again.js +3 -3
  73. package/src/exports/scorm12.js +1 -1
  74. package/src/exports/scorm2004.js +1 -1
  75. package/src/helpers/scheduled_commit.ts +42 -0
  76. package/src/interfaces/IBaseAPI.ts +35 -0
  77. package/src/types/api_types.ts +32 -0
  78. package/src/utilities/debounce.ts +31 -0
  79. package/src/utilities.ts +338 -0
  80. package/tea.yaml +6 -0
  81. package/test/{AICC.spec.js → AICC.spec.ts} +79 -71
  82. package/test/Scorm12API.spec.ts +833 -0
  83. package/test/Scorm2004API.spec.ts +1298 -0
  84. package/test/api_helpers.ts +176 -0
  85. package/test/cmi/aicc_cmi.spec.ts +845 -0
  86. package/test/cmi/{scorm12_cmi.spec.js → scorm12_cmi.spec.ts} +253 -271
  87. package/test/cmi/scorm2004_cmi.spec.ts +1031 -0
  88. package/test/cmi_helpers.ts +207 -0
  89. package/test/exceptions.spec.ts +79 -0
  90. package/test/field_values.ts +202 -0
  91. package/test/types/api_types.spec.ts +126 -0
  92. package/test/utilities/debounce.spec.ts +56 -0
  93. package/test/utilities.spec.ts +322 -0
  94. package/tsconfig.json +18 -0
  95. package/webpack.config.js +65 -0
  96. package/.circleci/config.yml +0 -99
  97. package/.codeclimate.yml +0 -7
  98. package/.eslintrc.js +0 -36
  99. package/src/.flowconfig +0 -11
  100. package/src/AICC.js +0 -68
  101. package/src/BaseAPI.js +0 -1275
  102. package/src/Scorm12API.js +0 -308
  103. package/src/Scorm2004API.js +0 -572
  104. package/src/cmi/aicc_cmi.js +0 -1141
  105. package/src/cmi/common.js +0 -328
  106. package/src/cmi/scorm12_cmi.js +0 -1312
  107. package/src/cmi/scorm2004_cmi.js +0 -1692
  108. package/src/constants/api_constants.js +0 -218
  109. package/src/constants/error_codes.js +0 -87
  110. package/src/constants/language_constants.js +0 -76
  111. package/src/constants/regex.js +0 -84
  112. package/src/exceptions.js +0 -104
  113. package/src/utilities.js +0 -242
  114. package/test/Scorm12API.spec.js +0 -528
  115. package/test/Scorm2004API.spec.js +0 -775
  116. package/test/abstract_classes.spec.js +0 -17
  117. package/test/api_helpers.js +0 -128
  118. package/test/cmi/aicc_cmi.spec.js +0 -684
  119. package/test/cmi/scorm2004_cmi.spec.js +0 -1066
  120. package/test/cmi_helpers.js +0 -161
  121. package/test/exceptions.spec.js +0 -71
  122. package/test/field_values.js +0 -353
  123. package/test/utilities.spec.js +0 -339
  124. package/webpack.js +0 -78
@@ -1,572 +0,0 @@
1
- // @flow
2
- import BaseAPI from './BaseAPI';
3
- import {
4
- ADL,
5
- CMI,
6
- CMICommentsObject,
7
- CMIInteractionsCorrectResponsesObject,
8
- CMIInteractionsObject,
9
- CMIInteractionsObjectivesObject,
10
- 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';
18
-
19
- const scorm2004_constants = APIConstants.scorm2004;
20
- const global_constants = APIConstants.global;
21
- const scorm2004_error_codes = ErrorCodes.scorm2004;
22
- const correct_responses = Responses.correct;
23
- const scorm2004_regex = Regex.scorm2004;
24
-
25
- /**
26
- * API class for SCORM 2004
27
- */
28
- export default class Scorm2004API extends BaseAPI {
29
- #version: '1.0';
30
-
31
- /**
32
- * Constructor for SCORM 2004 API
33
- * @param {object} settings
34
- */
35
- constructor(settings: {}) {
36
- const finalSettings = {
37
- ...{
38
- mastery_override: false,
39
- }, ...settings,
40
- };
41
-
42
- super(scorm2004_error_codes, finalSettings);
43
-
44
- this.cmi = new CMI();
45
- this.adl = new ADL();
46
-
47
- // Rename functions to match 2004 Spec and expose to modules
48
- this.Initialize = this.lmsInitialize;
49
- this.Terminate = this.lmsTerminate;
50
- this.GetValue = this.lmsGetValue;
51
- this.SetValue = this.lmsSetValue;
52
- this.Commit = this.lmsCommit;
53
- this.GetLastError = this.lmsGetLastError;
54
- this.GetErrorString = this.lmsGetErrorString;
55
- this.GetDiagnostic = this.lmsGetDiagnostic;
56
- }
57
-
58
- /**
59
- * Getter for #version
60
- * @return {string}
61
- */
62
- get version() {
63
- return this.#version;
64
- }
65
-
66
- /**
67
- * @return {string} bool
68
- */
69
- lmsInitialize() {
70
- this.cmi.initialize();
71
- return this.initialize('Initialize');
72
- }
73
-
74
- /**
75
- * @return {string} bool
76
- */
77
- lmsTerminate() {
78
- const result = this.terminate('Terminate', true);
79
-
80
- if (result === global_constants.SCORM_TRUE) {
81
- if (this.adl.nav.request !== '_none_') {
82
- switch (this.adl.nav.request) {
83
- case 'continue':
84
- this.processListeners('SequenceNext');
85
- break;
86
- case 'previous':
87
- this.processListeners('SequencePrevious');
88
- break;
89
- case 'choice':
90
- this.processListeners('SequenceChoice');
91
- break;
92
- case 'exit':
93
- this.processListeners('SequenceExit');
94
- break;
95
- case 'exitAll':
96
- this.processListeners('SequenceExitAll');
97
- break;
98
- case 'abandon':
99
- this.processListeners('SequenceAbandon');
100
- break;
101
- case 'abandonAll':
102
- this.processListeners('SequenceAbandonAll');
103
- break;
104
- }
105
- } else if (this.settings.autoProgress) {
106
- this.processListeners('SequenceNext');
107
- }
108
- }
109
-
110
- return result;
111
- }
112
-
113
- /**
114
- * @param {string} CMIElement
115
- * @return {string}
116
- */
117
- lmsGetValue(CMIElement) {
118
- return this.getValue('GetValue', true, CMIElement);
119
- }
120
-
121
- /**
122
- * @param {string} CMIElement
123
- * @param {any} value
124
- * @return {string}
125
- */
126
- lmsSetValue(CMIElement, value) {
127
- return this.setValue('SetValue', 'Commit', true, CMIElement, value);
128
- }
129
-
130
- /**
131
- * Orders LMS to store all content parameters
132
- *
133
- * @return {string} bool
134
- */
135
- lmsCommit() {
136
- return this.commit('Commit');
137
- }
138
-
139
- /**
140
- * Returns last error code
141
- *
142
- * @return {string}
143
- */
144
- lmsGetLastError() {
145
- return this.getLastError('GetLastError');
146
- }
147
-
148
- /**
149
- * Returns the errorNumber error description
150
- *
151
- * @param {(string|number)} CMIErrorCode
152
- * @return {string}
153
- */
154
- lmsGetErrorString(CMIErrorCode) {
155
- return this.getErrorString('GetErrorString', CMIErrorCode);
156
- }
157
-
158
- /**
159
- * Returns a comprehensive description of the errorNumber error.
160
- *
161
- * @param {(string|number)} CMIErrorCode
162
- * @return {string}
163
- */
164
- lmsGetDiagnostic(CMIErrorCode) {
165
- return this.getDiagnostic('GetDiagnostic', CMIErrorCode);
166
- }
167
-
168
- /**
169
- * Sets a value on the CMI Object
170
- *
171
- * @param {string} CMIElement
172
- * @param {any} value
173
- * @return {string}
174
- */
175
- setCMIValue(CMIElement, value) {
176
- return this._commonSetCMIValue('SetValue', true, CMIElement, value);
177
- }
178
-
179
- /**
180
- * Gets or builds a new child element to add to the array.
181
- *
182
- * @param {string} CMIElement
183
- * @param {any} value
184
- * @param {boolean} foundFirstIndex
185
- * @return {any}
186
- */
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('.');
195
- const index = Number(parts[2]);
196
- const interaction = this.cmi.interactions.childArray[index];
197
- if (this.isInitialized()) {
198
- if (!interaction.type) {
199
- this.throwSCORMError(
200
- scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
201
- } else {
202
- this.checkDuplicateChoiceResponse(interaction, value);
203
-
204
- const response_type = correct_responses[interaction.type];
205
- if (response_type) {
206
- this.checkValidResponseType(response_type, value, interaction.type);
207
- } else {
208
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
209
- 'Incorrect Response Type: ' + interaction.type);
210
- }
211
- }
212
- }
213
- if (this.lastErrorCode === 0) {
214
- newChild = new CMIInteractionsCorrectResponsesObject();
215
- }
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);
228
- }
229
-
230
- return newChild;
231
- }
232
-
233
- /**
234
- * Checks for valid response types
235
- * @param {object} response_type
236
- * @param {any} value
237
- * @param {string} interaction_type
238
- */
239
- checkValidResponseType(response_type, value, interaction_type) {
240
- let nodes = [];
241
- if (response_type?.delimiter) {
242
- nodes = String(value).split(response_type.delimiter);
243
- } else {
244
- nodes[0] = value;
245
- }
246
-
247
- if (nodes.length > 0 && nodes.length <= response_type.max) {
248
- this.checkCorrectResponseValue(interaction_type, nodes, value);
249
- } else if (nodes.length > response_type.max) {
250
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
251
- 'Data Model Element Pattern Too Long');
252
- }
253
- }
254
-
255
- /**
256
- * Checks for duplicate 'choice' responses.
257
- * @param {CMIInteractionsObject} interaction
258
- * @param {any} value
259
- */
260
- checkDuplicateChoiceResponse(interaction, value) {
261
- 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++) {
265
- const response = interaction.correct_responses.childArray[i];
266
- if (response.pattern === value) {
267
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE);
268
- }
269
- }
270
- }
271
- }
272
-
273
- /**
274
- * Validate correct response.
275
- * @param {string} CMIElement
276
- * @param {*} value
277
- */
278
- validateCorrectResponse(CMIElement, value) {
279
- const parts = CMIElement.split('.');
280
- const index = Number(parts[2]);
281
- const pattern_index = Number(parts[4]);
282
- const interaction = this.cmi.interactions.childArray[index];
283
-
284
- const interaction_count = interaction.correct_responses._count;
285
- this.checkDuplicateChoiceResponse(interaction, value);
286
-
287
- const response_type = correct_responses[interaction.type];
288
- if (typeof response_type.limit === 'undefined' || interaction_count <=
289
- response_type.limit) {
290
- this.checkValidResponseType(response_type, value, interaction.type);
291
-
292
- if (this.lastErrorCode === 0 &&
293
- (!response_type.duplicate ||
294
- !this.checkDuplicatedPattern(interaction.correct_responses,
295
- pattern_index, value)) ||
296
- (this.lastErrorCode === 0 && value === '')) {
297
- // do nothing, we want the inverse
298
- } else {
299
- if (this.lastErrorCode === 0) {
300
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
301
- 'Data Model Element Pattern Already Exists');
302
- }
303
- }
304
- } else {
305
- this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
306
- 'Data Model Element Collection Limit Reached');
307
- }
308
- }
309
-
310
- /**
311
- * Gets a value from the CMI Object
312
- *
313
- * @param {string} CMIElement
314
- * @return {*}
315
- */
316
- getCMIValue(CMIElement) {
317
- return this._commonGetCMIValue('GetValue', true, CMIElement);
318
- }
319
-
320
- /**
321
- * Returns the message that corresponds to errorNumber.
322
- *
323
- * @param {(string|number)} errorNumber
324
- * @param {boolean} detail
325
- * @return {string}
326
- */
327
- getLmsErrorMessageDetails(errorNumber, detail) {
328
- let basicMessage = '';
329
- let detailMessage = '';
330
-
331
- // Set error number to string since inconsistent from modules if string or number
332
- errorNumber = String(errorNumber);
333
- if (scorm2004_constants.error_descriptions[errorNumber]) {
334
- basicMessage = scorm2004_constants.error_descriptions[errorNumber].basicMessage;
335
- detailMessage = scorm2004_constants.error_descriptions[errorNumber].detailMessage;
336
- }
337
-
338
- return detail ? detailMessage : basicMessage;
339
- }
340
-
341
- /**
342
- * Check to see if a correct_response value has been duplicated
343
- * @param {CMIArray} correct_response
344
- * @param {number} current_index
345
- * @param {*} value
346
- * @return {boolean}
347
- */
348
- checkDuplicatedPattern = (correct_response, current_index, value) => {
349
- let found = false;
350
- const count = correct_response._count;
351
- for (let i = 0; i < count && !found; i++) {
352
- if (i !== current_index && correct_response.childArray[i] === value) {
353
- found = true;
354
- }
355
- }
356
- return found;
357
- };
358
-
359
- /**
360
- * Checks for a valid correct_response value
361
- * @param {string} interaction_type
362
- * @param {Array} nodes
363
- * @param {*} value
364
- */
365
- checkCorrectResponseValue(interaction_type, nodes, value) {
366
- const response = correct_responses[interaction_type];
367
- 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)$')) {
371
- nodes[i] = this.removeCorrectResponsePrefixes(nodes[i]);
372
- }
373
-
374
- if (response?.delimiter2) {
375
- const values = nodes[i].split(response.delimiter2);
376
- if (values.length === 2) {
377
- const matches = values[0].match(formatRegex);
378
- if (!matches) {
379
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
380
- } else {
381
- if (!values[1].match(new RegExp(response.format2))) {
382
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
383
- }
384
- }
385
- } else {
386
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
387
- }
388
- } else {
389
- const matches = nodes[i].match(formatRegex);
390
- if ((!matches && value !== '') ||
391
- (!matches && interaction_type === 'true-false')) {
392
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
393
- } else {
394
- if (interaction_type === 'numeric' && nodes.length > 1) {
395
- if (Number(nodes[0]) > Number(nodes[1])) {
396
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
397
- }
398
- } else {
399
- if (nodes[i] !== '' && response.unique) {
400
- for (let j = 0; j < i && this.lastErrorCode === 0; j++) {
401
- if (nodes[i] === nodes[j]) {
402
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
403
- }
404
- }
405
- }
406
- }
407
- }
408
- }
409
- }
410
- }
411
-
412
- /**
413
- * Remove prefixes from correct_response
414
- * @param {string} node
415
- * @return {*}
416
- */
417
- removeCorrectResponsePrefixes(node) {
418
- let seenOrder = false;
419
- let seenCase = false;
420
- let seenLang = false;
421
-
422
- const prefixRegex = new RegExp(
423
- '^({(lang|case_matters|order_matters)=([^}]+)})');
424
- let matches = node.match(prefixRegex);
425
- let langMatches = null;
426
- while (matches) {
427
- switch (matches[2]) {
428
- case 'lang':
429
- langMatches = node.match(scorm2004_regex.CMILangcr);
430
- if (langMatches) {
431
- const lang = langMatches[3];
432
- if (lang !== undefined && lang.length > 0) {
433
- if (ValidLanguages[lang.toLowerCase()] === undefined) {
434
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
435
- }
436
- }
437
- }
438
- seenLang = true;
439
- break;
440
- case 'case_matters':
441
- if (!seenLang && !seenOrder && !seenCase) {
442
- if (matches[3] !== 'true' && matches[3] !== 'false') {
443
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
444
- }
445
- }
446
-
447
- seenCase = true;
448
- break;
449
- case 'order_matters':
450
- if (!seenCase && !seenLang && !seenOrder) {
451
- if (matches[3] !== 'true' && matches[3] !== 'false') {
452
- this.throwSCORMError(scorm2004_error_codes.TYPE_MISMATCH);
453
- }
454
- }
455
-
456
- seenOrder = true;
457
- break;
458
- default:
459
- break;
460
- }
461
- node = node.substr(matches[1].length);
462
- matches = node.match(prefixRegex);
463
- }
464
-
465
- return node;
466
- }
467
-
468
- /**
469
- * Replace the whole API with another
470
- * @param {Scorm2004API} newAPI
471
- */
472
- replaceWithAnotherScormAPI(newAPI) {
473
- // Data Model
474
- this.cmi = newAPI.cmi;
475
- this.adl = newAPI.adl;
476
- }
477
-
478
- /**
479
- * Render the cmi object to the proper format for LMS commit
480
- *
481
- * @param {boolean} terminateCommit
482
- * @return {object|Array}
483
- */
484
- renderCommitCMI(terminateCommit: boolean) {
485
- const cmiExport = this.renderCMIToJSONObject();
486
-
487
- if (terminateCommit) {
488
- cmiExport.cmi.total_time = this.cmi.getCurrentTotalTime();
489
- }
490
-
491
- const result = [];
492
- const flattened = Utilities.flatten(cmiExport);
493
- switch (this.settings.dataCommitFormat) {
494
- case 'flattened':
495
- return Utilities.flatten(cmiExport);
496
- case 'params':
497
- for (const item in flattened) {
498
- if ({}.hasOwnProperty.call(flattened, item)) {
499
- result.push(`${item}=${flattened[item]}`);
500
- }
501
- }
502
- return result;
503
- case 'json':
504
- default:
505
- return cmiExport;
506
- }
507
- }
508
-
509
- /**
510
- * Attempts to store the data to the LMS
511
- *
512
- * @param {boolean} terminateCommit
513
- * @return {string}
514
- */
515
- storeData(terminateCommit: boolean) {
516
- if (terminateCommit) {
517
- if (this.cmi.mode === 'normal') {
518
- if (this.cmi.credit === 'credit') {
519
- if (this.cmi.completion_threshold && this.cmi.progress_measure) {
520
- if (this.cmi.progress_measure >= this.cmi.completion_threshold) {
521
- console.debug('Setting Completion Status: Completed');
522
- this.cmi.completion_status = 'completed';
523
- } else {
524
- console.debug('Setting Completion Status: Incomplete');
525
- this.cmi.completion_status = 'incomplete';
526
- }
527
- }
528
- if (this.cmi.scaled_passing_score && this.cmi.score.scaled) {
529
- if (this.cmi.score.scaled >= this.cmi.scaled_passing_score) {
530
- console.debug('Setting Success Status: Passed');
531
- this.cmi.success_status = 'passed';
532
- } else {
533
- console.debug('Setting Success Status: Failed');
534
- this.cmi.success_status = 'failed';
535
- }
536
- }
537
- }
538
- }
539
- }
540
-
541
- let navRequest = false;
542
- if (this.adl.nav.request !== (this.startingData?.adl?.nav?.request) &&
543
- this.adl.nav.request !== '_none_') {
544
- this.adl.nav.request = encodeURIComponent(this.adl.nav.request);
545
- navRequest = true;
546
- }
547
-
548
- const commitObject = this.renderCommitCMI(terminateCommit ||
549
- this.settings.alwaysSendTotalTime);
550
-
551
- if (this.apiLogLevel === global_constants.LOG_LEVEL_DEBUG) {
552
- console.debug('Commit (terminated: ' +
553
- (terminateCommit ? 'yes' : 'no') + '): ');
554
- console.debug(commitObject);
555
- }
556
- if (this.settings.lmsCommitUrl) {
557
- const result = this.processHttpRequest(this.settings.lmsCommitUrl,
558
- commitObject, terminateCommit);
559
-
560
- // check if this is a sequencing call, and then call the necessary JS
561
- {
562
- if (navRequest && result.navRequest !== undefined &&
563
- result.navRequest !== '') {
564
- Function(`"use strict";(() => { ${result.navRequest} })()`)();
565
- }
566
- }
567
- return result;
568
- } else {
569
- return global_constants.SCORM_TRUE;
570
- }
571
- }
572
- }