@01-edu/shared 2.0.4 → 2.0.6
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/dist/attrs-defs.js +1 -0
- package/dist/attrs.js +1 -0
- package/dist/bin/check-definitions.js +3 -0
- package/dist/chunk-BLXMKMNK.js +1 -0
- package/dist/chunk-FQWECXED.js +1 -0
- package/dist/chunk-IF63VBJO.js +1 -0
- package/dist/chunk-K5Z4W5GV.js +1 -0
- package/dist/chunk-MV3DQ3PZ.js +1 -0
- package/dist/chunk-NR2KVFFU.js +1 -0
- package/dist/chunk-T2KIY67K.js +1 -0
- package/dist/chunk-YJMXNRLI.js +1 -0
- package/dist/chunk-ZI7IBRHE.js +1 -0
- package/dist/definitions-checker.js +1 -0
- package/dist/event-utils.js +1 -0
- package/dist/games-utils.js +1 -0
- package/dist/graph.js +1 -0
- package/dist/hasura-core.js +1 -0
- package/dist/hasura-model.js +34 -0
- package/dist/hasura-prepare.js +1 -0
- package/dist/modular-steps-utils.js +1 -0
- package/dist/object-structure.js +1 -0
- package/dist/onboarding.js +1 -0
- package/dist/path.js +1 -0
- package/dist/qa-utils.js +1 -0
- package/dist/score.js +1 -0
- package/dist/skill-definitions.js +1 -0
- package/dist/toolbox.js +1 -0
- package/package.json +23 -5
- package/attrs-defs.js +0 -4273
- package/attrs.js +0 -423
- package/bin/check-definitions.js +0 -74
- package/definitions-checker.js +0 -233
- package/event-utils.js +0 -58
- package/graph.js +0 -96
- package/languages.js +0 -147
- package/object-structure.ts +0 -60
- package/onboarding.js +0 -25
- package/path.js +0 -73
- package/programming-languages.js +0 -21
- package/score.js +0 -80
- package/skill-definitions.js +0 -359
- package/toolbox.js +0 -532
package/definitions-checker.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { attributes, relationAttributes } from './attrs.js'
|
|
2
|
-
import { childTypes, objectTypes } from './object-structure.ts'
|
|
3
|
-
|
|
4
|
-
const normalize = str =>
|
|
5
|
-
str
|
|
6
|
-
.toLowerCase()
|
|
7
|
-
.replaceAll(/[^a-z0-9]+/g, ' ')
|
|
8
|
-
.trim()
|
|
9
|
-
.replaceAll(' ', '-')
|
|
10
|
-
|
|
11
|
-
const assertDef = def => {
|
|
12
|
-
const {
|
|
13
|
-
type,
|
|
14
|
-
name,
|
|
15
|
-
attrs,
|
|
16
|
-
children: _children,
|
|
17
|
-
childrenAttrs,
|
|
18
|
-
referencePath: _referencePath,
|
|
19
|
-
...rest
|
|
20
|
-
} = def
|
|
21
|
-
const [extra] = Object.keys(rest)
|
|
22
|
-
if (extra) {
|
|
23
|
-
throw Error(
|
|
24
|
-
`Unexpected property ${extra}, did you mean to define an attribute ?`,
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
if (type === 'campus') throw Error(`Campuses can't be defined in definitions`)
|
|
28
|
-
if (!objectTypes.has(type)) throw Error(`Invalid type property`)
|
|
29
|
-
if (!name || typeof name !== 'string') throw Error(`Invalid name property`)
|
|
30
|
-
if (!attrs || typeof attrs !== 'object' || Array.isArray(attrs)) {
|
|
31
|
-
throw Error(`Invalid attrs property`)
|
|
32
|
-
}
|
|
33
|
-
if (childrenAttrs) throw Error(`childrenAttrs is no longer supported`)
|
|
34
|
-
|
|
35
|
-
for (const key of Object.keys(attrs || {})) {
|
|
36
|
-
if (relationAttributes[key]) {
|
|
37
|
-
throw Error(
|
|
38
|
-
`Attr ${key} should be defined in the relation with its parent, not on the object itself.`,
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const matches = attributes[key]
|
|
43
|
-
if (!matches) throw Error(`Undefined attr ${key}`)
|
|
44
|
-
const attrDefs = matches[type]
|
|
45
|
-
if (!attrDefs) {
|
|
46
|
-
const types = Object.keys(matches).join(', ')
|
|
47
|
-
throw Error(`${type} does not match any of ${types} for attr ${key}`)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (attrDefs.deprecated) {
|
|
51
|
-
throw Error(`attr ${key} deprecated: ${attrDefs.deprecated}`)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const buildTree = (
|
|
57
|
-
{ name, type, attrs, children, referencePath },
|
|
58
|
-
parent,
|
|
59
|
-
depth,
|
|
60
|
-
) => {
|
|
61
|
-
// As we check for the parent / child type structure, this should never happen
|
|
62
|
-
// so we did not bother to make a more descriptive error for this case
|
|
63
|
-
if (depth > 100) throw Error('Unexpected very deep tree, maybe circular ?')
|
|
64
|
-
const object = { name, type, attrs, children: {}, referencePath, parent }
|
|
65
|
-
if (!children) return object
|
|
66
|
-
let prev
|
|
67
|
-
for (const [key, { ref, ...rest }] of Object.entries(children)) {
|
|
68
|
-
const child = buildTree(ref, object, (depth || 0) + 1)
|
|
69
|
-
child.attrs = { ...child.attrs, ...rest }
|
|
70
|
-
prev && (prev.next = child)
|
|
71
|
-
child.prev = prev
|
|
72
|
-
object.children[key] = child
|
|
73
|
-
}
|
|
74
|
-
return object
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const assertRelation = (parent, key, relation) => {
|
|
78
|
-
if (!/^[a-z0-9-]*$/.test(key)) {
|
|
79
|
-
throw Error(
|
|
80
|
-
`Invalid key for child ${key} Kebab-case key suggestion: ${normalize(
|
|
81
|
-
key,
|
|
82
|
-
)}`,
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const child = relation.ref
|
|
87
|
-
const { type } = child
|
|
88
|
-
const allowedTypes = childTypes[parent.type]
|
|
89
|
-
if (!allowedTypes.includes(type)) {
|
|
90
|
-
throw Error(`Type ${type} ${key} is not a possible child`)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Should never happen
|
|
94
|
-
if (parent.referencePath === child.referencePath) {
|
|
95
|
-
throw Error(`Self reference in child ${key}`)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
for (const key of Object.keys(relation)) {
|
|
99
|
-
if (key === 'ref') continue
|
|
100
|
-
const matches = attributes[key]
|
|
101
|
-
if (matches?.[type]?.restrictive) {
|
|
102
|
-
throw Error(
|
|
103
|
-
`Attr ${key} should be defined on the object itself, not in the relation with its parent.`,
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
const relMatches = relationAttributes[key]
|
|
107
|
-
if (!matches && !relMatches) throw Error(`Undefined attr ${key}`)
|
|
108
|
-
const attrDefs = (relMatches?.[parent.type] || matches)[type]
|
|
109
|
-
if (!attrDefs) {
|
|
110
|
-
const types = Object.keys(matches).join(', ')
|
|
111
|
-
throw Error(`${type} does not match any of ${types} for attr ${key}`)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (attrDefs.deprecated) {
|
|
115
|
-
throw Error(`attr ${key} deprecated: ${attrDefs.deprecated}`)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const checkAttrs = object => {
|
|
121
|
-
for (const [key, value] of Object.entries(object.attrs)) {
|
|
122
|
-
try {
|
|
123
|
-
const attrDefs =
|
|
124
|
-
relationAttributes[key]?.[object.parent?.type]?.[object.type] ||
|
|
125
|
-
attributes[key][object.type]
|
|
126
|
-
|
|
127
|
-
if (value?.type === 'function') {
|
|
128
|
-
const fn = attrDefs.functionsByName?.[value.name]
|
|
129
|
-
if (!fn) throw Error(`function ${value.name} not found for attr ${key}`)
|
|
130
|
-
} else if (!attrDefs.check(value, object)) {
|
|
131
|
-
throw Error(`wrong type for attr ${key}`)
|
|
132
|
-
}
|
|
133
|
-
} catch (err) {
|
|
134
|
-
err.parentRef = object.parent?.referencePath
|
|
135
|
-
err.childRef = object.referencePath
|
|
136
|
-
err.value = value
|
|
137
|
-
err.key = key
|
|
138
|
-
throw err
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
for (const child of Object.values(object.children)) {
|
|
143
|
-
checkAttrs(child)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const isExam = def => def.type === 'exam'
|
|
148
|
-
const assertExams = definitions => {
|
|
149
|
-
const groups = {}
|
|
150
|
-
for (const exam of definitions.filter(isExam)) {
|
|
151
|
-
let prevExamGroup = 0
|
|
152
|
-
for (const [key, exercise] of Object.entries(exam.children)) {
|
|
153
|
-
try {
|
|
154
|
-
const { group } = exercise
|
|
155
|
-
if (!group) throw Error('missing exam group')
|
|
156
|
-
|
|
157
|
-
const groupDiff = group - prevExamGroup
|
|
158
|
-
prevExamGroup = group
|
|
159
|
-
if (groupDiff > 1) throw Error('exam must not have gaps in groups')
|
|
160
|
-
if (groupDiff < 0) {
|
|
161
|
-
throw Error('exercise must be sorted by group from lower to greater')
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// exam exercise group should stay consistent across all exams
|
|
165
|
-
const prevGroup = groups[key]
|
|
166
|
-
if (prevGroup == null) {
|
|
167
|
-
groups[key] = group
|
|
168
|
-
} else if (prevGroup !== group) {
|
|
169
|
-
throw Error('Exercise used in different exam groups')
|
|
170
|
-
}
|
|
171
|
-
} catch (err) {
|
|
172
|
-
err.exam = exam.referencePath
|
|
173
|
-
err.exercise = exercise.ref.referencePath
|
|
174
|
-
throw err
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export const checkAndBuildDefinitions = async readDef => {
|
|
181
|
-
const cache = {}
|
|
182
|
-
const getDefs = async ([key, relation]) => {
|
|
183
|
-
let def
|
|
184
|
-
try {
|
|
185
|
-
const cached = cache[key]
|
|
186
|
-
def = await (cached || (cache[key] = readDef(key)))
|
|
187
|
-
relation && (relation.ref = def)
|
|
188
|
-
if (cached) return [] // skip assert and children checks if already cached
|
|
189
|
-
} catch (err) {
|
|
190
|
-
err.name = key
|
|
191
|
-
throw err
|
|
192
|
-
}
|
|
193
|
-
try {
|
|
194
|
-
assertDef(def)
|
|
195
|
-
} catch (err) {
|
|
196
|
-
err.type = def.type
|
|
197
|
-
err.referencePath = def.referencePath
|
|
198
|
-
throw err
|
|
199
|
-
}
|
|
200
|
-
const relations = Object.entries(def.children || {}).map(getDefs)
|
|
201
|
-
try {
|
|
202
|
-
return [def, ...(await Promise.all(relations)).flat()]
|
|
203
|
-
} catch (err) {
|
|
204
|
-
// Some content may be used at multiple place (ex: exam exercises)
|
|
205
|
-
// so we may have multiple parents
|
|
206
|
-
key && (err.parents || (err.parents = [])).push(key)
|
|
207
|
-
throw err
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const definitions = await getDefs([])
|
|
212
|
-
|
|
213
|
-
// Assert all relations looks ok, possible child / parent, allowed attributes
|
|
214
|
-
for (const def of definitions) {
|
|
215
|
-
if (!def.children) continue
|
|
216
|
-
try {
|
|
217
|
-
for (const entry of Object.entries(def.children)) {
|
|
218
|
-
assertRelation(def, entry[0], entry[1])
|
|
219
|
-
}
|
|
220
|
-
} catch (err) {
|
|
221
|
-
err.type = def.type
|
|
222
|
-
err.referencePath = def.referencePath
|
|
223
|
-
throw err
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Check all attributes in context
|
|
228
|
-
const root = buildTree(definitions[0])
|
|
229
|
-
checkAttrs(root)
|
|
230
|
-
assertExams(definitions)
|
|
231
|
-
|
|
232
|
-
return { definitions, root }
|
|
233
|
-
}
|
package/event-utils.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export const SEC = 1000
|
|
2
|
-
export const MIN = 60 * SEC
|
|
3
|
-
export const HOUR = 60 * MIN
|
|
4
|
-
export const DAY = 24 * HOUR
|
|
5
|
-
export const WEEK = 7 * DAY
|
|
6
|
-
|
|
7
|
-
export const numTime = date => new Date(date).getTime()
|
|
8
|
-
export const numToISOString = number =>
|
|
9
|
-
number ? new Date(number).toISOString() : Number.NaN
|
|
10
|
-
export const getChildRegistrationStartAt = (parentEventStartAt, child) => {
|
|
11
|
-
const {
|
|
12
|
-
startAfter = 0,
|
|
13
|
-
eventStartDelay = 0,
|
|
14
|
-
registrationDuration,
|
|
15
|
-
} = child.attrs
|
|
16
|
-
return (
|
|
17
|
-
numTime(parentEventStartAt) +
|
|
18
|
-
(startAfter - (eventStartDelay + registrationDuration)) * MIN
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
export const getChildRegistrationEndAt = (parentEventStartAt, child) => {
|
|
22
|
-
const { startAfter = 0, eventStartDelay = 0 } = child.attrs
|
|
23
|
-
return numTime(parentEventStartAt) + (startAfter - eventStartDelay) * MIN
|
|
24
|
-
}
|
|
25
|
-
export const getChildEventStartAt = (parentEventStartAt, { attrs }) =>
|
|
26
|
-
numTime(parentEventStartAt) + (attrs.startAfter || 0) * MIN
|
|
27
|
-
|
|
28
|
-
export const getChildEventEndAt = (parentEventStartAt, child) => {
|
|
29
|
-
const { startAfter = 0, eventDuration } = child.attrs
|
|
30
|
-
return numTime(parentEventStartAt) + (startAfter + eventDuration) * MIN
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const getChildEventInfo = (parentEventStartAt, child) => ({
|
|
34
|
-
startAt: numToISOString(
|
|
35
|
-
getChildRegistrationStartAt(parentEventStartAt, child),
|
|
36
|
-
),
|
|
37
|
-
endAt: numToISOString(getChildRegistrationEndAt(parentEventStartAt, child)),
|
|
38
|
-
eventJoinedAt: numToISOString(
|
|
39
|
-
getChildEventStartAt(parentEventStartAt, child),
|
|
40
|
-
),
|
|
41
|
-
eventEndAt: numToISOString(getChildEventEndAt(parentEventStartAt, child)),
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
// NB: useful when creating event for first time (add event)
|
|
45
|
-
export const getEndOfEvent = ({ eventJoinedAt }, object) =>
|
|
46
|
-
numTime(eventJoinedAt) + object.attrs.eventDuration * MIN
|
|
47
|
-
|
|
48
|
-
// TODO: rename this fn - also used for project
|
|
49
|
-
// the best would be to find a word to label the child items that are not events
|
|
50
|
-
export const getQuestStartAt = (parentEventStartAt, quest) =>
|
|
51
|
-
numTime(parentEventStartAt) + quest.attrs.delay
|
|
52
|
-
export const getQuestExtraEndAt = (questStartAt, quest) => {
|
|
53
|
-
const { scopeExtraDuration, duration } = quest.attrs
|
|
54
|
-
return questStartAt + ((scopeExtraDuration || 0) + (duration || 1)) * DAY
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// TODO: rename isPassed
|
|
58
|
-
export const isFinished = date => new Date(date).getTime() < Date.now()
|
package/graph.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
const isCoreObj = (contentShape, coreKey) =>
|
|
2
|
-
typeof contentShape === 'object' && Object.keys(contentShape)[0] === coreKey
|
|
3
|
-
const isSatteliteObj = (contentShape, satteliteKey) =>
|
|
4
|
-
typeof contentShape === 'object' &&
|
|
5
|
-
Object.values(contentShape)[0].some(sat => sat === satteliteKey)
|
|
6
|
-
|
|
7
|
-
export const getCoreSattelites = (coreObject, objectsList) => {
|
|
8
|
-
const { key, parent } = coreObject
|
|
9
|
-
const objects = objectsList || Object.values(parent.children)
|
|
10
|
-
const sattelitesSection = parent.attrs.graph.innerCircle.find(
|
|
11
|
-
s => s.type === 'slice' && s.innerArc.contents.find(c => isCoreObj(c, key)),
|
|
12
|
-
)
|
|
13
|
-
if (!sattelitesSection) return []
|
|
14
|
-
const sattelitesObject = sattelitesSection.innerArc.contents.find(c =>
|
|
15
|
-
isCoreObj(c, key),
|
|
16
|
-
)
|
|
17
|
-
const sattelitesList = new Set(...Object.values(sattelitesObject))
|
|
18
|
-
|
|
19
|
-
return objects.filter(o => sattelitesList.has(o.key))
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const getCoreOfSattelite = (satteliteObject, objectsList) => {
|
|
23
|
-
const { key, parent } = satteliteObject
|
|
24
|
-
const objects = objectsList || Object.values(parent.children)
|
|
25
|
-
const sattelitesSection = parent.attrs.graph?.innerCircle?.find(
|
|
26
|
-
s =>
|
|
27
|
-
s.type === 'slice' &&
|
|
28
|
-
s.innerArc?.contents.find(c => isSatteliteObj(c, key)),
|
|
29
|
-
)
|
|
30
|
-
if (!sattelitesSection) return undefined
|
|
31
|
-
const coreObject = sattelitesSection.innerArc.contents.find(c =>
|
|
32
|
-
isSatteliteObj(c, key),
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
return objects.filter(o => o.key === Object.keys(coreObject)[0])
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const flatGraphContents = graph => [
|
|
39
|
-
...(graph.centralPoint ? [graph.centralPoint] : []),
|
|
40
|
-
...(graph.innerCircle || []).flatMap(section =>
|
|
41
|
-
section.type === 'slice'
|
|
42
|
-
? [
|
|
43
|
-
...(section.entryPoint ? [section.entryPoint] : []),
|
|
44
|
-
...(section.innerArc?.contents || []).flatMap(c =>
|
|
45
|
-
typeof c === 'string' ? c : Object.entries(c)[0].flat(),
|
|
46
|
-
),
|
|
47
|
-
...(section.outerArcs || []).flatMap(arc => arc.contents || []),
|
|
48
|
-
]
|
|
49
|
-
: section.contents,
|
|
50
|
-
),
|
|
51
|
-
...(graph.middleCircle || []).flatMap(arc => arc.contents || []),
|
|
52
|
-
...(graph.outerCircle || []).flatMap(arc => arc.contents || []),
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
// WARNING: without central point (for linear graph, already destructured)
|
|
56
|
-
export const flatAtomeAndCoreContents = graph => [
|
|
57
|
-
...(graph.innerCircle || []).flatMap(section =>
|
|
58
|
-
section.type === 'slice'
|
|
59
|
-
? [
|
|
60
|
-
...(section.entryPoint ? [section.entryPoint] : []),
|
|
61
|
-
...(section.innerArc?.contents || []).flatMap(c =>
|
|
62
|
-
typeof c === 'string' ? c : Object.keys(c)[0],
|
|
63
|
-
),
|
|
64
|
-
...(section.outerArcs || []).flatMap(arc => arc.contents || []),
|
|
65
|
-
]
|
|
66
|
-
: section.contents,
|
|
67
|
-
),
|
|
68
|
-
...(graph.middleCircle || []).flatMap(arc => arc.contents || []),
|
|
69
|
-
...(graph.outerCircle || []).flatMap(arc => arc.contents || []),
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
export const limitations = {
|
|
73
|
-
LINE: {
|
|
74
|
-
maxLinesCount: 6,
|
|
75
|
-
maxContentsCount: 7, // 7 contents max split along a single line
|
|
76
|
-
},
|
|
77
|
-
SLICE: {
|
|
78
|
-
maxSlicesCount: 4,
|
|
79
|
-
innerCircle: {
|
|
80
|
-
maxSubContentsCount: 5, // 5 sub-contents max by content
|
|
81
|
-
maxContentsCount: 30, // 30 contents max spread evenly over the number of inner cirlces of slices
|
|
82
|
-
},
|
|
83
|
-
outerArc: {
|
|
84
|
-
maxArcsCount: 2,
|
|
85
|
-
maxContentsCount: 10, // 10 contents max spread evenly over the 1 or 2 outer arcs
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
MIDDLE_CIRCLE: {
|
|
89
|
-
maxArcsCount: 8,
|
|
90
|
-
maxContentsCount: 70, // 70 contents max spread evenly over the number of arcs
|
|
91
|
-
},
|
|
92
|
-
OUTER_CIRCLE: {
|
|
93
|
-
maxArcsCount: 9,
|
|
94
|
-
maxContentsCount: 90, // 90 contents max spread evenly over the number of arcs
|
|
95
|
-
},
|
|
96
|
-
}
|
package/languages.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
export const languages = {
|
|
2
|
-
ab: 'Abkhazian',
|
|
3
|
-
aa: 'Afar',
|
|
4
|
-
af: 'Afrikaans',
|
|
5
|
-
sq: 'Albanian',
|
|
6
|
-
am: 'Amharic',
|
|
7
|
-
ar: 'Arabic',
|
|
8
|
-
hy: 'Armenian',
|
|
9
|
-
as: 'Assamese',
|
|
10
|
-
ay: 'Aymara',
|
|
11
|
-
az: 'Azerbaijani',
|
|
12
|
-
ba: 'Bashkir',
|
|
13
|
-
eu: 'Basque',
|
|
14
|
-
bn: 'Bengali (Bangla)',
|
|
15
|
-
dz: 'Bhutani',
|
|
16
|
-
bh: 'Bihari',
|
|
17
|
-
bi: 'Bislama',
|
|
18
|
-
br: 'Breton',
|
|
19
|
-
bg: 'Bulgarian',
|
|
20
|
-
my: 'Burmese',
|
|
21
|
-
be: 'Byelorussian (Belarusian)',
|
|
22
|
-
km: 'Cambodian',
|
|
23
|
-
ca: 'Catalan',
|
|
24
|
-
zh: 'Chinese (Simplified)',
|
|
25
|
-
// zh: 'Chinese (Traditional)',
|
|
26
|
-
co: 'Corsican',
|
|
27
|
-
hr: 'Croatian',
|
|
28
|
-
cs: 'Czech',
|
|
29
|
-
da: 'Danish',
|
|
30
|
-
nl: 'Dutch',
|
|
31
|
-
en: 'English',
|
|
32
|
-
eo: 'Esperanto',
|
|
33
|
-
et: 'Estonian',
|
|
34
|
-
fo: 'Faeroese',
|
|
35
|
-
fa: 'Farsi',
|
|
36
|
-
fj: 'Fiji',
|
|
37
|
-
fi: 'Finnish',
|
|
38
|
-
fr: 'French',
|
|
39
|
-
fy: 'Frisian',
|
|
40
|
-
gl: 'Galician',
|
|
41
|
-
gd: 'Gaelic (Scottish)',
|
|
42
|
-
gv: 'Gaelic (Manx)',
|
|
43
|
-
ka: 'Georgian',
|
|
44
|
-
de: 'German',
|
|
45
|
-
el: 'Greek',
|
|
46
|
-
kl: 'Greenlandic',
|
|
47
|
-
gn: 'Guarani',
|
|
48
|
-
gu: 'Gujarati',
|
|
49
|
-
ha: 'Hausa',
|
|
50
|
-
he: 'Hebrew',
|
|
51
|
-
hi: 'Hindi',
|
|
52
|
-
hu: 'Hungarian',
|
|
53
|
-
is: 'Icelandic',
|
|
54
|
-
id: 'Indonesian',
|
|
55
|
-
ia: 'Interlingua',
|
|
56
|
-
ie: 'Interlingue',
|
|
57
|
-
iu: 'Inuktitut',
|
|
58
|
-
ik: 'Inupiak',
|
|
59
|
-
ga: 'Irish',
|
|
60
|
-
it: 'Italian',
|
|
61
|
-
ja: 'Japanese',
|
|
62
|
-
// jv: 'Javanese',
|
|
63
|
-
kn: 'Kannada',
|
|
64
|
-
ks: 'Kashmiri',
|
|
65
|
-
kk: 'Kazakh',
|
|
66
|
-
rw: 'Kinyarwanda (Ruanda)',
|
|
67
|
-
ky: 'Kirghiz',
|
|
68
|
-
rn: 'Kirundi (Rundi)',
|
|
69
|
-
ko: 'Korean',
|
|
70
|
-
ku: 'Kurdish',
|
|
71
|
-
lo: 'Laothian',
|
|
72
|
-
la: 'Latin',
|
|
73
|
-
lv: 'Latvian (Lettish)',
|
|
74
|
-
li: 'Limburgish ( Limburger)',
|
|
75
|
-
ln: 'Lingala',
|
|
76
|
-
lt: 'Lithuanian',
|
|
77
|
-
mk: 'Macedonian',
|
|
78
|
-
mg: 'Malagasy',
|
|
79
|
-
ms: 'Malay',
|
|
80
|
-
ml: 'Malayalam',
|
|
81
|
-
mt: 'Maltese',
|
|
82
|
-
mi: 'Maori',
|
|
83
|
-
mr: 'Marathi',
|
|
84
|
-
mo: 'Moldavian',
|
|
85
|
-
mn: 'Mongolian',
|
|
86
|
-
na: 'Nauru',
|
|
87
|
-
ne: 'Nepali',
|
|
88
|
-
no: 'Norwegian',
|
|
89
|
-
oc: 'Occitan',
|
|
90
|
-
or: 'Oriya',
|
|
91
|
-
om: 'Oromo (Afan, Galla)',
|
|
92
|
-
ps: 'Pashto (Pushto)',
|
|
93
|
-
pl: 'Polish',
|
|
94
|
-
pt: 'Portuguese',
|
|
95
|
-
pa: 'Punjabi',
|
|
96
|
-
qu: 'Quechua',
|
|
97
|
-
rm: 'Rhaeto-Romance',
|
|
98
|
-
ro: 'Romanian',
|
|
99
|
-
ru: 'Russian',
|
|
100
|
-
sm: 'Samoan',
|
|
101
|
-
sg: 'Sangro',
|
|
102
|
-
sa: 'Sanskrit',
|
|
103
|
-
sr: 'Serbian',
|
|
104
|
-
sh: 'Serbo-Croatian',
|
|
105
|
-
st: 'Sesotho',
|
|
106
|
-
tn: 'Setswana',
|
|
107
|
-
sn: 'Shona',
|
|
108
|
-
sd: 'Sindhi',
|
|
109
|
-
si: 'Sinhalese',
|
|
110
|
-
ss: 'Siswati',
|
|
111
|
-
sk: 'Slovak',
|
|
112
|
-
sl: 'Slovenian',
|
|
113
|
-
so: 'Somali',
|
|
114
|
-
es: 'Spanish',
|
|
115
|
-
su: 'Sundanese',
|
|
116
|
-
sw: 'Swahili (Kiswahili)',
|
|
117
|
-
sv: 'Swedish',
|
|
118
|
-
tl: 'Tagalog',
|
|
119
|
-
tg: 'Tajik',
|
|
120
|
-
ta: 'Tamil',
|
|
121
|
-
tt: 'Tatar',
|
|
122
|
-
te: 'Telugu',
|
|
123
|
-
th: 'Thai',
|
|
124
|
-
bo: 'Tibetan',
|
|
125
|
-
ti: 'Tigrinya',
|
|
126
|
-
to: 'Tonga',
|
|
127
|
-
ts: 'Tsonga',
|
|
128
|
-
tr: 'Turkish',
|
|
129
|
-
tk: 'Turkmen',
|
|
130
|
-
tw: 'Twi',
|
|
131
|
-
ug: 'Uighur',
|
|
132
|
-
uk: 'Ukrainian',
|
|
133
|
-
ur: 'Urdu',
|
|
134
|
-
uz: 'Uzbek',
|
|
135
|
-
vi: 'Vietnamese',
|
|
136
|
-
vo: 'Volapük',
|
|
137
|
-
cy: 'Welsh',
|
|
138
|
-
wo: 'Wolof',
|
|
139
|
-
xh: 'Xhosa',
|
|
140
|
-
yi: 'Yiddish',
|
|
141
|
-
yo: 'Yoruba',
|
|
142
|
-
zu: 'Zulu',
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export const languagesByName = Object.fromEntries(
|
|
146
|
-
Object.entries(languages).map(([code, language]) => [language, code]),
|
|
147
|
-
)
|
package/object-structure.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
export const onboardingTypes = new Set([
|
|
2
|
-
'onboarding',
|
|
3
|
-
'piscine-registration',
|
|
4
|
-
'interview',
|
|
5
|
-
'games',
|
|
6
|
-
'administration',
|
|
7
|
-
'module-registration',
|
|
8
|
-
'form-step',
|
|
9
|
-
'sign-step',
|
|
10
|
-
'upload-step',
|
|
11
|
-
'contact-validation-step',
|
|
12
|
-
'avatar-step',
|
|
13
|
-
] as const)
|
|
14
|
-
|
|
15
|
-
type Extract<T> = [T] extends [Set<infer V>] ? V : never
|
|
16
|
-
|
|
17
|
-
export const objectTypes = new Set([
|
|
18
|
-
'module',
|
|
19
|
-
'piscine',
|
|
20
|
-
'exam',
|
|
21
|
-
'raid',
|
|
22
|
-
'quest',
|
|
23
|
-
'exercise',
|
|
24
|
-
'project',
|
|
25
|
-
'signup',
|
|
26
|
-
'campus',
|
|
27
|
-
...onboardingTypes,
|
|
28
|
-
] as const)
|
|
29
|
-
|
|
30
|
-
export type ObjectType = Extract<typeof objectTypes>
|
|
31
|
-
export const childTypes = {
|
|
32
|
-
campus: ['signup', 'onboarding', 'piscine', 'module'],
|
|
33
|
-
signup: [
|
|
34
|
-
'form-step',
|
|
35
|
-
'sign-step',
|
|
36
|
-
'upload-step',
|
|
37
|
-
'contact-validation-step',
|
|
38
|
-
'avatar-step',
|
|
39
|
-
],
|
|
40
|
-
onboarding: [
|
|
41
|
-
'games',
|
|
42
|
-
'administration',
|
|
43
|
-
'interview',
|
|
44
|
-
'piscine-registration',
|
|
45
|
-
'module-registration',
|
|
46
|
-
],
|
|
47
|
-
administration: [
|
|
48
|
-
'form-step',
|
|
49
|
-
'sign-step',
|
|
50
|
-
'upload-step',
|
|
51
|
-
'contact-validation-step',
|
|
52
|
-
'avatar-step',
|
|
53
|
-
],
|
|
54
|
-
piscine: ['quest', 'exam', 'raid', 'project'],
|
|
55
|
-
exam: ['exercise'],
|
|
56
|
-
quest: ['exercise'],
|
|
57
|
-
module: ['project', 'piscine', 'exam'],
|
|
58
|
-
} as const satisfies Partial<Record<ObjectType, ObjectType[]>>
|
|
59
|
-
|
|
60
|
-
export type ChildTypes = typeof childTypes
|
package/onboarding.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export const prevValidated = (key, object) => {
|
|
2
|
-
const { prev } = (
|
|
3
|
-
object.parent.type !== 'onboarding' ? object : object.parent
|
|
4
|
-
).children[key]
|
|
5
|
-
if (!prev) return true
|
|
6
|
-
return prev.attrs.status === 'succeeded'
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const nextStep = (key, object) => {
|
|
10
|
-
const { next } = (object.type === 'onboarding' ? object : object.parent)
|
|
11
|
-
.children[key]
|
|
12
|
-
|
|
13
|
-
return next ? next.path : undefined
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const getOnboardingStep = onboarding => {
|
|
17
|
-
if (!onboarding) return undefined
|
|
18
|
-
const children = Object.values(onboarding.children)
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
children.find(
|
|
22
|
-
({ attrs }) => attrs.status === 'available' || attrs.status === 'failed',
|
|
23
|
-
) || children[children.length - 1]
|
|
24
|
-
)
|
|
25
|
-
}
|
package/path.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @returns {string} the relative path converted to absolute
|
|
3
|
-
* @argument relativePath {string} a relative path
|
|
4
|
-
* @argument currentPath {string} the current absolute path
|
|
5
|
-
*/
|
|
6
|
-
export const getAbsolutePath = (relativePath, currentPath) => {
|
|
7
|
-
if (isAbsolutePath(relativePath)) {
|
|
8
|
-
throw new Error("'relativePath' must be a relative path")
|
|
9
|
-
}
|
|
10
|
-
// Ignore trailing `/` in the relative path
|
|
11
|
-
if (relativePath[relativePath.length - 1] === '/') {
|
|
12
|
-
relativePath = relativePath.slice(0, -1)
|
|
13
|
-
}
|
|
14
|
-
if (!isAbsolutePath(currentPath)) {
|
|
15
|
-
throw Error('the currentPath has to be an absolute path')
|
|
16
|
-
}
|
|
17
|
-
const absSegments = currentPath.split('/')
|
|
18
|
-
const pathSegments = relativePath.split('/')
|
|
19
|
-
for (const segment of pathSegments) {
|
|
20
|
-
if (segment === '..') {
|
|
21
|
-
if (absSegments.length > 0) {
|
|
22
|
-
absSegments.pop()
|
|
23
|
-
} else {
|
|
24
|
-
throw Error(
|
|
25
|
-
`Incorrect relative path = ${relativePath}, current path = ${currentPath}`,
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
} else if (segment !== '.') {
|
|
29
|
-
absSegments.push(segment)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return absSegments.join('/')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const walk = (object, segment) => {
|
|
36
|
-
if (!object) return
|
|
37
|
-
if (segment === '.') return object
|
|
38
|
-
return segment === '..' ? object.parent : object.children[segment]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @param {string} relativePath - a relative path
|
|
43
|
-
* @param {Object} currentObj - the object from where the relative path starts
|
|
44
|
-
* @param {Object} [opts = { throwError: true } ] - options object with boolean property `throwError` to throw an error in case the path is invalid or no object is found
|
|
45
|
-
* @returns {Object} - the object in the relative path
|
|
46
|
-
*/
|
|
47
|
-
export const getObjectFromRelativePath = (
|
|
48
|
-
relativePath,
|
|
49
|
-
currentObj,
|
|
50
|
-
opts = { throwError: true },
|
|
51
|
-
) => {
|
|
52
|
-
const currentPath = currentObj.path
|
|
53
|
-
if (isAbsolutePath(relativePath)) {
|
|
54
|
-
if (opts.throwError) throw Error("'relativePath' must be a relative path")
|
|
55
|
-
console.error("'relativePath' must be a relative path")
|
|
56
|
-
return undefined
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Ignore trailing `/` in the relative path
|
|
60
|
-
if (relativePath[relativePath.length - 1] === '/') {
|
|
61
|
-
relativePath = relativePath.slice(0, -1)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const matchingObject = relativePath.split('/').reduce(walk, currentObj)
|
|
65
|
-
if (matchingObject) return matchingObject
|
|
66
|
-
|
|
67
|
-
const errorMessage = `Incorrect relative path '${relativePath}': no object found — current path = '${currentPath}'`
|
|
68
|
-
if (opts.throwError) throw Error(errorMessage)
|
|
69
|
-
console.error(errorMessage)
|
|
70
|
-
return undefined
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const isAbsolutePath = path => path.startsWith('/')
|