fcad-core-dragon 2.0.0-beta.1 → 2.0.0-beta.2
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.
- package/{.eslintrc.js → .eslintrc.cjs} +13 -18
- package/bk.scss +117 -0
- package/package.json +23 -39
- package/src/$locales/en.json +30 -16
- package/src/$locales/fr.json +29 -16
- package/src/components/AppBase.vue +740 -305
- package/src/components/AppBaseButton.vue +33 -5
- package/src/components/AppBaseErrorDisplay.vue +43 -35
- package/src/components/AppBaseModule.vue +447 -623
- package/src/components/AppBasePage.vue +37 -25
- package/src/components/AppCompAudio.vue +266 -0
- package/src/components/AppCompBranchButtons.vue +52 -63
- package/src/components/AppCompButtonProgress.vue +1 -16
- package/src/components/AppCompCarousel.vue +43 -39
- package/src/components/AppCompInputCheckBox.vue +9 -3
- package/src/components/AppCompInputDropdown.vue +2 -4
- package/src/components/AppCompInputRadio.vue +8 -15
- package/src/components/AppCompInputTextTable.vue +15 -12
- package/src/components/AppCompInputTextToFillDropdown.vue +16 -14
- package/src/components/AppCompInputTextToFillText.vue +2 -2
- package/src/components/AppCompJauge.vue +13 -1
- package/src/components/AppCompMenu.vue +203 -10
- package/src/components/AppCompMenuItem.vue +20 -3
- package/src/components/AppCompNavigation.vue +351 -355
- package/src/components/AppCompNoteCall.vue +62 -47
- package/src/components/AppCompNoteCredit.vue +182 -79
- package/src/components/AppCompPlayBar.vue +975 -1023
- package/src/components/AppCompPlayBarProgress.vue +73 -0
- package/src/components/AppCompPopUp.vue +175 -114
- package/src/components/AppCompQuiz.vue +67 -81
- package/src/components/AppCompQuizRecall.vue +32 -5
- package/src/components/AppCompSVG.vue +66 -40
- package/src/components/AppCompSettingsMenu.vue +6 -8
- package/src/components/AppCompTableOfContent.vue +166 -45
- package/src/components/AppCompVideoPlayer.vue +154 -110
- package/src/components/BaseModule.vue +21 -17
- package/src/main.js +124 -88
- package/src/mixins/$mediaMixins.js +827 -0
- package/src/mixins/$pageMixins.js +65 -109
- package/src/mixins/$quizMixins.js +12 -26
- package/src/mixins/timerMixin.js +8 -9
- package/src/module/store.js +187 -68
- package/src/module/xapi/ADL.js +90 -53
- package/src/module/xapi/Crypto/Hasher.js +8 -8
- package/src/module/xapi/Crypto/WordArray.js +6 -6
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
- package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
- package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
- package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
- package/src/module/xapi/Crypto/encoders/Base.js +7 -7
- package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
- package/src/module/xapi/Crypto/encoders/Hex.js +2 -2
- package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
- package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
- package/src/module/xapi/Statement/index.js +1 -1
- package/src/module/xapi/launch.js +10 -10
- package/src/module/xapi/utils.js +17 -17
- package/src/module/xapi/wrapper.js +123 -50
- package/src/module/xapi/xapiStatement.js +29 -29
- package/src/plugins/helper.js +8 -9
- package/src/plugins/i18n.js +23 -10
- package/src/plugins/scorm.js +14 -14
- package/src/router/index.js +3 -4
- package/src/router/routes.js +10 -30
- package/src/shared/generalfuncs.js +31 -24
- package/src/shared/validators.js +730 -20
- package/.prettierrc.js +0 -5
- package/babel.config.js +0 -3
- package/src/components/AppBaseDragChoice.vue +0 -91
- package/src/components/AppBaseDropZone.vue +0 -112
- package/src/components/AppCompBif.vue +0 -120
- package/src/components/AppCompDragAndDrop.vue +0 -339
- package/src/components/AppCompInputAssociation.vue +0 -332
- package/src/components/AppCompMediaPlayer.vue +0 -397
- package/src/plugins/timeManager.js +0 -77
- package/src/routes_bckp.js +0 -313
- package/src/routes_static.js +0 -344
- package/vue.config.js +0 -83
package/src/shared/validators.js
CHANGED
|
@@ -6,10 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
const validatefileContent = (fName, fData, requiredArgs = {}) => {
|
|
8
8
|
let err = null
|
|
9
|
-
if (
|
|
9
|
+
if (import.meta.env.DEV) {
|
|
10
10
|
switch (fName) {
|
|
11
11
|
case 'menuSettings': {
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
keys4Lesson,
|
|
14
|
+
keys4ActivityMando,
|
|
15
|
+
keys4ActivityOpt,
|
|
16
|
+
keys4Anchors
|
|
17
|
+
} = requiredArgs
|
|
13
18
|
|
|
14
19
|
//*validate that data is an {Object}. if Not send error message
|
|
15
20
|
if (fData.constructor !== Object)
|
|
@@ -17,27 +22,44 @@ const validatefileContent = (fName, fData, requiredArgs = {}) => {
|
|
|
17
22
|
|
|
18
23
|
if (Object.entries(fData).length > 0) {
|
|
19
24
|
const content = Object.entries(fData)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
+
}
|
|
26
35
|
}
|
|
27
36
|
}
|
|
37
|
+
|
|
28
38
|
// Validate that each entry has the required key
|
|
29
39
|
if (!err) {
|
|
40
|
+
// remove key lessonTitle
|
|
41
|
+
content.shift()
|
|
30
42
|
for (let el of content) {
|
|
31
43
|
const entry = el[1]
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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}`
|
|
35
58
|
break
|
|
36
59
|
} else {
|
|
37
|
-
|
|
38
|
-
switch (k) {
|
|
60
|
+
switch (m) {
|
|
39
61
|
case 'anchors':
|
|
40
|
-
if (entry[
|
|
62
|
+
if (entry[m].constructor !== Array)
|
|
41
63
|
err = `💥 Invalid anchors declaration for 👉 ${el[0]} 👈 in ➡ menu.setting.j \n 🚩Must be of type {Array}`
|
|
42
64
|
else {
|
|
43
65
|
const anchors = entry.anchors
|
|
@@ -64,14 +86,12 @@ const validatefileContent = (fName, fData, requiredArgs = {}) => {
|
|
|
64
86
|
|
|
65
87
|
break
|
|
66
88
|
default:
|
|
67
|
-
if (entry[
|
|
68
|
-
err = `Invalid 👉 ${
|
|
89
|
+
if (entry[m].constructor !== String)
|
|
90
|
+
err = `Invalid 👉 ${m} 👈 declaration for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Must be of type {String}`
|
|
69
91
|
break
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
94
|
}
|
|
73
|
-
|
|
74
|
-
if (err) break
|
|
75
95
|
}
|
|
76
96
|
}
|
|
77
97
|
}
|
|
@@ -88,7 +108,334 @@ const validatefileContent = (fName, fData, requiredArgs = {}) => {
|
|
|
88
108
|
**/
|
|
89
109
|
const validateVideoData = (data) => {
|
|
90
110
|
const errorList = []
|
|
91
|
-
if (
|
|
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
|
+
|
|
132
|
+
if (!data['mSources']) {
|
|
133
|
+
errStringInConsole = ` Missing 👉 mSources 👈 declaration for video element`
|
|
134
|
+
|
|
135
|
+
errString = `l'Attribut 👉 mSources 👈 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
|
+
|
|
143
|
+
//Start validation of keys in data
|
|
144
|
+
if (!errString) {
|
|
145
|
+
expectedKeys.forEach((k) => {
|
|
146
|
+
if (!data[k] && k !== 'mSources') return
|
|
147
|
+
|
|
148
|
+
switch (k) {
|
|
149
|
+
case 'mSources':
|
|
150
|
+
if (
|
|
151
|
+
data['mSources'].constructor !== Array ||
|
|
152
|
+
data['mSources'].length < 1
|
|
153
|
+
) {
|
|
154
|
+
errStringInConsole =
|
|
155
|
+
'\n 💥 Invalid type declaration for mSources.\n 🚩 Must be of type Array'
|
|
156
|
+
|
|
157
|
+
errString = `l'Attribut 👉 mSources 👈 pour le media doit être de type Array`
|
|
158
|
+
|
|
159
|
+
errorList.push(errString)
|
|
160
|
+
console.warn(
|
|
161
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
162
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
break
|
|
166
|
+
|
|
167
|
+
case 'mSubtitles':
|
|
168
|
+
{
|
|
169
|
+
//Validate required keys in Subtitle definition
|
|
170
|
+
let expectedKeys = ['label', 'src', 'srclang']
|
|
171
|
+
//we only accept one subtitle and must be defined as an Object with 3 keys
|
|
172
|
+
if (
|
|
173
|
+
data['mSubtitles'].constructor !== Array ||
|
|
174
|
+
!data['mSubtitles'].length
|
|
175
|
+
) {
|
|
176
|
+
errStringInConsole = `\n 💥 Invalid type declaration for mSubtitles.\n 🚩 Must be of type Array with at list one Object defined with: ${expectedKeys}`
|
|
177
|
+
|
|
178
|
+
errString = `l'Attribut 👉 mSubtitles 👈 doit être de type Array avec au moins un Objet: {${expectedKeys}} `
|
|
179
|
+
|
|
180
|
+
console.warn(
|
|
181
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
182
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return errorList.push(errString)
|
|
186
|
+
}
|
|
187
|
+
//Validate definition for each Subtitle Object
|
|
188
|
+
for (const obj of data['mSubtitles']) {
|
|
189
|
+
const objIndex = data['mSubtitles'].indexOf(obj)
|
|
190
|
+
expectedKeys.forEach((expected) => {
|
|
191
|
+
if (!obj[expected]) {
|
|
192
|
+
errStringInConsole = `\n 💥 Missing key 👉 ${expected} 👈 for mSubtitles No.${
|
|
193
|
+
objIndex + 1
|
|
194
|
+
}.\n 🚩 required keys are: ${expectedKeys} `
|
|
195
|
+
|
|
196
|
+
errString = `l'Attribut 👉 ${expected} 👈 pour le sous-titre No.${
|
|
197
|
+
objIndex + 1
|
|
198
|
+
} n'est pas défini`
|
|
199
|
+
|
|
200
|
+
console.warn(
|
|
201
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
202
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
203
|
+
)
|
|
204
|
+
return errorList.push(errString)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Only none empty String type Accepted
|
|
208
|
+
if (
|
|
209
|
+
obj[expected].constructor === String &&
|
|
210
|
+
obj[expected].trim().length
|
|
211
|
+
)
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
errStringInConsole = `\n 💥 Invalid type declaration for 👉${expected}👈 in mSubtitles No.${
|
|
215
|
+
objIndex + 1
|
|
216
|
+
}.\n 🚩 Must be none-empty String `
|
|
217
|
+
|
|
218
|
+
errString = `l'Attribut 👉${expected}👈 du sous-titre No.${
|
|
219
|
+
objIndex + 1
|
|
220
|
+
} doit être de type String et ne peut pas être vide. `
|
|
221
|
+
|
|
222
|
+
console.warn(
|
|
223
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
224
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
errorList.push(errString)
|
|
228
|
+
})
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
break
|
|
232
|
+
case 'mPoster':
|
|
233
|
+
//Only type String allowed and must not be empty
|
|
234
|
+
if (
|
|
235
|
+
data['mPoster'] &&
|
|
236
|
+
data['mPoster'].constructor == String &&
|
|
237
|
+
data['mPoster'].trim().length
|
|
238
|
+
)
|
|
239
|
+
return
|
|
240
|
+
|
|
241
|
+
errStringInConsole = `\n 💥 Invalid type declaration for 👉 mPoster 👈.\n 🚩 Must be none-empty String `
|
|
242
|
+
|
|
243
|
+
errString = `l'Attribut 👉 mPoster 👈 doit être de type String et ne peut pas être vide. `
|
|
244
|
+
|
|
245
|
+
errorList.push(errString)
|
|
246
|
+
console.warn(
|
|
247
|
+
`%c WARNING!>>> VIDEO: ${errStringInConsole}`,
|
|
248
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
break
|
|
252
|
+
case 'mTranscript':
|
|
253
|
+
//Only type String allowed and must not be empty
|
|
254
|
+
if (
|
|
255
|
+
data['mTranscript'] &&
|
|
256
|
+
data['mTranscript'].constructor == String &&
|
|
257
|
+
data['mTranscript'].trim().length
|
|
258
|
+
)
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
errStringInConsole = `\n 💥 Invalid type declaration for 👉 mTranscript 👈 .\n 🚩 Must be none-empty String `
|
|
262
|
+
|
|
263
|
+
errString = `l'Attribut 👉 mTranscript 👈 doit être de type String et ne peut pas être vide. `
|
|
264
|
+
|
|
265
|
+
console.warn(
|
|
266
|
+
`%c WARNING!>>> VIDEO: ${errStringInConsole}`,
|
|
267
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
268
|
+
)
|
|
269
|
+
errorList.push(errString)
|
|
270
|
+
|
|
271
|
+
break
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return errorList
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @description Validator for the content of audio props
|
|
281
|
+
* @param {Object} data- Object definition to validate
|
|
282
|
+
**/
|
|
283
|
+
const validateAudioData = (data) => {
|
|
284
|
+
const errorList = []
|
|
285
|
+
let currentProperties = Object.getOwnPropertyNames(data)
|
|
286
|
+
if (import.meta.env.DEV) {
|
|
287
|
+
//errorList.push('test')
|
|
288
|
+
|
|
289
|
+
const requiredProperties = ['id', 'mTitle', 'mSources', 'mTranscript']
|
|
290
|
+
|
|
291
|
+
const optionalProperties = ['mPoster', 'mAlt']
|
|
292
|
+
|
|
293
|
+
const allProperties = [
|
|
294
|
+
...requiredProperties,
|
|
295
|
+
...optionalProperties,
|
|
296
|
+
...['__ob__']
|
|
297
|
+
]
|
|
298
|
+
|
|
299
|
+
let errStringInConsole = null
|
|
300
|
+
let errString = null
|
|
301
|
+
|
|
302
|
+
//** Validate if data exist and is an object**/
|
|
303
|
+
if (!data || data.constructor !== Object || Object.keys(data).length < 1) {
|
|
304
|
+
errStringInConsole = `\n 💥 Invalid declaration for audio element`
|
|
305
|
+
console.warn(
|
|
306
|
+
`%c WARNING!>>> AUDIO: ${errStringInConsole}`,
|
|
307
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
308
|
+
)
|
|
309
|
+
errString = `Déclaration invalide pour Objet audData. Ce doit être un objet non vide.`
|
|
310
|
+
errorList.push(errString)
|
|
311
|
+
return errorList
|
|
312
|
+
}
|
|
313
|
+
//** Validate if all the properties are right**/
|
|
314
|
+
let wrongProperties = checkerWrong(allProperties, currentProperties)
|
|
315
|
+
if (wrongProperties.length > 0) {
|
|
316
|
+
console.warn(
|
|
317
|
+
`%c WARNING!>>> AppCompAudio : audData property ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
|
|
318
|
+
'background: orange; color: white; display: block; margin:5px;'
|
|
319
|
+
)
|
|
320
|
+
errString = `Propriété invalide pour audData: ${wrongProperties}. Les propriétés requises sont: ${requiredProperties} et les propriétés facultatives sont: ${optionalProperties}`
|
|
321
|
+
errorList.push(errString)
|
|
322
|
+
return errorList
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
//** Validate if all the required properties are in the data */
|
|
326
|
+
let missingRequired = checkerMissing(requiredProperties, currentProperties)
|
|
327
|
+
if (missingRequired.length > 0) {
|
|
328
|
+
console.warn(
|
|
329
|
+
`%c WARNING!>>> AppCompAudio : audData missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
|
|
330
|
+
'background: orange; color: white; display: block; margin:5px;'
|
|
331
|
+
)
|
|
332
|
+
errString = `Propriété requise manquante pour audData: ${missingRequired}. Les propriétés requises sont: ${requiredProperties} et les propriétés facultatives sont: ${optionalProperties}`
|
|
333
|
+
errorList.push(errString)
|
|
334
|
+
return errorList
|
|
335
|
+
}
|
|
336
|
+
/***Validate data values */
|
|
337
|
+
if (errorList.length == 0) {
|
|
338
|
+
let invalidString = []
|
|
339
|
+
let invalidArray = []
|
|
340
|
+
let invalidProperties = []
|
|
341
|
+
currentProperties.forEach((p) => {
|
|
342
|
+
switch (p) {
|
|
343
|
+
case 'mTitle':
|
|
344
|
+
case 'mTranscript':
|
|
345
|
+
case 'mPoster':
|
|
346
|
+
case 'mAlt':
|
|
347
|
+
if (data[p] && data[p].constructor == String) {
|
|
348
|
+
data[p].trim().length == 0 ? invalidString.push(p) : ''
|
|
349
|
+
} else {
|
|
350
|
+
invalidString.push(p)
|
|
351
|
+
}
|
|
352
|
+
break
|
|
353
|
+
case 'mSources': {
|
|
354
|
+
if (data[p] && data[p].constructor == Array) {
|
|
355
|
+
data[p].length == 0 ? invalidArray.push(p) : ''
|
|
356
|
+
} else {
|
|
357
|
+
invalidArray.push(p)
|
|
358
|
+
}
|
|
359
|
+
if (invalidArray.length === 0) {
|
|
360
|
+
//Valider les attributs de mSources
|
|
361
|
+
for (let i in data[p]) {
|
|
362
|
+
let object = data[p][i]
|
|
363
|
+
if ('src' in object && 'type' in object) {
|
|
364
|
+
if (
|
|
365
|
+
object['src'].constructor != String &&
|
|
366
|
+
object['type'].constructor != String
|
|
367
|
+
) {
|
|
368
|
+
invalidProperties.push(p)
|
|
369
|
+
} else {
|
|
370
|
+
object['src'].trim().length == 0
|
|
371
|
+
? invalidString.push(p)
|
|
372
|
+
: ''
|
|
373
|
+
object['type'].trim().length == 0
|
|
374
|
+
? invalidString.push(p)
|
|
375
|
+
: ''
|
|
376
|
+
}
|
|
377
|
+
} else {
|
|
378
|
+
invalidProperties.push(p)
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
break
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
})
|
|
386
|
+
//Display error for each type
|
|
387
|
+
//String
|
|
388
|
+
let sL = invalidString.length
|
|
389
|
+
if (sL > 0) {
|
|
390
|
+
errStringInConsole = `\n 💥 Invalid value type for 👉${invalidString}👈 \n 🚩 Must be none-empty String `
|
|
391
|
+
|
|
392
|
+
errString = `${sL > 1 ? 'Les ' : "L'"}attribut${
|
|
393
|
+
sL > 1 ? 's ' : ''
|
|
394
|
+
} 👉${invalidString}👈 doi${
|
|
395
|
+
sL > 1 ? 'ven' : ''
|
|
396
|
+
}t être de type String et ne peu${sL > 1 ? 'ven' : ''}t pas être vide. `
|
|
397
|
+
|
|
398
|
+
console.warn(
|
|
399
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
400
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
401
|
+
)
|
|
402
|
+
errorList.push(errString)
|
|
403
|
+
}
|
|
404
|
+
//Array
|
|
405
|
+
let aL = invalidArray.length
|
|
406
|
+
if (aL > 0) {
|
|
407
|
+
errStringInConsole = `\n 💥 Invalid value type for 👉${invalidArray}👈 \n 🚩 Must be none-empty Array`
|
|
408
|
+
|
|
409
|
+
errString = `${aL > 1 ? 'Les ' : "L'"}attribut${
|
|
410
|
+
aL > 1 ? 's ' : ''
|
|
411
|
+
} 👉${invalidArray}👈 doi${
|
|
412
|
+
sL > 1 ? 'ven' : ''
|
|
413
|
+
}t être de type Array et ne peu${aL > 1 ? 'ven' : ''}t pas être vide. `
|
|
414
|
+
|
|
415
|
+
console.warn(
|
|
416
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
417
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
418
|
+
)
|
|
419
|
+
errorList.push(errString)
|
|
420
|
+
}
|
|
421
|
+
let pL = invalidProperties.length
|
|
422
|
+
if (pL > 0) {
|
|
423
|
+
errStringInConsole = `\n 💥 Invalid value type for 👉src and/or type👈 in mSources \n 🚩 They are required and must be none-empty strings`
|
|
424
|
+
|
|
425
|
+
errString = `${pL > 1 ? 'Les ' : "L'"}attribut${
|
|
426
|
+
pL > 1 ? 's ' : ''
|
|
427
|
+
} 👉src and/or type👈 de mSources doi${
|
|
428
|
+
sL > 1 ? 'ven' : ''
|
|
429
|
+
}t être de type String et ne peu${pL > 1 ? 'ven' : ''}t pas être vide. `
|
|
430
|
+
|
|
431
|
+
console.warn(
|
|
432
|
+
`%c WARNING!>>> ${errStringInConsole}`,
|
|
433
|
+
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
434
|
+
)
|
|
435
|
+
errorList.push(errString)
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/*if (import.meta.env.DEV) {
|
|
92
439
|
let errStringInConsole = null
|
|
93
440
|
let errString = null
|
|
94
441
|
const expectedKeys = ['mSources', 'mSubtitles', 'mPoster', 'mTranscript']
|
|
@@ -242,8 +589,371 @@ const validateVideoData = (data) => {
|
|
|
242
589
|
}
|
|
243
590
|
})
|
|
244
591
|
}
|
|
592
|
+
}*/
|
|
245
593
|
}
|
|
246
594
|
return errorList
|
|
247
595
|
}
|
|
596
|
+
//Get all the invalids properties from the object
|
|
597
|
+
/*Add element from target array that are NOT in arr to the wrongArray*/
|
|
598
|
+
const checkerWrong = (arr, target) => {
|
|
599
|
+
let wrongArray = []
|
|
600
|
+
target.every((v) => {
|
|
601
|
+
if (arr.includes(v)) {
|
|
602
|
+
return true
|
|
603
|
+
} else {
|
|
604
|
+
wrongArray.push(v)
|
|
605
|
+
return true
|
|
606
|
+
}
|
|
607
|
+
})
|
|
608
|
+
return wrongArray
|
|
609
|
+
}
|
|
610
|
+
//Get all the required properties that are missing from the object
|
|
611
|
+
/*Add element from the arr that are NOT in target arr to the missingArray*/
|
|
612
|
+
const checkerMissing = (arr, target) => {
|
|
613
|
+
let missingArray = []
|
|
614
|
+
arr.every((v) => {
|
|
615
|
+
if (target.includes(v)) {
|
|
616
|
+
return true
|
|
617
|
+
} else {
|
|
618
|
+
missingArray.push(v)
|
|
619
|
+
return true
|
|
620
|
+
}
|
|
621
|
+
})
|
|
622
|
+
return missingArray
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
const ERR_TYPE = {
|
|
626
|
+
err0: `\n 💥 Missing \x1B[1m$attr$ \x1B[0mfor $comp$. \x1B[1m$attr$ \x1B[0m should be provided with following attributes: \x1B[1m{$data$}`,
|
|
627
|
+
err1: `\n 💥 Invalid declaration for \x1B[1m$wrd$ \x1B[0m object`,
|
|
628
|
+
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`,
|
|
629
|
+
err3: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`,
|
|
630
|
+
err4: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
const ERR_TYPE_MSG = {
|
|
634
|
+
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>`,
|
|
635
|
+
err1: `\n Déclaration invalide pour <b>$wrd$</b>. Assurez-vous que l'application a du data.`,
|
|
636
|
+
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`,
|
|
637
|
+
err3: `\n L'attribut 👉<b>$key$</b>👈 est manquant dans <b>$el$</b>. Les attributs requis sont: <b>$args$</b>`
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* @description Validator for the content of app data.
|
|
642
|
+
* App data is used as setting for the application
|
|
643
|
+
* @param {Object} data - the Object definition to validate
|
|
644
|
+
* @param {Boolean} silent - if Validator should diplay error in console
|
|
645
|
+
*
|
|
646
|
+
**/
|
|
647
|
+
|
|
648
|
+
const validateAppContent = (data, silent = false) => {
|
|
649
|
+
let errorInConsole = []
|
|
650
|
+
let errorList = []
|
|
651
|
+
|
|
652
|
+
const requiredArgs = [
|
|
653
|
+
'lang',
|
|
654
|
+
'specification',
|
|
655
|
+
'id',
|
|
656
|
+
'crs_id',
|
|
657
|
+
'idb_id',
|
|
658
|
+
'no_menu',
|
|
659
|
+
'is_single_activity',
|
|
660
|
+
'auto_next_activity'
|
|
661
|
+
]
|
|
662
|
+
|
|
663
|
+
//Validate not empty data
|
|
664
|
+
if (Object.keys(data).length == 0) {
|
|
665
|
+
const reg = /(\$comp\$)|(\$data\$)|(\$attr\$)/g
|
|
666
|
+
|
|
667
|
+
errorInConsole.push(
|
|
668
|
+
ERR_TYPE.err0.replace(reg, (e) => {
|
|
669
|
+
if (e == '$comp$') return 'app-base'
|
|
670
|
+
if (e == '$data$') return requiredArgs.toString().replaceAll(',', ', ')
|
|
671
|
+
if (e == '$attr$') return 'app-config'
|
|
672
|
+
})
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
errorList.push(
|
|
676
|
+
ERR_TYPE_MSG.err0.replace(reg, (e) => {
|
|
677
|
+
if (e == '$comp$') return 'app-base'
|
|
678
|
+
if (e == '$data$') return requiredArgs.toString().replaceAll(',', ', ')
|
|
679
|
+
if (e == '$attr$') return 'app-config'
|
|
680
|
+
})
|
|
681
|
+
)
|
|
682
|
+
|
|
683
|
+
console.warn(errorInConsole[0])
|
|
684
|
+
|
|
685
|
+
return errorList
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
let stringType = ['lang', 'specification', 'id', 'crs_id', 'idb_id']
|
|
689
|
+
let boolType = [
|
|
690
|
+
'no_menu',
|
|
691
|
+
'is_single_activity',
|
|
692
|
+
'auto_next_activity',
|
|
693
|
+
'remote'
|
|
694
|
+
]
|
|
695
|
+
let objectType = ['actor', 'linkedResource']
|
|
696
|
+
let optionalArgs = ['remote', 'actor', 'linkedResource']
|
|
697
|
+
|
|
698
|
+
const { errorInConsole: errCons, errorList: errList } = validateObjType(
|
|
699
|
+
data,
|
|
700
|
+
{
|
|
701
|
+
stringType,
|
|
702
|
+
boolType,
|
|
703
|
+
objectType
|
|
704
|
+
},
|
|
705
|
+
optionalArgs,
|
|
706
|
+
'App.vue'
|
|
707
|
+
)
|
|
708
|
+
|
|
709
|
+
errorList = [...errorList, ...errList]
|
|
710
|
+
errorInConsole = [...errorInConsole, ...errCons]
|
|
711
|
+
|
|
712
|
+
//===========Optional Keys should be of correct type when declared =================//
|
|
713
|
+
// Has actor defined
|
|
714
|
+
if (data['actor']) {
|
|
715
|
+
let { errorInConsole: err1, errorList: err2 } = validateObjType(
|
|
716
|
+
data['actor'],
|
|
717
|
+
{
|
|
718
|
+
stringType: ['name', 'mbox']
|
|
719
|
+
},
|
|
720
|
+
'actor'
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
errorList = [...errorList, ...err2]
|
|
724
|
+
errorInConsole = [...errorInConsole, ...err1]
|
|
725
|
+
}
|
|
726
|
+
// Has LinkedResource defined
|
|
727
|
+
if (data['linkedResource']) {
|
|
728
|
+
let { errorInConsole: err1, errorList: err2 } = validateObjType(
|
|
729
|
+
data['linkedResource'],
|
|
730
|
+
{
|
|
731
|
+
stringType: ['url', 'id']
|
|
732
|
+
},
|
|
733
|
+
'linkedResource'
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
errorList = [...errorList, ...err2]
|
|
737
|
+
errorInConsole = [...errorInConsole, ...err1]
|
|
738
|
+
}
|
|
739
|
+
// Has endpointConfig defined
|
|
740
|
+
if (data['endpointConfig']) {
|
|
741
|
+
let { errorInConsole: err1, errorList: err2 } = validateObjType(
|
|
742
|
+
data['endpointConfig'],
|
|
743
|
+
{
|
|
744
|
+
stringType: ['auth', 'endpoint']
|
|
745
|
+
},
|
|
746
|
+
'endpointConfig'
|
|
747
|
+
)
|
|
748
|
+
errorList = [...errorList, ...err2]
|
|
749
|
+
errorInConsole = [...errorInConsole, ...err1]
|
|
750
|
+
}
|
|
751
|
+
//================== END Optional Keys ====================//
|
|
752
|
+
|
|
753
|
+
//Should display error to console
|
|
754
|
+
if (errorList.length && !silent) {
|
|
755
|
+
let txt = '⚠️ You have the following Errors:'
|
|
756
|
+
console.group(`%c ${txt}`, 'background:#ffc13a7d')
|
|
757
|
+
errorInConsole.forEach((err) => console.warn(err))
|
|
758
|
+
console.groupEnd()
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
return errorList
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* @description - Method to validate that given object attributes hold expected types
|
|
766
|
+
* @param {Object} Obj - object to validate
|
|
767
|
+
* @param {Object} Args - List of expected type groups - each type group must be an array of attributes with the same type
|
|
768
|
+
* @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
|
|
769
|
+
* @param {Array} err - list off errors to be added to
|
|
770
|
+
* @return {Object} list of errors - {errorInConsole, errorList} : errorlist can be used to display messages on template and
|
|
771
|
+
* errorInConsole to display messages in browser console
|
|
772
|
+
* @exemple - Given $user= {name:'toto', username:'totoEscargot', id:'id001', age:23, books:['one', 'two', 'three'] }
|
|
773
|
+
* Use validator on $user: validateObjType($user, {stringType:['name', 'username' , 'id'], numbType:['age'], arrayType:['books']})
|
|
774
|
+
* Will fail if any listed attribute not in $user or have wrong value. Error messages will be in console
|
|
775
|
+
*
|
|
776
|
+
*/
|
|
777
|
+
|
|
778
|
+
const validateObjType = (
|
|
779
|
+
Obj,
|
|
780
|
+
Args = {
|
|
781
|
+
boolType: null,
|
|
782
|
+
arrayType: null,
|
|
783
|
+
stringType: null,
|
|
784
|
+
objectType: null,
|
|
785
|
+
numbType: null
|
|
786
|
+
},
|
|
787
|
+
notRequiredArgs = null,
|
|
788
|
+
compName = 'component',
|
|
789
|
+
err = null
|
|
790
|
+
) => {
|
|
791
|
+
let errorInConsole = err && err.errorInConsole ? err.errorInConsole : []
|
|
792
|
+
let errorList = err && err.errorList ? err.errorLIst : []
|
|
793
|
+
let optionalArgs =
|
|
794
|
+
notRequiredArgs && notRequiredArgs.length ? notRequiredArgs : []
|
|
795
|
+
//=====Expected Arguments validation =================//
|
|
796
|
+
//Should have an object argument
|
|
797
|
+
if (!Obj) throw new Error(`No valid arguments provided`)
|
|
798
|
+
|
|
799
|
+
//validate Args Keys type
|
|
800
|
+
for (const _type in Args) {
|
|
801
|
+
// Should be a required type
|
|
802
|
+
if (
|
|
803
|
+
![
|
|
804
|
+
'boolType',
|
|
805
|
+
'arrayType',
|
|
806
|
+
'stringType',
|
|
807
|
+
'objectType',
|
|
808
|
+
'numbType'
|
|
809
|
+
].includes(_type)
|
|
810
|
+
)
|
|
811
|
+
throw new Error(`Unknown types declaration : ${_type}`)
|
|
812
|
+
|
|
813
|
+
if (Args[_type] && Args[_type].length) {
|
|
814
|
+
for (let el of Args[_type]) {
|
|
815
|
+
//Check that each given element is a string
|
|
816
|
+
if (el.constructor !== String)
|
|
817
|
+
throw new Error(
|
|
818
|
+
`Invalid type detected in ${JSON.stringify(
|
|
819
|
+
Args[_type]
|
|
820
|
+
)}. Item ${Args[_type].indexOf(el) + 1} should be a String`
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
let reg = /(\$el\$)|(\$type\$)|(\$attr\$)/g
|
|
824
|
+
|
|
825
|
+
let isOptionalArg = optionalArgs.includes(el) ? true : false
|
|
826
|
+
|
|
827
|
+
switch (true) {
|
|
828
|
+
// Check That each given element exist in data if not optional
|
|
829
|
+
case Obj[el] === undefined && !isOptionalArg: {
|
|
830
|
+
reg = /(\$key\$)|(\$el\$)|(\$args\$)/g
|
|
831
|
+
const reg2 = /\[|\]|/g
|
|
832
|
+
|
|
833
|
+
errorInConsole.push(
|
|
834
|
+
ERR_TYPE.err3.replace(reg, (e) => {
|
|
835
|
+
if (e == '$key$') return el
|
|
836
|
+
if (e == '$el$') return compName
|
|
837
|
+
if (e == '$args$') return JSON.stringify(Args[_type])
|
|
838
|
+
})
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
errorList.push(
|
|
842
|
+
ERR_TYPE_MSG.err3.replace(reg, (e) => {
|
|
843
|
+
if (e == '$key$') return el
|
|
844
|
+
if (e == '$el$') return compName || 'Composant'
|
|
845
|
+
if (e == '$args$')
|
|
846
|
+
return JSON.stringify(Args[_type]).replaceAll(reg2, '')
|
|
847
|
+
})
|
|
848
|
+
)
|
|
849
|
+
break
|
|
850
|
+
}
|
|
851
|
+
//Should have Correct Types $attr$ $el$ $type$
|
|
852
|
+
case _type == 'boolType' &&
|
|
853
|
+
Obj[el] !== undefined &&
|
|
854
|
+
Obj[el].constructor !== Boolean:
|
|
855
|
+
errorInConsole.push(
|
|
856
|
+
ERR_TYPE.err2.replace(reg, (e) => {
|
|
857
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
858
|
+
if (e == '$el$') return el
|
|
859
|
+
if (e == '$type$') return 'Boolean'
|
|
860
|
+
})
|
|
861
|
+
)
|
|
862
|
+
errorList.push(
|
|
863
|
+
ERR_TYPE_MSG.err2.replace(reg, (e) => {
|
|
864
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
865
|
+
if (e == '$el$') return el
|
|
866
|
+
if (e == '$type$') return 'Boolean'
|
|
867
|
+
})
|
|
868
|
+
)
|
|
869
|
+
break
|
|
870
|
+
|
|
871
|
+
case _type == 'stringType' &&
|
|
872
|
+
Obj[el] !== undefined &&
|
|
873
|
+
(Obj[el].constructor !== String || !Obj[el].trim().length):
|
|
874
|
+
errorInConsole.push(
|
|
875
|
+
ERR_TYPE.err2.replace(reg, (e) => {
|
|
876
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
877
|
+
if (e == '$el$') return el
|
|
878
|
+
if (e == '$type$') return 'String'
|
|
879
|
+
})
|
|
880
|
+
)
|
|
881
|
+
errorList.push(
|
|
882
|
+
ERR_TYPE_MSG.err2.replace(reg, (e) => {
|
|
883
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
884
|
+
if (e == '$el$') return el
|
|
885
|
+
if (e == '$type$') return 'String'
|
|
886
|
+
})
|
|
887
|
+
)
|
|
888
|
+
break
|
|
889
|
+
|
|
890
|
+
case _type == 'arrayType' &&
|
|
891
|
+
Obj[el] !== undefined &&
|
|
892
|
+
(Obj[el].constructor !== Array || !Obj[el].length):
|
|
893
|
+
errorInConsole.push(
|
|
894
|
+
ERR_TYPE.err2.replace(reg, (e) => {
|
|
895
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
896
|
+
if (e == '$el$') return el
|
|
897
|
+
if (e == '$type$') return 'Array'
|
|
898
|
+
})
|
|
899
|
+
)
|
|
900
|
+
errorList.push(
|
|
901
|
+
ERR_TYPE_MSG.err2.replace(reg, (e) => {
|
|
902
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
903
|
+
if (e == '$el$') return el
|
|
904
|
+
if (e == '$type$') return 'Array'
|
|
905
|
+
})
|
|
906
|
+
)
|
|
907
|
+
break
|
|
908
|
+
|
|
909
|
+
case _type == 'numberType' &&
|
|
910
|
+
Obj[el] !== undefined &&
|
|
911
|
+
Obj[el].constructor !== Number:
|
|
912
|
+
errorInConsole.push(
|
|
913
|
+
ERR_TYPE.err2.replace(reg, (e) => {
|
|
914
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
915
|
+
if (e == '$el$') return el
|
|
916
|
+
if (e == '$type$') return 'Number'
|
|
917
|
+
})
|
|
918
|
+
)
|
|
919
|
+
errorList.push(
|
|
920
|
+
ERR_TYPE_MSG.err2.replace(reg, (e) => {
|
|
921
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
922
|
+
if (e == '$el$') return el
|
|
923
|
+
if (e == '$type$') return 'Number'
|
|
924
|
+
})
|
|
925
|
+
)
|
|
926
|
+
break
|
|
927
|
+
|
|
928
|
+
case _type == 'objectType' &&
|
|
929
|
+
Obj[el] !== undefined &&
|
|
930
|
+
Obj[el].constructor !== Object:
|
|
931
|
+
errorInConsole.push(
|
|
932
|
+
ERR_TYPE.err2.replace(reg, (e) => {
|
|
933
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
934
|
+
if (e == '$el$') return el
|
|
935
|
+
if (e == '$type$') return 'Object'
|
|
936
|
+
})
|
|
937
|
+
)
|
|
938
|
+
errorList.push(
|
|
939
|
+
ERR_TYPE_MSG.err2.replace(reg, (e) => {
|
|
940
|
+
if (e == '$attr$') return compName || 'Composant'
|
|
941
|
+
if (e == '$el$') return el
|
|
942
|
+
if (e == '$type$') return 'Object'
|
|
943
|
+
})
|
|
944
|
+
)
|
|
945
|
+
break
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
return { errorInConsole, errorList }
|
|
952
|
+
}
|
|
248
953
|
|
|
249
|
-
export {
|
|
954
|
+
export {
|
|
955
|
+
validateVideoData,
|
|
956
|
+
validateAudioData,
|
|
957
|
+
validatefileContent,
|
|
958
|
+
validateAppContent
|
|
959
|
+
}
|