@01-edu/shared 2.0.5 → 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.
Files changed (45) hide show
  1. package/dist/attrs-defs.js +1 -0
  2. package/dist/attrs.js +1 -0
  3. package/dist/bin/check-definitions.js +3 -0
  4. package/dist/chunk-BLXMKMNK.js +1 -0
  5. package/dist/chunk-FQWECXED.js +1 -0
  6. package/dist/chunk-IF63VBJO.js +1 -0
  7. package/dist/chunk-K5Z4W5GV.js +1 -0
  8. package/dist/chunk-MV3DQ3PZ.js +1 -0
  9. package/dist/chunk-NR2KVFFU.js +1 -0
  10. package/dist/chunk-T2KIY67K.js +1 -0
  11. package/dist/chunk-YJMXNRLI.js +1 -0
  12. package/dist/chunk-ZI7IBRHE.js +1 -0
  13. package/dist/definitions-checker.js +1 -0
  14. package/dist/event-utils.js +1 -0
  15. package/dist/games-utils.js +1 -0
  16. package/dist/graph.js +1 -0
  17. package/dist/hasura-core.js +1 -0
  18. package/dist/hasura-model.js +34 -0
  19. package/dist/hasura-prepare.js +1 -0
  20. package/dist/modular-steps-utils.js +1 -0
  21. package/dist/object-structure.js +1 -0
  22. package/dist/onboarding.js +1 -0
  23. package/dist/path.js +1 -0
  24. package/dist/qa-utils.js +1 -0
  25. package/dist/score.js +1 -0
  26. package/dist/skill-definitions.js +1 -0
  27. package/dist/toolbox.js +1 -0
  28. package/package.json +17 -6
  29. package/attrs-defs.js +0 -4273
  30. package/attrs.js +0 -423
  31. package/bin/check-definitions.js +0 -74
  32. package/definitions-checker.js +0 -233
  33. package/event-utils.js +0 -58
  34. package/graph.js +0 -96
  35. package/hasura-core.js +0 -217
  36. package/hasura-model.js +0 -138
  37. package/hasura-prepare.js +0 -44
  38. package/languages.js +0 -147
  39. package/onboarding.js +0 -25
  40. package/path.js +0 -73
  41. package/programming-languages.js +0 -21
  42. package/qa-utils.js +0 -13
  43. package/score.js +0 -80
  44. package/skill-definitions.js +0 -359
  45. package/toolbox.js +0 -532
package/hasura-model.js DELETED
@@ -1,138 +0,0 @@
1
- export const buildModel =
2
- prepare =>
3
- (name, key = 'id', type = 'Int') => {
4
- const list = `${key}_list`
5
- const insertQuery = prepare(`
6
- mutation insert_${name} ($objects: [${name}_insert_input!]!){
7
- insert_${name} (objects: $objects) { returning { ${key} } }
8
- }`)
9
-
10
- const updateQuery = prepare(`
11
- mutation update_${name} ($${key}: ${type}!, $changes: ${name}_set_input!) {
12
- update_${name} (where: {${key}: {_eq: $${key}}}, _set: $changes) { affected_rows }
13
- }`)
14
-
15
- const updateQueryAll = prepare(`
16
- mutation update_${name} ($${list}: [${type}!], $changes: ${name}_set_input!) {
17
- update_${name} (where: {${key}: {_in: $${list}}}, _set: $changes) { affected_rows }
18
- }`)
19
-
20
- const deleteQuery = prepare(`
21
- mutation delete_${name} ($${key}: ${type}!) {
22
- delete_${name} (where: {${key}: {_eq: $${key}}}) { affected_rows }
23
- }`)
24
-
25
- const deleteQueryAll = prepare(`
26
- mutation delete_${name} ($${list}: [${type}!]) {
27
- delete_${name} (where: {id: {_in: $${list}} }) { affected_rows }
28
- }`)
29
-
30
- const getCountQuery = prepare(`
31
- query ${name}_count {
32
- ${name}_aggregate { aggregate { count } }
33
- }`)
34
-
35
- const getKey = _ => _[key]
36
- const updateOne = ({ [key]: _, ...changes }) =>
37
- updateQuery({ [key]: _, changes })
38
-
39
- const mutations = {
40
- key,
41
- list,
42
- insertQuery,
43
- deleteQuery,
44
- updateQuery,
45
- updateQueryAll,
46
- deleteQueryAll,
47
- remove: _ =>
48
- Array.isArray(_)
49
- ? deleteQueryAll({ [list]: _ })
50
- : deleteQuery({ [key]: _ }),
51
- update: (changes, _) => {
52
- if (!_) return updateOne(changes)
53
- return Array.isArray(_)
54
- ? updateQueryAll({ changes, [list]: _ })
55
- : updateQuery({ changes, [key]: _ })
56
- },
57
- add: async _ => {
58
- const isArray = Array.isArray(_)
59
- const result = await insertQuery.all({ objects: isArray ? _ : [_] })
60
-
61
- return isArray
62
- ? result[`insert_${name}`].returning.map(getKey)
63
- : result[`insert_${name}`].returning[0][key]
64
- },
65
- }
66
-
67
- return fields => {
68
- const oneById = `($${key}: ${type}!) {
69
- ${name} (where: {${key}: {_eq: $${key}}} limit: 1) {${key} ${fields}}
70
- }`
71
-
72
- const allById = `($${list}: [${type}!]) {
73
- ${name} (where: {${key}: {_in: $${list}}}) {${key} ${fields}}
74
- }`
75
-
76
- const byWhere = `($where: ${name}_bool_exp!) {
77
- ${name} (where: $where) {${key} ${fields}}
78
- }`
79
-
80
- const toPaginate = `(
81
- $where: ${name}_bool_exp!, $orderBy: ${name}_order_by!, $limit: Int!, $offset: Int!,
82
- ) {
83
- ${name} ( order_by: [$orderBy] offset: $offset limit: $limit where: $where ) { ${fields} }
84
- }`
85
-
86
- const toPaginateWithCount = `(
87
- $where: ${name}_bool_exp!, $orderBy: ${name}_order_by!, $limit: Int!, $offset: Int!,
88
- ) {
89
- ${name} ( order_by: [$orderBy] offset: $offset limit: $limit where: $where ) { ${fields} }
90
- ${name}_aggregate (where: $where) { aggregate { count } }
91
- }`
92
-
93
- const selectQuery = prepare(`query ${oneById}`)
94
- const selectQueryAll = prepare(`query ${allById}`)
95
- const selectQueryWhere = prepare(`query ${byWhere}`)
96
- const selectQueryPaginated = prepare(
97
- `query get_${name}_paginate ${toPaginate}`,
98
- )
99
- const selectQueryPaginatedWithCount = prepare(
100
- `query get_${name}_with_count ${toPaginateWithCount}`,
101
- )
102
- const subscribeQuery = prepare(`subscription ${oneById}`)
103
- const subscribeQueryAll = prepare(`subscription ${allById}`)
104
- const subscribeQueryWhere = prepare(`subscription ${byWhere}`)
105
-
106
- return {
107
- ...mutations,
108
- selectQuery,
109
- selectQueryAll,
110
- selectQueryWhere,
111
- subscribeQuery,
112
- subscribeQueryAll,
113
- subscribeQueryWhere,
114
- get: _ => {
115
- if (Array.isArray(_)) return selectQueryAll({ [list]: _ })
116
- return _ && typeof _ === 'object'
117
- ? selectQueryWhere({ where: _ })
118
- : selectQuery.one(_ && { [key]: _ })
119
- },
120
- subscribe: (sub, _) => {
121
- if (Array.isArray(_)) return subscribeQueryAll(sub, { [list]: _ })
122
- return _ && typeof _ === 'object'
123
- ? subscribeQueryWhere(sub, { where: _ })
124
- : subscribeQuery.one(sub, _ && { [key]: _ })
125
- },
126
- getCount: async elems => (await getCountQuery(elems)).aggregate.count,
127
- getPaginated: selectQueryPaginated,
128
- getPaginatedWithCount: async elems => {
129
- const elemsWithCount = await selectQueryPaginatedWithCount.all(elems)
130
-
131
- return {
132
- [name]: elemsWithCount[name],
133
- count: elemsWithCount[`${name}_aggregate`].aggregate.count,
134
- }
135
- },
136
- }
137
- }
138
- }
package/hasura-prepare.js DELETED
@@ -1,44 +0,0 @@
1
- const get = _ => Object.values(_)[0]
2
- const getAll = _ => _
3
- const getOne = _ => Object.values(_)[0][0]
4
- export const prepare = ({ runFromString, subscribeFromString }, query) => {
5
- if (typeof query !== 'string') {
6
- throw Error(`Query must be a string but was ${typeof query}`)
7
- }
8
-
9
- let [_, type, name] = query.split(/^\s*(\w+)(?:\s+(\w+))?\b/)
10
- if (!type) {
11
- type = 'query'
12
- } else if (!/^(subscription|mutation|query)$/.test(type)) {
13
- throw Error(`Invalid query, type must be query, mutation or subscription`)
14
- }
15
- name || (name = `${type}_${query.split(/{\s*(.+?)\b/)[1]}`)
16
- const payload = JSON.stringify({ query })
17
- const noVars = payload
18
- const base = payload.slice(0, -1)
19
- const build = vars => {
20
- if (!vars) return noVars
21
- if (typeof vars === 'function') {
22
- throw Error(
23
- 'variables should not be functions, verify the order of your parameters',
24
- )
25
- }
26
- const stringified = JSON.stringify(vars)
27
- if (stringified === '{}') return noVars
28
- return `${base},"variables":${stringified}}`
29
- }
30
- const map =
31
- type === 'subscription'
32
- ? mapper => (sub, vars) =>
33
- subscribeFromString(value => sub(mapper(value)), build(vars), name)
34
- : mapper => async vars => mapper(await runFromString(build(vars), name))
35
-
36
- const run = map(get)
37
- run.all = map(getAll)
38
- run.one = map(getOne)
39
- run.map = map
40
- run.query = query
41
- return run
42
- }
43
-
44
- export const initPrepare = client => query => prepare(client, query)
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/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('/')
@@ -1,21 +0,0 @@
1
- // because of the nature of esbuild we have to put the import string hard coded
2
- export const langTypeInfo = {
3
- go: { lang: 'go', load: () => import('@codemirror/lang-go') },
4
- bash: { lang: 'bash', load: () => import('@fig/lezer-bash') },
5
- sh: { lang: 'shell', load: () => import('@fig/lezer-bash') },
6
- // The `label` is used for the UI (StatusBar) so it still shows "dart" instead of "javascript"
7
- dart: {
8
- label: 'dart',
9
- lang: 'javascript',
10
- load: () => import('@codemirror/lang-javascript'),
11
- },
12
- css: { lang: 'css', load: () => import('@codemirror/lang-css') },
13
- html: { lang: 'html', load: () => import('@codemirror/lang-html') },
14
- js: { lang: 'javascript', load: () => import('@codemirror/lang-javascript') },
15
- md: { lang: 'markdown', load: () => import('@codemirror/lang-markdown') },
16
- rs: { lang: 'rust', load: () => import('@codemirror/lang-rust') },
17
- py: { lang: 'python', load: () => import('@codemirror/lang-python') },
18
- java: { lang: 'java', load: () => import('@codemirror/lang-java') },
19
- json: { lang: 'json', load: () => import('@codemirror/lang-json') },
20
- }
21
- export const supportedLang = new Set(Object.keys(langTypeInfo))
package/qa-utils.js DELETED
@@ -1,13 +0,0 @@
1
- export const stringifyJSX = value => {
2
- if (!value) return ''
3
- if (typeof value === 'string') return value
4
- if (Array.isArray(value)) return value.map(stringifyJSX).join('')
5
- return stringifyJSX(value.props?.children)
6
- }
7
-
8
- export const toTestId = value =>
9
- stringifyJSX(value)
10
- .toLowerCase()
11
- .replace(/([^a-z0-9]+)/g, ' ')
12
- .trim()
13
- .replaceAll(' ', '-')
package/score.js DELETED
@@ -1,80 +0,0 @@
1
- const levelPoints = 5
2
- export const gamesScoring = {
3
- memory: {
4
- maxLevel: 22,
5
- minRatio: 1,
6
- freeAttempts: 1000,
7
- maxAttempts: 1000,
8
- shouldFailUnderScore: 30,
9
- shouldFailUnderLevel: 7,
10
- shouldSucceedFromScore: 60,
11
- shouldSucceedFromLevel: 15,
12
- },
13
- zzle: {
14
- maxLevel: 18,
15
- minRatio: 1,
16
- freeAttempts: 1000,
17
- maxAttempts: 1000,
18
- shouldFailUnderScore: 20,
19
- shouldFailUnderLevel: 3,
20
- shouldSucceedFromScore: 50,
21
- shouldSucceedFromLevel: 10,
22
- },
23
- }
24
-
25
- for (const game of Object.values(gamesScoring)) {
26
- game.levels = [...Array(game.maxLevel + 50).keys()].map(index => ({
27
- maxScore: ((index + 1) / 15 + 1) * levelPoints,
28
- }))
29
- game.maxScore = game.levels
30
- .slice(0, game.maxLevel)
31
- .reduce((acc, level) => acc + level.maxScore, 0)
32
- }
33
-
34
- const projectValue = (count, max, minRatio, free) => {
35
- const dist = 1 - minRatio
36
- const diff = max - (count - free)
37
-
38
- if (count <= free || minRatio === 1) return 1
39
- if (diff < 1) return minRatio
40
- return (diff / max) * dist + minRatio
41
- }
42
-
43
- const getLevelRatio = (gameName, levelAttempts) => {
44
- const { minRatio, freeAttempts, maxAttempts } = gamesScoring[gameName]
45
-
46
- return projectValue(levelAttempts, maxAttempts, minRatio, freeAttempts)
47
- }
48
-
49
- export const getLevelScore = (gameName, levelAttempts, levelNumber) =>
50
- // TODO: reduce level score differences
51
- (levelNumber / 15 + 1) * levelPoints * getLevelRatio(gameName, levelAttempts)
52
-
53
- export const getLevelMaxPoints = (levelIndex, gameName) =>
54
- gamesScoring[gameName].levels[levelIndex].maxScore
55
-
56
- export const getLevelsScore = (gameName, results) =>
57
- results
58
- .map((level, levelIndex) =>
59
- getLevelScore(gameName, level.attempts, levelIndex + 1),
60
- )
61
- .reduce((a, b) => a + b, 0)
62
-
63
- export const getGameScores = (gameName, gamePoints, results) => {
64
- const totalLevelsScore = getLevelsScore(gameName, results)
65
- const ratio = totalLevelsScore / gamesScoring[gameName].maxScore
66
-
67
- return {
68
- ratio,
69
- percent: ratio * 100, // TODO: represent the percentage of level done
70
- points: gamePoints * ratio,
71
- }
72
- }
73
-
74
- export const getGlobalScore = games => {
75
- const totalScoreInPercent = games
76
- .map(game => getGameScores(game.name, game.points, game.results).percent)
77
- .reduce((a, b) => a + b, 0)
78
-
79
- return totalScoreInPercent / games.length
80
- }