Sync
This commit is contained in:
		
							parent
							
								
									38acfa6a4a
								
							
						
					
					
						commit
						197d1d9ae2
					
				
					 13 changed files with 372 additions and 120 deletions
				
			
		|  | @ -35,7 +35,21 @@ import { Language } from '../content/language.js'; | |||
|  *         groups: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             $ref: '#/components/schemas/Group' | ||||
|  *             type: string | ||||
|  *             description: ID of a group | ||||
|  *         links: | ||||
|  *           type: object | ||||
|  *           properties: | ||||
|  *             self: | ||||
|  *               type: string | ||||
|  *               description: Path to the assignment | ||||
|  *               example: '/assignment/0' | ||||
|  *             submissions: | ||||
|  *               type: array | ||||
|  *               items: | ||||
|  *                 type: string | ||||
|  *                 description: Path to the submissions for this assignment | ||||
|  *                 example: '/assignment/0/submissions' | ||||
|  *       required: | ||||
|  *         - within | ||||
|  *         - id | ||||
|  |  | |||
|  | @ -2,6 +2,10 @@ import { Entity, Enum, ManyToOne } from '@mikro-orm/core'; | |||
| import { Student } from '../users/student.entity.js'; | ||||
| import { Class } from './class.entity.js'; | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * tags: [Class] | ||||
|  */ | ||||
| @Entity() | ||||
| export class ClassJoinRequest { | ||||
|     @ManyToOne({ | ||||
|  |  | |||
|  | @ -9,6 +9,35 @@ import { v4 } from 'uuid'; | |||
| import { Teacher } from '../users/teacher.entity.js'; | ||||
| import { Student } from '../users/student.entity.js'; | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * tags: | ||||
|  *   name: Class | ||||
|  *   description: API for managing classes | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     Class: | ||||
|  *       type: object | ||||
|  *       properties: | ||||
|  *         classId: | ||||
|  *           type: integer | ||||
|  *           format: int8 | ||||
|  *         displayName: | ||||
|  *           type: string | ||||
|  *         teachers: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             type: string | ||||
|  *             description: The id of a teacher | ||||
|  *         students: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             type: string | ||||
|  *             description: The id of a student | ||||
|  *       required: | ||||
|  *         - teachers | ||||
|  *         - students | ||||
|  */ | ||||
| @Entity() | ||||
| export class Class { | ||||
|     @PrimaryKey() | ||||
|  |  | |||
|  | @ -1,6 +1,28 @@ | |||
| import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; | ||||
| import { LearningObject } from './learning-object.entity.js'; | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     Attachment: | ||||
|  *       type: object | ||||
|  *       properties: | ||||
|  *         learningObject: | ||||
|  *           $ref: '#/components/schemas/LearningObject' | ||||
|  *         sequenceNumber: | ||||
|  *           type: integer | ||||
|  *         mimeType: | ||||
|  *           type: string | ||||
|  *         content: | ||||
|  *           type: string | ||||
|  *           format: binary | ||||
|  *       required: | ||||
|  *         - learningObject | ||||
|  *         - sequenceNumber | ||||
|  *         - mimeType | ||||
|  *         - content | ||||
|  */ | ||||
| @Entity() | ||||
| export class Attachment { | ||||
|     @ManyToOne({ | ||||
|  |  | |||
|  | @ -1,3 +1,23 @@ | |||
| /** | ||||
|  * @swagger | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     Language: | ||||
|  *       type: string | ||||
|  *       enum: | ||||
|  *         - nl | ||||
|  *         - fr | ||||
|  *         - en | ||||
|  *         - de | ||||
|  *   parameters: | ||||
|  *     Language: | ||||
|  *       in: query | ||||
|  *       name: language | ||||
|  *       description: Language of the content | ||||
|  *       required: false | ||||
|  *       schema: | ||||
|  *         $ref: '#/components/schemas/Language' | ||||
|  */ | ||||
| export enum Language { | ||||
|     Dutch = 'nl', | ||||
|     French = 'fr', | ||||
|  |  | |||
|  | @ -12,6 +12,80 @@ import { Language } from './language.js'; | |||
| import { Attachment } from './attachment.entity.js'; | ||||
| import { Teacher } from '../users/teacher.entity.js'; | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * tags: | ||||
|  *   name: LearningObject | ||||
|  *   description: API for managing learning objects | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     LearningObject: | ||||
|  *       type: object | ||||
|  *       properties: | ||||
|  *         hruid: | ||||
|  *           type: string | ||||
|  *         language: | ||||
|  *           $ref: '#/components/schemas/Language' | ||||
|  *         version: | ||||
|  *           type: string | ||||
|  *           default: '1' | ||||
|  *         admins: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             $ref: '#/components/schemas/Teacher' | ||||
|  *         title: | ||||
|  *           type: string | ||||
|  *         description: | ||||
|  *           type: string | ||||
|  *         contentType: | ||||
|  *           type: string | ||||
|  *         keywords: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             type: string | ||||
|  *         targetAges: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             type: integer | ||||
|  *           nullable: true | ||||
|  *         teacherExclusive: | ||||
|  *           type: boolean | ||||
|  *           default: false | ||||
|  *         skosConcepts: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             type: string | ||||
|  *         educationalGoals: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             $ref: '#/components/schemas/EducationalGoal' | ||||
|  *         copyright: | ||||
|  *           type: string | ||||
|  *           default: '' | ||||
|  *         license: | ||||
|  *           type: string | ||||
|  *           default: '' | ||||
|  *         difficulty: | ||||
|  *           type: integer | ||||
|  *           nullable: true | ||||
|  *         estimatedTime: | ||||
|  *           type: integer | ||||
|  *         returnValue: | ||||
|  *           $ref: '#/components/schemas/ReturnValue' | ||||
|  *         available: | ||||
|  *           type: boolean | ||||
|  *           default: true | ||||
|  *         contentLocation: | ||||
|  *           type: string | ||||
|  *           nullable: true | ||||
|  *         attachments: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             $ref: '#/components/schemas/Attachment' | ||||
|  *         content: | ||||
|  *           type: string | ||||
|  *           format: binary | ||||
|  */ | ||||
| @Entity() | ||||
| export class LearningObject { | ||||
|     @PrimaryKey({ type: 'string' }) | ||||
|  | @ -101,6 +175,18 @@ export class LearningObject { | |||
|     content!: Buffer; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     EducationalGoal: | ||||
|  *       type: object | ||||
|  *       properties: | ||||
|  *         source: | ||||
|  *           type: string | ||||
|  *         id: | ||||
|  *           type: string | ||||
|  */ | ||||
| @Embeddable() | ||||
| export class EducationalGoal { | ||||
|     @Property({ type: 'string' }) | ||||
|  | @ -110,6 +196,22 @@ export class EducationalGoal { | |||
|     id!: string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     ReturnValue: | ||||
|  *       type: object | ||||
|  *       properties: | ||||
|  *         callbackUrl: | ||||
|  *           type: string | ||||
|  *           format: uri | ||||
|  *         callbackSchema: | ||||
|  *           type: string | ||||
|  *       required: | ||||
|  *         - callbackUrl | ||||
|  *         - callbackSchema | ||||
|  */ | ||||
| @Embeddable() | ||||
| export class ReturnValue { | ||||
|     @Property({ type: 'string' }) | ||||
|  |  | |||
|  | @ -11,6 +11,46 @@ import { | |||
| import { Language } from './language.js'; | ||||
| import { Teacher } from '../users/teacher.entity.js'; | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * tags: | ||||
|  *   name: LearningPath | ||||
|  *   description: API for managing learning paths | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     LearningPath: | ||||
|  *       type: object | ||||
|  *       required: | ||||
|  *         - hruid | ||||
|  *         - language | ||||
|  *         - admins | ||||
|  *         - title | ||||
|  *         - description | ||||
|  *         - image | ||||
|  *       properties: | ||||
|  *         hruid: | ||||
|  *           type: string | ||||
|  *           description: Human readable identifier | ||||
|  *         language: | ||||
|  *           description: Language of the learning path | ||||
|  *           schema: | ||||
|  *             $ref: '#/components/schemas/Language' | ||||
|  *         admins: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             $ref: '#/components/schemas/Teacher' | ||||
|  *         title: | ||||
|  *           type: string | ||||
|  *         description: | ||||
|  *           type: string | ||||
|  *         image: | ||||
|  *           type: string | ||||
|  *         nodes: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             schema: | ||||
|  *               $ref: '#/components/schemas/LearningPathNode' | ||||
|  */ | ||||
| @Entity() | ||||
| export class LearningPath { | ||||
|     @PrimaryKey({ type: 'string' }) | ||||
|  |  | |||
|  | @ -2,6 +2,23 @@ import { Collection, Entity, ManyToMany } from '@mikro-orm/core'; | |||
| import { User } from './user.entity.js'; | ||||
| import { Class } from '../classes/class.entity.js'; | ||||
| 
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * tags: | ||||
|  *   name: Teacher | ||||
|  *   description: API for managing teachers | ||||
|  * components: | ||||
|  *   schemas: | ||||
|  *     Teacher: | ||||
|  *       type: object | ||||
|  *       required: | ||||
|  *         - classes | ||||
|  *       properties: | ||||
|  *         classes: | ||||
|  *           type: array | ||||
|  *           items: | ||||
|  *             $ref: '#/components/schemas/Class' | ||||
|  */ | ||||
| @Entity() | ||||
| export class Teacher extends User { | ||||
|     @ManyToMany(() => { | ||||
|  |  | |||
|  | @ -1,7 +1,40 @@ | |||
| /** | ||||
|  * @swagger | ||||
|  * components: | ||||
|  *   parameters: | ||||
|  *     id: | ||||
|  *       in: path | ||||
|  *       name: id | ||||
|  *       schema: | ||||
|  *         type: string | ||||
|  *       description: The id of the class | ||||
|  *       required: true | ||||
|  *       example: 0 | ||||
|  */ | ||||
| 
 | ||||
| import express from 'express'; | ||||
| const router = express.Router(); | ||||
| 
 | ||||
| // Root endpoint used to search objects
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * /class: | ||||
|  *   get: | ||||
|  *     summary: Get a list of classes | ||||
|  *     tags: [Class] | ||||
|  *     responses: | ||||
|  *       200: | ||||
|  *         description: A list of classes | ||||
|  *         content: | ||||
|  *           application/json: | ||||
|  *             schema: | ||||
|  *               type: object | ||||
|  *               properties: | ||||
|  *                 classes: | ||||
|  *                  type: array | ||||
|  *                  items: | ||||
|  *                    type: string | ||||
|  *                    example: '0' | ||||
|  */ | ||||
| router.get('/', (req, res) => { | ||||
|     res.json({ | ||||
|         classes: ['0', '1'], | ||||
|  | @ -9,6 +42,22 @@ router.get('/', (req, res) => { | |||
| }); | ||||
| 
 | ||||
| // Information about an class with id 'id'
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * /class/{id}: | ||||
|  *   get: | ||||
|  *     summary: Get a class by id | ||||
|  *     tags: [Class] | ||||
|  *     parameters: | ||||
|  *       - $ref: '#/components/parameters/id' | ||||
|  *     responses: | ||||
|  *       200: | ||||
|  *         description: A class | ||||
|  *         content: | ||||
|  *           application/json: | ||||
|  *             schema: | ||||
|  *               $ref: '#/components/schemas/Class' | ||||
|  */ | ||||
| router.get('/:id', (req, res) => { | ||||
|     res.json({ | ||||
|         id: req.params.id, | ||||
|  |  | |||
|  | @ -1,3 +1,10 @@ | |||
| /** | ||||
|  * @swagger | ||||
|  * tags: | ||||
|  *   name: LearningObject | ||||
|  *   description: API for managing learning objects | ||||
|  */ | ||||
| 
 | ||||
| import express from 'express'; | ||||
| import { | ||||
|     getAllLearningObjects, | ||||
|  | @ -8,20 +15,67 @@ const router = express.Router(); | |||
| 
 | ||||
| // DWENGO learning objects
 | ||||
| 
 | ||||
| // Queries: hruid(path), full, language
 | ||||
| // Route to fetch list of learning objects based on hruid of learning path
 | ||||
| 
 | ||||
| // Route 1: list of object hruids
 | ||||
| // Example 1: http://localhost:3000/learningObject?hruid=un_artificiele_intelligentie
 | ||||
| 
 | ||||
| // Route 2: list of object data
 | ||||
| // Example 2: http://localhost:3000/learningObject?full=true&hruid=un_artificiele_intelligentie
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * /learningObject: | ||||
|  *   get: | ||||
|  *     summary: Get a list of learning objects | ||||
|  *     tags: [LearningObject] | ||||
|  *     parameters: | ||||
|  *       - in: query | ||||
|  *         name: hruid | ||||
|  *         schema: | ||||
|  *           type: string | ||||
|  *         description: | ||||
|  *           The hruid of the learning path to get learning objects from | ||||
|  *         example: un_artificiele_intelligentie | ||||
|  *       - in: query | ||||
|  *         name: full | ||||
|  *         description: Whether to return full object data | ||||
|  *       - $ref: '#/components/parameters/Language' | ||||
|  *     responses: | ||||
|  *       200: | ||||
|  *         description: A list of learning objects | ||||
|  *         content: | ||||
|  *           application/json: | ||||
|  *             schema: | ||||
|  *               type: array | ||||
|  *               items: | ||||
|  *                 $ref: '#/components/schemas/LearningObject' | ||||
|  *       400: | ||||
|  *         description: HRUID query is required | ||||
|  *       500: | ||||
|  *         description: Internal server error | ||||
|  */ | ||||
| router.get('/', getAllLearningObjects); | ||||
| 
 | ||||
| // Parameter: hruid of learning object
 | ||||
| // Query: language
 | ||||
| // Route to fetch data of one learning object based on its hruid
 | ||||
| // Example: http://localhost:3000/learningObject/un_ai7
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * /learningObject/{hruid}: | ||||
|  *   get: | ||||
|  *     summary: Get a learning object by hruid | ||||
|  *     tags: [LearningObject] | ||||
|  *     parameters: | ||||
|  *       - in: path | ||||
|  *         name: hruid | ||||
|  *         schema: | ||||
|  *           type: string | ||||
|  *         required: true | ||||
|  *         description: The hruid of the learning object | ||||
|  *         example: un_ai7 | ||||
|  *       - $ref: '#/components/parameters/Language' | ||||
|  *     responses: | ||||
|  *       200: | ||||
|  *         description: A learning object | ||||
|  *         content: | ||||
|  *           application/json: | ||||
|  *             schema: | ||||
|  *               $ref: "#/components/schemas/LearningObject" | ||||
|  *       400: | ||||
|  *         description: HRUID parameter is required | ||||
|  *       500: | ||||
|  *         description: Internal server error | ||||
|  */ | ||||
| router.get('/:hruid', getLearningObject); | ||||
| 
 | ||||
| export default router; | ||||
|  |  | |||
|  | @ -2,6 +2,10 @@ import express from 'express'; | |||
| const router = express.Router(); | ||||
| 
 | ||||
| // Root endpoint used to search objects
 | ||||
| /** | ||||
|  * @swagger | ||||
|  * /question | ||||
|  */ | ||||
| router.get('/', (req, res) => { | ||||
|     res.json({ | ||||
|         questions: ['0', '1'], | ||||
|  |  | |||
|  | @ -1,9 +1,11 @@ | |||
| import { fetchWithLogging } from '../util/apiHelper.js'; | ||||
| import { DWENGO_API_BASE } from '../config.js'; | ||||
| import { | ||||
|     LearningPath, | ||||
|     LearningPathResponse, | ||||
| } from '../interfaces/learningPath.js'; | ||||
| import { | ||||
|     LearningPath | ||||
| } from '../entities/content/learning-path.entity.js'; | ||||
| import { getLogger, Logger } from '../logging/initalize.js'; | ||||
| 
 | ||||
| const logger: Logger = getLogger(); | ||||
|  |  | |||
							
								
								
									
										105
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										105
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -56,7 +56,6 @@ | |||
|                 "ts-node": "^10.9.2", | ||||
|                 "tsx": "^4.19.3", | ||||
|                 "typescript": "^5.7.3", | ||||
|                 "typescript-json-schema": "^0.65.1", | ||||
|                 "vitest": "^3.0.6" | ||||
|             } | ||||
|         }, | ||||
|  | @ -6355,13 +6354,6 @@ | |||
|             "version": "1.0.1", | ||||
|             "license": "MIT" | ||||
|         }, | ||||
|         "node_modules/path-equal": { | ||||
|             "version": "1.2.5", | ||||
|             "resolved": "https://registry.npmjs.org/path-equal/-/path-equal-1.2.5.tgz", | ||||
|             "integrity": "sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==", | ||||
|             "dev": true, | ||||
|             "license": "MIT" | ||||
|         }, | ||||
|         "node_modules/path-exists": { | ||||
|             "version": "4.0.0", | ||||
|             "dev": true, | ||||
|  | @ -8296,103 +8288,6 @@ | |||
|                 "typescript": ">=4.8.4 <5.8.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema": { | ||||
|             "version": "0.65.1", | ||||
|             "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.65.1.tgz", | ||||
|             "integrity": "sha512-tuGH7ff2jPaUYi6as3lHyHcKpSmXIqN7/mu50x3HlYn0EHzLpmt3nplZ7EuhUkO0eqDRc9GqWNkfjgBPIS9kxg==", | ||||
|             "dev": true, | ||||
|             "license": "BSD-3-Clause", | ||||
|             "dependencies": { | ||||
|                 "@types/json-schema": "^7.0.9", | ||||
|                 "@types/node": "^18.11.9", | ||||
|                 "glob": "^7.1.7", | ||||
|                 "path-equal": "^1.2.5", | ||||
|                 "safe-stable-stringify": "^2.2.0", | ||||
|                 "ts-node": "^10.9.1", | ||||
|                 "typescript": "~5.5.0", | ||||
|                 "yargs": "^17.1.1" | ||||
|             }, | ||||
|             "bin": { | ||||
|                 "typescript-json-schema": "bin/typescript-json-schema" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema/node_modules/@types/node": { | ||||
|             "version": "18.19.79", | ||||
|             "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.79.tgz", | ||||
|             "integrity": "sha512-90K8Oayimbctc5zTPHPfZloc/lGVs7f3phUAAMcTgEPtg8kKquGZDERC8K4vkBYkQQh48msiYUslYtxTWvqcAg==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "undici-types": "~5.26.4" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema/node_modules/brace-expansion": { | ||||
|             "version": "1.1.11", | ||||
|             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||
|             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "balanced-match": "^1.0.0", | ||||
|                 "concat-map": "0.0.1" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema/node_modules/glob": { | ||||
|             "version": "7.2.3", | ||||
|             "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", | ||||
|             "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", | ||||
|             "deprecated": "Glob versions prior to v9 are no longer supported", | ||||
|             "dev": true, | ||||
|             "license": "ISC", | ||||
|             "dependencies": { | ||||
|                 "fs.realpath": "^1.0.0", | ||||
|                 "inflight": "^1.0.4", | ||||
|                 "inherits": "2", | ||||
|                 "minimatch": "^3.1.1", | ||||
|                 "once": "^1.3.0", | ||||
|                 "path-is-absolute": "^1.0.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "*" | ||||
|             }, | ||||
|             "funding": { | ||||
|                 "url": "https://github.com/sponsors/isaacs" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema/node_modules/minimatch": { | ||||
|             "version": "3.1.2", | ||||
|             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", | ||||
|             "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", | ||||
|             "dev": true, | ||||
|             "license": "ISC", | ||||
|             "dependencies": { | ||||
|                 "brace-expansion": "^1.1.7" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "*" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema/node_modules/typescript": { | ||||
|             "version": "5.5.4", | ||||
|             "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", | ||||
|             "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", | ||||
|             "dev": true, | ||||
|             "license": "Apache-2.0", | ||||
|             "bin": { | ||||
|                 "tsc": "bin/tsc", | ||||
|                 "tsserver": "bin/tsserver" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=14.17" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-json-schema/node_modules/undici-types": { | ||||
|             "version": "5.26.5", | ||||
|             "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", | ||||
|             "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", | ||||
|             "dev": true, | ||||
|             "license": "MIT" | ||||
|         }, | ||||
|         "node_modules/undici-types": { | ||||
|             "version": "6.20.0", | ||||
|             "license": "MIT" | ||||
|  |  | |||
		Reference in a new issue