fcad-core-dragon 2.0.0-beta.1 → 2.0.0-beta.3

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 (118) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/{.eslintrc.js → .eslintrc.cjs} +81 -86
  4. package/CHANGELOG +364 -364
  5. package/README.md +71 -71
  6. package/bk.scss +117 -0
  7. package/package.json +61 -63
  8. package/src/$locales/en.json +143 -179
  9. package/src/$locales/fr.json +105 -181
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +1054 -614
  12. package/src/components/AppBaseButton.vue +87 -63
  13. package/src/components/AppBaseErrorDisplay.vue +438 -420
  14. package/src/components/AppBaseFlipCard.vue +84 -83
  15. package/src/components/AppBaseModule.vue +1673 -1842
  16. package/src/components/AppBasePage.vue +779 -312
  17. package/src/components/AppBasePopover.vue +41 -0
  18. package/src/components/AppCompAudio.vue +234 -0
  19. package/src/components/AppCompBranchButtons.vue +552 -582
  20. package/src/components/AppCompButtonProgress.vue +126 -147
  21. package/src/components/AppCompCarousel.vue +298 -192
  22. package/src/components/AppCompInputCheckBoxNext.vue +195 -0
  23. package/src/components/AppCompInputDropdownNext.vue +159 -0
  24. package/src/components/AppCompInputRadioNext.vue +152 -0
  25. package/src/components/{AppCompInputTextBox.vue → AppCompInputTextNext.vue} +106 -91
  26. package/src/components/AppCompInputTextTableNext.vue +141 -0
  27. package/src/components/AppCompInputTextToFillDropdownNext.vue +230 -0
  28. package/src/components/{AppCompInputTextToFillText.vue → AppCompInputTextToFillNext.vue} +171 -164
  29. package/src/components/AppCompJauge.vue +74 -55
  30. package/src/components/AppCompMenu.vue +413 -209
  31. package/src/components/AppCompMenuItem.vue +228 -174
  32. package/src/components/AppCompNavigation.vue +960 -949
  33. package/src/components/AppCompNoteCall.vue +133 -126
  34. package/src/components/AppCompNoteCredit.vue +292 -164
  35. package/src/components/AppCompPlayBar.vue +1218 -1319
  36. package/src/components/AppCompPlayBarNext.vue +2052 -0
  37. package/src/components/AppCompPlayBarProgress.vue +82 -0
  38. package/src/components/AppCompPopUpNext.vue +503 -0
  39. package/src/components/{AppCompQuiz.vue → AppCompQuizNext.vue} +2904 -2989
  40. package/src/components/AppCompQuizRecall.vue +276 -250
  41. package/src/components/AppCompSVGNext.vue +347 -0
  42. package/src/components/AppCompSettingsMenu.vue +172 -171
  43. package/src/components/AppCompTableOfContent.vue +387 -264
  44. package/src/components/AppCompTranscript.vue +24 -19
  45. package/src/components/AppCompVideoPlayer.vue +368 -336
  46. package/src/components/AppCompViewDisplay.vue +6 -6
  47. package/src/components/BaseModule.vue +72 -67
  48. package/src/composables/useQuiz.js +206 -0
  49. package/src/externalComps/ModuleView.vue +22 -0
  50. package/src/externalComps/SummaryView.vue +91 -0
  51. package/src/main.js +272 -227
  52. package/src/mixins/$mediaMixins.js +819 -0
  53. package/src/mixins/timerMixin.js +155 -156
  54. package/src/module/stores/appStore.js +893 -0
  55. package/src/module/xapi/ADL.js +376 -339
  56. package/src/module/xapi/Crypto/Hasher.js +241 -241
  57. package/src/module/xapi/Crypto/WordArray.js +278 -278
  58. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  59. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -319
  60. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  61. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  62. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  63. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  64. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  65. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  66. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  67. package/src/module/xapi/Crypto/index.js +53 -53
  68. package/src/module/xapi/Statement/activity.js +47 -47
  69. package/src/module/xapi/Statement/agent.js +55 -55
  70. package/src/module/xapi/Statement/group.js +26 -26
  71. package/src/module/xapi/Statement/index.js +259 -259
  72. package/src/module/xapi/Statement/statement.js +253 -253
  73. package/src/module/xapi/Statement/statementRef.js +23 -23
  74. package/src/module/xapi/Statement/substatement.js +22 -22
  75. package/src/module/xapi/Statement/verb.js +36 -36
  76. package/src/module/xapi/activitytypes.js +17 -17
  77. package/src/module/xapi/launch.js +157 -157
  78. package/src/module/xapi/utils.js +167 -167
  79. package/src/module/xapi/verbs.js +294 -294
  80. package/src/module/xapi/wrapper.js +1963 -1890
  81. package/src/module/xapi/xapiStatement.js +444 -444
  82. package/src/plugins/bus.js +8 -3
  83. package/src/plugins/gsap.js +14 -17
  84. package/src/plugins/helper.js +308 -295
  85. package/src/plugins/i18n.js +44 -31
  86. package/src/plugins/idb.js +219 -212
  87. package/src/plugins/save.js +37 -37
  88. package/src/plugins/scorm.js +287 -287
  89. package/src/plugins/xapi.js +11 -11
  90. package/src/public/index.html +33 -21
  91. package/src/router/index.js +43 -41
  92. package/src/router/routes.js +312 -337
  93. package/src/shared/generalfuncs.js +210 -188
  94. package/src/shared/validators.js +1069 -249
  95. package/vite.config.js +27 -0
  96. package/.prettierrc.js +0 -5
  97. package/babel.config.js +0 -3
  98. package/src/components/AppBaseDragChoice.vue +0 -91
  99. package/src/components/AppBaseDropZone.vue +0 -112
  100. package/src/components/AppCompBif.vue +0 -120
  101. package/src/components/AppCompDragAndDrop.vue +0 -339
  102. package/src/components/AppCompInputAssociation.vue +0 -332
  103. package/src/components/AppCompInputCheckBox.vue +0 -227
  104. package/src/components/AppCompInputDropdown.vue +0 -184
  105. package/src/components/AppCompInputRadio.vue +0 -169
  106. package/src/components/AppCompInputTextTable.vue +0 -155
  107. package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
  108. package/src/components/AppCompMediaPlayer.vue +0 -397
  109. package/src/components/AppCompPopUp.vue +0 -522
  110. package/src/components/AppCompPopover.vue +0 -27
  111. package/src/components/AppCompSVG.vue +0 -309
  112. package/src/mixins/$pageMixins.js +0 -459
  113. package/src/mixins/$quizMixins.js +0 -456
  114. package/src/module/store.js +0 -895
  115. package/src/plugins/timeManager.js +0 -77
  116. package/src/routes_bckp.js +0 -313
  117. package/src/routes_static.js +0 -344
  118. package/vue.config.js +0 -83
@@ -1,249 +1,1069 @@
1
- /**
2
- * @description Validator for the content of menu setting file
3
- * @param {String} fName- name of the file for use case
4
- * @param {Object} fData: file's data to validate
5
- * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
6
- */
7
- const validatefileContent = (fName, fData, requiredArgs = {}) => {
8
- let err = null
9
- if (process.env.NODE_ENV === 'development') {
10
- switch (fName) {
11
- case 'menuSettings': {
12
- const { keys4Activity, keys4Anchors } = requiredArgs
13
-
14
- //*validate that data is an {Object}. if Not send error message
15
- if (fData.constructor !== Object)
16
- err = '💥Invalid file provided for menu settings'
17
-
18
- if (Object.entries(fData).length > 0) {
19
- const content = Object.entries(fData)
20
-
21
- for (let el of content) {
22
- // validate that the content of each entry is an object
23
- if (el[1].constructor !== Object || !Object.keys(el[1]).length) {
24
- err = `💥 invalid data provided for key 👉 ${el[0]} 👈 in ➡ menu.setting.js \n 🚩Must be of type {Object}`
25
- break
26
- }
27
- }
28
- // Validate that each entry has the required key
29
- if (!err) {
30
- for (let el of content) {
31
- const entry = el[1]
32
- for (let k of keys4Activity) {
33
- if (!entry[k]) {
34
- err = `💥 Missing 👉 ${k} 👈 in ${el[0]} in ➡ menu.setting.js \n 🚩Allowed indexes are: 👉 ${keys4Activity}`
35
- break
36
- } else {
37
- //validate that each entry as correct value type
38
- switch (k) {
39
- case 'anchors':
40
- if (entry[k].constructor !== Array)
41
- err = `💥 Invalid anchors declaration for 👉 ${el[0]} 👈 in ➡ menu.setting.j \n 🚩Must be of type {Array}`
42
- else {
43
- const anchors = entry.anchors
44
-
45
- for (let a of anchors) {
46
- //trow error if numbers of keys are not the same as required
47
- const a_numb = anchors.indexOf(a) + 1
48
- if (Object.keys(a).length !== keys4Anchors.length) {
49
- err = `💥 Invalid declaration in 👉anchor ${a_numb}👈 for ${el[0]} in ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
50
- break
51
- }
52
- // Validated that required keys condition and type is met
53
- for (let k of keys4Anchors) {
54
- if (!a[k]) {
55
- err = `💥 Missing 👉 ${k} 👈 for anchor ${a_numb} ${el[0]} ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
56
- } else if (a[k].constructor !== String) {
57
- err = `💥 Invalid 👉 ${k} 👈 declaration for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Must be of type {String}`
58
- }
59
- if (err) break
60
- }
61
- if (err) break
62
- }
63
- }
64
-
65
- break
66
- default:
67
- if (entry[k].constructor !== String)
68
- err = `Invalid 👉 ${k} 👈 declaration for ${el[0]} in ➡ menu.setting.js \n 🚩 Must be of type {String}`
69
- break
70
- }
71
- }
72
- }
73
-
74
- if (err) break
75
- }
76
- }
77
- }
78
- break
79
- }
80
- }
81
- }
82
- return err
83
- }
84
-
85
- /**
86
- * @description Validator for the content of menu setting file
87
- * @param {Object} data- Object definition to validate
88
- **/
89
- const validateVideoData = (data) => {
90
- const errorList = []
91
- if (process.env.NODE_ENV === 'development') {
92
- let errStringInConsole = null
93
- let errString = null
94
- const expectedKeys = ['mSources', 'mSubtitles', 'mPoster', 'mTranscript']
95
-
96
- if (!data || data.constructor !== Object || Object.keys(data).length < 1) {
97
- errStringInConsole = `\n 💥 Invalid declaration for video element`
98
- console.warn(
99
- `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
100
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
101
- )
102
- errString = `Declaration invalide pour Objet video.`
103
- errorList.push(errString)
104
- }
105
-
106
- if (!data['mSources']) {
107
- errStringInConsole = ` Missing 👉 mSources 👈 declaration for video element`
108
-
109
- errString = `l'Attribut 👉 mSources 👈 pour l'Objet video n'est pas defini. `
110
- console.warn(
111
- `%c WARNING!>>> ${errStringInConsole}`,
112
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
113
- )
114
- errorList.push(errString)
115
- }
116
-
117
- //Start validation of keys in data
118
- if (!errString) {
119
- expectedKeys.forEach((k) => {
120
- if (!data[k] && k !== 'mSources') return
121
-
122
- switch (k) {
123
- case 'mSources':
124
- if (
125
- data['mSources'].constructor !== Array ||
126
- data['mSources'].length < 1
127
- ) {
128
- errStringInConsole =
129
- '\n 💥 Invalid type declaration for mSources.\n 🚩 Must be of type Array'
130
-
131
- errString = `l'Attribut 👉 mSources 👈 pour le media doit être de type Array`
132
-
133
- errorList.push(errString)
134
- console.warn(
135
- `%c WARNING!>>> ${errStringInConsole}`,
136
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
137
- )
138
- }
139
- break
140
-
141
- case 'mSubtitles':
142
- {
143
- //Validate required keys in Subtitle definition
144
- let expectedKeys = ['label', 'src', 'srclang']
145
- //we only accept one subtitle and must be defined as an Object with 3 keys
146
- if (
147
- data['mSubtitles'].constructor !== Array ||
148
- !data['mSubtitles'].length
149
- ) {
150
- errStringInConsole = `\n 💥 Invalid type declaration for mSubtitles.\n 🚩 Must be of type Array with at list one Object defined with: ${expectedKeys}`
151
-
152
- errString = `l'Attribut 👉 mSubtitles 👈 doit être de type Array avec au moins un Objet: {${expectedKeys}} `
153
-
154
- console.warn(
155
- `%c WARNING!>>> ${errStringInConsole}`,
156
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
157
- )
158
-
159
- return errorList.push(errString)
160
- }
161
- //Validate definition for each Subtitle Object
162
- for (const obj of data['mSubtitles']) {
163
- const objIndex = data['mSubtitles'].indexOf(obj)
164
- expectedKeys.forEach((expected) => {
165
- if (!obj[expected]) {
166
- errStringInConsole = `\n 💥 Missing key 👉 ${expected} 👈 for mSubtitles No.${objIndex +
167
- 1}.\n 🚩 required keys are: ${expectedKeys} `
168
-
169
- errString = `l'Attribut 👉 ${expected} 👈 pour le sous-titre No.${objIndex +
170
- 1} n'est pas défini`
171
-
172
- console.warn(
173
- `%c WARNING!>>> ${errStringInConsole}`,
174
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
175
- )
176
- return errorList.push(errString)
177
- }
178
-
179
- // Only none empty String type Accepted
180
- if (
181
- obj[expected].constructor === String &&
182
- obj[expected].trim().length
183
- )
184
- return
185
-
186
- errStringInConsole = `\n 💥 Invalid type declaration for 👉${expected}👈 in mSubtitles No.${objIndex +
187
- 1}.\n 🚩 Must be none-empty String `
188
-
189
- errString = `l'Attribut 👉${expected}👈 du sous-titre No.${objIndex +
190
- 1} doit être de type String et ne peut pas être vide. `
191
-
192
- console.warn(
193
- `%c WARNING!>>> ${errStringInConsole}`,
194
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
195
- )
196
-
197
- errorList.push(errString)
198
- })
199
- }
200
- }
201
- break
202
- case 'mPoster':
203
- //Only type String allowed and must not be empty
204
- if (
205
- data['mPoster'] &&
206
- data['mPoster'].constructor == String &&
207
- data['mPoster'].trim().length
208
- )
209
- return
210
-
211
- errStringInConsole = `\n 💥 Invalid type declaration for 👉 mPoster 👈.\n 🚩 Must be none-empty String `
212
-
213
- errString = `l'Attribut 👉 mPoster 👈 doit être de type String et ne peut pas être vide. `
214
-
215
- errorList.push(errString)
216
- console.warn(
217
- `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
218
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
219
- )
220
-
221
- break
222
- case 'mTranscript':
223
- //Only type String allowed and must not be empty
224
- if (
225
- data['mTranscript'] &&
226
- data['mTranscript'].constructor == String &&
227
- data['mTranscript'].trim().length
228
- )
229
- return
230
-
231
- errStringInConsole = `\n 💥 Invalid type declaration for 👉 mTranscript 👈 .\n 🚩 Must be none-empty String `
232
-
233
- errString = `l'Attribut 👉 mTranscript 👈 doit être de type String et ne peut pas être vide. `
234
-
235
- console.warn(
236
- `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
237
- 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
238
- )
239
- errorList.push(errString)
240
-
241
- break
242
- }
243
- })
244
- }
245
- }
246
- return errorList
247
- }
248
-
249
- export { validateVideoData, validatefileContent }
1
+ /**
2
+ * @description Validator for the content of menu setting file
3
+ * @param {String} fName- name of the file for use case
4
+ * @param {Object} fData: file's data to validate
5
+ * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
6
+ */
7
+ const validatefileContent = (fName, fData, requiredArgs = {}) => {
8
+ let err = null
9
+ if (import.meta.env.DEV) {
10
+ switch (fName) {
11
+ case 'menuSettings': {
12
+ const {
13
+ keys4Lesson,
14
+ keys4ActivityMando,
15
+ keys4ActivityOpt,
16
+ keys4Anchors
17
+ } = requiredArgs
18
+
19
+ //*validate that data is an {Object}. if Not send error message
20
+ if (fData.constructor !== Object)
21
+ err = '💥Invalid file provided for menu settings'
22
+
23
+ if (Object.entries(fData).length > 0) {
24
+ const content = Object.entries(fData)
25
+ if (content.length != keys4Lesson.length) {
26
+ err = `!!!! 💥 Missing activity in➡ menu.setting.js \n 🚩Must declare all activity in menu.setting.js`
27
+ break
28
+ } else {
29
+ for (let [index, el] of content.entries()) {
30
+ //validate that the content of each entry is valide
31
+ if (el[0] !== keys4Lesson[index]) {
32
+ err = `!!!! 💥 invalid data provided for key 👉 ${el[0]} 👈 in ➡ menu.setting.js \n 🚩 All activity must be listed and you must have a lesson title`
33
+ break
34
+ }
35
+ }
36
+ }
37
+
38
+ // Validate that each entry has the required key
39
+ if (!err) {
40
+ // remove key lessonTitle
41
+ content.shift()
42
+ for (let el of content) {
43
+ const entry = el[1]
44
+ const tabEntrykey = Object.keys(entry)
45
+
46
+ //Validate that entry has optional key
47
+ if (!tabEntrykey.includes(keys4ActivityOpt[0])) {
48
+ if (!tabEntrykey.includes(keys4ActivityOpt[1])) {
49
+ err = `💥 Missing 👉 ${keys4ActivityOpt[0]} or ${keys4ActivityOpt[1]} 👈 in ${el[0]} in ➡ menu.setting.js \n 🚩One of thess two keys are mandatory : 👉 ${keys4ActivityOpt}`
50
+ break
51
+ }
52
+ }
53
+
54
+ //Validate that entry has mandatory key
55
+ for (let m of keys4ActivityMando) {
56
+ if (!tabEntrykey.includes(m)) {
57
+ err = `💥 Missing 👉 ${m} 👈 in ${el[0]} in ➡ menu.setting.js \n 🚩All this key are mandatory : 👉 ${keys4ActivityMando}`
58
+ break
59
+ } else {
60
+ switch (m) {
61
+ case 'anchors':
62
+ if (entry[m].constructor !== Array)
63
+ err = `💥 Invalid anchors declaration for 👉 ${el[0]} 👈 in ➡ menu.setting.j \n 🚩Must be of type {Array}`
64
+ else {
65
+ const anchors = entry.anchors
66
+
67
+ for (let a of anchors) {
68
+ //trow error if numbers of keys are not the same as required
69
+ const a_numb = anchors.indexOf(a) + 1
70
+ if (Object.keys(a).length !== keys4Anchors.length) {
71
+ err = `💥 Invalid declaration in 👉anchor ${a_numb}👈 for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
72
+ break
73
+ }
74
+ // Validated that required keys condition and type is met
75
+ for (let k of keys4Anchors) {
76
+ if (!a[k]) {
77
+ err = `💥 Missing 👉 ${k} 👈 for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
78
+ } else if (a[k].constructor !== String) {
79
+ err = `💥 Invalid 👉 ${k} 👈 declaration for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Must be of type {String}`
80
+ }
81
+ if (err) break
82
+ }
83
+ if (err) break
84
+ }
85
+ }
86
+
87
+ break
88
+ default:
89
+ if (entry[m].constructor !== String)
90
+ err = `Invalid 👉 ${m} 👈 declaration for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Must be of type {String}`
91
+ break
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ break
99
+ }
100
+ }
101
+ }
102
+ return err
103
+ }
104
+
105
+ /**
106
+ * @description Validator for the content of menu setting file
107
+ * @param {Object} data- Object definition to validate
108
+ **/
109
+ const validateVideoData = (data) => {
110
+ const errorList = []
111
+ if (import.meta.env.DEV) {
112
+ let errStringInConsole = null
113
+ let errString = null
114
+ const expectedKeys = [
115
+ 'id',
116
+ 'mSources',
117
+ 'mSubtitles',
118
+ 'mPoster',
119
+ 'mTranscript'
120
+ ]
121
+
122
+ if (!data || data.constructor !== Object || Object.keys(data).length < 1) {
123
+ errStringInConsole = `\n 💥 Invalid declaration for video element`
124
+ console.warn(
125
+ `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
126
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
127
+ )
128
+ errString = `Declaration invalide pour Objet video.`
129
+ errorList.push(errString)
130
+ }
131
+ //Must have mSources
132
+ if (!data['mSources']) {
133
+ errStringInConsole = ` Missing 👉 mSources 👈 declaration for video element`
134
+
135
+ errString = `l'Attribut <b>mSources</b> pour l'Objet video n'est pas defini. `
136
+ console.warn(
137
+ `%c WARNING!>>> ${errStringInConsole}`,
138
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
139
+ )
140
+ errorList.push(errString)
141
+ }
142
+ //Must have id
143
+ if (!data['id']) {
144
+ errStringInConsole = ` Missing 👉 id 👈 declaration for video element`
145
+
146
+ errString = `l'Attribut <b>id</b> pour l'objet video n'est pas defini. `
147
+ console.warn(
148
+ `%c WARNING!>>> ${errStringInConsole}`,
149
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
150
+ )
151
+ errorList.push(errString)
152
+ }
153
+ //Start validation of keys in data
154
+ if (!errString) {
155
+ expectedKeys.forEach((k) => {
156
+ if (!data[k] && k !== 'mSources') return
157
+
158
+ switch (k) {
159
+ case 'id':
160
+ if (data['id'].constructor !== String || data['id'].length < 1) {
161
+ errStringInConsole =
162
+ '\n 💥 Invalid type declaration for id.\n 🚩 Must be of type Array'
163
+
164
+ errString = `l'Attribut <b>id</b> pour le media doit être de type <i>String</i>`
165
+
166
+ errorList.push(errString)
167
+ console.warn(
168
+ `%c WARNING!>>> ${errStringInConsole}`,
169
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
170
+ )
171
+ }
172
+ break
173
+ case 'mSources':
174
+ if (
175
+ data['mSources'].constructor !== Array ||
176
+ data['mSources'].length < 1
177
+ ) {
178
+ errStringInConsole =
179
+ '\n 💥 Invalid type declaration for mSources.\n 🚩 Must be of type Array'
180
+
181
+ errString = `l'Attribut 👉 mSources 👈 pour le media doit être de type Array`
182
+
183
+ errorList.push(errString)
184
+ console.warn(
185
+ `%c WARNING!>>> ${errStringInConsole}`,
186
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
187
+ )
188
+ }
189
+ break
190
+
191
+ case 'mSubtitles':
192
+ {
193
+ //Validate required keys in Subtitle definition
194
+ let expectedKeys = ['label', 'src', 'srclang']
195
+ //we only accept one subtitle and must be defined as an Object with 3 keys
196
+ if (
197
+ data['mSubtitles'].constructor !== Array ||
198
+ !data['mSubtitles'].length
199
+ ) {
200
+ errStringInConsole = `\n 💥 Invalid type declaration for mSubtitles.\n 🚩 Must be of type Array with at list one Object defined with: ${expectedKeys}`
201
+
202
+ errString = `l'Attribut 👉 mSubtitles 👈 doit être de type Array avec au moins un Objet: {${expectedKeys}} `
203
+
204
+ console.warn(
205
+ `%c WARNING!>>> ${errStringInConsole}`,
206
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
207
+ )
208
+
209
+ return errorList.push(errString)
210
+ }
211
+ //Validate definition for each Subtitle Object
212
+ for (const obj of data['mSubtitles']) {
213
+ const objIndex = data['mSubtitles'].indexOf(obj)
214
+ expectedKeys.forEach((expected) => {
215
+ if (!obj[expected]) {
216
+ errStringInConsole = `\n 💥 Missing key 👉 ${expected} 👈 for mSubtitles No.${
217
+ objIndex + 1
218
+ }.\n 🚩 required keys are: ${expectedKeys} `
219
+
220
+ errString = `l'Attribut 👉 ${expected} 👈 pour le sous-titre No.${
221
+ objIndex + 1
222
+ } n'est pas défini`
223
+
224
+ console.warn(
225
+ `%c WARNING!>>> ${errStringInConsole}`,
226
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
227
+ )
228
+ return errorList.push(errString)
229
+ }
230
+
231
+ // Only none empty String type Accepted
232
+ if (
233
+ obj[expected].constructor === String &&
234
+ obj[expected].trim().length
235
+ )
236
+ return
237
+
238
+ errStringInConsole = `\n 💥 Invalid type declaration for 👉${expected}👈 in mSubtitles No.${
239
+ objIndex + 1
240
+ }.\n 🚩 Must be none-empty String `
241
+
242
+ errString = `l'Attribut 👉${expected}👈 du sous-titre No.${
243
+ objIndex + 1
244
+ } doit être de type String et ne peut pas être vide. `
245
+
246
+ console.warn(
247
+ `%c WARNING!>>> ${errStringInConsole}`,
248
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
249
+ )
250
+
251
+ errorList.push(errString)
252
+ })
253
+ }
254
+ }
255
+ break
256
+ case 'mPoster':
257
+ //Only type String allowed and must not be empty
258
+ if (
259
+ data['mPoster'] &&
260
+ data['mPoster'].constructor == String &&
261
+ data['mPoster'].trim().length
262
+ )
263
+ return
264
+
265
+ errStringInConsole = `\n 💥 Invalid type declaration for 👉 mPoster 👈.\n 🚩 Must be none-empty String `
266
+
267
+ errString = `l'Attribut 👉 mPoster 👈 doit être de type String et ne peut pas être vide. `
268
+
269
+ errorList.push(errString)
270
+ console.warn(
271
+ `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
272
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
273
+ )
274
+
275
+ break
276
+ case 'mTranscript':
277
+ //Only type String allowed and must not be empty
278
+ if (
279
+ data['mTranscript'] &&
280
+ data['mTranscript'].constructor == String &&
281
+ data['mTranscript'].trim().length
282
+ )
283
+ return
284
+
285
+ errStringInConsole = `\n 💥 Invalid type declaration for 👉 mTranscript 👈 .\n 🚩 Must be none-empty String `
286
+
287
+ errString = `l'Attribut 👉 mTranscript 👈 doit être de type String et ne peut pas être vide. `
288
+
289
+ console.warn(
290
+ `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
291
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
292
+ )
293
+ errorList.push(errString)
294
+
295
+ break
296
+ }
297
+ })
298
+ }
299
+ }
300
+ return errorList
301
+ }
302
+
303
+ /**
304
+ * @description Validator for the content of audio props
305
+ * @param {Object} data- Object definition to validate
306
+ **/
307
+ const validateAudioData = (data) => {
308
+ const errorList = []
309
+ let currentProperties = Object.getOwnPropertyNames(data)
310
+ if (process.env.NODE_ENV === 'development') {
311
+ //errorList.push('test')
312
+
313
+ const requiredProperties = ['id', 'mTitle', 'mSources', 'mTranscript']
314
+
315
+ const optionalProperties = ['mPoster', 'mAlt']
316
+
317
+ const allProperties = [
318
+ ...requiredProperties,
319
+ ...optionalProperties,
320
+ ...['__ob__']
321
+ ]
322
+
323
+ let errStringInConsole = null
324
+ let errString = null
325
+
326
+ //** Validate if data exist and is an object**/
327
+ if (!data || data.constructor !== Object || Object.keys(data).length < 1) {
328
+ errStringInConsole = `\n 💥 Invalid declaration for audio element`
329
+ console.warn(
330
+ `%c WARNING!>>> AUDIO: ${errStringInConsole}`,
331
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
332
+ )
333
+ errString = `Déclaration invalide pour Objet audData. Ce doit être un objet non vide.`
334
+ errorList.push(errString)
335
+ return errorList
336
+ }
337
+ //** Validate if all the properties are right**/
338
+ let wrongProperties = checkerWrong(allProperties, currentProperties)
339
+ if (wrongProperties.length > 0) {
340
+ console.warn(
341
+ `%c WARNING!>>> AppCompAudio : audData property ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
342
+ 'background: orange; color: white; display: block; margin:5px;'
343
+ )
344
+ errString = `Propriété invalide pour audData: ${wrongProperties}. Les propriétés requises sont: ${requiredProperties} et les propriétés facultatives sont: ${optionalProperties}`
345
+ errorList.push(errString)
346
+ return errorList
347
+ }
348
+
349
+ //** Validate if all the required properties are in the data */
350
+ let missingRequired = checkerMissing(requiredProperties, currentProperties)
351
+ if (missingRequired.length > 0) {
352
+ console.warn(
353
+ `%c WARNING!>>> AppCompAudio : audData missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
354
+ 'background: orange; color: white; display: block; margin:5px;'
355
+ )
356
+ errString = `Propriété requise manquante pour audData: <b>${missingRequired}</b>. Les propriétés requises sont: <i>${requiredProperties}</i> et les propriétés facultatives sont: <i>${optionalProperties}</i>`
357
+ errorList.push(errString)
358
+ return errorList
359
+ }
360
+ /***Validate data values */
361
+ if (errorList.length == 0) {
362
+ let invalidString = []
363
+ let invalidArray = []
364
+ let invalidProperties = []
365
+ currentProperties.forEach((p) => {
366
+ switch (p) {
367
+ case 'mTitle':
368
+ case 'mTranscript':
369
+ case 'mPoster':
370
+ case 'mAlt':
371
+ if (data[p] && data[p].constructor == String) {
372
+ data[p].trim().length == 0 ? invalidString.push(p) : ''
373
+ } else {
374
+ invalidString.push(p)
375
+ }
376
+ break
377
+ case 'mSources': {
378
+ if (data[p] && data[p].constructor == Array) {
379
+ data[p].length == 0 ? invalidArray.push(p) : ''
380
+ } else {
381
+ invalidArray.push(p)
382
+ }
383
+ if (invalidArray.length === 0) {
384
+ //Valider les attributs de mSources
385
+ for (let i in data[p]) {
386
+ let object = data[p][i]
387
+ if ('src' in object && 'type' in object) {
388
+ if (
389
+ object['src'].constructor != String &&
390
+ object['type'].constructor != String
391
+ ) {
392
+ invalidProperties.push(p)
393
+ } else {
394
+ object['src'].trim().length == 0
395
+ ? invalidString.push(p)
396
+ : ''
397
+ object['type'].trim().length == 0
398
+ ? invalidString.push(p)
399
+ : ''
400
+ }
401
+ } else {
402
+ invalidProperties.push(p)
403
+ }
404
+ }
405
+ }
406
+ break
407
+ }
408
+ }
409
+ })
410
+ //Display error for each type
411
+ //String
412
+ let sL = invalidString.length
413
+ if (sL > 0) {
414
+ errStringInConsole = `\n 💥 Invalid value type for 👉${invalidString}👈 \n 🚩 Must be none-empty String `
415
+
416
+ errString = `${sL > 1 ? 'Les ' : "L'"}attribut${
417
+ sL > 1 ? 's ' : ''
418
+ } 👉${invalidString}👈 doi${
419
+ sL > 1 ? 'ven' : ''
420
+ }t être de type String et ne peu${sL > 1 ? 'ven' : ''}t pas être vide. `
421
+
422
+ console.warn(
423
+ `%c WARNING!>>> ${errStringInConsole}`,
424
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
425
+ )
426
+ errorList.push(errString)
427
+ }
428
+ //Array
429
+ let aL = invalidArray.length
430
+ if (aL > 0) {
431
+ errStringInConsole = `\n 💥 Invalid value type for 👉${invalidArray}👈 \n 🚩 Must be none-empty Array`
432
+
433
+ errString = `${aL > 1 ? 'Les ' : "L'"}attribut${
434
+ aL > 1 ? 's ' : ''
435
+ } 👉${invalidArray}👈 doi${
436
+ sL > 1 ? 'ven' : ''
437
+ }t être de type Array et ne peu${aL > 1 ? 'ven' : ''}t pas être vide. `
438
+
439
+ console.warn(
440
+ `%c WARNING!>>> ${errStringInConsole}`,
441
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
442
+ )
443
+ errorList.push(errString)
444
+ }
445
+ let pL = invalidProperties.length
446
+ if (pL > 0) {
447
+ errStringInConsole = `\n 💥 Invalid value type for 👉src and/or type👈 in mSources \n 🚩 They are required and must be none-empty strings`
448
+
449
+ errString = `${pL > 1 ? 'Les ' : "L'"}attribut${
450
+ pL > 1 ? 's ' : ''
451
+ } 👉src and/or type👈 de mSources doi${
452
+ sL > 1 ? 'ven' : ''
453
+ }t être de type String et ne peu${pL > 1 ? 'ven' : ''}t pas être vide. `
454
+
455
+ console.warn(
456
+ `%c WARNING!>>> ${errStringInConsole}`,
457
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
458
+ )
459
+ errorList.push(errString)
460
+ }
461
+ }
462
+ /*if (process.env.NODE_ENV === 'development') {
463
+ let errStringInConsole = null
464
+ let errString = null
465
+ const expectedKeys = ['mSources', 'mSubtitles', 'mPoster', 'mTranscript']
466
+
467
+ if (!data || data.constructor !== Object || Object.keys(data).length < 1) {
468
+ errStringInConsole = `\n 💥 Invalid declaration for video element`
469
+ console.warn(
470
+ `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
471
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
472
+ )
473
+ errString = `Declaration invalide pour Objet video.`
474
+ errorList.push(errString)
475
+ }
476
+
477
+ if (!data['mSources']) {
478
+ errStringInConsole = ` Missing 👉 mSources 👈 declaration for video element`
479
+
480
+ errString = `l'Attribut 👉 mSources 👈 pour l'Objet video n'est pas defini. `
481
+ console.warn(
482
+ `%c WARNING!>>> ${errStringInConsole}`,
483
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
484
+ )
485
+ errorList.push(errString)
486
+ }
487
+
488
+ //Start validation of keys in data
489
+ if (!errString) {
490
+ expectedKeys.forEach((k) => {
491
+ if (!data[k] && k !== 'mSources') return
492
+
493
+ switch (k) {
494
+ case 'mSources':
495
+ if (
496
+ data['mSources'].constructor !== Array ||
497
+ data['mSources'].length < 1
498
+ ) {
499
+ errStringInConsole =
500
+ '\n 💥 Invalid type declaration for mSources.\n 🚩 Must be of type Array'
501
+
502
+ errString = `l'Attribut 👉 mSources 👈 pour le media doit être de type Array`
503
+
504
+ errorList.push(errString)
505
+ console.warn(
506
+ `%c WARNING!>>> ${errStringInConsole}`,
507
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
508
+ )
509
+ }
510
+ break
511
+
512
+ case 'mSubtitles':
513
+ {
514
+ //Validate required keys in Subtitle definition
515
+ let expectedKeys = ['label', 'src', 'srclang']
516
+ //we only accept one subtitle and must be defined as an Object with 3 keys
517
+ if (
518
+ data['mSubtitles'].constructor !== Array ||
519
+ !data['mSubtitles'].length
520
+ ) {
521
+ errStringInConsole = `\n 💥 Invalid type declaration for mSubtitles.\n 🚩 Must be of type Array with at list one Object defined with: ${expectedKeys}`
522
+
523
+ errString = `l'Attribut 👉 mSubtitles 👈 doit être de type Array avec au moins un Objet: {${expectedKeys}} `
524
+
525
+ console.warn(
526
+ `%c WARNING!>>> ${errStringInConsole}`,
527
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
528
+ )
529
+
530
+ return errorList.push(errString)
531
+ }
532
+ //Validate definition for each Subtitle Object
533
+ for (const obj of data['mSubtitles']) {
534
+ const objIndex = data['mSubtitles'].indexOf(obj)
535
+ expectedKeys.forEach((expected) => {
536
+ if (!obj[expected]) {
537
+ errStringInConsole = `\n 💥 Missing key 👉 ${expected} 👈 for mSubtitles No.${objIndex +
538
+ 1}.\n 🚩 required keys are: ${expectedKeys} `
539
+
540
+ errString = `l'Attribut 👉 ${expected} 👈 pour le sous-titre No.${objIndex +
541
+ 1} n'est pas défini`
542
+
543
+ console.warn(
544
+ `%c WARNING!>>> ${errStringInConsole}`,
545
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
546
+ )
547
+ return errorList.push(errString)
548
+ }
549
+
550
+ // Only none empty String type Accepted
551
+ if (
552
+ obj[expected].constructor === String &&
553
+ obj[expected].trim().length
554
+ )
555
+ return
556
+
557
+ errStringInConsole = `\n 💥 Invalid type declaration for 👉${expected}👈 in mSubtitles No.${objIndex +
558
+ 1}.\n 🚩 Must be none-empty String `
559
+
560
+ errString = `l'Attribut 👉${expected}👈 du sous-titre No.${objIndex +
561
+ 1} doit être de type String et ne peut pas être vide. `
562
+
563
+ console.warn(
564
+ `%c WARNING!>>> ${errStringInConsole}`,
565
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
566
+ )
567
+
568
+ errorList.push(errString)
569
+ })
570
+ }
571
+ }
572
+ break
573
+ case 'mPoster':
574
+ //Only type String allowed and must not be empty
575
+ if (
576
+ data['mPoster'] &&
577
+ data['mPoster'].constructor == String &&
578
+ data['mPoster'].trim().length
579
+ )
580
+ return
581
+
582
+ errStringInConsole = `\n 💥 Invalid type declaration for 👉 mPoster 👈.\n 🚩 Must be none-empty String `
583
+
584
+ errString = `l'Attribut 👉 mPoster 👈 doit être de type String et ne peut pas être vide. `
585
+
586
+ errorList.push(errString)
587
+ console.warn(
588
+ `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
589
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
590
+ )
591
+
592
+ break
593
+ case 'mTranscript':
594
+ //Only type String allowed and must not be empty
595
+ if (
596
+ data['mTranscript'] &&
597
+ data['mTranscript'].constructor == String &&
598
+ data['mTranscript'].trim().length
599
+ )
600
+ return
601
+
602
+ errStringInConsole = `\n 💥 Invalid type declaration for 👉 mTranscript 👈 .\n 🚩 Must be none-empty String `
603
+
604
+ errString = `l'Attribut 👉 mTranscript 👈 doit être de type String et ne peut pas être vide. `
605
+
606
+ console.warn(
607
+ `%c WARNING!>>> VIDEO: ${errStringInConsole}`,
608
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
609
+ )
610
+ errorList.push(errString)
611
+
612
+ break
613
+ }
614
+ })
615
+ }
616
+ }*/
617
+ }
618
+ return errorList
619
+ }
620
+ //Get all the invalids properties from the object
621
+ /*Add element from target array that are NOT in arr to the wrongArray*/
622
+ const checkerWrong = (arr, target) => {
623
+ let wrongArray = []
624
+ target.every((v) => {
625
+ if (arr.includes(v)) {
626
+ return true
627
+ } else {
628
+ wrongArray.push(v)
629
+ return true
630
+ }
631
+ })
632
+ return wrongArray
633
+ }
634
+ //Get all the required properties that are missing from the object
635
+ /*Add element from the arr that are NOT in target arr to the missingArray*/
636
+ const checkerMissing = (arr, target) => {
637
+ let missingArray = []
638
+ arr.every((v) => {
639
+ if (target.includes(v)) {
640
+ return true
641
+ } else {
642
+ missingArray.push(v)
643
+ return true
644
+ }
645
+ })
646
+ return missingArray
647
+ }
648
+
649
+ const ERR_TYPE = {
650
+ err0: `\n 💥 Missing \x1B[1m$attr$ \x1B[0mfor $comp$. \x1B[1m$attr$ \x1B[0m should be provided with following attributes: \x1B[1m{$data$}`,
651
+ err1: `\n 💥 Invalid declaration for \x1B[1m$wrd$ \x1B[0m object`,
652
+ err2: `\n 💥 Invalid type declaration for 👉\x1B[1m$attr$ \x1B[0m👈 in \x1B[1m$el$\x1B[0m. Expected is \x1B[3m$type$ \x1B[0mtype with some value`,
653
+ err3: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`,
654
+ err4: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`
655
+ }
656
+
657
+ const ERR_TYPE_MSG = {
658
+ err0: `\n Données manquantes pour <span style='text-transform: uppercase;'>$comp$</span>. Assurez-vous que le composant reçoit l'attribut <b>$attr$</b> avec des données pour: <b>$data$</b>`,
659
+ err1: `\n Déclaration invalide pour <b>$wrd$</b>. Assurez-vous que l'application a du data.`,
660
+ err2: `\n Vous avez une declaration invalide dans <b>$attr$</b>. 👉<b>$el$</b>👈 n'accepte que le type <i>$type$</i> et ne peut pas être vide`,
661
+ err3: `\n L'attribut 👉<b>$key$</b>👈 est manquant dans <b>$el$</b>. Les attributs requis sont: <b>$args$</b>`
662
+ }
663
+
664
+ /**
665
+ * @description Validator for the content of app data.
666
+ * App data is used as setting for the application
667
+ * @param {Object} data - the Object definition to validate
668
+ * @param {Boolean} silent - if Validator should diplay error in console
669
+ *
670
+ **/
671
+
672
+ const validateAppContent = (data, silent = false) => {
673
+ let errorInConsole = []
674
+ let errorList = []
675
+
676
+ const requiredArgs = [
677
+ 'lang',
678
+ 'specification',
679
+ 'id',
680
+ 'crs_id',
681
+ 'idb_id',
682
+ 'no_menu',
683
+ 'is_single_activity',
684
+ 'auto_next_activity'
685
+ ]
686
+
687
+ //Validate not empty data
688
+ if (Object.keys(data).length == 0) {
689
+ const reg = /(\$comp\$)|(\$data\$)|(\$attr\$)/g
690
+
691
+ errorInConsole.push(
692
+ ERR_TYPE.err0.replace(reg, (e) => {
693
+ if (e == '$comp$') return 'app-base'
694
+ if (e == '$data$') return requiredArgs.toString().replaceAll(',', ', ')
695
+ if (e == '$attr$') return 'app-config'
696
+ })
697
+ )
698
+
699
+ errorList.push(
700
+ ERR_TYPE_MSG.err0.replace(reg, (e) => {
701
+ if (e == '$comp$') return 'app-base'
702
+ if (e == '$data$') return requiredArgs.toString().replaceAll(',', ', ')
703
+ if (e == '$attr$') return 'app-config'
704
+ })
705
+ )
706
+
707
+ console.warn(errorInConsole[0])
708
+
709
+ return errorList
710
+ }
711
+
712
+ let stringType = ['lang', 'specification', 'id', 'crs_id', 'idb_id']
713
+ let boolType = [
714
+ 'no_menu',
715
+ 'is_single_activity',
716
+ 'auto_next_activity',
717
+ 'remote'
718
+ ]
719
+ let objectType = ['actor', 'linkedResource']
720
+ let optionalArgs = ['remote', 'actor', 'linkedResource']
721
+
722
+ const { errorInConsole: errCons, errorList: errList } = validateObjType(
723
+ data,
724
+ {
725
+ stringType,
726
+ boolType,
727
+ objectType
728
+ },
729
+ optionalArgs,
730
+ 'App.vue'
731
+ )
732
+
733
+ errorList = [...errorList, ...errList]
734
+ errorInConsole = [...errorInConsole, ...errCons]
735
+
736
+ //===========Optional Keys should be of correct type when declared =================//
737
+ // Has actor defined
738
+ if (data['actor']) {
739
+ let { errorInConsole: err1, errorList: err2 } = validateObjType(
740
+ data['actor'],
741
+ {
742
+ stringType: ['name', 'mbox']
743
+ },
744
+ 'actor'
745
+ )
746
+
747
+ errorList = [...errorList, ...err2]
748
+ errorInConsole = [...errorInConsole, ...err1]
749
+ }
750
+ // Has LinkedResource defined
751
+ if (data['linkedResource']) {
752
+ let { errorInConsole: err1, errorList: err2 } = validateObjType(
753
+ data['linkedResource'],
754
+ {
755
+ stringType: ['url', 'id']
756
+ },
757
+ 'linkedResource'
758
+ )
759
+
760
+ errorList = [...errorList, ...err2]
761
+ errorInConsole = [...errorInConsole, ...err1]
762
+ }
763
+ // Has endpointConfig defined
764
+ if (data['endpointConfig']) {
765
+ let { errorInConsole: err1, errorList: err2 } = validateObjType(
766
+ data['endpointConfig'],
767
+ {
768
+ stringType: ['auth', 'endpoint']
769
+ },
770
+ 'endpointConfig'
771
+ )
772
+ errorList = [...errorList, ...err2]
773
+ errorInConsole = [...errorInConsole, ...err1]
774
+ }
775
+ //================== END Optional Keys ====================//
776
+
777
+ //Should display error to console
778
+ if (errorList.length && !silent) {
779
+ let txt = '⚠️ You have the following Errors:'
780
+ console.group(`%c ${txt}`, 'background:#ffc13a7d')
781
+ errorInConsole.forEach((err) => console.warn(err))
782
+ console.groupEnd()
783
+ }
784
+
785
+ return errorList
786
+ }
787
+
788
+ /**
789
+ * @description - Method to validate that given object attributes hold expected types
790
+ * @param {Object} Obj - object to validate
791
+ * @param {Object} Args - List of expected type groups - each type group must be an array of attributes with the same type
792
+ * @param {Array} notRequiredArgs - list of field that should be considered as optional in the object. Will not give error if not * provided but will be validated if they are present with wrong type or empty
793
+ * @param {Array} compName - Name of the component- will be display in error message
794
+ * @param {Array} err - list off errors to be added to
795
+ * @return {Object} list of errors - {errorInConsole, errorList} : errorlist can be used to display messages on template and
796
+ * errorInConsole to display messages in browser console
797
+ * @exemple - Given $user= {name:'toto', username:'totoEscargot', id:'id001', age:23, books:['one', 'two', 'three'] }
798
+ * Use validator on $user: validateObjType($user, {stringType:['name', 'username' , 'id'], numbType:['age'], arrayType:['books']})
799
+ * Will fail if any listed attribute not in $user or have wrong value. Error messages will be in console
800
+ *
801
+ */
802
+
803
+ const validateObjType = (
804
+ Obj,
805
+ Args = {
806
+ boolType: null,
807
+ arrayType: null,
808
+ stringType: null,
809
+ objectType: null,
810
+ numbType: null
811
+ },
812
+ notRequiredArgs = null,
813
+ compName = 'component',
814
+ err = null
815
+ ) => {
816
+ let errorInConsole = err && err.errorInConsole ? err.errorInConsole : []
817
+ let errorList = err && err.errorList ? err.errorLIst : []
818
+ let optionalArgs =
819
+ notRequiredArgs && notRequiredArgs.length ? notRequiredArgs : []
820
+ //=====Expected Arguments validation =================//
821
+ //Should have an object argument
822
+ if (!Obj) throw new Error(`No valid arguments provided`)
823
+
824
+ //validate Args Keys type
825
+ for (const _type in Args) {
826
+ // Should be a required type
827
+ if (
828
+ ![
829
+ 'boolType',
830
+ 'arrayType',
831
+ 'stringType',
832
+ 'objectType',
833
+ 'numbType'
834
+ ].includes(_type)
835
+ )
836
+ throw new Error(`Unknown types declaration : ${_type}`)
837
+
838
+ if (Args[_type] && Args[_type].length) {
839
+ for (let el of Args[_type]) {
840
+ //Check that each given element is a string
841
+ if (el.constructor !== String)
842
+ throw new Error(
843
+ `Invalid type detected in ${JSON.stringify(
844
+ Args[_type]
845
+ )}. Item ${Args[_type].indexOf(el) + 1} should be a String`
846
+ )
847
+
848
+ let reg = /(\$el\$)|(\$type\$)|(\$attr\$)/g
849
+
850
+ let isOptionalArg = optionalArgs.includes(el) ? true : false
851
+
852
+ switch (true) {
853
+ // Check That each given element exist in data if not optional
854
+ case Obj[el] === undefined && !isOptionalArg: {
855
+ reg = /(\$key\$)|(\$el\$)|(\$args\$)/g
856
+ const reg2 = /\[|\]|/g
857
+
858
+ errorInConsole.push(
859
+ ERR_TYPE.err3.replace(reg, (e) => {
860
+ if (e == '$key$') return el
861
+ if (e == '$el$') return compName
862
+ if (e == '$args$') return JSON.stringify(Args[_type])
863
+ })
864
+ )
865
+
866
+ errorList.push(
867
+ ERR_TYPE_MSG.err3.replace(reg, (e) => {
868
+ if (e == '$key$') return el
869
+ if (e == '$el$') return compName || 'Composant'
870
+ if (e == '$args$')
871
+ return JSON.stringify(Args[_type]).replaceAll(reg2, '')
872
+ })
873
+ )
874
+ break
875
+ }
876
+ //Should have Correct Types $attr$ $el$ $type$
877
+ case _type == 'boolType' &&
878
+ Obj[el] !== undefined &&
879
+ Obj[el].constructor !== Boolean:
880
+ errorInConsole.push(
881
+ ERR_TYPE.err2.replace(reg, (e) => {
882
+ if (e == '$attr$') return compName || 'Composant'
883
+ if (e == '$el$') return el
884
+ if (e == '$type$') return 'Boolean'
885
+ })
886
+ )
887
+ errorList.push(
888
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
889
+ if (e == '$attr$') return compName || 'Composant'
890
+ if (e == '$el$') return el
891
+ if (e == '$type$') return 'Boolean'
892
+ })
893
+ )
894
+ break
895
+
896
+ case _type == 'stringType' &&
897
+ Obj[el] !== undefined &&
898
+ (Obj[el].constructor !== String || !Obj[el].trim().length):
899
+ errorInConsole.push(
900
+ ERR_TYPE.err2.replace(reg, (e) => {
901
+ if (e == '$attr$') return compName || 'Composant'
902
+ if (e == '$el$') return el
903
+ if (e == '$type$') return 'String'
904
+ })
905
+ )
906
+ errorList.push(
907
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
908
+ if (e == '$attr$') return compName || 'Composant'
909
+ if (e == '$el$') return el
910
+ if (e == '$type$') return 'String'
911
+ })
912
+ )
913
+ break
914
+
915
+ case _type == 'arrayType' &&
916
+ Obj[el] !== undefined &&
917
+ (Obj[el].constructor !== Array || !Obj[el].length):
918
+ errorInConsole.push(
919
+ ERR_TYPE.err2.replace(reg, (e) => {
920
+ if (e == '$attr$') return compName || 'Composant'
921
+ if (e == '$el$') return el
922
+ if (e == '$type$') return 'Array'
923
+ })
924
+ )
925
+ errorList.push(
926
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
927
+ if (e == '$attr$') return compName || 'Composant'
928
+ if (e == '$el$') return el
929
+ if (e == '$type$') return 'Array'
930
+ })
931
+ )
932
+ break
933
+
934
+ case _type == 'numberType' &&
935
+ Obj[el] !== undefined &&
936
+ Obj[el].constructor !== Number:
937
+ errorInConsole.push(
938
+ ERR_TYPE.err2.replace(reg, (e) => {
939
+ if (e == '$attr$') return compName || 'Composant'
940
+ if (e == '$el$') return el
941
+ if (e == '$type$') return 'Number'
942
+ })
943
+ )
944
+ errorList.push(
945
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
946
+ if (e == '$attr$') return compName || 'Composant'
947
+ if (e == '$el$') return el
948
+ if (e == '$type$') return 'Number'
949
+ })
950
+ )
951
+ break
952
+
953
+ case _type == 'objectType' &&
954
+ Obj[el] !== undefined &&
955
+ Obj[el].constructor !== Object:
956
+ errorInConsole.push(
957
+ ERR_TYPE.err2.replace(reg, (e) => {
958
+ if (e == '$attr$') return compName || 'Composant'
959
+ if (e == '$el$') return el
960
+ if (e == '$type$') return 'Object'
961
+ })
962
+ )
963
+ errorList.push(
964
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
965
+ if (e == '$attr$') return compName || 'Composant'
966
+ if (e == '$el$') return el
967
+ if (e == '$type$') return 'Object'
968
+ })
969
+ )
970
+ break
971
+ }
972
+ }
973
+ }
974
+ }
975
+
976
+ return { errorInConsole, errorList }
977
+ }
978
+ /**
979
+ * @description - Method validate the definition of SVG data.
980
+ * @param {Array || Object } SVGData - the data defining the SVG to render
981
+ * @return true - if valid
982
+ * */
983
+
984
+ const validateSvgDefinition = (SVGData) => {
985
+ //Should be Array of Object
986
+ if (SVGData.constructor !== Array && SVGData.constructor !== Object)
987
+ throw new Error('Unsupported Type for SVG data')
988
+ let Errors = []
989
+ let SVGDef = SVGData.constructor == Object ? new Array(SVGData) : SVGData
990
+ //Should validate the entries for each SVG definition as the required entries
991
+
992
+ for (const s_def of SVGDef) {
993
+ let i = SVGDef.indexOf(s_def)
994
+ let stringType = ['id', 'viewBox']
995
+ let arrayType = ['paths']
996
+ let { errorInConsole: errCons } = validateObjType(
997
+ s_def,
998
+ {
999
+ stringType,
1000
+ arrayType
1001
+ },
1002
+ 'viewBox',
1003
+ `SVG ${i + 1}`
1004
+ )
1005
+ Errors.push(...errCons)
1006
+ if (errCons.length) {
1007
+ errCons.forEach((err) => console.warn(err))
1008
+ break
1009
+ }
1010
+
1011
+ //Should validate that each element in the path attributes is an object of type string and has the id attribute
1012
+
1013
+ for (const _path of s_def.paths) {
1014
+ let index = s_def.paths.indexOf(_path)
1015
+ if (_path.constructor !== Object)
1016
+ throw Error(
1017
+ `Unexpected definition for path ${index + 1} in SVG ${i + 1}. Expecting Object but received ${typeof _path}`
1018
+ )
1019
+
1020
+ let stringType = ['d']
1021
+
1022
+ let { errorInConsole: errCons } = validateObjType(
1023
+ _path,
1024
+ {
1025
+ stringType
1026
+ },
1027
+ null,
1028
+ `SVG path ${index + 1}`
1029
+ )
1030
+ Errors.push(...errCons)
1031
+ if (errCons.length) {
1032
+ errCons.forEach((err) => console.warn(err))
1033
+ break
1034
+ }
1035
+
1036
+ //validate each entries in path
1037
+ for (const _key in _path) {
1038
+ if (_key == 'd') continue //skip
1039
+ //all keys in path should be of type String and not empty
1040
+ let stringType = [_key]
1041
+
1042
+ let { errorInConsole: errCons } = validateObjType(
1043
+ _path,
1044
+ {
1045
+ stringType
1046
+ },
1047
+ null,
1048
+ `SVG path ${index + 1}`
1049
+ )
1050
+ Errors.push(...errCons)
1051
+ if (errCons.length) {
1052
+ errCons.forEach((err) => console.log(err))
1053
+ break
1054
+ }
1055
+ }
1056
+ }
1057
+ }
1058
+
1059
+ if (Errors.length) throw new Error('Error SVG')
1060
+ return true
1061
+ }
1062
+
1063
+ export {
1064
+ validateVideoData,
1065
+ validateAudioData,
1066
+ validatefileContent,
1067
+ validateAppContent,
1068
+ validateSvgDefinition
1069
+ }