| 18 | } from '../service/server'; |
| 19 | |
| 20 | async function _parseDagJson(domainId: string, _dag: string): Promise<Tdoc['dag']> { |
| 21 | const parsed = []; |
| 22 | try { |
| 23 | const dag = JSON.parse(_dag); |
| 24 | assert(dag instanceof Array, 'dag must be an array'); |
| 25 | const ids = new Set(dag.map((s) => s._id)); |
| 26 | assert(dag.length, 'must have at least one node'); |
| 27 | assert(dag.length === ids.size, '_id must be unique'); |
| 28 | for (const node of dag) { |
| 29 | assert(node._id, 'each node should have a _id'); |
| 30 | assert(node.title, 'each node shoule have a title'); |
| 31 | assert(node.requireNids instanceof Array); |
| 32 | assert(node.pids instanceof Array); |
| 33 | assert(node.pids.length, 'each node must contain at lease one problem'); |
| 34 | for (const nid of node.requireNids) { |
| 35 | assert(ids.has(nid), `required nid ${nid} not found`); |
| 36 | } |
| 37 | const tasks = []; |
| 38 | for (const i in node.pids) { |
| 39 | tasks.push(problem.get(domainId, node.pids[i]).then((pdoc) => { |
| 40 | if (!pdoc) throw new ProblemNotFoundError(domainId, node.pids[i]); |
| 41 | node.pids[i] = pdoc.docId; |
| 42 | })); |
| 43 | } |
| 44 | // eslint-disable-next-line no-await-in-loop |
| 45 | await Promise.all(tasks); |
| 46 | const newNode = { |
| 47 | _id: +node._id, |
| 48 | title: node.title, |
| 49 | requireNids: Array.from(new Set(node.requireNids)), |
| 50 | pids: Array.from(new Set(node.pids)), |
| 51 | }; |
| 52 | parsed.push(newNode); |
| 53 | } |
| 54 | } catch (e) { |
| 55 | throw new ValidationError('dag', null, e instanceof ProblemNotFoundError ? e : e.message); |
| 56 | } |
| 57 | return parsed; |
| 58 | } |
| 59 | |
| 60 | class TrainingMainHandler extends Handler { |
| 61 | @param('page', Types.PositiveInt, true) |