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
@@ -0,0 +1,1426 @@
1
+ import {
2
+ BaseCMI,
3
+ BaseRootCMI,
4
+ checkValidFormat,
5
+ checkValidRange,
6
+ CMIArray,
7
+ CMIScore,
8
+ } from "./common";
9
+ import APIConstants from "../constants/api_constants";
10
+ import ErrorCodes from "../constants/error_codes";
11
+ import Regex from "../constants/regex";
12
+ import { Scorm12ValidationError } from "../exceptions";
13
+ import * as Util from "../utilities";
14
+
15
+ const scorm12_constants = APIConstants.scorm12;
16
+ const scorm12_regex = Regex.scorm12;
17
+ const scorm12_error_codes = ErrorCodes.scorm12;
18
+
19
+ /**
20
+ * Helper method, no reason to have to pass the same error codes every time
21
+ * @param {string} value
22
+ * @param {string} regexPattern
23
+ * @param {boolean} allowEmptyString
24
+ * @return {boolean}
25
+ */
26
+ export function check12ValidFormat(
27
+ value: string,
28
+ regexPattern: string,
29
+ allowEmptyString?: boolean,
30
+ ): boolean {
31
+ return checkValidFormat(
32
+ value,
33
+ regexPattern,
34
+ scorm12_error_codes.TYPE_MISMATCH,
35
+ Scorm12ValidationError,
36
+ allowEmptyString,
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Helper method, no reason to have to pass the same error codes every time
42
+ * @param {string} value
43
+ * @param {string} rangePattern
44
+ * @param {boolean} allowEmptyString
45
+ * @return {boolean}
46
+ */
47
+ export function check12ValidRange(
48
+ value: any,
49
+ rangePattern: string,
50
+ allowEmptyString?: boolean,
51
+ ): boolean {
52
+ if (!allowEmptyString && value === "") {
53
+ throw new Scorm12ValidationError(scorm12_error_codes.VALUE_OUT_OF_RANGE);
54
+ }
55
+
56
+ return checkValidRange(
57
+ value,
58
+ rangePattern,
59
+ scorm12_error_codes.VALUE_OUT_OF_RANGE,
60
+ Scorm12ValidationError,
61
+ );
62
+ }
63
+
64
+ /**
65
+ * Class representing the cmi object for SCORM 1.2
66
+ */
67
+ export class CMI extends BaseRootCMI {
68
+ private readonly __children: string = "";
69
+ private __version: string = "3.4";
70
+ private _launch_data: string = "";
71
+ private _comments: string = "";
72
+ private _comments_from_lms: string = "";
73
+
74
+ /**
75
+ * Constructor for the SCORM 1.2 cmi object
76
+ * @param {string} cmi_children
77
+ * @param {(CMIStudentData|AICCCMIStudentData)} student_data
78
+ * @param {boolean} initialized
79
+ */
80
+ constructor(
81
+ cmi_children?: string,
82
+ student_data?: CMIStudentData,
83
+ initialized?: boolean,
84
+ ) {
85
+ super();
86
+ if (initialized) this.initialize();
87
+ this.__children = cmi_children
88
+ ? cmi_children
89
+ : scorm12_constants.cmi_children;
90
+ this.core = new CMICore();
91
+ this.objectives = new CMIObjectives();
92
+ this.student_data = student_data ? student_data : new CMIStudentData();
93
+ this.student_preference = new CMIStudentPreference();
94
+ this.interactions = new CMIInteractions();
95
+ }
96
+
97
+ public core: CMICore;
98
+ public objectives: CMIObjectives;
99
+ public student_data: CMIStudentData;
100
+ public student_preference: CMIStudentPreference;
101
+ public interactions: CMIInteractions;
102
+
103
+ /**
104
+ * Called when the API has been initialized after the CMI has been created
105
+ */
106
+ initialize() {
107
+ super.initialize();
108
+ this.core?.initialize();
109
+ this.objectives?.initialize();
110
+ this.student_data?.initialize();
111
+ this.student_preference?.initialize();
112
+ this.interactions?.initialize();
113
+ }
114
+
115
+ /**
116
+ * toJSON for cmi
117
+ *
118
+ * @return {
119
+ * {
120
+ * suspend_data: string,
121
+ * launch_data: string,
122
+ * comments: string,
123
+ * comments_from_lms: string,
124
+ * core: CMICore,
125
+ * objectives: CMIObjectives,
126
+ * student_data: CMIStudentData,
127
+ * student_preference: CMIStudentPreference,
128
+ * interactions: CMIInteractions
129
+ * }
130
+ * }
131
+ */
132
+ toJSON(): {
133
+ suspend_data: string;
134
+ launch_data: string;
135
+ comments: string;
136
+ comments_from_lms: string;
137
+ core: CMICore;
138
+ objectives: CMIObjectives;
139
+ student_data: CMIStudentData;
140
+ student_preference: CMIStudentPreference;
141
+ interactions: CMIInteractions;
142
+ } {
143
+ this.jsonString = true;
144
+ const result = {
145
+ suspend_data: this.suspend_data,
146
+ launch_data: this.launch_data,
147
+ comments: this.comments,
148
+ comments_from_lms: this.comments_from_lms,
149
+ core: this.core,
150
+ objectives: this.objectives,
151
+ student_data: this.student_data,
152
+ student_preference: this.student_preference,
153
+ interactions: this.interactions,
154
+ };
155
+ delete this.jsonString;
156
+ return result;
157
+ }
158
+
159
+ /**
160
+ * Getter for __version
161
+ * @return {string}
162
+ */
163
+ get _version(): string {
164
+ return this.__version;
165
+ }
166
+
167
+ /**
168
+ * Setter for __version. Just throws an error.
169
+ * @param {string} _version
170
+ */
171
+ set _version(_version: string) {
172
+ throw new Scorm12ValidationError(scorm12_error_codes.INVALID_SET_VALUE);
173
+ }
174
+
175
+ /**
176
+ * Getter for __children
177
+ * @return {string}
178
+ */
179
+ get _children(): string {
180
+ return this.__children;
181
+ }
182
+
183
+ /**
184
+ * Setter for __version. Just throws an error.
185
+ * @param {string} _children
186
+ */
187
+ set _children(_children: string) {
188
+ throw new Scorm12ValidationError(scorm12_error_codes.INVALID_SET_VALUE);
189
+ }
190
+
191
+ /**
192
+ * Getter for _suspend_data
193
+ * @return {string}
194
+ */
195
+ get suspend_data(): string {
196
+ return this.core?.suspend_data;
197
+ }
198
+
199
+ /**
200
+ * Setter for _suspend_data
201
+ * @param {string} suspend_data
202
+ */
203
+ set suspend_data(suspend_data: string) {
204
+ if (this.core) {
205
+ this.core.suspend_data = suspend_data;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Getter for _launch_data
211
+ * @return {string}
212
+ */
213
+ get launch_data(): string {
214
+ return this._launch_data;
215
+ }
216
+
217
+ /**
218
+ * Setter for _launch_data. Can only be called before initialization.
219
+ * @param {string} launch_data
220
+ */
221
+ set launch_data(launch_data: string) {
222
+ if (this.initialized) {
223
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
224
+ } else {
225
+ this._launch_data = launch_data;
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Getter for _comments
231
+ * @return {string}
232
+ */
233
+ get comments(): string {
234
+ return this._comments;
235
+ }
236
+
237
+ /**
238
+ * Setter for _comments
239
+ * @param {string} comments
240
+ */
241
+ set comments(comments: string) {
242
+ if (check12ValidFormat(comments, scorm12_regex.CMIString4096, true)) {
243
+ this._comments = comments;
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Getter for _comments_from_lms
249
+ * @return {string}
250
+ */
251
+ get comments_from_lms(): string {
252
+ return this._comments_from_lms;
253
+ }
254
+
255
+ /**
256
+ * Setter for _comments_from_lms. Can only be called before initialization.
257
+ * @param {string} comments_from_lms
258
+ */
259
+ set comments_from_lms(comments_from_lms: string) {
260
+ if (this.initialized) {
261
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
262
+ } else {
263
+ this._comments_from_lms = comments_from_lms;
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Adds the current session time to the existing total time.
269
+ *
270
+ * @return {string}
271
+ */
272
+ getCurrentTotalTime(): string {
273
+ return this.core.getCurrentTotalTime(this.start_time);
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Class representing the cmi.core object
279
+ * @extends BaseCMI
280
+ */
281
+
282
+ export class CMICore extends BaseCMI {
283
+ /**
284
+ * Constructor for cmi.core
285
+ */
286
+ constructor() {
287
+ super();
288
+ this.score = new CMIScore({
289
+ score_children: scorm12_constants.score_children,
290
+ score_range: scorm12_regex.score_range,
291
+ invalidErrorCode: scorm12_error_codes.INVALID_SET_VALUE,
292
+ invalidTypeCode: scorm12_error_codes.TYPE_MISMATCH,
293
+ invalidRangeCode: scorm12_error_codes.VALUE_OUT_OF_RANGE,
294
+ errorClass: Scorm12ValidationError,
295
+ });
296
+ }
297
+
298
+ public readonly score: CMIScore;
299
+
300
+ /**
301
+ * Called when the API has been initialized after the CMI has been created
302
+ */
303
+ initialize() {
304
+ super.initialize();
305
+ this.score?.initialize();
306
+ }
307
+
308
+ private __children = scorm12_constants.core_children;
309
+ private _student_id = "";
310
+ private _student_name = "";
311
+ private _lesson_location = "";
312
+ private _credit = "";
313
+ private _lesson_status = "not attempted";
314
+ private _entry = "";
315
+ private _total_time = "";
316
+ private _lesson_mode = "normal";
317
+ private _exit = "";
318
+ private _session_time = "00:00:00";
319
+ private _suspend_data = "";
320
+
321
+ /**
322
+ * Getter for __children
323
+ * @return {string}
324
+ * @private
325
+ */
326
+ get _children(): string {
327
+ return this.__children;
328
+ }
329
+
330
+ /**
331
+ * Setter for __children. Just throws an error.
332
+ * @param {string} _children
333
+ * @private
334
+ */
335
+ set _children(_children: string) {
336
+ throw new Scorm12ValidationError(scorm12_error_codes.INVALID_SET_VALUE);
337
+ }
338
+
339
+ /**
340
+ * Getter for _student_id
341
+ * @return {string}
342
+ */
343
+ get student_id(): string {
344
+ return this._student_id;
345
+ }
346
+
347
+ /**
348
+ * Setter for _student_id. Can only be called before initialization.
349
+ * @param {string} student_id
350
+ */
351
+ set student_id(student_id: string) {
352
+ if (this.initialized) {
353
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
354
+ } else {
355
+ this._student_id = student_id;
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Getter for _student_name
361
+ * @return {string}
362
+ */
363
+ get student_name(): string {
364
+ return this._student_name;
365
+ }
366
+
367
+ /**
368
+ * Setter for _student_name. Can only be called before initialization.
369
+ * @param {string} student_name
370
+ */
371
+ set student_name(student_name: string) {
372
+ if (this.initialized) {
373
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
374
+ } else {
375
+ this._student_name = student_name;
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Getter for _lesson_location
381
+ * @return {string}
382
+ */
383
+ get lesson_location(): string {
384
+ return this._lesson_location;
385
+ }
386
+
387
+ /**
388
+ * Setter for _lesson_location
389
+ * @param {string} lesson_location
390
+ */
391
+ set lesson_location(lesson_location: string) {
392
+ if (check12ValidFormat(lesson_location, scorm12_regex.CMIString256, true)) {
393
+ this._lesson_location = lesson_location;
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Getter for _credit
399
+ * @return {string}
400
+ */
401
+ get credit(): string {
402
+ return this._credit;
403
+ }
404
+
405
+ /**
406
+ * Setter for _credit. Can only be called before initialization.
407
+ * @param {string} credit
408
+ */
409
+ set credit(credit: string) {
410
+ if (this.initialized) {
411
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
412
+ } else {
413
+ this._credit = credit;
414
+ }
415
+ }
416
+
417
+ /**
418
+ * Getter for _lesson_status
419
+ * @return {string}
420
+ */
421
+ get lesson_status(): string {
422
+ return this._lesson_status;
423
+ }
424
+
425
+ /**
426
+ * Setter for _lesson_status
427
+ * @param {string} lesson_status
428
+ */
429
+ set lesson_status(lesson_status: string) {
430
+ if (this.initialized) {
431
+ if (check12ValidFormat(lesson_status, scorm12_regex.CMIStatus)) {
432
+ this._lesson_status = lesson_status;
433
+ }
434
+ } else {
435
+ if (check12ValidFormat(lesson_status, scorm12_regex.CMIStatus2)) {
436
+ this._lesson_status = lesson_status;
437
+ }
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Getter for _entry
443
+ * @return {string}
444
+ */
445
+ get entry(): string {
446
+ return this._entry;
447
+ }
448
+
449
+ /**
450
+ * Setter for _entry. Can only be called before initialization.
451
+ * @param {string} entry
452
+ */
453
+ set entry(entry: string) {
454
+ if (this.initialized) {
455
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
456
+ } else {
457
+ this._entry = entry;
458
+ }
459
+ }
460
+
461
+ /**
462
+ * Getter for _total_time
463
+ * @return {string}
464
+ */
465
+ get total_time(): string {
466
+ return this._total_time;
467
+ }
468
+
469
+ /**
470
+ * Setter for _total_time. Can only be called before initialization.
471
+ * @param {string} total_time
472
+ */
473
+ set total_time(total_time: string) {
474
+ if (this.initialized) {
475
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
476
+ } else {
477
+ this._total_time = total_time;
478
+ }
479
+ }
480
+
481
+ /**
482
+ * Getter for _lesson_mode
483
+ * @return {string}
484
+ */
485
+ get lesson_mode(): string {
486
+ return this._lesson_mode;
487
+ }
488
+
489
+ /**
490
+ * Setter for _lesson_mode. Can only be called before initialization.
491
+ * @param {string} lesson_mode
492
+ */
493
+ set lesson_mode(lesson_mode: string) {
494
+ if (this.initialized) {
495
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
496
+ } else {
497
+ this._lesson_mode = lesson_mode;
498
+ }
499
+ }
500
+
501
+ /**
502
+ * Getter for _exit. Should only be called during JSON export.
503
+ * @return {string}
504
+ */
505
+ get exit(): string {
506
+ if (!this.jsonString) {
507
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
508
+ }
509
+ return this._exit;
510
+ }
511
+
512
+ /**
513
+ * Setter for _exit
514
+ * @param {string} exit
515
+ */
516
+ set exit(exit: string) {
517
+ if (check12ValidFormat(exit, scorm12_regex.CMIExit, true)) {
518
+ this._exit = exit;
519
+ }
520
+ }
521
+
522
+ /**
523
+ * Getter for _session_time. Should only be called during JSON export.
524
+ * @return {string}
525
+ */
526
+ get session_time(): string {
527
+ if (!this.jsonString) {
528
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
529
+ }
530
+ return this._session_time;
531
+ }
532
+
533
+ /**
534
+ * Setter for _session_time
535
+ * @param {string} session_time
536
+ */
537
+ set session_time(session_time: string) {
538
+ if (check12ValidFormat(session_time, scorm12_regex.CMITimespan)) {
539
+ this._session_time = session_time;
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Getter for _suspend_data
545
+ * @return {string}
546
+ */
547
+ get suspend_data(): string {
548
+ return this._suspend_data;
549
+ }
550
+
551
+ /**
552
+ * Setter for _suspend_data
553
+ * @param {string} suspend_data
554
+ */
555
+ set suspend_data(suspend_data: string) {
556
+ if (check12ValidFormat(suspend_data, scorm12_regex.CMIString4096, true)) {
557
+ this._suspend_data = suspend_data;
558
+ }
559
+ }
560
+
561
+ /**
562
+ * Adds the current session time to the existing total time.
563
+ * @param {number} start_time
564
+ * @return {string}
565
+ */
566
+ getCurrentTotalTime(start_time: number | undefined): string {
567
+ let sessionTime = this._session_time;
568
+ const startTime = start_time;
569
+
570
+ if (typeof startTime !== "undefined" && startTime !== null) {
571
+ const seconds = new Date().getTime() - startTime;
572
+ sessionTime = Util.getSecondsAsHHMMSS(seconds / 1000);
573
+ }
574
+
575
+ return Util.addHHMMSSTimeStrings(
576
+ this._total_time,
577
+ sessionTime,
578
+ new RegExp(scorm12_regex.CMITimespan),
579
+ );
580
+ }
581
+
582
+ /**
583
+ * toJSON for cmi.core
584
+ *
585
+ * @return {
586
+ * {
587
+ * student_name: string,
588
+ * entry: string,
589
+ * exit: string,
590
+ * score: CMIScore,
591
+ * student_id: string,
592
+ * lesson_mode: string,
593
+ * lesson_location: string,
594
+ * lesson_status: string,
595
+ * credit: string,
596
+ * session_time: string
597
+ * }
598
+ * }
599
+ */
600
+ toJSON(): {
601
+ student_name: string;
602
+ entry: string;
603
+ exit: string;
604
+ score: CMIScore;
605
+ student_id: string;
606
+ lesson_mode: string;
607
+ lesson_location: string;
608
+ lesson_status: string;
609
+ credit: string;
610
+ session_time: string;
611
+ } {
612
+ this.jsonString = true;
613
+ const result = {
614
+ student_id: this.student_id,
615
+ student_name: this.student_name,
616
+ lesson_location: this.lesson_location,
617
+ credit: this.credit,
618
+ lesson_status: this.lesson_status,
619
+ entry: this.entry,
620
+ lesson_mode: this.lesson_mode,
621
+ exit: this.exit,
622
+ session_time: this.session_time,
623
+ score: this.score,
624
+ };
625
+ delete this.jsonString;
626
+ return result;
627
+ }
628
+ }
629
+
630
+ /**
631
+ * Class representing SCORM 1.2's `cmi.objectives` object
632
+ * @extends CMIArray
633
+ */
634
+
635
+ export class CMIObjectives extends CMIArray {
636
+ /**
637
+ * Constructor for `cmi.objectives`
638
+ */
639
+ constructor() {
640
+ super({
641
+ children: scorm12_constants.objectives_children,
642
+ errorCode: scorm12_error_codes.INVALID_SET_VALUE,
643
+ errorClass: Scorm12ValidationError,
644
+ });
645
+ }
646
+ }
647
+
648
+ /**
649
+ * Class representing SCORM 1.2's cmi.student_data object
650
+ * @extends BaseCMI
651
+ */
652
+
653
+ export class CMIStudentData extends BaseCMI {
654
+ private __children;
655
+ private _mastery_score = "";
656
+ private _max_time_allowed = "";
657
+ private _time_limit_action = "";
658
+
659
+ /**
660
+ * Constructor for cmi.student_data
661
+ * @param {string} student_data_children
662
+ */
663
+ constructor(student_data_children?: string) {
664
+ super();
665
+ this.__children = student_data_children
666
+ ? student_data_children
667
+ : scorm12_constants.student_data_children;
668
+ }
669
+
670
+ /**
671
+ * Getter for __children
672
+ * @return {string}
673
+ * @private
674
+ */
675
+ get _children(): string {
676
+ return this.__children;
677
+ }
678
+
679
+ /**
680
+ * Setter for __children. Just throws an error.
681
+ * @param {string} _children
682
+ * @private
683
+ */
684
+ set _children(_children: string) {
685
+ throw new Scorm12ValidationError(scorm12_error_codes.INVALID_SET_VALUE);
686
+ }
687
+
688
+ /**
689
+ * Getter for _master_score
690
+ * @return {string}
691
+ */
692
+ get mastery_score(): string {
693
+ return this._mastery_score;
694
+ }
695
+
696
+ /**
697
+ * Setter for _master_score. Can only be called before initialization.
698
+ * @param {string} mastery_score
699
+ */
700
+ set mastery_score(mastery_score: string) {
701
+ if (this.initialized) {
702
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
703
+ } else {
704
+ this._mastery_score = mastery_score;
705
+ }
706
+ }
707
+
708
+ /**
709
+ * Getter for _max_time_allowed
710
+ * @return {string}
711
+ */
712
+ get max_time_allowed(): string {
713
+ return this._max_time_allowed;
714
+ }
715
+
716
+ /**
717
+ * Setter for _max_time_allowed. Can only be called before initialization.
718
+ * @param {string} max_time_allowed
719
+ */
720
+ set max_time_allowed(max_time_allowed: string) {
721
+ if (this.initialized) {
722
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
723
+ } else {
724
+ this._max_time_allowed = max_time_allowed;
725
+ }
726
+ }
727
+
728
+ /**
729
+ * Getter for _time_limit_action
730
+ * @return {string}
731
+ */
732
+ get time_limit_action(): string {
733
+ return this._time_limit_action;
734
+ }
735
+
736
+ /**
737
+ * Setter for _time_limit_action. Can only be called before initialization.
738
+ * @param {string} time_limit_action
739
+ */
740
+ set time_limit_action(time_limit_action: string) {
741
+ if (this.initialized) {
742
+ throw new Scorm12ValidationError(scorm12_error_codes.READ_ONLY_ELEMENT);
743
+ } else {
744
+ this._time_limit_action = time_limit_action;
745
+ }
746
+ }
747
+
748
+ /**
749
+ * toJSON for cmi.student_data
750
+ *
751
+ * @return {
752
+ * {
753
+ * max_time_allowed: string,
754
+ * time_limit_action: string,
755
+ * mastery_score: string
756
+ * }
757
+ * }
758
+ */
759
+ toJSON(): {
760
+ mastery_score: string;
761
+ max_time_allowed: string;
762
+ time_limit_action: string;
763
+ } {
764
+ this.jsonString = true;
765
+ const result = {
766
+ mastery_score: this.mastery_score,
767
+ max_time_allowed: this.max_time_allowed,
768
+ time_limit_action: this.time_limit_action,
769
+ };
770
+ delete this.jsonString;
771
+ return result;
772
+ }
773
+ }
774
+
775
+ /**
776
+ * Class representing SCORM 1.2's cmi.student_preference object
777
+ * @extends BaseCMI
778
+ */
779
+ export class CMIStudentPreference extends BaseCMI {
780
+ private __children;
781
+
782
+ /**
783
+ * Constructor for cmi.student_preference
784
+ * @param {string} student_preference_children
785
+ */
786
+ constructor(student_preference_children?: string) {
787
+ super();
788
+ this.__children = student_preference_children
789
+ ? student_preference_children
790
+ : scorm12_constants.student_preference_children;
791
+ }
792
+
793
+ private _audio = "";
794
+ private _language = "";
795
+ private _speed = "";
796
+ private _text = "";
797
+
798
+ /**
799
+ * Getter for __children
800
+ * @return {string}
801
+ * @private
802
+ */
803
+ get _children(): string {
804
+ return this.__children;
805
+ }
806
+
807
+ /**
808
+ * Setter for __children. Just throws an error.
809
+ * @param {string} _children
810
+ * @private
811
+ */
812
+ set _children(_children: string) {
813
+ throw new Scorm12ValidationError(scorm12_error_codes.INVALID_SET_VALUE);
814
+ }
815
+
816
+ /**
817
+ * Getter for _audio
818
+ * @return {string}
819
+ */
820
+ get audio(): string {
821
+ return this._audio;
822
+ }
823
+
824
+ /**
825
+ * Setter for _audio
826
+ * @param {string} audio
827
+ */
828
+ set audio(audio: string) {
829
+ if (
830
+ check12ValidFormat(audio, scorm12_regex.CMISInteger) &&
831
+ check12ValidRange(audio, scorm12_regex.audio_range)
832
+ ) {
833
+ this._audio = audio;
834
+ }
835
+ }
836
+
837
+ /**
838
+ * Getter for _language
839
+ * @return {string}
840
+ */
841
+ get language(): string {
842
+ return this._language;
843
+ }
844
+
845
+ /**
846
+ * Setter for _language
847
+ * @param {string} language
848
+ */
849
+ set language(language: string) {
850
+ if (check12ValidFormat(language, scorm12_regex.CMIString256)) {
851
+ this._language = language;
852
+ }
853
+ }
854
+
855
+ /**
856
+ * Getter for _speed
857
+ * @return {string}
858
+ */
859
+ get speed(): string {
860
+ return this._speed;
861
+ }
862
+
863
+ /**
864
+ * Setter for _speed
865
+ * @param {string} speed
866
+ */
867
+ set speed(speed: string) {
868
+ if (
869
+ check12ValidFormat(speed, scorm12_regex.CMISInteger) &&
870
+ check12ValidRange(speed, scorm12_regex.speed_range)
871
+ ) {
872
+ this._speed = speed;
873
+ }
874
+ }
875
+
876
+ /**
877
+ * Getter for _text
878
+ * @return {string}
879
+ */
880
+ get text(): string {
881
+ return this._text;
882
+ }
883
+
884
+ /**
885
+ * Setter for _text
886
+ * @param {string} text
887
+ */
888
+ set text(text: string) {
889
+ if (
890
+ check12ValidFormat(text, scorm12_regex.CMISInteger) &&
891
+ check12ValidRange(text, scorm12_regex.text_range)
892
+ ) {
893
+ this._text = text;
894
+ }
895
+ }
896
+
897
+ /**
898
+ * toJSON for cmi.student_preference
899
+ *
900
+ * @return {
901
+ * {
902
+ * audio: string,
903
+ * language: string,
904
+ * speed: string,
905
+ * text: string
906
+ * }
907
+ * }
908
+ */
909
+ toJSON(): {
910
+ audio: string;
911
+ language: string;
912
+ speed: string;
913
+ text: string;
914
+ } {
915
+ this.jsonString = true;
916
+ const result = {
917
+ audio: this.audio,
918
+ language: this.language,
919
+ speed: this.speed,
920
+ text: this.text,
921
+ };
922
+ delete this.jsonString;
923
+ return result;
924
+ }
925
+ }
926
+
927
+ /**
928
+ * Class representing SCORM 1.2's `cmi.interactions` object
929
+ * @extends BaseCMI
930
+ */
931
+
932
+ export class CMIInteractions extends CMIArray {
933
+ /**
934
+ * Constructor for `cmi.interactions`
935
+ */
936
+ constructor() {
937
+ super({
938
+ children: scorm12_constants.interactions_children,
939
+ errorCode: scorm12_error_codes.INVALID_SET_VALUE,
940
+ errorClass: Scorm12ValidationError,
941
+ });
942
+ }
943
+ }
944
+
945
+ /**
946
+ * Class representing SCORM 1.2's cmi.interactions.n object
947
+ * @extends BaseCMI
948
+ */
949
+
950
+ export class CMIInteractionsObject extends BaseCMI {
951
+ /**
952
+ * Constructor for cmi.interactions.n object
953
+ */
954
+ constructor() {
955
+ super();
956
+ this.objectives = new CMIArray({
957
+ errorCode: scorm12_error_codes.INVALID_SET_VALUE,
958
+ errorClass: Scorm12ValidationError,
959
+ children: scorm12_constants.objectives_children,
960
+ });
961
+ this.correct_responses = new CMIArray({
962
+ errorCode: scorm12_error_codes.INVALID_SET_VALUE,
963
+ errorClass: Scorm12ValidationError,
964
+ children: scorm12_constants.correct_responses_children,
965
+ });
966
+ }
967
+
968
+ public readonly objectives: CMIArray;
969
+ public readonly correct_responses: CMIArray;
970
+
971
+ /**
972
+ * Called when the API has been initialized after the CMI has been created
973
+ */
974
+ initialize() {
975
+ super.initialize();
976
+ this.objectives?.initialize();
977
+ this.correct_responses?.initialize();
978
+ }
979
+
980
+ private _id = "";
981
+ private _time = "";
982
+ private _type = "";
983
+ private _weighting = "";
984
+ private _student_response = "";
985
+ private _result = "";
986
+ private _latency = "";
987
+
988
+ /**
989
+ * Getter for _id. Should only be called during JSON export.
990
+ * @return {string}
991
+ */
992
+ get id(): string {
993
+ if (!this.jsonString) {
994
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
995
+ }
996
+ return this._id;
997
+ }
998
+
999
+ /**
1000
+ * Setter for _id
1001
+ * @param {string} id
1002
+ */
1003
+ set id(id: string) {
1004
+ if (check12ValidFormat(id, scorm12_regex.CMIIdentifier)) {
1005
+ this._id = id;
1006
+ }
1007
+ }
1008
+
1009
+ /**
1010
+ * Getter for _time. Should only be called during JSON export.
1011
+ * @return {string}
1012
+ */
1013
+ get time(): string {
1014
+ if (!this.jsonString) {
1015
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1016
+ }
1017
+ return this._time;
1018
+ }
1019
+
1020
+ /**
1021
+ * Setter for _time
1022
+ * @param {string} time
1023
+ */
1024
+ set time(time: string) {
1025
+ if (check12ValidFormat(time, scorm12_regex.CMITime)) {
1026
+ this._time = time;
1027
+ }
1028
+ }
1029
+
1030
+ /**
1031
+ * Getter for _type. Should only be called during JSON export.
1032
+ * @return {string}
1033
+ */
1034
+ get type(): string {
1035
+ if (!this.jsonString) {
1036
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1037
+ }
1038
+ return this._type;
1039
+ }
1040
+
1041
+ /**
1042
+ * Setter for _type
1043
+ * @param {string} type
1044
+ */
1045
+ set type(type: string) {
1046
+ if (check12ValidFormat(type, scorm12_regex.CMIType)) {
1047
+ this._type = type;
1048
+ }
1049
+ }
1050
+
1051
+ /**
1052
+ * Getter for _weighting. Should only be called during JSON export.
1053
+ * @return {string}
1054
+ */
1055
+ get weighting(): string {
1056
+ if (!this.jsonString) {
1057
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1058
+ }
1059
+ return this._weighting;
1060
+ }
1061
+
1062
+ /**
1063
+ * Setter for _weighting
1064
+ * @param {string} weighting
1065
+ */
1066
+ set weighting(weighting: string) {
1067
+ if (
1068
+ check12ValidFormat(weighting, scorm12_regex.CMIDecimal) &&
1069
+ check12ValidRange(weighting, scorm12_regex.weighting_range)
1070
+ ) {
1071
+ this._weighting = weighting;
1072
+ }
1073
+ }
1074
+
1075
+ /**
1076
+ * Getter for _student_response. Should only be called during JSON export.
1077
+ * @return {string}
1078
+ */
1079
+ get student_response(): string {
1080
+ if (!this.jsonString) {
1081
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1082
+ }
1083
+ return this._student_response;
1084
+ }
1085
+
1086
+ /**
1087
+ * Setter for _student_response
1088
+ * @param {string} student_response
1089
+ */
1090
+ set student_response(student_response: string) {
1091
+ if (check12ValidFormat(student_response, scorm12_regex.CMIFeedback, true)) {
1092
+ this._student_response = student_response;
1093
+ }
1094
+ }
1095
+
1096
+ /**
1097
+ * Getter for _result. Should only be called during JSON export.
1098
+ * @return {string}
1099
+ */
1100
+ get result(): string {
1101
+ if (!this.jsonString) {
1102
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1103
+ }
1104
+ return this._result;
1105
+ }
1106
+
1107
+ /**
1108
+ * Setter for _result
1109
+ * @param {string} result
1110
+ */
1111
+ set result(result: string) {
1112
+ if (check12ValidFormat(result, scorm12_regex.CMIResult)) {
1113
+ this._result = result;
1114
+ }
1115
+ }
1116
+
1117
+ /**
1118
+ * Getter for _latency. Should only be called during JSON export.
1119
+ * @return {string}
1120
+ */
1121
+ get latency(): string {
1122
+ if (!this.jsonString) {
1123
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1124
+ }
1125
+ return this._latency;
1126
+ }
1127
+
1128
+ /**
1129
+ * Setter for _latency
1130
+ * @param {string} latency
1131
+ */
1132
+ set latency(latency: string) {
1133
+ if (check12ValidFormat(latency, scorm12_regex.CMITimespan)) {
1134
+ this._latency = latency;
1135
+ }
1136
+ }
1137
+
1138
+ /**
1139
+ * toJSON for cmi.interactions.n
1140
+ *
1141
+ * @return {
1142
+ * {
1143
+ * id: string,
1144
+ * time: string,
1145
+ * type: string,
1146
+ * weighting: string,
1147
+ * student_response: string,
1148
+ * result: string,
1149
+ * latency: string,
1150
+ * objectives: CMIArray,
1151
+ * correct_responses: CMIArray
1152
+ * }
1153
+ * }
1154
+ */
1155
+ toJSON(): {
1156
+ id: string;
1157
+ time: string;
1158
+ type: string;
1159
+ weighting: string;
1160
+ student_response: string;
1161
+ result: string;
1162
+ latency: string;
1163
+ objectives: CMIArray;
1164
+ correct_responses: CMIArray;
1165
+ } {
1166
+ this.jsonString = true;
1167
+ const result = {
1168
+ id: this.id,
1169
+ time: this.time,
1170
+ type: this.type,
1171
+ weighting: this.weighting,
1172
+ student_response: this.student_response,
1173
+ result: this.result,
1174
+ latency: this.latency,
1175
+ objectives: this.objectives,
1176
+ correct_responses: this.correct_responses,
1177
+ };
1178
+ delete this.jsonString;
1179
+ return result;
1180
+ }
1181
+ }
1182
+
1183
+ /**
1184
+ * Class representing SCORM 1.2's cmi.objectives.n object
1185
+ * @extends BaseCMI
1186
+ */
1187
+ export class CMIObjectivesObject extends BaseCMI {
1188
+ /**
1189
+ * Constructor for cmi.objectives.n
1190
+ */
1191
+ constructor() {
1192
+ super();
1193
+ this.score = new CMIScore({
1194
+ score_children: scorm12_constants.score_children,
1195
+ score_range: scorm12_regex.score_range,
1196
+ invalidErrorCode: scorm12_error_codes.INVALID_SET_VALUE,
1197
+ invalidTypeCode: scorm12_error_codes.TYPE_MISMATCH,
1198
+ invalidRangeCode: scorm12_error_codes.VALUE_OUT_OF_RANGE,
1199
+ errorClass: Scorm12ValidationError,
1200
+ });
1201
+ }
1202
+
1203
+ public readonly score: CMIScore;
1204
+
1205
+ private _id = "";
1206
+ private _status = "";
1207
+
1208
+ /**
1209
+ * Getter for _id
1210
+ * @return {string}
1211
+ */
1212
+ get id(): string {
1213
+ return this._id;
1214
+ }
1215
+
1216
+ /**
1217
+ * Setter for _id
1218
+ * @param {string} id
1219
+ */
1220
+ set id(id: string) {
1221
+ if (check12ValidFormat(id, scorm12_regex.CMIIdentifier)) {
1222
+ this._id = id;
1223
+ }
1224
+ }
1225
+
1226
+ /**
1227
+ * Getter for _status
1228
+ * @return {string}
1229
+ */
1230
+ get status(): string {
1231
+ return this._status;
1232
+ }
1233
+
1234
+ /**
1235
+ * Setter for _status
1236
+ * @param {string} status
1237
+ */
1238
+ set status(status: string) {
1239
+ if (check12ValidFormat(status, scorm12_regex.CMIStatus2)) {
1240
+ this._status = status;
1241
+ }
1242
+ }
1243
+
1244
+ /**
1245
+ * toJSON for cmi.objectives.n
1246
+ * @return {
1247
+ * {
1248
+ * id: string,
1249
+ * status: string,
1250
+ * score: CMIScore
1251
+ * }
1252
+ * }
1253
+ */
1254
+ toJSON(): {
1255
+ id: string;
1256
+ status: string;
1257
+ score: CMIScore;
1258
+ } {
1259
+ this.jsonString = true;
1260
+ const result = {
1261
+ id: this.id,
1262
+ status: this.status,
1263
+ score: this.score,
1264
+ };
1265
+ delete this.jsonString;
1266
+ return result;
1267
+ }
1268
+ }
1269
+
1270
+ /**
1271
+ * Class representing SCORM 1.2's cmi.interactions.n.objectives.n object
1272
+ * @extends BaseCMI
1273
+ */
1274
+ export class CMIInteractionsObjectivesObject extends BaseCMI {
1275
+ /**
1276
+ * Constructor for cmi.interactions.n.objectives.n
1277
+ */
1278
+ constructor() {
1279
+ super();
1280
+ }
1281
+
1282
+ private _id = "";
1283
+
1284
+ /**
1285
+ * Getter for _id
1286
+ * @return {string}
1287
+ */
1288
+ get id(): string {
1289
+ return this._id;
1290
+ }
1291
+
1292
+ /**
1293
+ * Setter for _id
1294
+ * @param {string} id
1295
+ */
1296
+ set id(id: string) {
1297
+ if (check12ValidFormat(id, scorm12_regex.CMIIdentifier)) {
1298
+ this._id = id;
1299
+ }
1300
+ }
1301
+
1302
+ /**
1303
+ * toJSON for cmi.interactions.n.objectives.n
1304
+ * @return {
1305
+ * {
1306
+ * id: string
1307
+ * }
1308
+ * }
1309
+ */
1310
+ toJSON(): {
1311
+ id: string;
1312
+ } {
1313
+ this.jsonString = true;
1314
+ const result = {
1315
+ id: this.id,
1316
+ };
1317
+ delete this.jsonString;
1318
+ return result;
1319
+ }
1320
+ }
1321
+
1322
+ /**
1323
+ * Class representing SCORM 1.2's cmi.interactions.correct_responses.n object
1324
+ * @extends BaseCMI
1325
+ */
1326
+ export class CMIInteractionsCorrectResponsesObject extends BaseCMI {
1327
+ /**
1328
+ * Constructor for cmi.interactions.correct_responses.n
1329
+ */
1330
+ constructor() {
1331
+ super();
1332
+ }
1333
+
1334
+ private _pattern = "";
1335
+
1336
+ /**
1337
+ * Getter for _pattern
1338
+ * @return {string}
1339
+ */
1340
+ get pattern(): string {
1341
+ if (!this.jsonString) {
1342
+ throw new Scorm12ValidationError(scorm12_error_codes.WRITE_ONLY_ELEMENT);
1343
+ }
1344
+ return this._pattern;
1345
+ }
1346
+
1347
+ /**
1348
+ * Setter for _pattern
1349
+ * @param {string} pattern
1350
+ */
1351
+ set pattern(pattern: string) {
1352
+ if (check12ValidFormat(pattern, scorm12_regex.CMIFeedback, true)) {
1353
+ this._pattern = pattern;
1354
+ }
1355
+ }
1356
+
1357
+ /**
1358
+ * toJSON for cmi.interactions.correct_responses.n
1359
+ * @return {
1360
+ * {
1361
+ * pattern: string
1362
+ * }
1363
+ * }
1364
+ */
1365
+ toJSON(): {
1366
+ pattern: string;
1367
+ } {
1368
+ this.jsonString = true;
1369
+ const result = {
1370
+ pattern: this._pattern,
1371
+ };
1372
+ delete this.jsonString;
1373
+ return result;
1374
+ }
1375
+ }
1376
+
1377
+ /**
1378
+ * Class for AICC Navigation object
1379
+ */
1380
+ export class NAV extends BaseCMI {
1381
+ /**
1382
+ * Constructor for NAV object
1383
+ */
1384
+ constructor() {
1385
+ super();
1386
+ }
1387
+
1388
+ private _event = "";
1389
+
1390
+ /**
1391
+ * Getter for _event
1392
+ * @return {string}
1393
+ */
1394
+ get event(): string {
1395
+ return this._event;
1396
+ }
1397
+
1398
+ /**
1399
+ * Setter for _event
1400
+ * @param {string} event
1401
+ */
1402
+ set event(event: string) {
1403
+ if (check12ValidFormat(event, scorm12_regex.NAVEvent)) {
1404
+ this._event = event;
1405
+ }
1406
+ }
1407
+
1408
+ /**
1409
+ * toJSON for nav object
1410
+ * @return {
1411
+ * {
1412
+ * event: string
1413
+ * }
1414
+ * }
1415
+ */
1416
+ toJSON(): {
1417
+ event: string;
1418
+ } {
1419
+ this.jsonString = true;
1420
+ const result = {
1421
+ event: this.event,
1422
+ };
1423
+ delete this.jsonString;
1424
+ return result;
1425
+ }
1426
+ }