fcad-core-dragon 2.0.0-beta.0 β†’ 2.0.0-beta.1

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 (49) hide show
  1. package/README.md +1 -1
  2. package/package.json +7 -9
  3. package/src/$locales/en.json +39 -15
  4. package/src/$locales/fr.json +48 -23
  5. package/src/components/AppBase.vue +245 -266
  6. package/src/components/AppBaseErrorDisplay.vue +29 -0
  7. package/src/components/AppBaseModule.vue +485 -232
  8. package/src/components/AppBasePage.vue +28 -54
  9. package/src/components/AppCompBif.vue +120 -0
  10. package/src/components/AppCompBranchButtons.vue +31 -30
  11. package/src/components/AppCompButtonProgress.vue +35 -46
  12. package/src/components/AppCompCarousel.vue +154 -247
  13. package/src/components/AppCompJauge.vue +1 -2
  14. package/src/components/AppCompMediaPlayer.vue +106 -74
  15. package/src/components/AppCompMenu.vue +87 -81
  16. package/src/components/AppCompMenuItem.vue +48 -90
  17. package/src/components/AppCompNavigation.vue +949 -0
  18. package/src/components/AppCompNoteCall.vue +126 -0
  19. package/src/components/AppCompNoteCredit.vue +164 -0
  20. package/src/components/AppCompPlayBar.vue +864 -1085
  21. package/src/components/AppCompPopUp.vue +26 -27
  22. package/src/components/AppCompPopover.vue +27 -0
  23. package/src/components/AppCompQuiz.vue +27 -36
  24. package/src/components/AppCompQuizRecall.vue +250 -0
  25. package/src/components/AppCompSVG.vue +309 -0
  26. package/src/components/AppCompSettingsMenu.vue +1 -0
  27. package/src/components/AppCompTableOfContent.vue +140 -85
  28. package/src/components/AppCompTranscript.vue +19 -0
  29. package/src/components/AppCompVideoPlayer.vue +336 -0
  30. package/src/components/BaseModule.vue +24 -105
  31. package/src/main.js +18 -9
  32. package/src/mixins/$pageMixins.js +106 -28
  33. package/src/mixins/timerMixin.js +31 -7
  34. package/src/module/store.js +33 -12
  35. package/src/module/xapi/Crypto/encoders/Hex.js +2 -1
  36. package/src/module/xapi/wrapper.js +4 -4
  37. package/src/plugins/gsap.js +4 -1
  38. package/src/plugins/helper.js +53 -18
  39. package/src/plugins/idb.js +1 -0
  40. package/src/public/index.html +1 -1
  41. package/src/router/index.js +41 -0
  42. package/src/router/routes.js +337 -0
  43. package/src/routes_bckp.js +313 -0
  44. package/src/routes_static.js +344 -0
  45. package/src/shared/generalfuncs.js +79 -4
  46. package/src/shared/validators.js +249 -0
  47. package/src/components/AppCompNavigationFull.vue +0 -1791
  48. package/src/components/AppCompToolTip.vue +0 -94
  49. package/src/routes.js +0 -734
@@ -0,0 +1,344 @@
1
+ import Router from 'vue-router'
2
+ import AppCompViewDisplay from './components/AppCompViewDisplay.vue'
3
+ import store from './module/store'
4
+ import { fileAssets } from './shared/generalfuncs'
5
+ // const _path = require('path')
6
+
7
+ /**
8
+ * The router Module defines the routes of the App by:
9
+ * loading the required files for module and activities pages,
10
+ * dynamically creating the navigation route of module base on the file in VIEWS folder
11
+ * dynamically creating the navigation routes of activities and branchings base on the files contained in the MODULE
12
+ * Creating Redirection routes for navigation error
13
+ * Adding the pages for the module in the STORE
14
+ */
15
+
16
+ const _routes = [] // routes of the app
17
+ let errorType = null
18
+ let newRoute = null // wrapper for module routes
19
+ const _allFiles = fileAssets.getActivities()
20
+ let mappedFiles = fileAssets.buildMapTree(_allFiles)
21
+ let menuCreated = false
22
+
23
+ /**
24
+ * 1- Preparing the router to catch failing navigation error from browser by
25
+ * Redefining the Router push method
26
+ * ref: https://stackoverflow.com/questions/57837758/ navigationduplicated-navigating-to-current-location-search-is-not-allowed
27
+ */
28
+ const originalPush = Router.prototype.push
29
+ Router.prototype.push = function push(location) {
30
+ return originalPush.call(this, location).catch((err) => err)
31
+ }
32
+
33
+ // Creating 1st route: redirection for none existing route to home(Module)
34
+ _routes.push({
35
+ path: '*',
36
+ redirect: {
37
+ name: '404'
38
+ }
39
+ })
40
+
41
+ /**
42
+ * 2 - Creating the 2nd route: The App module route
43
+ */
44
+ // Load all the files in the VIEWS folder
45
+
46
+ const defaultRoute = {
47
+ path: '/',
48
+ component: AppCompViewDisplay,
49
+ children: []
50
+ }
51
+ errorType = false
52
+
53
+ const staticSummary = {
54
+ path: '/menu',
55
+ component: () =>
56
+ import(/* webpackChunkName: "menu" */ `@/views/SummaryView.vue`),
57
+ name: 'menu',
58
+ meta: {
59
+ type: 'page_menu'
60
+ }
61
+ }
62
+
63
+ const staticModule = {
64
+ path: '',
65
+ component: () =>
66
+ import(/* webpackChunkName: "home" */ `@/views/ModuleView.vue`),
67
+ name: 'module',
68
+ children: [
69
+ {
70
+ path: 'introduction',
71
+ component: AppCompViewDisplay,
72
+ children: [
73
+ {
74
+ path: 'page-1',
75
+ name: 'introduction',
76
+ component: () =>
77
+ import(/* webpackChunkName: "gpNested" */ `@/module/A02/P01.vue`),
78
+ meta: {
79
+ id: 'P01',
80
+ activity_ref: 'A00',
81
+ type: 'normal',
82
+ parent: {
83
+ _ref: 'P01',
84
+ _path: 'introduction',
85
+ _namedRoute: 'introduction'
86
+ }
87
+ }
88
+ }
89
+ ],
90
+ meta: {
91
+ id: 'A00',
92
+ children: [
93
+ {
94
+ _ref: 'P01',
95
+ _path: 'page-1',
96
+ _namedRoute: 'introduction'
97
+ }
98
+ ]
99
+ }
100
+ },
101
+ {
102
+ path: 'activite-1',
103
+ component: AppCompViewDisplay,
104
+ children: [
105
+ {
106
+ path: 'page-1',
107
+ name: 'activite_1',
108
+ component: () =>
109
+ import(/* webpackChunkName: "gpNested" */ `@/module/A01/P01.vue`),
110
+ meta: {
111
+ id: 'P01',
112
+ activity_ref: 'A01',
113
+ type: 'normal',
114
+ parent: {
115
+ _ref: 'P01',
116
+ _path: 'activite-1',
117
+ _namedRoute: 'activity_1'
118
+ }
119
+ }
120
+ },
121
+ {
122
+ path: 'page-2',
123
+ name: 'activite_1.page_2',
124
+ component: () =>
125
+ import(/* webpackChunkName: "gpNested" */ `@/module/A01/P02.vue`),
126
+ meta: {
127
+ id: 'P02',
128
+ activity_ref: 'A01',
129
+ type: 'branching',
130
+ parent: {
131
+ _ref: 'P01',
132
+ _path: 'activite-1',
133
+ _namedRoute: 'activity_1'
134
+ },
135
+ children: [
136
+ {
137
+ _ref: 'P02_E01',
138
+ _path: 'branch-1',
139
+ _namedRoute: 'A01.page_2.branching_1.branch_1'
140
+ },
141
+ {
142
+ _ref: 'P02_E02',
143
+ _path: 'branch-2',
144
+ _namedRoute: 'A01.page_2.branching_1.branch_2'
145
+ },
146
+ {
147
+ _ref: 'P02_E03',
148
+ _path: 'branch-3',
149
+ _namedRoute: 'A01.page_2.branching_1.branch_3'
150
+ }
151
+ ]
152
+ },
153
+ children: [
154
+ {
155
+ path: 'branch-1',
156
+ name: 'A01.page_2.branching_1.branch_1',
157
+ component: () =>
158
+ import(
159
+ /* webpackChunkName: "gpNested" */ `@/module/A01/P02_E01.vue`
160
+ ),
161
+ meta: {
162
+ id: 'P02_E01',
163
+ activity_ref: 'A01',
164
+ type: 'branch',
165
+ branching_ref: 'A01.P02.branching_1',
166
+ parent: {
167
+ _ref: 'P02',
168
+ _path: 'activite-1.page-2',
169
+ _namedRoute: 'activity_1.page_2'
170
+ }
171
+ }
172
+ },
173
+ {
174
+ path: 'branch-2',
175
+ name: 'A01.page_2.branching_1.branch_2',
176
+ component: () =>
177
+ import(
178
+ /* webpackChunkName: "gpNested" */ `@/module/A01/P02_E02.vue`
179
+ ),
180
+ meta: {
181
+ id: 'P02_E02',
182
+ activity_ref: 'A01',
183
+ type: 'branch',
184
+ branching_ref: 'A01.P02.branching_1',
185
+ parent: {
186
+ _ref: 'P02',
187
+ _path: 'activite-1.page-2',
188
+ _namedRoute: 'activity_1.page_2'
189
+ }
190
+ }
191
+ },
192
+ {
193
+ path: 'branch-3',
194
+ name: 'A01.page_2.branching_1.branch_3',
195
+ component: () =>
196
+ import(
197
+ /* webpackChunkName: "gpNested" */ `@/module/A01/P02_E03.vue`
198
+ ),
199
+ meta: {
200
+ id: 'P02_E03',
201
+ activity_ref: 'A01',
202
+ type: 'branch',
203
+ branching_ref: 'A01.P02.branching_1',
204
+ parent: {
205
+ _ref: 'P02',
206
+ _path: 'activite-1.page-2',
207
+ _namedRoute: 'activity_1.page_2'
208
+ }
209
+ }
210
+ }
211
+ ]
212
+ },
213
+ {
214
+ path: 'page-3',
215
+ name: 'activite_1.page_3',
216
+ component: () =>
217
+ import(/* webpackChunkName: "gpNested" */ `@/module/A01/P03.vue`),
218
+ meta: {
219
+ id: 'P03',
220
+ activity_ref: 'A01',
221
+ type: 'normal',
222
+ parent: {
223
+ _ref: 'P01',
224
+ _path: 'activite-1',
225
+ _namedRoute: 'activity_1'
226
+ }
227
+ }
228
+ }
229
+ ],
230
+ meta: {
231
+ id: 'A01',
232
+ children: [
233
+ {
234
+ _ref: 'P01',
235
+ _path: 'page-1',
236
+ _namedRoute: 'activite_1'
237
+ },
238
+ {
239
+ _ref: 'P02',
240
+ _path: 'page-2',
241
+ _namedRoute: 'activite_1.page_2'
242
+ },
243
+ {
244
+ _ref: 'P03',
245
+ _path: 'page-3',
246
+ _namedRoute: 'activite_1.page_3'
247
+ }
248
+ ]
249
+ }
250
+ },
251
+ {
252
+ path: 'activite-2',
253
+ component: AppCompViewDisplay,
254
+ children: [
255
+ {
256
+ path: 'page-1',
257
+ name: 'activite_2',
258
+ component: () =>
259
+ import(/* webpackChunkName: "gpNested" */ `@/module/A02/P01.vue`),
260
+ meta: {
261
+ id: 'P01',
262
+ activity_ref: 'A02',
263
+ type: 'normal',
264
+ parent: {
265
+ _ref: 'P01',
266
+ _path: 'activite-2',
267
+ _namedRoute: 'activity_2'
268
+ }
269
+ }
270
+ }
271
+ ],
272
+ meta: {
273
+ id: 'A02',
274
+ children: [
275
+ {
276
+ _ref: 'P01',
277
+ _path: 'page-1',
278
+ _namedRoute: 'activite_2'
279
+ }
280
+ ]
281
+ }
282
+ }
283
+ ],
284
+ meta: {
285
+ id: 'mod_00100',
286
+ type: 'normal',
287
+ children: [
288
+ {
289
+ _ref: 'A01',
290
+ _path: 'introduction',
291
+ _namedRoute: 'introduction'
292
+ },
293
+ {
294
+ _ref: 'A01',
295
+ _path: 'activite-1',
296
+ _namedRoute: 'activite_1'
297
+ },
298
+ {
299
+ _ref: 'A02',
300
+ _path: 'activite-2',
301
+ _namedRoute: 'activite_2'
302
+ }
303
+ ]
304
+ }
305
+ }
306
+ defaultRoute.children.push(staticModule)
307
+ defaultRoute.children.push(staticSummary)
308
+ if (!errorType) {
309
+ // add the newRoute to the routes array
310
+ _routes.push(defaultRoute)
311
+ } else {
312
+ // create Route for error non-existing files
313
+ _routes.push({
314
+ path: '/',
315
+ component: () =>
316
+ import(
317
+ /* webpackChunkName: "gpNested" */ `./components/AppBaseErrorDisplay.vue`
318
+ ),
319
+ props: {
320
+ errorMessage: errorType
321
+ }
322
+ })
323
+ }
324
+ // Routes for errors : 404
325
+ _routes.push({
326
+ path: '/404',
327
+ name: '404',
328
+ component: () =>
329
+ import(
330
+ /* webpackChunkName: "gpNested" */ `./components/AppBaseErrorDisplay.vue`
331
+ ),
332
+ props: {
333
+ errorMessage: '404'
334
+ }
335
+ })
336
+
337
+ // Add register Module pages to store
338
+ store.state.thisModule.activities = mappedFiles
339
+
340
+ // exporting routes object
341
+ export default {
342
+ base: process.env.BASE_URL,
343
+ routes: [..._routes]
344
+ }
@@ -2,16 +2,16 @@ const allfile = require.context('@/', true, /\.vue$/) //get all .vue file at the
2
2
 
3
3
  const fileAssets = {
4
4
  // return the collection of all the files in the project directory
5
- allFiles: () => allfile,
5
+ allFiles: () => allfile.keys(),
6
6
 
7
7
  // Return all the file in './views' with the Name Module
8
- getModule: () => {
9
- return allfile.keys().filter((file) => file.startsWith('./views/Module'))
8
+ getViews: () => {
9
+ return fileAssets.allFiles().filter((file) => file.startsWith('./views'))
10
10
  },
11
11
  // return all files that are in the folder './src/module' of the project with name respecting following condition:
12
12
  // must start with a capital P followed by a digit (P0, P1, P2...) and not contain keyword "copy"
13
13
  getActivities: () => {
14
- return allfile.keys().filter((file) => {
14
+ return fileAssets.allFiles().filter((file) => {
15
15
  if (
16
16
  file.startsWith('./module/A') &&
17
17
  /^P[0-9]{2,3}/.test(file.split('/')[3]) &&
@@ -107,6 +107,81 @@ const fileAssets = {
107
107
  }
108
108
  }
109
109
  return err
110
+ },
111
+
112
+ /**
113
+ * @description Validator for the content of menu setting file
114
+ * @param {String} a- array of file for use case
115
+ * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
116
+ */
117
+ buildMapTree: (a) => {
118
+ // Load files in module folder
119
+ if (a.length < 0) return
120
+
121
+ const mapTree = new Map()
122
+ // There is a file in the module folder
123
+
124
+ a.forEach((key) => {
125
+ const fileRef = key.replace(/(\.\/)/g, '')
126
+ const splitted = fileRef.split('/')
127
+ const activityName = splitted[1]
128
+ const fileName = splitted[splitted.length - 1].replace(/(\.vue)/g, '')
129
+ const fileContent = fileAssets.fetchFileContent(`./${fileRef}`).default
130
+
131
+ if (!Object.keys(fileContent).includes('data')) return
132
+ // Handling single page type
133
+ // adding the page in a map for the Pages
134
+
135
+ // Add the key in the map for the routes if it is not in the map, with its data as new Map;
136
+ if (!mapTree.get(activityName)) {
137
+ mapTree.set(activityName, new Map())
138
+ }
139
+
140
+ if (fileName.length === 3) {
141
+ mapTree.get(activityName).set(fileName, {
142
+ ref: fileRef,
143
+ content: fileContent.data()
144
+ }) // add entry for the page
145
+ }
146
+ // Handleling Groupe page type
147
+ else if (fileName.length > 3 && fileName.includes('_')) {
148
+ const keyToFind = fileName.split('_', 1)[0] // Pxx
149
+ const KeyToAdd = fileName.split('_')[1] // Exx
150
+
151
+ // // search for the page key in the map
152
+ if (!mapTree.get(activityName).has(keyToFind)) return
153
+
154
+ // save a reference for the value of the key
155
+ const tempSave = mapTree.get(activityName).get(keyToFind)
156
+
157
+ // transform value of found key to a new map
158
+ if (!mapTree.get(activityName).get(keyToFind).size) {
159
+ mapTree.get(activityName).set(keyToFind, new Map())
160
+ // Update reference of key's
161
+ mapTree
162
+ .get(activityName)
163
+ .get(keyToFind)
164
+ .set(keyToFind, tempSave)
165
+ }
166
+
167
+ // Add page EXX in Map if it is not already added
168
+ if (
169
+ !mapTree
170
+ .get(activityName)
171
+ .get(keyToFind)
172
+ .get(KeyToAdd)
173
+ )
174
+ mapTree
175
+ .get(activityName)
176
+ .get(keyToFind)
177
+ .set(fileName, {
178
+ ref: fileRef,
179
+ content: fileContent.data()
180
+ })
181
+ }
182
+ })
183
+
184
+ return mapTree
110
185
  }
111
186
  }
112
187
 
@@ -0,0 +1,249 @@
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 }