diff --git a/.env.example b/.env.example
index 5afe160..d5bf431 100644
--- a/.env.example
+++ b/.env.example
@@ -1,4 +1,5 @@
-DATABASE_URL="postgresql://postgres:randompassword@localhost:5432/mydb?schema=public"
+NODE_ENV=development
-## if no password, use this instead:
-# DATABASE_URL="postgresql://postgres@localhost:5432/mydb?schema=public"
\ No newline at end of file
+PORT=3000
+
+DATABASE_URL="postgresql://postgres@localhost:5432/planifetsDB?schema=public"
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
index 1254834..4e693a9 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,44 +1,45 @@
-module.exports = {
- parser: '@typescript-eslint/parser',
- parserOptions: {
- project: 'tsconfig.json',
- tsconfigRootDir: __dirname,
- sourceType: 'module',
- },
- plugins: ['@typescript-eslint/eslint-plugin', 'import', 'simple-import-sort'],
- extends: [
- 'plugin:@typescript-eslint/recommended',
- 'plugin:prettier/recommended',
- 'airbnb-typescript/base',
- ],
- root: true,
- env: {
- node: true,
- jest: true,
- },
- ignorePatterns: ['.eslintrc.js', 'dist/'],
- rules: {
- '@typescript-eslint/interface-name-prefix': 'off',
- '@typescript-eslint/lines-between-class-members': 'off',
- complexity: ['warn', { max: 10 }],
- complexity: ['error', { max: 15 }],
- '@typescript-eslint/explicit-member-accessibility': [
- 'error',
- {
- overrides: {
- constructors: 'no-public',
- },
- },
- ],
- 'simple-import-sort/imports': 'error',
- 'simple-import-sort/exports': 'error',
- 'prettier/prettier': [
- 'error',
- {
- endOfLine: 'lf',
- },
- ],
- indent: 'off',
- '@typescript-eslint/indent': 'off',
- },
-};
+module.exports = {
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ project: 'tsconfig.json',
+ tsconfigRootDir: __dirname,
+ sourceType: 'module',
+ },
+ plugins: ['@typescript-eslint/eslint-plugin', 'import', 'simple-import-sort'],
+ extends: [
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:prettier/recommended',
+ 'airbnb-typescript/base',
+ ],
+ root: true,
+ env: {
+ node: true,
+ jest: true,
+ },
+ ignorePatterns: ['.eslintrc.js', 'dist/'],
+ rules: {
+ '@typescript-eslint/interface-name-prefix': 'off',
+ '@typescript-eslint/lines-between-class-members': 'off',
+ complexity: ['warn', { max: 10 }],
+ complexity: ['error', { max: 15 }],
+ '@typescript-eslint/explicit-member-accessibility': [
+ 'error',
+ {
+ overrides: {
+ constructors: 'no-public',
+ },
+ },
+ ],
+ 'simple-import-sort/imports': 'error',
+ 'simple-import-sort/exports': 'error',
+ 'prettier/prettier': [
+ 'error',
+ {
+ endOfLine: 'lf',
+ },
+ ],
+ '@typescript-eslint/brace-style': 'off',
+ indent: 'off',
+ '@typescript-eslint/indent': 'off',
+ },
+};
diff --git a/.prettierrc b/.prettierrc
index 6145d88..4959830 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,7 +1,8 @@
-{
- "tabWidth": 2,
- "useTabs": false,
- "semi": true,
- "singleQuote": true,
- "trailingComma": "all"
-}
\ No newline at end of file
+{
+ "tabWidth": 2,
+ "useTabs": false,
+ "semi": true,
+ "singleQuote": true,
+ "trailingComma": "all",
+ "endOfLine": "lf"
+}
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 4fc402f..3f1abb8 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,7 +1,7 @@
{
- "recommendations": [
- "dbaeumer.vscode-eslint",
- "esbenp.prettier-vscode",
- "rvest.vs-code-prettier-eslint"
- ]
-}
\ No newline at end of file
+ "recommendations": [
+ "dbaeumer.vscode-eslint",
+ "esbenp.prettier-vscode",
+ "abians.prisma-generate-uml"
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 519c62a..67e00b8 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,5 +5,6 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
- "files.eol": "\n"
+ "files.eol": "\n",
+ "typescript.preferences.importModuleSpecifier": "relative",
}
diff --git a/package.json b/package.json
index 2d2a037..b643258 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "planif-ets-backend",
+ "name": "planifets-backend",
"version": "0.0.1",
"description": "",
"author": "",
@@ -13,7 +13,7 @@
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
- "lint": "eslint .",
+ "lint": "eslint src --ext .ts",
"refresh": "rm -rf dist && rm -rf node_modules && yarn cache clean && yarn install",
"prisma:generate": "prisma generate",
"prisma:preview": "prisma migrate dev --create-only",
@@ -35,8 +35,9 @@
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.2.1",
"@nestjs/core": "^10.0.0",
+ "@nestjs/mapped-types": "^2.0.5",
"@nestjs/platform-express": "^10.0.0",
- "@prisma/client": "^5.7.1",
+ "@prisma/client": "^5.15.0",
"axios": "^1.6.8",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
@@ -69,6 +70,7 @@
"prettier": "^3.2.5",
"prettier-eslint": "^16.3.0",
"prisma": "^5.7.1",
+ "prisma-erd-generator": "^1.11.2",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
@@ -95,4 +97,4 @@
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
-}
\ No newline at end of file
+}
diff --git a/prisma/ERD.svg b/prisma/ERD.svg
new file mode 100644
index 0000000..71de221
--- /dev/null
+++ b/prisma/ERD.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/prisma/migrations/20240622070105_add_program_type_table_values/migration.sql b/prisma/migrations/20240622070105_add_program_type_table_values/migration.sql
new file mode 100644
index 0000000..d7419f4
--- /dev/null
+++ b/prisma/migrations/20240622070105_add_program_type_table_values/migration.sql
@@ -0,0 +1,23 @@
+/*
+ Warnings:
+
+ - You are about to drop the column `abbreviation` on the `Program` table. All the data in the column will be lost.
+ - You are about to drop the column `type` on the `Program` table. All the data in the column will be lost.
+ - A unique constraint covering the columns `[code,title]` on the table `Program` will be added. If there are existing duplicate values, this will fail.
+
+*/
+-- AlterTable
+ALTER TABLE "Program" DROP COLUMN "abbreviation",
+DROP COLUMN "type",
+ADD COLUMN "types" INTEGER[];
+
+-- CreateTable
+CREATE TABLE "ProgramType" (
+ "id" INTEGER NOT NULL,
+ "title" TEXT NOT NULL,
+
+ CONSTRAINT "ProgramType_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Program_code_title_key" ON "Program"("code", "title");
diff --git a/prisma/migrations/20240724005644_add_program_type_relation_and_update_session_table/migration.sql b/prisma/migrations/20240724005644_add_program_type_relation_and_update_session_table/migration.sql
new file mode 100644
index 0000000..0c8b516
--- /dev/null
+++ b/prisma/migrations/20240724005644_add_program_type_relation_and_update_session_table/migration.sql
@@ -0,0 +1,34 @@
+/*
+ Warnings:
+
+ - You are about to drop the column `unstructuredPrerequisites` on the `Course` table. All the data in the column will be lost.
+ - You are about to drop the column `types` on the `Program` table. All the data in the column will be lost.
+ - You are about to drop the column `name` on the `Session` table. All the data in the column will be lost.
+ - Added the required column `programTypeId` to the `Program` table without a default value. This is not possible if the table is not empty.
+ - Added the required column `trimester` to the `Session` table without a default value. This is not possible if the table is not empty.
+
+*/
+-- CreateEnum
+CREATE TYPE "Trimester" AS ENUM ('A', 'E', 'H');
+
+-- AlterTable
+ALTER TABLE "Course" DROP COLUMN "unstructuredPrerequisites";
+
+-- AlterTable
+ALTER TABLE "Program" DROP COLUMN "types",
+ADD COLUMN "programTypeId" INTEGER NOT NULL;
+
+-- AlterTable
+CREATE SEQUENCE programtype_id_seq;
+ALTER TABLE "ProgramType" ALTER COLUMN "id" SET DEFAULT nextval('programtype_id_seq');
+ALTER SEQUENCE programtype_id_seq OWNED BY "ProgramType"."id";
+
+-- AlterTable
+ALTER TABLE "Session" DROP COLUMN "name",
+ADD COLUMN "trimester" "Trimester" NOT NULL;
+
+-- CreateIndex
+CREATE INDEX "Program_programTypeId_idx" ON "Program"("programTypeId");
+
+-- AddForeignKey
+ALTER TABLE "Program" ADD CONSTRAINT "Program_programTypeId_fkey" FOREIGN KEY ("programTypeId") REFERENCES "ProgramType"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/prisma/migrations/20240724060002_update_many_to_many_program_type_to_program/migration.sql b/prisma/migrations/20240724060002_update_many_to_many_program_type_to_program/migration.sql
new file mode 100644
index 0000000..3b822cd
--- /dev/null
+++ b/prisma/migrations/20240724060002_update_many_to_many_program_type_to_program/migration.sql
@@ -0,0 +1,15 @@
+/*
+ Warnings:
+
+ - You are about to drop the column `programTypeId` on the `Program` table. All the data in the column will be lost.
+
+*/
+-- DropForeignKey
+ALTER TABLE "Program" DROP CONSTRAINT "Program_programTypeId_fkey";
+
+-- DropIndex
+DROP INDEX "Program_programTypeId_idx";
+
+-- AlterTable
+ALTER TABLE "Program" DROP COLUMN "programTypeId",
+ADD COLUMN "programTypeIds" TEXT NOT NULL DEFAULT '[]';
diff --git a/prisma/migrations/20240724061353_update_program_table_add_cycle_update_program_type_type/migration.sql b/prisma/migrations/20240724061353_update_program_table_add_cycle_update_program_type_type/migration.sql
new file mode 100644
index 0000000..b05004a
--- /dev/null
+++ b/prisma/migrations/20240724061353_update_program_table_add_cycle_update_program_type_type/migration.sql
@@ -0,0 +1,16 @@
+/*
+ Warnings:
+
+ - Added the required column `cycle` to the `Program` table without a default value. This is not possible if the table is not empty.
+ - Changed the type of `programTypeIds` on the `Program` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
+
+*/
+-- AlterTable
+ALTER TABLE "Program" ADD COLUMN "cycle" INTEGER NOT NULL,
+ALTER COLUMN "credits" SET DATA TYPE TEXT,
+DROP COLUMN "programTypeIds",
+ADD COLUMN "programTypeIds" JSONB NOT NULL;
+
+-- AlterTable
+ALTER TABLE "ProgramType" ALTER COLUMN "id" DROP DEFAULT;
+DROP SEQUENCE "programtype_id_seq";
diff --git a/prisma/migrations/20240803014322_update_trimester_enum/migration.sql b/prisma/migrations/20240803014322_update_trimester_enum/migration.sql
new file mode 100644
index 0000000..b241af8
--- /dev/null
+++ b/prisma/migrations/20240803014322_update_trimester_enum/migration.sql
@@ -0,0 +1,14 @@
+/*
+ Warnings:
+
+ - The values [A,E,H] on the enum `Trimester` will be removed. If these variants are still used in the database, this will fail.
+
+*/
+-- AlterEnum
+BEGIN;
+CREATE TYPE "Trimester_new" AS ENUM ('AUTOMNE', 'ETE', 'HIVER');
+ALTER TABLE "Session" ALTER COLUMN "trimester" TYPE "Trimester_new" USING ("trimester"::text::"Trimester_new");
+ALTER TYPE "Trimester" RENAME TO "Trimester_old";
+ALTER TYPE "Trimester_new" RENAME TO "Trimester";
+DROP TYPE "Trimester_old";
+COMMIT;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index b69dd13..eca9e6e 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -5,70 +5,86 @@ generator client {
provider = "prisma-client-js"
}
+generator erd {
+ provider = "prisma-erd-generator"
+ theme = "neutral"
+}
+
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
+enum Trimester {
+ AUTOMNE
+ ETE
+ HIVER
+}
+
model Session {
- id String @id @default(uuid())
- name String
+ id String @id @default(uuid())
+ trimester Trimester
year Int
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
courseInstances CourseInstance[]
}
model CourseInstance {
- id String @id @default(uuid())
+ id String @id @default(uuid())
courseId String
sessionId String
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
course Course @relation(fields: [courseId], references: [id])
session Session @relation(fields: [sessionId], references: [id])
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
@@unique([courseId, sessionId])
@@index([courseId, sessionId])
}
model Course {
- id String @id @default(uuid())
- programId String
- code String @unique
- title String
- description String
- credits Int
- unstructuredPrerequisites String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- programs ProgramCourse[]
- courseInstances CourseInstance[]
+ id String @id
+ programId String
+ code String @unique
+ title String
+ description String
+ credits Int
+ programs ProgramCourse[]
+ courseInstances CourseInstance[]
prerequisites CoursePrerequisite[] @relation("CourseToPrerequisite")
prerequisiteOf CoursePrerequisite[] @relation("PrerequisiteToCourse")
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
@@index([code, programId])
}
model CoursePrerequisite {
courseId String
- course Course @relation("CourseToPrerequisite", fields: [courseId], references: [id])
prerequisiteId String
- prerequisite Course @relation("PrerequisiteToCourse", fields: [prerequisiteId], references: [id])
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
+
+ course Course @relation("CourseToPrerequisite", fields: [courseId], references: [id])
+ prerequisite Course @relation("PrerequisiteToCourse", fields: [prerequisiteId], references: [id])
+
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
@@id([courseId, prerequisiteId])
}
model ProgramCourse {
courseId String
- course Course @relation(fields: [courseId], references: [id])
programId String
- program Program @relation(fields: [programId], references: [id])
+
+ course Course @relation(fields: [courseId], references: [id])
+ program Program @relation(fields: [programId], references: [id])
+
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -76,17 +92,24 @@ model ProgramCourse {
}
model Program {
- id String @id @default(uuid())
- code Int @unique
+ id String @id
+ code Int @unique
title String
- credits Int
- type String
+ credits String
+ cycle Int
url String
- abbreviation String?
+ programTypeIds Json
horaireCoursPdfJson Json?
planificationPdfJson Json?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
+ courses ProgramCourse[]
+
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ @@unique([code, title])
+}
- courses ProgramCourse[]
+model ProgramType {
+ id Int @id
+ title String
}
diff --git a/prisma/seeds/programs/programs.json b/prisma/seeds/programs/programs.json
deleted file mode 100644
index 785fc0e..0000000
--- a/prisma/seeds/programs/programs.json
+++ /dev/null
@@ -1,87 +0,0 @@
-[
- {
- "code": "7625",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-construction"
- },
- {
- "code": "7694",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-electrique"
- },
- {
- "code": "7084",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-logiciel"
- },
- {
- "code": "7684",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-mecanique"
- },
- {
- "code": "6556",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-operations-logistique"
- },
- {
- "code": "6557",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-production-automatisee"
- },
- {
- "code": "7086",
- "type": "premier-cycle",
- "url": "baccalaureat-genie-des-ti"
- },
- {
- "code": "6646",
- "type": "premier-cycle",
- "url": "baccalaureat-informatique-distribuee"
- },
- {
- "code": "5766",
- "type": "premier-cycle",
- "url": "cheminement-universitaire-technologie"
- },
- {
- "code": "4567",
- "type": "premier-cycle",
- "url": "certificat-economie-estimation"
- },
- {
- "code": "4412",
- "type": "premier-cycle",
- "url": "certificat-gestion-assurance-qualite"
- },
- {
- "code": "4563",
- "type": "premier-cycle",
- "url": "certificat-gestion-construction"
- },
- {
- "code": "4684",
- "type": "premier-cycle",
- "url": "certificat-gestion-immobiliere"
- },
- {
- "code": "4329",
- "type": "premier-cycle",
- "url": "certificat-production-industrielle"
- },
- {
- "code": "4288",
- "type": "premier-cycle",
- "url": "certificat-telecommunications"
- },
- {
- "code": "1822",
- "type": "deuxieme-cycle",
- "url": "maitrise-genie-logiciel"
- },
- {
- "code": "3178",
- "type": "deuxieme-cycle",
- "url": "dess-technologies-information"
- }
-]
\ No newline at end of file
diff --git a/src/app.controller.ts b/src/app.controller.ts
new file mode 100644
index 0000000..f56c3eb
--- /dev/null
+++ b/src/app.controller.ts
@@ -0,0 +1,9 @@
+import { Controller, Get } from '@nestjs/common';
+
+@Controller()
+export class AppController {
+ @Get()
+ public getHello(): string {
+ return 'Hello World!';
+ }
+}
diff --git a/src/app.module.ts b/src/app.module.ts
index 1722d29..2f2c3dc 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -2,11 +2,31 @@ import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
+import { AppController } from './app.controller';
+import { EtsController } from './common/api-helper/ets/ets.controller';
+import { EtsModule } from './common/api-helper/ets/ets.module';
+import { FileUtil } from './common/utils/pdf/fileUtil';
+import { PdfController } from './common/website-helper/pdf/pdf.controller';
+import { HoraireCoursService } from './common/website-helper/pdf/pdf-parser/horaire/horaire-cours.service';
+import { PlanificationCoursService } from './common/website-helper/pdf/pdf-parser/planification/planification-cours.service';
import config from './config/configuration';
-import { PdfController } from './pdf/pdf.controller';
-import { HoraireCoursService } from './pdf/pdf-parser/horaire/horaire-cours.service';
-import { PlanificationCoursService } from './pdf/pdf-parser/planification/planification-cours.service';
-import { FileUtil } from './utils/pdf/fileUtil';
+import { CourseController } from './course/course.controller';
+import { CourseModule } from './course/course.module';
+import { CourseService } from './course/course.service';
+import { CourseInstanceController } from './course-instance/course-instance.controller';
+import { CourseInstanceModule } from './course-instance/course-instance.module';
+import { CourseInstanceService } from './course-instance/course-instance.service';
+import { CoursePrerequisiteController } from './course-prerequisite/course-prerequisite.controller';
+import { CoursePrerequisiteModule } from './course-prerequisite/course-prerequisite.module';
+import { CoursePrerequisiteService } from './course-prerequisite/course-prerequisite.service';
+import { PrismaModule } from './prisma/prisma.module';
+import { PrismaService } from './prisma/prisma.service';
+import { ProgramController } from './program/program.controller';
+import { ProgramModule } from './program/program.module';
+import { ProgramService } from './program/program.service';
+import { SessionController } from './session/session.controller';
+import { SessionModule } from './session/session.module';
+import { SessionService } from './session/session.service';
@Module({
imports: [
@@ -16,8 +36,37 @@ import { FileUtil } from './utils/pdf/fileUtil';
envFilePath: '.env',
}),
HttpModule,
+ PrismaModule,
+ EtsModule,
+
+ CourseModule,
+ CourseInstanceModule,
+ CoursePrerequisiteModule,
+ SessionModule,
+ ProgramModule,
+ ],
+ providers: [
+ PrismaService,
+ FileUtil,
+ HoraireCoursService,
+ PlanificationCoursService,
+
+ CourseService,
+ CourseInstanceService,
+ CoursePrerequisiteService,
+ ProgramService,
+ SessionService,
+ ],
+ controllers: [
+ AppController,
+ PdfController,
+ EtsController,
+
+ CourseController,
+ CourseInstanceController,
+ CoursePrerequisiteController,
+ ProgramController,
+ SessionController,
],
- providers: [HoraireCoursService, PlanificationCoursService, FileUtil],
- controllers: [PdfController],
})
export class AppModule {}
diff --git a/src/common/api-helper/ets/course/ets-course.controller.ts b/src/common/api-helper/ets/course/ets-course.controller.ts
new file mode 100644
index 0000000..681ee32
--- /dev/null
+++ b/src/common/api-helper/ets/course/ets-course.controller.ts
@@ -0,0 +1,26 @@
+import { Controller, Get, Param } from '@nestjs/common';
+
+import {
+ EtsCourseService,
+ IEtsCourse,
+ IEtsCoursesData,
+} from './ets-course.service';
+
+@Controller('ets/courses')
+export class EtsCourseController {
+ constructor(private readonly etsCourseService: EtsCourseService) {}
+
+ @Get()
+ public fetchAllCourses(): Promise {
+ return this.etsCourseService.fetchAllCourses();
+ }
+
+ @Get(':id')
+ public fetchCoursesById(@Param('id') id: string): Promise {
+ if (!id) {
+ throw new Error('The id parameter is required');
+ }
+
+ return this.etsCourseService.fetchCoursesById(id);
+ }
+}
diff --git a/src/common/api-helper/ets/course/ets-course.service.ts b/src/common/api-helper/ets/course/ets-course.service.ts
new file mode 100644
index 0000000..5cb3032
--- /dev/null
+++ b/src/common/api-helper/ets/course/ets-course.service.ts
@@ -0,0 +1,56 @@
+import { HttpService } from '@nestjs/axios';
+import { Injectable } from '@nestjs/common';
+import { firstValueFrom } from 'rxjs';
+
+import {
+ ETS_API_GET_ALL_COURSES,
+ ETS_API_GET_COURSES_BY_IDS,
+} from '../../../constants/url';
+
+export interface IEtsCoursesData {
+ id: number;
+ title: string;
+ code: string;
+ cycle: string | null;
+}
+
+export interface IEtsCourse extends IEtsCoursesData {
+ credits: string;
+}
+
+@Injectable()
+export class EtsCourseService {
+ constructor(private readonly httpService: HttpService) {}
+
+ // Fetches all courses
+ public async fetchAllCourses(): Promise {
+ const response = await firstValueFrom(
+ this.httpService.get(ETS_API_GET_ALL_COURSES),
+ );
+
+ const courses = response.data.results;
+ return courses.map((course: IEtsCoursesData) => ({
+ id: course.id,
+ title: course.title,
+ code: course.code,
+ cycle: course.cycle,
+ }));
+ }
+
+ // Fetches one or more courses by their ids
+ // The ids are passed as a string with comma-separated values, ex: "349682,349710"
+ public async fetchCoursesById(ids: string): Promise {
+ const response = await firstValueFrom(
+ this.httpService.get(`${ETS_API_GET_COURSES_BY_IDS}${ids}`),
+ );
+
+ const courses = response.data;
+ return courses.map((course: IEtsCourse) => ({
+ id: course.id,
+ title: course.title,
+ code: course.code,
+ cycle: course.cycle,
+ credits: course.credits,
+ }));
+ }
+}
diff --git a/src/common/api-helper/ets/ets.controller.ts b/src/common/api-helper/ets/ets.controller.ts
new file mode 100644
index 0000000..33ddd92
--- /dev/null
+++ b/src/common/api-helper/ets/ets.controller.ts
@@ -0,0 +1,35 @@
+import { Controller, Get, Param } from '@nestjs/common';
+
+import {
+ EtsCourseService,
+ IEtsCourse,
+ IEtsCoursesData,
+} from './course/ets-course.service';
+import { EtsProgramService } from './program/ets-program.service';
+
+@Controller('ets')
+export class EtsController {
+ constructor(
+ private readonly etsCourseService: EtsCourseService,
+ private readonly etsProgramService: EtsProgramService,
+ ) {}
+
+ @Get('courses')
+ public fetchAllCourses(): Promise {
+ return this.etsCourseService.fetchAllCourses();
+ }
+
+ @Get('courses/:id')
+ public fetchCoursesById(@Param('id') id: string): Promise {
+ if (!id) {
+ throw new Error('The id parameter is required');
+ }
+
+ return this.etsCourseService.fetchCoursesById(id);
+ }
+
+ @Get('programs')
+ public async fetchAllPrograms() {
+ return this.etsProgramService.fetchAllPrograms();
+ }
+}
diff --git a/src/common/api-helper/ets/ets.module.ts b/src/common/api-helper/ets/ets.module.ts
new file mode 100644
index 0000000..5d1588b
--- /dev/null
+++ b/src/common/api-helper/ets/ets.module.ts
@@ -0,0 +1,14 @@
+import { HttpModule } from '@nestjs/axios';
+import { Module } from '@nestjs/common';
+
+import { EtsCourseService } from './course/ets-course.service';
+import { EtsController } from './ets.controller';
+import { EtsProgramService } from './program/ets-program.service';
+
+@Module({
+ imports: [HttpModule],
+ controllers: [EtsController],
+ providers: [EtsCourseService, EtsProgramService],
+ exports: [EtsCourseService, EtsProgramService],
+})
+export class EtsModule {}
diff --git a/src/common/api-helper/ets/header.interceptor.ts b/src/common/api-helper/ets/header.interceptor.ts
new file mode 100644
index 0000000..0b222f8
--- /dev/null
+++ b/src/common/api-helper/ets/header.interceptor.ts
@@ -0,0 +1,26 @@
+import { HttpService } from '@nestjs/axios';
+import {
+ CallHandler,
+ ExecutionContext,
+ Injectable,
+ NestInterceptor,
+} from '@nestjs/common';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+@Injectable()
+export class HeaderInterceptor implements NestInterceptor {
+ constructor(private readonly httpService: HttpService) {
+ this.httpService.axiosRef.interceptors.request.use((config) => {
+ config.headers.Accept = 'application/json';
+ return config;
+ });
+ }
+
+ public intercept(
+ context: ExecutionContext,
+ next: CallHandler,
+ ): Observable {
+ return next.handle().pipe(map((data) => data));
+ }
+}
diff --git a/src/common/api-helper/ets/program/ets-program.service.ts b/src/common/api-helper/ets/program/ets-program.service.ts
new file mode 100644
index 0000000..78636df
--- /dev/null
+++ b/src/common/api-helper/ets/program/ets-program.service.ts
@@ -0,0 +1,49 @@
+import { HttpService } from '@nestjs/axios';
+import { Injectable } from '@nestjs/common';
+import { firstValueFrom } from 'rxjs';
+
+import { ETS_API_GET_ALL_PROGRAMS } from '../../../constants/url';
+
+type Program = {
+ id: number;
+ title: string;
+ cycle: string;
+ code: string;
+ credits: string;
+ types: number[];
+ url: string;
+};
+
+export interface ProgramType {
+ id: number;
+ title: string;
+}
+
+@Injectable()
+export class EtsProgramService {
+ constructor(private readonly httpService: HttpService) {}
+
+ public async fetchAllPrograms(): Promise<{
+ types: ProgramType[];
+ programs: Program[];
+ }> {
+ const response = await firstValueFrom(
+ this.httpService.get(ETS_API_GET_ALL_PROGRAMS),
+ );
+
+ const types: ProgramType[] = response.data.types;
+ const programs: Program[] = response.data.results.map(
+ (program: Program) => ({
+ id: program.id,
+ title: program.title,
+ cycle: program.cycle,
+ code: program.code,
+ credits: program.credits,
+ types: program.types,
+ url: program.url,
+ }),
+ );
+
+ return { types, programs };
+ }
+}
diff --git a/src/constants/error-messages.ts b/src/common/constants/error-messages.ts
similarity index 100%
rename from src/constants/error-messages.ts
rename to src/common/constants/error-messages.ts
diff --git a/src/common/constants/url.ts b/src/common/constants/url.ts
new file mode 100644
index 0000000..c879fbe
--- /dev/null
+++ b/src/common/constants/url.ts
@@ -0,0 +1,18 @@
+export const ETS_BASE_URL = 'https://www.etsmtl.ca/';
+
+/*
+ * ETS website
+ */
+export const PROGRAM_BASE_URL = `${ETS_BASE_URL}etude/`;
+export const COURSE_BASE_URL = `${ETS_BASE_URL}cours/`;
+
+/*
+ * ETS API
+ */
+export const ETS_API_BASE_URL = `${ETS_BASE_URL}api/`;
+
+export const ETS_API_GET_ALL_PROGRAMS = `${ETS_API_BASE_URL}search/programme-index`;
+export const ETS_API_GET_COURSES_BY_IDS = `${ETS_API_BASE_URL}courses/get?ids=`;
+export const ETS_API_GET_ALL_COURSES = `${ETS_API_BASE_URL}search/cours-index`;
+
+export const ETS_API_GET_ALL_DEPARTEMENTS = `${ETS_API_BASE_URL}search?s="departement="`;
diff --git a/src/common/exceptions/dtos/uuid.dto.ts b/src/common/exceptions/dtos/uuid.dto.ts
new file mode 100644
index 0000000..e2bb472
--- /dev/null
+++ b/src/common/exceptions/dtos/uuid.dto.ts
@@ -0,0 +1,6 @@
+import { IsUUID } from 'class-validator';
+
+export class UuidDto {
+ @IsUUID()
+ public id!: string;
+}
diff --git a/src/http-exception.filter.ts b/src/common/exceptions/http-exception.filter.ts
similarity index 100%
rename from src/http-exception.filter.ts
rename to src/common/exceptions/http-exception.filter.ts
diff --git a/src/pdf/pipes/course-code-validation-pipe.ts b/src/common/pipes/models/course/course-code-validation-pipe.ts
similarity index 100%
rename from src/pdf/pipes/course-code-validation-pipe.ts
rename to src/common/pipes/models/course/course-code-validation-pipe.ts
diff --git a/src/utils/pdf/fileUtil.ts b/src/common/utils/pdf/fileUtil.ts
similarity index 81%
rename from src/utils/pdf/fileUtil.ts
rename to src/common/utils/pdf/fileUtil.ts
index 6389b89..f543d2e 100644
--- a/src/utils/pdf/fileUtil.ts
+++ b/src/common/utils/pdf/fileUtil.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@nestjs/common';
+import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import fs from 'fs';
import path from 'path';
@@ -7,9 +7,11 @@ import path from 'path';
export class FileUtil {
constructor(private configService: ConfigService) {}
+ private logger = new Logger(FileUtil.name);
+
public writeDataToFile(data: T, fileName: string): Promise {
const pdfOutputPath =
- this.configService.get('pdfOutputPath') ||
+ this.configService.get('pdfOutputPath') ??
path.join(__dirname, fileName);
const filePath = path.join(pdfOutputPath, fileName);
@@ -31,12 +33,13 @@ export class FileUtil {
JSON.stringify(data, urlDecodeReplacer, 2),
(err) => {
if (err) {
- console.error('Error encountered while writing file: ', err);
+ this.logger.error('Error encountered while writing file: ', err);
reject(err);
} else {
- console.log(
+ this.logger.log(
`File "${fileName}" successfully written to "${filePath}"`,
);
+
resolve(filePath);
}
},
diff --git a/src/utils/pdf/parser/pdfParserUtil.ts b/src/common/utils/pdf/parser/pdfParserUtil.ts
similarity index 100%
rename from src/utils/pdf/parser/pdfParserUtil.ts
rename to src/common/utils/pdf/parser/pdfParserUtil.ts
diff --git a/src/utils/pdf/parser/textExtractorUtil.ts b/src/common/utils/pdf/parser/textExtractorUtil.ts
similarity index 100%
rename from src/utils/pdf/parser/textExtractorUtil.ts
rename to src/common/utils/pdf/parser/textExtractorUtil.ts
diff --git a/src/utils/url/urlUtils.ts b/src/common/utils/url/urlUtils.ts
similarity index 100%
rename from src/utils/url/urlUtils.ts
rename to src/common/utils/url/urlUtils.ts
diff --git a/src/pdf/pdf-parser/horaire/Group.ts b/src/common/website-helper/pdf/pdf-parser/horaire/Group.ts
similarity index 100%
rename from src/pdf/pdf-parser/horaire/Group.ts
rename to src/common/website-helper/pdf/pdf-parser/horaire/Group.ts
diff --git a/src/pdf/pdf-parser/horaire/HoraireCours.ts b/src/common/website-helper/pdf/pdf-parser/horaire/HoraireCours.ts
similarity index 95%
rename from src/pdf/pdf-parser/horaire/HoraireCours.ts
rename to src/common/website-helper/pdf/pdf-parser/horaire/HoraireCours.ts
index 29865a9..8ec2de9 100644
--- a/src/pdf/pdf-parser/horaire/HoraireCours.ts
+++ b/src/common/website-helper/pdf/pdf-parser/horaire/HoraireCours.ts
@@ -1,4 +1,4 @@
-import { CourseCodeValidationPipe } from '../../pipes/course-code-validation-pipe';
+import { CourseCodeValidationPipe } from '../../../../pipes/models/course/course-code-validation-pipe';
import { Group, IGroup } from './Group';
import { IHoraireCours } from './horaire-cours.types';
import { Period } from './Period';
diff --git a/src/pdf/pdf-parser/horaire/Period.ts b/src/common/website-helper/pdf/pdf-parser/horaire/Period.ts
similarity index 100%
rename from src/pdf/pdf-parser/horaire/Period.ts
rename to src/common/website-helper/pdf/pdf-parser/horaire/Period.ts
diff --git a/src/pdf/pdf-parser/horaire/horaire-cours.service.ts b/src/common/website-helper/pdf/pdf-parser/horaire/horaire-cours.service.ts
similarity index 94%
rename from src/pdf/pdf-parser/horaire/horaire-cours.service.ts
rename to src/common/website-helper/pdf/pdf-parser/horaire/horaire-cours.service.ts
index 8fe9aa8..facf404 100644
--- a/src/pdf/pdf-parser/horaire/horaire-cours.service.ts
+++ b/src/common/website-helper/pdf/pdf-parser/horaire/horaire-cours.service.ts
@@ -1,10 +1,10 @@
import { HttpService } from '@nestjs/axios';
-import { Injectable } from '@nestjs/common';
+import { Injectable, Logger } from '@nestjs/common';
import { Output, Page, Text } from 'pdf2json';
import { firstValueFrom } from 'rxjs';
-import { PdfParserUtil } from '../../../utils/pdf/parser/pdfParserUtil';
-import { TextExtractor } from '../../../utils/pdf/parser/textExtractorUtil';
+import { PdfParserUtil } from '../../../../utils/pdf/parser/pdfParserUtil';
+import { TextExtractor } from '../../../../utils/pdf/parser/textExtractorUtil';
import { Group } from './Group';
import { HoraireCours } from './HoraireCours';
import { Period } from './Period';
@@ -16,6 +16,8 @@ export class HoraireCoursService {
constructor(private httpService: HttpService) {}
+ private logger = new Logger(HoraireCoursService.name);
+
public async parsePdfFromUrl(pdfUrl: string) {
try {
const response = await firstValueFrom(
@@ -72,8 +74,7 @@ export class HoraireCoursService {
return serializedCourses;
} catch (err) {
- console.error('Error parsing pdf data: ' + err);
- console.log(err);
+ this.logger.error('Error parsing pdf data: ' + err);
throw new Error('Error processing PDF data: ' + err);
}
}
diff --git a/src/pdf/pdf-parser/horaire/horaire-cours.types.ts b/src/common/website-helper/pdf/pdf-parser/horaire/horaire-cours.types.ts
similarity index 100%
rename from src/pdf/pdf-parser/horaire/horaire-cours.types.ts
rename to src/common/website-helper/pdf/pdf-parser/horaire/horaire-cours.types.ts
diff --git a/src/pdf/pdf-parser/planification/Row.ts b/src/common/website-helper/pdf/pdf-parser/planification/Row.ts
similarity index 100%
rename from src/pdf/pdf-parser/planification/Row.ts
rename to src/common/website-helper/pdf/pdf-parser/planification/Row.ts
diff --git a/src/pdf/pdf-parser/planification/planification-cours.service.ts b/src/common/website-helper/pdf/pdf-parser/planification/planification-cours.service.ts
similarity index 73%
rename from src/pdf/pdf-parser/planification/planification-cours.service.ts
rename to src/common/website-helper/pdf/pdf-parser/planification/planification-cours.service.ts
index 9bb8b65..78a85df 100644
--- a/src/pdf/pdf-parser/planification/planification-cours.service.ts
+++ b/src/common/website-helper/pdf/pdf-parser/planification/planification-cours.service.ts
@@ -3,10 +3,10 @@ import { Injectable } from '@nestjs/common';
import { Fill, Output, Page, Text } from 'pdf2json';
import { firstValueFrom } from 'rxjs';
-import { PdfParserUtil } from '../../../utils/pdf/parser/pdfParserUtil';
-import { TextExtractor } from '../../../utils/pdf/parser/textExtractorUtil';
-import { CourseCodeValidationPipe } from '../../pipes/course-code-validation-pipe';
-import { PlanificationCours } from './planification-cours.types';
+import { CourseCodeValidationPipe } from '../../../../pipes/models/course/course-code-validation-pipe';
+import { PdfParserUtil } from '../../../../utils/pdf/parser/pdfParserUtil';
+import { TextExtractor } from '../../../../utils/pdf/parser/textExtractorUtil';
+import { ICoursePlanification } from './planification-cours.types';
import { Row } from './Row';
@Injectable()
@@ -17,7 +17,9 @@ export class PlanificationCoursService {
constructor(private httpService: HttpService) {}
- public async parsePdfFromUrl(pdfUrl: string): Promise {
+ public async parsePdfFromUrl(
+ pdfUrl: string,
+ ): Promise {
try {
const response = await firstValueFrom(
this.httpService.get(pdfUrl, { responseType: 'arraybuffer' }),
@@ -31,23 +33,23 @@ export class PlanificationCoursService {
}
}
- private parsePlanificationCoursPdf(
+ public parsePlanificationCoursPdf(
pdfBuffer: Buffer,
pdfUrl: string,
- ): Promise {
+ ): Promise {
return PdfParserUtil.parsePdfBuffer(pdfBuffer, (pdfData) =>
this.processPdfData(pdfData, pdfUrl),
);
}
- private processPdfData(
+ public processPdfData(
pdfData: Output,
pdfUrl: string,
- ): PlanificationCours[] {
+ ): ICoursePlanification[] {
try {
const headerCells: Row[] = this.parseHeaderCells(pdfData);
- const courses: PlanificationCours[] = [];
- let currentCourse: PlanificationCours = this.initializeCourse();
+ const courses: ICoursePlanification[] = [];
+ let currentCourse: ICoursePlanification = this.initializeCourse();
pdfData.Pages.forEach((page: Page) => {
page.Texts.forEach((textItem: Text) => {
@@ -66,17 +68,18 @@ export class PlanificationCoursService {
}
currentCourse = this.initializeCourse();
currentCourse.code = textContent;
- } else {
// Process other columns
- if (currentColumn && this.isSession(currentColumn.headerName)) {
- // Check and add availability
- if (this.isAvailability(textContent)) {
- const availabilityKey = currentColumn.headerName; // Example: 'E23'
- if (currentCourse.available[availabilityKey]) {
- currentCourse.available[availabilityKey] += ` ${textContent}`;
- } else {
- currentCourse.available[availabilityKey] = textContent;
- }
+ } else if (
+ currentColumn &&
+ this.isSession(currentColumn.headerName)
+ ) {
+ // Check and add availability
+ if (this.isAvailability(textContent)) {
+ const availabilityKey = currentColumn.headerName; // Example: 'E23'
+ if (currentCourse.available[availabilityKey]) {
+ currentCourse.available[availabilityKey] += ` ${textContent}`;
+ } else {
+ currentCourse.available[availabilityKey] = textContent;
}
}
}
@@ -96,7 +99,7 @@ export class PlanificationCoursService {
}
}
- private initializeCourse(): PlanificationCours {
+ private initializeCourse(): ICoursePlanification {
return {
code: '',
available: {},
@@ -104,7 +107,7 @@ export class PlanificationCoursService {
}
// Example: [ code, title, H24, E24, A24, H25, E25]
- private parseHeaderCells(pdfData: { Pages: Page[] }): Row[] {
+ public parseHeaderCells(pdfData: { Pages: Page[] }): Row[] {
const columns: Row[] = [];
const headerFills = pdfData.Pages[0].Fills.filter(
(fill: Fill) => fill.clr === 5,
diff --git a/src/pdf/pdf-parser/planification/planification-cours.types.ts b/src/common/website-helper/pdf/pdf-parser/planification/planification-cours.types.ts
similarity index 57%
rename from src/pdf/pdf-parser/planification/planification-cours.types.ts
rename to src/common/website-helper/pdf/pdf-parser/planification/planification-cours.types.ts
index 0f92bae..08e9c58 100644
--- a/src/pdf/pdf-parser/planification/planification-cours.types.ts
+++ b/src/common/website-helper/pdf/pdf-parser/planification/planification-cours.types.ts
@@ -1,4 +1,4 @@
-export interface PlanificationCours {
+export interface ICoursePlanification {
code: string;
available: Record;
}
diff --git a/src/pdf/pdf.controller.ts b/src/common/website-helper/pdf/pdf.controller.ts
similarity index 90%
rename from src/pdf/pdf.controller.ts
rename to src/common/website-helper/pdf/pdf.controller.ts
index 7f259f5..45ae9dd 100644
--- a/src/pdf/pdf.controller.ts
+++ b/src/common/website-helper/pdf/pdf.controller.ts
@@ -6,11 +6,11 @@ import {
Query,
} from '@nestjs/common';
-import { ERROR_MESSAGES } from '../constants/error-messages';
+import { ERROR_MESSAGES } from '../../constants/error-messages';
import { HoraireCoursService } from './pdf-parser/horaire/horaire-cours.service';
import { IHoraireCours } from './pdf-parser/horaire/horaire-cours.types';
import { PlanificationCoursService } from './pdf-parser/planification/planification-cours.service';
-import { PlanificationCours } from './pdf-parser/planification/planification-cours.types';
+import { ICoursePlanification } from './pdf-parser/planification/planification-cours.types';
@Controller('pdf')
export class PdfController {
@@ -46,7 +46,7 @@ export class PdfController {
@Get('planification-cours')
public async parsePlanificationCoursPdf(
@Query('program') programCode: string,
- ): Promise {
+ ): Promise {
if (!programCode) {
throw new HttpException(
ERROR_MESSAGES.REQUIRED_PDF_URL,
diff --git a/src/course-instance/course-instance.controller.ts b/src/course-instance/course-instance.controller.ts
new file mode 100644
index 0000000..e037d73
--- /dev/null
+++ b/src/course-instance/course-instance.controller.ts
@@ -0,0 +1,21 @@
+import { Controller, Get, Param } from '@nestjs/common';
+import { CourseInstance } from '@prisma/client';
+
+import { CourseInstanceService } from './course-instance.service';
+
+@Controller('course-instances')
+export class CourseInstanceController {
+ constructor(private readonly courseInstanceService: CourseInstanceService) {}
+
+ @Get(':id')
+ public getCourseInstance(
+ @Param('id') id: string,
+ ): Promise {
+ return this.courseInstanceService.getCourseInstance({ id });
+ }
+
+ @Get()
+ public getAllCourseInstances(): Promise {
+ return this.courseInstanceService.getAllCourseInstances();
+ }
+}
diff --git a/src/course-instance/course-instance.module.ts b/src/course-instance/course-instance.module.ts
new file mode 100644
index 0000000..5ab71a9
--- /dev/null
+++ b/src/course-instance/course-instance.module.ts
@@ -0,0 +1,12 @@
+import { Module } from '@nestjs/common';
+
+import { PrismaModule } from '../prisma/prisma.module';
+import { CourseInstanceController } from './course-instance.controller';
+import { CourseInstanceService } from './course-instance.service';
+
+@Module({
+ imports: [PrismaModule],
+ controllers: [CourseInstanceController],
+ providers: [CourseInstanceService],
+})
+export class CourseInstanceModule {}
diff --git a/src/course-instance/course-instance.service.ts b/src/course-instance/course-instance.service.ts
new file mode 100644
index 0000000..ee2b352
--- /dev/null
+++ b/src/course-instance/course-instance.service.ts
@@ -0,0 +1,99 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { CourseInstance, Prisma } from '@prisma/client';
+
+import { PrismaService } from '../prisma/prisma.service';
+
+@Injectable()
+export class CourseInstanceService {
+ constructor(private readonly prisma: PrismaService) {}
+
+ private logger = new Logger(CourseInstanceService.name);
+
+ public getCourseInstance(
+ courseInstanceWhereUniqueInput: Prisma.CourseInstanceWhereUniqueInput,
+ ): Promise {
+ this.logger.log('courseInstanceById');
+
+ return this.prisma.courseInstance.findUnique({
+ where: courseInstanceWhereUniqueInput,
+ });
+ }
+
+ public async getAllCourseInstances(): Promise {
+ this.logger.log('courseInstances');
+
+ const courseInstances = await this.prisma.courseInstance.findMany();
+ return courseInstances;
+ }
+
+ public async getCourseInstancesBySessions(
+ sessionIds: string[],
+ ): Promise {
+ this.logger.log('getCourseInstancesBySessions', JSON.stringify(sessionIds));
+
+ return this.prisma.courseInstance.findMany({
+ where: {
+ sessionId: {
+ in: sessionIds,
+ },
+ },
+ });
+ }
+
+ // This will be used to get all the infos about a course instance
+ public async getCourseInstancesByCourse(
+ courseId: string,
+ ): Promise {
+ this.logger.log('getCourseInstancesByCourse', courseId);
+
+ return this.prisma.courseInstance.findMany({
+ where: { courseId },
+ include: {
+ course: true,
+ },
+ });
+ }
+
+ public async createCourseInstance(
+ data: Prisma.CourseInstanceCreateInput,
+ ): Promise {
+ this.logger.log('createCourseInstance', data);
+ const courseInstance = await this.prisma.courseInstance.create({
+ data,
+ });
+ return courseInstance;
+ }
+
+ public async updateCourseInstance(params: {
+ where: Prisma.CourseInstanceWhereUniqueInput;
+ data: Prisma.CourseInstanceUpdateInput;
+ }): Promise {
+ this.logger.log('updateCourseInstance', params);
+
+ const { data, where } = params;
+ return this.prisma.courseInstance.update({
+ data,
+ where,
+ });
+ }
+
+ public async deleteCourseInstance(
+ where: Prisma.CourseInstanceWhereUniqueInput,
+ ): Promise {
+ this.logger.log('deleteCourseInstance', where);
+
+ return this.prisma.courseInstance.delete({
+ where,
+ });
+ }
+
+ public async deleteCourseInstancesBySession(
+ sessionId: string,
+ ): Promise {
+ this.logger.log('deleteCourseInstancesBySession', sessionId);
+
+ return this.prisma.courseInstance.deleteMany({
+ where: { sessionId },
+ });
+ }
+}
diff --git a/src/course-prerequisite/course-prerequisite.controller.ts b/src/course-prerequisite/course-prerequisite.controller.ts
new file mode 100644
index 0000000..1ebf347
--- /dev/null
+++ b/src/course-prerequisite/course-prerequisite.controller.ts
@@ -0,0 +1,20 @@
+import { Controller, Get, Param } from '@nestjs/common';
+
+import { CoursePrerequisiteService } from './course-prerequisite.service';
+
+@Controller('course-prerequisites')
+export class CoursePrerequisiteController {
+ constructor(
+ private readonly coursePrerequisiteService: CoursePrerequisiteService,
+ ) {}
+
+ @Get(':courseId')
+ public async getCoursePrerequisites(@Param('courseId') courseId: string) {
+ return this.coursePrerequisiteService.getPrerequisites(courseId);
+ }
+
+ @Get()
+ public async getAllCoursePrerequisites() {
+ return this.coursePrerequisiteService.getAllCoursePrerequisites();
+ }
+}
diff --git a/src/course-prerequisite/course-prerequisite.module.ts b/src/course-prerequisite/course-prerequisite.module.ts
new file mode 100644
index 0000000..3925edc
--- /dev/null
+++ b/src/course-prerequisite/course-prerequisite.module.ts
@@ -0,0 +1,12 @@
+import { Module } from '@nestjs/common';
+
+import { PrismaModule } from '../prisma/prisma.module';
+import { CoursePrerequisiteController } from './course-prerequisite.controller';
+import { CoursePrerequisiteService } from './course-prerequisite.service';
+
+@Module({
+ imports: [PrismaModule],
+ controllers: [CoursePrerequisiteController],
+ providers: [CoursePrerequisiteService],
+})
+export class CoursePrerequisiteModule {}
diff --git a/src/course-prerequisite/course-prerequisite.service.ts b/src/course-prerequisite/course-prerequisite.service.ts
new file mode 100644
index 0000000..b6fe33e
--- /dev/null
+++ b/src/course-prerequisite/course-prerequisite.service.ts
@@ -0,0 +1,83 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { CoursePrerequisite, Prisma } from '@prisma/client';
+
+import { PrismaService } from '../prisma/prisma.service';
+
+@Injectable()
+export class CoursePrerequisiteService {
+ constructor(private readonly prisma: PrismaService) {}
+
+ private logger = new Logger(CoursePrerequisiteService.name);
+
+ public async getPrerequisites(courseId: string) {
+ this.logger.log('coursePrerequisiteById');
+
+ return this.prisma.coursePrerequisite.findMany({
+ where: { courseId },
+ include: { prerequisite: true },
+ });
+ }
+
+ public async getAllCoursePrerequisites() {
+ this.logger.log('getAllCoursePrerequisites');
+
+ return this.prisma.coursePrerequisite.findMany({
+ include: { prerequisite: true },
+ });
+ }
+
+ private async createCoursePrerequisite(
+ data: Prisma.CoursePrerequisiteCreateInput,
+ ): Promise {
+ this.logger.log('createCoursePrerequisite', data);
+
+ const courseId = data.course.connect?.id;
+ const prerequisiteId = data.prerequisite.connect?.id;
+
+ if (!courseId || !prerequisiteId) {
+ throw new Error('courseId and prerequisiteId must be provided.');
+ }
+
+ const existingPrerequisite =
+ await this.prisma.coursePrerequisite.findUnique({
+ where: {
+ courseId_prerequisiteId: {
+ courseId,
+ prerequisiteId,
+ },
+ },
+ });
+
+ if (existingPrerequisite) {
+ return existingPrerequisite;
+ }
+
+ return this.prisma.coursePrerequisite.create({
+ data,
+ });
+ }
+
+ public async createCoursePrerequisites(
+ data: Prisma.CoursePrerequisiteCreateInput[],
+ ): Promise {
+ this.logger.log('ensurePrerequisitesExist', data);
+
+ const ensuredPrerequisites = await Promise.all(
+ data.map((prerequisiteData) =>
+ this.createCoursePrerequisite(prerequisiteData),
+ ),
+ );
+
+ return ensuredPrerequisites;
+ }
+
+ public async deleteCoursePrerequisite(
+ where: Prisma.CoursePrerequisiteWhereUniqueInput,
+ ): Promise {
+ this.logger.log('deleteCoursePrerequisite', where);
+
+ return this.prisma.coursePrerequisite.delete({
+ where,
+ });
+ }
+}
diff --git a/src/course/course.controller.ts b/src/course/course.controller.ts
new file mode 100644
index 0000000..b0dc1eb
--- /dev/null
+++ b/src/course/course.controller.ts
@@ -0,0 +1,18 @@
+import { Controller, Get, Param } from '@nestjs/common';
+
+import { CourseService } from './course.service';
+
+@Controller('courses')
+export class CourseController {
+ constructor(private readonly courseService: CourseService) {}
+
+ @Get(':id')
+ public getCourse(@Param('id') id: string) {
+ return this.courseService.getCourse({ id });
+ }
+
+ @Get()
+ public getAllCourses() {
+ return this.courseService.getAllCourses();
+ }
+}
diff --git a/src/course/course.module.ts b/src/course/course.module.ts
new file mode 100644
index 0000000..35c6d1c
--- /dev/null
+++ b/src/course/course.module.ts
@@ -0,0 +1,12 @@
+import { Module } from '@nestjs/common';
+
+import { PrismaModule } from '../prisma/prisma.module';
+import { CourseController } from './course.controller';
+import { CourseService } from './course.service';
+
+@Module({
+ imports: [PrismaModule],
+ controllers: [CourseController],
+ providers: [CourseService],
+})
+export class CourseModule {}
diff --git a/src/course/course.service.ts b/src/course/course.service.ts
new file mode 100644
index 0000000..cae3536
--- /dev/null
+++ b/src/course/course.service.ts
@@ -0,0 +1,128 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { Course, Prisma, Session } from '@prisma/client';
+
+import { PrismaService } from '../prisma/prisma.service';
+
+@Injectable()
+export class CourseService {
+ constructor(private readonly prisma: PrismaService) {}
+
+ private logger = new Logger(CourseService.name);
+
+ public async getCourse(
+ courseWhereUniqueInput: Prisma.CourseWhereUniqueInput,
+ ): Promise {
+ this.logger.log('courseById', courseWhereUniqueInput);
+
+ const course = await this.prisma.course.findUnique({
+ where: courseWhereUniqueInput,
+ });
+
+ return course;
+ }
+
+ public async getAllCourses() {
+ this.logger.log('getAllCourses');
+
+ return this.prisma.course.findMany();
+ }
+
+ public async getCoursesByProgram(programId: string): Promise {
+ this.logger.log('getCoursesByProgram', programId);
+
+ return this.prisma.course.findMany({
+ where: {
+ programs: {
+ some: {
+ programId,
+ },
+ },
+ },
+ });
+ }
+
+ public async getCourseAvailability(
+ courseId: string,
+ ): Promise<{ session: Session; available: boolean }[]> {
+ this.logger.log('getCourseAvailability', courseId);
+
+ const courseInstances = await this.prisma.courseInstance.findMany({
+ where: { courseId },
+ include: {
+ session: true,
+ },
+ });
+
+ const sessionAvailability = courseInstances.map((instance) => ({
+ session: instance.session,
+ available: true,
+ }));
+
+ return sessionAvailability;
+ }
+
+ public async createCourse(data: Prisma.CourseCreateInput): Promise {
+ this.logger.log('createCourse', data);
+
+ const course = await this.prisma.course.create({
+ data,
+ });
+
+ return course;
+ }
+
+ public async updateCourse(params: {
+ where: Prisma.CourseWhereUniqueInput;
+ data: Prisma.CourseUpdateInput;
+ }): Promise {
+ this.logger.log('updateCourse', params);
+
+ const { data, where } = params;
+ return this.prisma.course.update({
+ data,
+ where,
+ });
+ }
+
+ private async upsertCourse(
+ courseData: Prisma.CourseCreateInput,
+ ): Promise {
+ const existingCourse = await this.prisma.course.findUnique({
+ where: { id: courseData.id },
+ });
+
+ if (existingCourse) {
+ if (JSON.stringify(existingCourse) !== JSON.stringify(courseData)) {
+ return this.updateCourse({
+ where: { id: courseData.id },
+ data: courseData,
+ });
+ }
+
+ return existingCourse;
+ }
+ return this.createCourse(courseData);
+ }
+
+ public async upsertCourses(
+ data: Prisma.CourseCreateInput[],
+ ): Promise {
+ this.logger.log('upsertCourses', data);
+
+ const upsertedCourses = await Promise.all(
+ data.map((courseData) => this.upsertCourse(courseData)),
+ );
+
+ return upsertedCourses;
+ }
+
+ public async deleteCourse(
+ where: Prisma.CourseWhereUniqueInput,
+ ): Promise {
+ this.logger.log('deleteCourse', where);
+
+ return this.prisma.course.delete({
+ where,
+ });
+ }
+}
diff --git a/src/main.ts b/src/main.ts
index d9b4fc9..7cb027e 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,7 +1,7 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
-import { HttpExceptionFilter } from './http-exception.filter';
+import { HttpExceptionFilter } from './common/exceptions/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
diff --git a/src/prisma/prisma.module.ts b/src/prisma/prisma.module.ts
new file mode 100644
index 0000000..b38960e
--- /dev/null
+++ b/src/prisma/prisma.module.ts
@@ -0,0 +1,11 @@
+import { Module } from '@nestjs/common';
+
+import { PrismaService } from './prisma.service';
+
+@Module({
+ imports: [],
+ controllers: [],
+ providers: [PrismaService],
+ exports: [PrismaService],
+})
+export class PrismaModule {}
diff --git a/src/prisma/prisma.service.ts b/src/prisma/prisma.service.ts
new file mode 100644
index 0000000..275dfca
--- /dev/null
+++ b/src/prisma/prisma.service.ts
@@ -0,0 +1,16 @@
+import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
+import { PrismaClient } from '@prisma/client';
+
+@Injectable()
+export class PrismaService
+ extends PrismaClient
+ implements OnModuleInit, OnModuleDestroy
+{
+ public async onModuleInit() {
+ await this.$connect();
+ }
+
+ public async onModuleDestroy() {
+ await this.$disconnect();
+ }
+}
diff --git a/src/program/program.controller.ts b/src/program/program.controller.ts
new file mode 100644
index 0000000..bb35b3a
--- /dev/null
+++ b/src/program/program.controller.ts
@@ -0,0 +1,27 @@
+import {
+ Controller,
+ Get,
+ Param,
+ UsePipes,
+ ValidationPipe,
+} from '@nestjs/common';
+import { Program } from '@prisma/client';
+
+import { UuidDto } from '../common/exceptions/dtos/uuid.dto';
+import { ProgramService } from './program.service';
+
+@Controller('programs')
+export class ProgramController {
+ constructor(private readonly programService: ProgramService) {}
+
+ @Get(':id')
+ @UsePipes(new ValidationPipe({ transform: true }))
+ public async getProgram(@Param() { id }: UuidDto): Promise {
+ return this.programService.getProgram({ id });
+ }
+
+ @Get()
+ public async getAllPrograms(): Promise {
+ return this.programService.getAllPrograms();
+ }
+}
diff --git a/src/program/program.module.ts b/src/program/program.module.ts
new file mode 100644
index 0000000..3e6cd69
--- /dev/null
+++ b/src/program/program.module.ts
@@ -0,0 +1,12 @@
+import { Module } from '@nestjs/common';
+
+import { PrismaModule } from '../prisma/prisma.module';
+import { ProgramController } from './program.controller';
+import { ProgramService } from './program.service';
+
+@Module({
+ imports: [PrismaModule],
+ controllers: [ProgramController],
+ providers: [ProgramService],
+})
+export class ProgramModule {}
diff --git a/src/program/program.service.ts b/src/program/program.service.ts
new file mode 100644
index 0000000..9e4d4d5
--- /dev/null
+++ b/src/program/program.service.ts
@@ -0,0 +1,96 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { Prisma, Program, ProgramType } from '@prisma/client';
+
+import { PrismaService } from '../prisma/prisma.service';
+
+@Injectable()
+export class ProgramService {
+ constructor(private readonly prisma: PrismaService) {}
+
+ private logger = new Logger(ProgramService.name);
+
+ public async getProgram(
+ programWhereUniqueInput: Prisma.ProgramWhereUniqueInput,
+ ): Promise {
+ this.logger.log('getProgram', programWhereUniqueInput);
+
+ return this.prisma.program.findUnique({
+ where: programWhereUniqueInput,
+ });
+ }
+
+ public async getAllPrograms(): Promise {
+ this.logger.log('getAllPrograms');
+
+ return this.prisma.program.findMany();
+ }
+
+ public async createProgram(
+ data: Prisma.ProgramCreateInput,
+ ): Promise {
+ this.logger.log('createProgram', data);
+
+ return this.prisma.program.create({
+ data: {
+ ...data,
+ programTypeIds: data.programTypeIds ?? '[]',
+ },
+ });
+ }
+
+ public async upsertProgram(
+ data: Prisma.ProgramCreateInput,
+ ): Promise {
+ this.logger.log('upsertProgram', data);
+
+ return this.prisma.program.upsert({
+ where: { id: data.id },
+ update: {
+ ...data,
+ updatedAt: new Date(),
+ programTypeIds: data.programTypeIds ?? '[]',
+ },
+ create: {
+ ...data,
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ programTypeIds: data.programTypeIds ?? '[]',
+ },
+ });
+ }
+
+ public async upsertPrograms(
+ data: Prisma.ProgramCreateInput[],
+ ): Promise {
+ this.logger.log('upsertPrograms', data);
+ return Promise.all(
+ data.map((programData) => this.upsertProgram(programData)),
+ );
+ }
+
+ public async createProgramTypes(types: ProgramType[]): Promise {
+ this.logger.log('createProgramTypes', types);
+
+ await Promise.all(
+ types.map((type) =>
+ this.prisma.programType.upsert({
+ where: { id: type.id },
+ update: { title: type.title },
+ create: {
+ id: type.id,
+ title: type.title,
+ },
+ }),
+ ),
+ );
+ }
+
+ public async deleteProgram(
+ where: Prisma.ProgramWhereUniqueInput,
+ ): Promise {
+ this.logger.log('deleteProgram', JSON.stringify(where));
+ return this.prisma.program.delete({
+ where,
+ });
+ }
+}
diff --git a/src/session/session.controller.ts b/src/session/session.controller.ts
new file mode 100644
index 0000000..66813f5
--- /dev/null
+++ b/src/session/session.controller.ts
@@ -0,0 +1,27 @@
+import {
+ Controller,
+ Get,
+ Param,
+ UsePipes,
+ ValidationPipe,
+} from '@nestjs/common';
+import { Session } from '@prisma/client';
+
+import { UuidDto } from '../common/exceptions/dtos/uuid.dto';
+import { SessionService } from './session.service';
+
+@Controller('sessions')
+export class SessionController {
+ constructor(private readonly sessionService: SessionService) {}
+
+ @Get(':id')
+ @UsePipes(new ValidationPipe({ transform: true }))
+ public async getSession(@Param() { id }: UuidDto): Promise {
+ return this.sessionService.getSession(id);
+ }
+
+ @Get()
+ public async getAllSessions(): Promise {
+ return this.sessionService.getAllSessions();
+ }
+}
diff --git a/src/session/session.module.ts b/src/session/session.module.ts
new file mode 100644
index 0000000..e429ff6
--- /dev/null
+++ b/src/session/session.module.ts
@@ -0,0 +1,12 @@
+import { Module } from '@nestjs/common';
+
+import { PrismaModule } from '../prisma/prisma.module';
+import { SessionController } from './session.controller';
+import { SessionService } from './session.service';
+
+@Module({
+ imports: [PrismaModule],
+ controllers: [SessionController],
+ providers: [SessionService],
+})
+export class SessionModule {}
diff --git a/src/session/session.service.ts b/src/session/session.service.ts
new file mode 100644
index 0000000..74abd42
--- /dev/null
+++ b/src/session/session.service.ts
@@ -0,0 +1,60 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { Prisma, Session, Trimester } from '@prisma/client';
+
+import { PrismaService } from '../prisma/prisma.service';
+
+@Injectable()
+export class SessionService {
+ constructor(private readonly prisma: PrismaService) {}
+
+ private logger = new Logger(SessionService.name);
+
+ public async getSession(id: string): Promise {
+ this.logger.log('getSession', id);
+
+ return this.prisma.session.findUnique({
+ where: { id },
+ });
+ }
+
+ public async getAllSessions(): Promise {
+ return this.prisma.session.findMany();
+ }
+
+ public async createSession(
+ data: Prisma.SessionCreateInput,
+ ): Promise {
+ return this.prisma.session.create({
+ data,
+ });
+ }
+
+ public async upsertSession(
+ id: string,
+ data: Prisma.SessionUpdateInput,
+ ): Promise {
+ const createSessionDto: Prisma.SessionCreateInput = {
+ ...data,
+ id,
+ trimester: data.trimester as Trimester,
+ year: data.year as number,
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ };
+
+ return this.prisma.session.upsert({
+ where: { id },
+ update: {
+ ...data,
+ updatedAt: new Date(),
+ },
+ create: createSessionDto,
+ });
+ }
+
+ public async removeSession(id: string): Promise {
+ return this.prisma.session.delete({
+ where: { id },
+ });
+ }
+}
diff --git a/test/common/api-helper/ets/course/ets-course.service.spec.ts b/test/common/api-helper/ets/course/ets-course.service.spec.ts
new file mode 100644
index 0000000..b26bfbe
--- /dev/null
+++ b/test/common/api-helper/ets/course/ets-course.service.spec.ts
@@ -0,0 +1,84 @@
+import { HttpService } from '@nestjs/axios';
+import { Test, TestingModule } from '@nestjs/testing';
+import { AxiosResponse } from 'axios';
+import { of } from 'rxjs';
+
+import {
+ EtsCourseService,
+ IEtsCourse,
+ IEtsCoursesData,
+} from '../../../../../src/common/api-helper/ets/course/ets-course.service';
+
+describe('EtsCourseService', () => {
+ let service: EtsCourseService;
+ let httpService: HttpService;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [
+ EtsCourseService,
+ {
+ provide: HttpService,
+ useValue: {
+ get: jest.fn(),
+ },
+ },
+ ],
+ }).compile();
+
+ service = module.get(EtsCourseService);
+ httpService = module.get(HttpService);
+ });
+
+ it('should fetch all courses', async () => {
+ const mockCourses: IEtsCoursesData[] = [
+ { id: 1, title: 'Course 1', code: 'C1', cycle: 'Cycle 1' },
+ { id: 2, title: 'Course 2', code: 'C2', cycle: 'Cycle 2' },
+ ];
+
+ const mockResponse: AxiosResponse<{ results: IEtsCoursesData[] }> = {
+ data: { results: mockCourses },
+ status: 200,
+ statusText: 'OK',
+ headers: {},
+ config: {
+ headers: {
+ get: () => 'application/json',
+ set: () => {},
+ has: () => true,
+ delete: () => true,
+ },
+ } as never,
+ };
+ jest.spyOn(httpService, 'get').mockReturnValue(of(mockResponse));
+
+ const result = await service.fetchAllCourses();
+ expect(result).toEqual(mockCourses);
+ });
+
+ it('should fetch courses by ids', async () => {
+ const mockCourses: IEtsCourse[] = [
+ { id: 1, title: 'Course 1', code: 'C1', cycle: 'Cycle 1', credits: '3' },
+ { id: 2, title: 'Course 2', code: 'C2', cycle: 'Cycle 2', credits: '4' },
+ ];
+
+ const mockResponse: AxiosResponse = {
+ data: mockCourses,
+ status: 200,
+ statusText: 'OK',
+ headers: {},
+ config: {
+ headers: {
+ get: () => 'application/json',
+ set: () => {},
+ has: () => true,
+ delete: () => true,
+ },
+ } as never,
+ };
+ jest.spyOn(httpService, 'get').mockReturnValue(of(mockResponse));
+
+ const result = await service.fetchCoursesById('1,2');
+ expect(result).toEqual(mockCourses);
+ });
+});
diff --git a/test/common/website-helper/pdf/pdf-parser/planification/planification-cours.service.test.ts b/test/common/website-helper/pdf/pdf-parser/planification/planification-cours.service.test.ts
new file mode 100644
index 0000000..009bcd3
--- /dev/null
+++ b/test/common/website-helper/pdf/pdf-parser/planification/planification-cours.service.test.ts
@@ -0,0 +1,56 @@
+import { HttpService } from '@nestjs/axios';
+import { Test, TestingModule } from '@nestjs/testing';
+import { AxiosResponse } from 'axios';
+import { of } from 'rxjs';
+
+import { PlanificationCoursService } from '../../../../../../src/common/website-helper/pdf/pdf-parser/planification/planification-cours.service';
+
+jest.mock('@nestjs/axios');
+jest.mock(
+ '../../../../../../src/common/pipes/models/course/course-code-validation-pipe',
+);
+jest.mock('../../../../../../src/common/utils/pdf/parser/pdfParserUtil');
+jest.mock('../../../../../../src/common/utils/pdf/parser/textExtractorUtil');
+
+describe('PlanificationCoursService', () => {
+ let service: PlanificationCoursService;
+ let httpService: HttpService;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [PlanificationCoursService, HttpService],
+ }).compile();
+
+ service = module.get(PlanificationCoursService);
+ httpService = module.get(HttpService);
+ });
+
+ describe('parsePdfFromUrl', () => {
+ it('should fetch and parse the PDF', async () => {
+ const pdfUrl =
+ 'https://horaire.etsmtl.ca/Horairepublication/Planification-7084.pdf';
+ const pdfBuffer = Buffer.from('sample pdf data');
+ const response: AxiosResponse = {
+ data: pdfBuffer,
+ status: 200,
+ statusText: 'OK',
+ headers: {} as never,
+ config: { headers: {} as never },
+ };
+
+ jest.spyOn(httpService, 'get').mockReturnValue(of(response));
+ jest.spyOn(service, 'parsePlanificationCoursPdf').mockResolvedValue([]);
+
+ const result = await service.parsePdfFromUrl(pdfUrl);
+
+ expect(httpService.get).toHaveBeenCalledWith(pdfUrl, {
+ responseType: 'arraybuffer',
+ });
+ expect(service.parsePlanificationCoursPdf).toHaveBeenCalledWith(
+ pdfBuffer,
+ pdfUrl,
+ );
+ expect(result).toEqual([]);
+ });
+ });
+});
diff --git a/test/course-instance/course-instance.controller.spec.ts b/test/course-instance/course-instance.controller.spec.ts
new file mode 100644
index 0000000..e1207ff
--- /dev/null
+++ b/test/course-instance/course-instance.controller.spec.ts
@@ -0,0 +1,22 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { CourseInstanceController } from '../../src/course-instance/course-instance.controller';
+import { CourseInstanceService } from '../../src/course-instance/course-instance.service';
+import { PrismaService } from '../../src/prisma/prisma.service';
+
+describe('CourseInstanceController', () => {
+ let controller: CourseInstanceController;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ controllers: [CourseInstanceController],
+ providers: [PrismaService, CourseInstanceService],
+ }).compile();
+
+ controller = module.get(CourseInstanceController);
+ });
+
+ it('should be defined', () => {
+ expect(controller).toBeDefined();
+ });
+});
diff --git a/test/course-instance/course-instance.service.spec.ts b/test/course-instance/course-instance.service.spec.ts
new file mode 100644
index 0000000..84ae409
--- /dev/null
+++ b/test/course-instance/course-instance.service.spec.ts
@@ -0,0 +1,20 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { CourseInstanceService } from '../../src/course-instance/course-instance.service';
+import { PrismaService } from '../../src/prisma/prisma.service';
+
+describe('CourseInstanceService', () => {
+ let service: CourseInstanceService;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [CourseInstanceService, PrismaService],
+ }).compile();
+
+ service = module.get(CourseInstanceService);
+ });
+
+ it('should be defined', () => {
+ expect(service).toBeDefined();
+ });
+});
diff --git a/test/course-prerequisite/course-prerequisite.controller.spec.ts b/test/course-prerequisite/course-prerequisite.controller.spec.ts
new file mode 100644
index 0000000..da1731c
--- /dev/null
+++ b/test/course-prerequisite/course-prerequisite.controller.spec.ts
@@ -0,0 +1,35 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { CoursePrerequisiteController } from '../../src/course-prerequisite/course-prerequisite.controller';
+import { CoursePrerequisiteService } from '../../src/course-prerequisite/course-prerequisite.service';
+import { PrismaService } from '../../src/prisma/prisma.service';
+
+describe('CoursePrerequisiteController', () => {
+ let controller: CoursePrerequisiteController;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ controllers: [CoursePrerequisiteController],
+ providers: [
+ CoursePrerequisiteService,
+ {
+ provide: PrismaService,
+ useValue: {
+ coursePrerequisite: {
+ findMany: jest.fn(),
+ findUnique: jest.fn(),
+ },
+ },
+ },
+ ],
+ }).compile();
+
+ controller = module.get(
+ CoursePrerequisiteController,
+ );
+ });
+
+ it('should be defined', () => {
+ expect(controller).toBeDefined();
+ });
+});
diff --git a/test/course-prerequisite/course-prerequisite.service.spec.ts b/test/course-prerequisite/course-prerequisite.service.spec.ts
new file mode 100644
index 0000000..08f9c00
--- /dev/null
+++ b/test/course-prerequisite/course-prerequisite.service.spec.ts
@@ -0,0 +1,34 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { CoursePrerequisiteService } from '../../src/course-prerequisite/course-prerequisite.service';
+import { PrismaService } from '../../src/prisma/prisma.service';
+
+describe('CoursePrerequisiteService', () => {
+ let service: CoursePrerequisiteService;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [
+ CoursePrerequisiteService,
+ {
+ provide: PrismaService,
+ useValue: {
+ coursePrerequisite: {
+ findMany: jest.fn(),
+ findUnique: jest.fn(),
+ create: jest.fn(),
+ update: jest.fn(),
+ delete: jest.fn(),
+ },
+ },
+ },
+ ],
+ }).compile();
+
+ service = module.get(CoursePrerequisiteService);
+ });
+
+ it('should be defined', () => {
+ expect(service).toBeDefined();
+ });
+});
diff --git a/test/course/course.controller.spec.ts b/test/course/course.controller.spec.ts
new file mode 100644
index 0000000..557ce1b
--- /dev/null
+++ b/test/course/course.controller.spec.ts
@@ -0,0 +1,22 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { CourseController } from '../../src/course/course.controller';
+import { CourseService } from '../../src/course/course.service';
+import { PrismaService } from '../../src/prisma/prisma.service';
+
+describe('CourseController', () => {
+ let controller: CourseController;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ controllers: [CourseController],
+ providers: [PrismaService, CourseService],
+ }).compile();
+
+ controller = module.get(CourseController);
+ });
+
+ it('should be defined', () => {
+ expect(controller).toBeDefined();
+ });
+});
diff --git a/test/course/course.service.spec.ts b/test/course/course.service.spec.ts
new file mode 100644
index 0000000..7bc86de
--- /dev/null
+++ b/test/course/course.service.spec.ts
@@ -0,0 +1,85 @@
+import { INestApplication, ValidationPipe } from '@nestjs/common';
+import { Test, TestingModule } from '@nestjs/testing';
+import { Course, Session } from '@prisma/client';
+import { useContainer } from 'class-validator';
+import * as request from 'supertest';
+
+import { AppModule } from '../../src/app.module';
+import { PrismaService } from '../../src/prisma/prisma.service';
+
+describe('CourseService (e2e)', () => {
+ let app: INestApplication;
+ let prisma: PrismaService;
+ let course: Course;
+ let session: Session;
+
+ const courseShape = expect.objectContaining({
+ id: expect.any(String),
+ programId: expect.any(String),
+ code: expect.any(String),
+ title: expect.any(String),
+ description: expect.any(String),
+ credits: expect.any(Number),
+ });
+
+ beforeAll(async () => {
+ const moduleFixture: TestingModule = await Test.createTestingModule({
+ imports: [AppModule],
+ }).compile();
+
+ app = moduleFixture.createNestApplication();
+ prisma = app.get(PrismaService);
+
+ useContainer(app.select(AppModule), { fallbackOnErrors: true });
+ app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
+
+ await app.init();
+
+ session = await prisma.session.create({
+ data: {
+ trimester: 'A',
+ year: 2021,
+ },
+ });
+
+ course = await prisma.course.create({
+ data: {
+ id: '1',
+ programId: '1',
+ code: 'CS101',
+ title: 'Introduction to Computer Science',
+ description: 'A basic course on computer science',
+ credits: 3,
+ },
+ });
+ });
+
+ afterAll(async () => {
+ await prisma.course.deleteMany();
+ await prisma.session.deleteMany();
+ await prisma.$disconnect();
+ await app.close();
+ });
+
+ describe('GET /courses', () => {
+ it('returns a list of courses', async () => {
+ const { status, body } = await request(app.getHttpServer()).get(
+ '/courses',
+ );
+
+ expect(status).toBe(200);
+ expect(body).toStrictEqual(expect.arrayContaining([courseShape]));
+ });
+ });
+
+ describe('GET /courses/:id', () => {
+ it('returns a course', async () => {
+ const { status, body } = await request(app.getHttpServer()).get(
+ `/courses/${course.id}`,
+ );
+
+ expect(status).toBe(200);
+ expect(body).toStrictEqual(courseShape);
+ });
+ });
+});
diff --git a/test/program/program.controller.spec.ts b/test/program/program.controller.spec.ts
new file mode 100644
index 0000000..4120ce6
--- /dev/null
+++ b/test/program/program.controller.spec.ts
@@ -0,0 +1,22 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { PrismaService } from '../../src/prisma/prisma.service';
+import { ProgramController } from '../../src/program/program.controller';
+import { ProgramService } from '../../src/program/program.service';
+
+describe('ProgramController', () => {
+ let controller: ProgramController;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ controllers: [ProgramController],
+ providers: [PrismaService, ProgramService],
+ }).compile();
+
+ controller = module.get(ProgramController);
+ });
+
+ it('should be defined', () => {
+ expect(controller).toBeDefined();
+ });
+});
diff --git a/test/program/program.service.spec.ts b/test/program/program.service.spec.ts
new file mode 100644
index 0000000..717b438
--- /dev/null
+++ b/test/program/program.service.spec.ts
@@ -0,0 +1,20 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { PrismaService } from '../../src/prisma/prisma.service';
+import { ProgramService } from '../../src/program/program.service';
+
+describe('ProgramService', () => {
+ let service: ProgramService;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [PrismaService, ProgramService],
+ }).compile();
+
+ service = module.get(ProgramService);
+ });
+
+ it('should be defined', () => {
+ expect(service).toBeDefined();
+ });
+});
diff --git a/test/session/session.controller.spec.ts b/test/session/session.controller.spec.ts
new file mode 100644
index 0000000..2358a37
--- /dev/null
+++ b/test/session/session.controller.spec.ts
@@ -0,0 +1,22 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { PrismaService } from '../../src/prisma/prisma.service';
+import { SessionController } from '../../src/session/session.controller';
+import { SessionService } from '../../src/session/session.service';
+
+describe('SessionController', () => {
+ let controller: SessionController;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ controllers: [SessionController],
+ providers: [PrismaService, SessionService],
+ }).compile();
+
+ controller = module.get(SessionController);
+ });
+
+ it('should be defined', () => {
+ expect(controller).toBeDefined();
+ });
+});
diff --git a/test/session/session.service.spec.ts b/test/session/session.service.spec.ts
new file mode 100644
index 0000000..386a45e
--- /dev/null
+++ b/test/session/session.service.spec.ts
@@ -0,0 +1,20 @@
+import { Test, TestingModule } from '@nestjs/testing';
+
+import { PrismaService } from '../../src/prisma/prisma.service';
+import { SessionService } from '../../src/session/session.service';
+
+describe('SessionService', () => {
+ let service: SessionService;
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [PrismaService, SessionService],
+ }).compile();
+
+ service = module.get(SessionService);
+ });
+
+ it('should be defined', () => {
+ expect(service).toBeDefined();
+ });
+});
diff --git a/tsconfig.json b/tsconfig.json
index e605c69..22ba488 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,6 +13,6 @@
"incremental": true,
"strict": true,
"strictBindCallApply": false,
- "typeRoots": ["node_modules/@types"],
+ "typeRoots": ["node_modules/@types"]
}
}
diff --git a/yarn.lock b/yarn.lock
index cddfb0d..dad770e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -338,6 +338,11 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+"@braintree/sanitize-url@^6.0.1":
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783"
+ integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==
+
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -681,6 +686,16 @@
resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe"
integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==
+"@mermaid-js/mermaid-cli@^10.6.1":
+ version "10.9.1"
+ resolved "https://registry.yarnpkg.com/@mermaid-js/mermaid-cli/-/mermaid-cli-10.9.1.tgz#9ccd0a9fdb09275817617665ee5432d352c838cc"
+ integrity sha512-ajpGUKmB5YbRRzrFR+0dbykF9mTvce4FpHWGYPYTry8ZsOgP6h7SUnojyCJDGgbReCnArODCM8L212qIcxshIw==
+ dependencies:
+ chalk "^5.0.1"
+ commander "^10.0.0"
+ mermaid "^10.8.0"
+ puppeteer "^19.0.0"
+
"@mole-inc/bin-wrapper@^8.0.1":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz#d7fd0ceb1cfa8a855293a3ed9d7d135f4d442f0e"
@@ -759,6 +774,11 @@
path-to-regexp "3.2.0"
tslib "2.6.2"
+"@nestjs/mapped-types@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz#485d6b44e19779c98d04e52bd1d2bcc7001df0ea"
+ integrity sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==
+
"@nestjs/platform-express@^10.0.0":
version "10.3.7"
resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-10.3.7.tgz#ae3fc59609bdc0ffc5029a6e74d59a5d1e257eef"
@@ -828,46 +848,72 @@
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
-"@prisma/client@^5.7.1":
- version "5.12.1"
- resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.12.1.tgz#c26a674fea76754b3a9e8b90a11e617f90212f76"
- integrity sha512-6/JnizEdlSBxDIdiLbrBdMW5NqDxOmhXAJaNXiPpgzAPr/nLZResT6MMpbOHLo5yAbQ1Vv5UU8PTPRzb0WIxdA==
-
-"@prisma/debug@5.12.1":
- version "5.12.1"
- resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.12.1.tgz#007c8ad2e466d565bcd0671b8846c27f8700c722"
- integrity sha512-kd/wNsR0klrv79o1ITsbWxYyh4QWuBidvxsXSParPsYSu0ircUmNk3q4ojsgNc3/81b0ozg76iastOG43tbf8A==
-
-"@prisma/engines-version@5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab":
- version "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab"
- resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab.tgz#c78d099a3fe86d446db7442e64e56987e39e7f32"
- integrity sha512-6yvO8s80Tym61aB4QNtYZfWVmE3pwqe807jEtzm8C5VDe7nw8O1FGX3TXUaXmWV0fQTIAfRbeL2Gwrndabp/0g==
-
-"@prisma/engines@5.12.1":
- version "5.12.1"
- resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.12.1.tgz#a50649427d627a9af962a188a84c65d61c6e2b3f"
- integrity sha512-HQDdglLw2bZR/TXD2Y+YfDMvi5Q8H+acbswqOsWyq9pPjBLYJ6gzM+ptlTU/AV6tl0XSZLU1/7F4qaWa8bqpJA==
- dependencies:
- "@prisma/debug" "5.12.1"
- "@prisma/engines-version" "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab"
- "@prisma/fetch-engine" "5.12.1"
- "@prisma/get-platform" "5.12.1"
-
-"@prisma/fetch-engine@5.12.1":
- version "5.12.1"
- resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.12.1.tgz#c38e9fa17fdc535b4c83cbb7645569ad0a511fa9"
- integrity sha512-qSs3KcX1HKcea1A+hlJVK/ljj0PNIUHDxAayGMvgJBqmaN32P9tCidlKz1EGv6WoRFICYnk3Dd/YFLBwnFIozA==
- dependencies:
- "@prisma/debug" "5.12.1"
- "@prisma/engines-version" "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab"
- "@prisma/get-platform" "5.12.1"
-
-"@prisma/get-platform@5.12.1":
- version "5.12.1"
- resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.12.1.tgz#33f427f6d744dee62a9e06858889691d78b50804"
- integrity sha512-pgIR+pSvhYHiUcqXVEZS31NrFOTENC9yFUdEAcx7cdQBoZPmHVjtjN4Ss6NzVDMYPrKJJ51U14EhEoeuBlMioQ==
- dependencies:
- "@prisma/debug" "5.12.1"
+"@prisma/client@^5.15.0":
+ version "5.15.1"
+ resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.15.1.tgz#68e1f8b092a0eed6cd61d5f94ed8bb5cc3bc8ca1"
+ integrity sha512-fmZRGmsUJ9+VwC/AvfP/PwdpD0xAEyPvNsD9/B3+GYpETq9VejVRT3PiqNvl76q1uYYzNZeo8u/LmzzTetHSEg==
+
+"@prisma/debug@5.15.0":
+ version "5.15.0"
+ resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.15.0.tgz#a4c1d8dbca9cf29aab1c82a56a65224ed3e05f13"
+ integrity sha512-QpEAOjieLPc/4sMny/WrWqtpIAmBYsgqwWlWwIctqZO0AbhQ9QcT6x2Ut3ojbDo/pFRCCA1Z1+xm2MUy7fAkZA==
+
+"@prisma/debug@5.17.0":
+ version "5.17.0"
+ resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.17.0.tgz#a765105848993984535b6066f8ebc6e6ead26533"
+ integrity sha512-l7+AteR3P8FXiYyo496zkuoiJ5r9jLQEdUuxIxNCN1ud8rdbH3GTxm+f+dCyaSv9l9WY+29L9czaVRXz9mULfg==
+
+"@prisma/engines-version@5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022":
+ version "5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022"
+ resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022.tgz#4469a372b74088db05c0fc8cff65f229b804fa51"
+ integrity sha512-3BEgZ41Qb4oWHz9kZNofToRvNeS4LZYaT9pienR1gWkjhky6t6K1NyeWNBkqSj2llgraUNbgMOCQPY4f7Qp5wA==
+
+"@prisma/engines@5.15.0":
+ version "5.15.0"
+ resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.15.0.tgz#bddf1973b5b0d2ebed473ed445b1a7c8dd23300b"
+ integrity sha512-hXL5Sn9hh/ZpRKWiyPA5GbvF3laqBHKt6Vo70hYqqOhh5e0ZXDzHcdmxNvOefEFeqxra2DMz2hNbFoPvqrVe1w==
+ dependencies:
+ "@prisma/debug" "5.15.0"
+ "@prisma/engines-version" "5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022"
+ "@prisma/fetch-engine" "5.15.0"
+ "@prisma/get-platform" "5.15.0"
+
+"@prisma/fetch-engine@5.15.0":
+ version "5.15.0"
+ resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.15.0.tgz#f5bafd6aed3f58c41b5d0d6f832d652aa5d4cde7"
+ integrity sha512-z6AY5yyXxc20Klj7wwnfGP0iIUkVKzybqapT02zLYR/nf9ynaeN8bq73WRmi1TkLYn+DJ5Qy+JGu7hBf1pE78A==
+ dependencies:
+ "@prisma/debug" "5.15.0"
+ "@prisma/engines-version" "5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022"
+ "@prisma/get-platform" "5.15.0"
+
+"@prisma/generator-helper@^4.0.0 || ^5.0.0":
+ version "5.17.0"
+ resolved "https://registry.yarnpkg.com/@prisma/generator-helper/-/generator-helper-5.17.0.tgz#e499b748f77225f4bf78ad3694a5c58a5ece27bd"
+ integrity sha512-UcYpNjjQNVHAjIxgjfXnF4fcKU7B2vuzG1L27xIV81xQoGSbxg7v670URBhd0/ZoE8v2Itj2bbuyezY1ViHVaA==
+ dependencies:
+ "@prisma/debug" "5.17.0"
+
+"@prisma/get-platform@5.15.0":
+ version "5.15.0"
+ resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.15.0.tgz#d39fbe8458432f76afeb6c9199bffae73db4f5cc"
+ integrity sha512-1GULDkW4+/VQb73vihxCBSc4Chc2x88MA+O40tcZFjmBzG4/fF44PaXFxUqKSFltxU9L9GIMLhh0Gfkk/pUbtg==
+ dependencies:
+ "@prisma/debug" "5.15.0"
+
+"@puppeteer/browsers@0.5.0":
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-0.5.0.tgz#1a1ee454b84a986b937ca2d93146f25a3fe8b670"
+ integrity sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ==
+ dependencies:
+ debug "4.3.4"
+ extract-zip "2.0.1"
+ https-proxy-agent "5.0.1"
+ progress "2.0.3"
+ proxy-from-env "1.1.0"
+ tar-fs "2.1.1"
+ unbzip2-stream "1.4.3"
+ yargs "17.7.1"
"@sinclair/typebox@^0.27.8":
version "0.27.8"
@@ -1082,6 +1128,30 @@
resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.5.tgz#14a3e83fa641beb169a2dd8422d91c3c345a9a78"
integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==
+"@types/d3-scale-chromatic@^3.0.0":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz#fc0db9c10e789c351f4c42d96f31f2e4df8f5644"
+ integrity sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==
+
+"@types/d3-scale@^4.0.3":
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb"
+ integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==
+ dependencies:
+ "@types/d3-time" "*"
+
+"@types/d3-time@*":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be"
+ integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==
+
+"@types/debug@^4.0.0":
+ version "4.1.12"
+ resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917"
+ integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==
+ dependencies:
+ "@types/ms" "*"
+
"@types/eslint-scope@^3.7.3":
version "3.7.7"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
@@ -1184,6 +1254,13 @@
dependencies:
"@types/node" "*"
+"@types/mdast@^3.0.0":
+ version "3.0.15"
+ resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5"
+ integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==
+ dependencies:
+ "@types/unist" "^2"
+
"@types/methods@^1.1.4":
version "1.1.4"
resolved "https://registry.yarnpkg.com/@types/methods/-/methods-1.1.4.tgz#d3b7ac30ac47c91054ea951ce9eed07b1051e547"
@@ -1194,6 +1271,11 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
+"@types/ms@*":
+ version "0.7.34"
+ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
+ integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
+
"@types/multer@^1.4.11":
version "1.4.11"
resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.11.tgz#c70792670513b4af1159a2b60bf48cc932af55c5"
@@ -1268,6 +1350,11 @@
dependencies:
"@types/superagent" "*"
+"@types/unist@^2", "@types/unist@^2.0.0":
+ version "2.0.10"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc"
+ integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==
+
"@types/validator@^13.11.8":
version "13.11.9"
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.9.tgz#adfe96520b437a0eaa798a475877bf2f75ee402d"
@@ -1285,7 +1372,14 @@
dependencies:
"@types/yargs-parser" "*"
-"@typescript-eslint/eslint-plugin@7.6.0", "@typescript-eslint/eslint-plugin@^7.5.0":
+"@types/yauzl@^2.9.1":
+ version "2.10.3"
+ resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999"
+ integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==
+ dependencies:
+ "@types/node" "*"
+
+"@typescript-eslint/eslint-plugin@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz#1f5df5cda490a0bcb6fbdd3382e19f1241024242"
integrity sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==
@@ -1302,7 +1396,22 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
-"@typescript-eslint/parser@7.6.0", "@typescript-eslint/parser@^7.5.0":
+"@typescript-eslint/eslint-plugin@^7.5.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz#3cdeb5d44d051b21a9567535dd90702b2a42c6ff"
+ integrity sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==
+ dependencies:
+ "@eslint-community/regexpp" "^4.10.0"
+ "@typescript-eslint/scope-manager" "7.13.0"
+ "@typescript-eslint/type-utils" "7.13.0"
+ "@typescript-eslint/utils" "7.13.0"
+ "@typescript-eslint/visitor-keys" "7.13.0"
+ graphemer "^1.4.0"
+ ignore "^5.3.1"
+ natural-compare "^1.4.0"
+ ts-api-utils "^1.3.0"
+
+"@typescript-eslint/parser@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.6.0.tgz#0aca5de3045d68b36e88903d15addaf13d040a95"
integrity sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==
@@ -1324,6 +1433,17 @@
"@typescript-eslint/visitor-keys" "6.21.0"
debug "^4.3.4"
+"@typescript-eslint/parser@^7.5.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.13.0.tgz#9489098d68d57ad392f507495f2b82ce8b8f0a6b"
+ integrity sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==
+ dependencies:
+ "@typescript-eslint/scope-manager" "7.13.0"
+ "@typescript-eslint/types" "7.13.0"
+ "@typescript-eslint/typescript-estree" "7.13.0"
+ "@typescript-eslint/visitor-keys" "7.13.0"
+ debug "^4.3.4"
+
"@typescript-eslint/scope-manager@6.21.0":
version "6.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1"
@@ -1332,6 +1452,14 @@
"@typescript-eslint/types" "6.21.0"
"@typescript-eslint/visitor-keys" "6.21.0"
+"@typescript-eslint/scope-manager@7.13.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz#6927d6451537ce648c6af67a2327378d4cc18462"
+ integrity sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==
+ dependencies:
+ "@typescript-eslint/types" "7.13.0"
+ "@typescript-eslint/visitor-keys" "7.13.0"
+
"@typescript-eslint/scope-manager@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz#1e9972f654210bd7500b31feadb61a233f5b5e9d"
@@ -1340,6 +1468,16 @@
"@typescript-eslint/types" "7.6.0"
"@typescript-eslint/visitor-keys" "7.6.0"
+"@typescript-eslint/type-utils@7.13.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz#4587282b5227a23753ea8b233805ecafc3924c76"
+ integrity sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==
+ dependencies:
+ "@typescript-eslint/typescript-estree" "7.13.0"
+ "@typescript-eslint/utils" "7.13.0"
+ debug "^4.3.4"
+ ts-api-utils "^1.3.0"
+
"@typescript-eslint/type-utils@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz#644f75075f379827d25fe0713e252ccd4e4a428c"
@@ -1355,6 +1493,11 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d"
integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==
+"@typescript-eslint/types@7.13.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.13.0.tgz#0cca95edf1f1fdb0cfe1bb875e121b49617477c5"
+ integrity sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==
+
"@typescript-eslint/types@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.6.0.tgz#53dba7c30c87e5f10a731054266dd905f1fbae38"
@@ -1374,6 +1517,20 @@
semver "^7.5.4"
ts-api-utils "^1.0.1"
+"@typescript-eslint/typescript-estree@7.13.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz#4cc24fc155088ebf3b3adbad62c7e60f72c6de1c"
+ integrity sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==
+ dependencies:
+ "@typescript-eslint/types" "7.13.0"
+ "@typescript-eslint/visitor-keys" "7.13.0"
+ debug "^4.3.4"
+ globby "^11.1.0"
+ is-glob "^4.0.3"
+ minimatch "^9.0.4"
+ semver "^7.6.0"
+ ts-api-utils "^1.3.0"
+
"@typescript-eslint/typescript-estree@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz#112a3775563799fd3f011890ac8322f80830ac17"
@@ -1388,6 +1545,16 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
+"@typescript-eslint/utils@7.13.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.13.0.tgz#f84e7e8aeceae945a9a3f40d077fd95915308004"
+ integrity sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.4.0"
+ "@typescript-eslint/scope-manager" "7.13.0"
+ "@typescript-eslint/types" "7.13.0"
+ "@typescript-eslint/typescript-estree" "7.13.0"
+
"@typescript-eslint/utils@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.6.0.tgz#e400d782280b6f724c8a1204269d984c79202282"
@@ -1409,6 +1576,14 @@
"@typescript-eslint/types" "6.21.0"
eslint-visitor-keys "^3.4.1"
+"@typescript-eslint/visitor-keys@7.13.0":
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz#2eb7ce8eb38c2b0d4a494d1fe1908e7071a1a353"
+ integrity sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==
+ dependencies:
+ "@typescript-eslint/types" "7.13.0"
+ eslint-visitor-keys "^3.4.3"
+
"@typescript-eslint/visitor-keys@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz#d1ce13145844379021e1f9bd102c1d78946f4e76"
@@ -1586,6 +1761,13 @@ acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
+agent-base@6:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
+ integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
+ dependencies:
+ debug "4"
+
ajv-formats@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
@@ -1916,7 +2098,7 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
-bl@^4.1.0:
+bl@^4.0.3, bl@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
@@ -1989,12 +2171,17 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
+buffer-crc32@~0.2.3:
+ version "0.2.13"
+ resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
+ integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
+
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
-buffer@^5.5.0:
+buffer@^5.2.1, buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
@@ -2091,7 +2278,7 @@ chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
-chalk@^5.3.0:
+chalk@^5.0.1, chalk@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385"
integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==
@@ -2101,6 +2288,11 @@ char-regex@^1.0.2:
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
+character-entities@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
+ integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
+
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@@ -2121,11 +2313,23 @@ chokidar@3.6.0, chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"
+chownr@^1.1.1:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
+ integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
+
chrome-trace-event@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
+chromium-bidi@0.4.7:
+ version "0.4.7"
+ resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.4.7.tgz#4c022c2b0fb1d1c9b571fadf373042160e71d236"
+ integrity sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ==
+ dependencies:
+ mitt "3.0.0"
+
ci-info@^3.2.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
@@ -2248,15 +2452,25 @@ commander@4.1.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+commander@7, commander@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
+ integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
+
+commander@^10.0.0:
+ version "10.0.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
+ integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
+
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-commander@^7.1.0:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
- integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
+commander@^8.3.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
+ integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
comment-json@4.2.3:
version "4.2.3"
@@ -2349,6 +2563,23 @@ cors@2.8.5:
object-assign "^4"
vary "^1"
+cose-base@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-1.0.3.tgz#650334b41b869578a543358b80cda7e0abe0a60a"
+ integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==
+ dependencies:
+ layout-base "^1.0.0"
+
+cosmiconfig@8.1.3:
+ version "8.1.3"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.1.3.tgz#0e614a118fcc2d9e5afc2f87d53cd09931015689"
+ integrity sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==
+ dependencies:
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ parse-json "^5.0.0"
+ path-type "^4.0.0"
+
cosmiconfig@^8.2.0:
version "8.3.6"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3"
@@ -2377,6 +2608,13 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+cross-fetch@3.1.5:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
+ integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
+ dependencies:
+ node-fetch "2.6.7"
+
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -2395,6 +2633,297 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
+cytoscape-cose-bilkent@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz#762fa121df9930ffeb51a495d87917c570ac209b"
+ integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==
+ dependencies:
+ cose-base "^1.0.0"
+
+cytoscape@^3.28.1:
+ version "3.30.1"
+ resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.30.1.tgz#9855a284aaefbaf2628fdc6cf956ba83c0ae511b"
+ integrity sha512-TRJc3HbBPkHd50u9YfJh2FxD1lDLZ+JXnJoyBn5LkncoeuT7fapO/Hq/Ed8TdFclaKshzInge2i30bg7VKeoPQ==
+
+"d3-array@1 - 2":
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
+ integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
+ dependencies:
+ internmap "^1.0.0"
+
+"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
+ integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
+ dependencies:
+ internmap "1 - 2"
+
+d3-axis@3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322"
+ integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==
+
+d3-brush@3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c"
+ integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==
+ dependencies:
+ d3-dispatch "1 - 3"
+ d3-drag "2 - 3"
+ d3-interpolate "1 - 3"
+ d3-selection "3"
+ d3-transition "3"
+
+d3-chord@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966"
+ integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==
+ dependencies:
+ d3-path "1 - 3"
+
+"d3-color@1 - 3", d3-color@3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
+ integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
+
+d3-contour@4:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-4.0.2.tgz#bb92063bc8c5663acb2422f99c73cbb6c6ae3bcc"
+ integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==
+ dependencies:
+ d3-array "^3.2.0"
+
+d3-delaunay@6:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-6.0.4.tgz#98169038733a0a5babbeda55054f795bb9e4a58b"
+ integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==
+ dependencies:
+ delaunator "5"
+
+"d3-dispatch@1 - 3", d3-dispatch@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e"
+ integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==
+
+"d3-drag@2 - 3", d3-drag@3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
+ integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
+ dependencies:
+ d3-dispatch "1 - 3"
+ d3-selection "3"
+
+"d3-dsv@1 - 3", d3-dsv@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73"
+ integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==
+ dependencies:
+ commander "7"
+ iconv-lite "0.6"
+ rw "1"
+
+"d3-ease@1 - 3", d3-ease@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
+ integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
+
+d3-fetch@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22"
+ integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==
+ dependencies:
+ d3-dsv "1 - 3"
+
+d3-force@3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4"
+ integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==
+ dependencies:
+ d3-dispatch "1 - 3"
+ d3-quadtree "1 - 3"
+ d3-timer "1 - 3"
+
+"d3-format@1 - 3", d3-format@3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
+ integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
+
+d3-geo@3:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.1.tgz#6027cf51246f9b2ebd64f99e01dc7c3364033a4d"
+ integrity sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==
+ dependencies:
+ d3-array "2.5.0 - 3"
+
+d3-hierarchy@3:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6"
+ integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==
+
+"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
+ integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
+ dependencies:
+ d3-color "1 - 3"
+
+d3-path@1:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
+ integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
+
+"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526"
+ integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==
+
+d3-polygon@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398"
+ integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==
+
+"d3-quadtree@1 - 3", d3-quadtree@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f"
+ integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==
+
+d3-random@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4"
+ integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==
+
+d3-sankey@^0.12.3:
+ version "0.12.3"
+ resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.12.3.tgz#b3c268627bd72e5d80336e8de6acbfec9d15d01d"
+ integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==
+ dependencies:
+ d3-array "1 - 2"
+ d3-shape "^1.2.0"
+
+d3-scale-chromatic@3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#34c39da298b23c20e02f1a4b239bd0f22e7f1314"
+ integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==
+ dependencies:
+ d3-color "1 - 3"
+ d3-interpolate "1 - 3"
+
+d3-scale@4:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
+ integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
+ dependencies:
+ d3-array "2.10.0 - 3"
+ d3-format "1 - 3"
+ d3-interpolate "1.2.0 - 3"
+ d3-time "2.1.1 - 3"
+ d3-time-format "2 - 4"
+
+"d3-selection@2 - 3", d3-selection@3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
+ integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
+
+d3-shape@3:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5"
+ integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==
+ dependencies:
+ d3-path "^3.1.0"
+
+d3-shape@^1.2.0:
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
+ integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
+ dependencies:
+ d3-path "1"
+
+"d3-time-format@2 - 4", d3-time-format@4:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
+ integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
+ dependencies:
+ d3-time "1 - 3"
+
+"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
+ integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
+ dependencies:
+ d3-array "2 - 3"
+
+"d3-timer@1 - 3", d3-timer@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
+ integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
+
+"d3-transition@2 - 3", d3-transition@3:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
+ integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
+ dependencies:
+ d3-color "1 - 3"
+ d3-dispatch "1 - 3"
+ d3-ease "1 - 3"
+ d3-interpolate "1 - 3"
+ d3-timer "1 - 3"
+
+d3-zoom@3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3"
+ integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==
+ dependencies:
+ d3-dispatch "1 - 3"
+ d3-drag "2 - 3"
+ d3-interpolate "1 - 3"
+ d3-selection "2 - 3"
+ d3-transition "2 - 3"
+
+d3@^7.4.0, d3@^7.8.2:
+ version "7.9.0"
+ resolved "https://registry.yarnpkg.com/d3/-/d3-7.9.0.tgz#579e7acb3d749caf8860bd1741ae8d371070cd5d"
+ integrity sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==
+ dependencies:
+ d3-array "3"
+ d3-axis "3"
+ d3-brush "3"
+ d3-chord "3"
+ d3-color "3"
+ d3-contour "4"
+ d3-delaunay "6"
+ d3-dispatch "3"
+ d3-drag "3"
+ d3-dsv "3"
+ d3-ease "3"
+ d3-fetch "3"
+ d3-force "3"
+ d3-format "3"
+ d3-geo "3"
+ d3-hierarchy "3"
+ d3-interpolate "3"
+ d3-path "3"
+ d3-polygon "3"
+ d3-quadtree "3"
+ d3-random "3"
+ d3-scale "4"
+ d3-scale-chromatic "3"
+ d3-selection "3"
+ d3-shape "3"
+ d3-time "3"
+ d3-time-format "4"
+ d3-timer "3"
+ d3-transition "3"
+ d3-zoom "3"
+
+dagre-d3-es@7.0.10:
+ version "7.0.10"
+ resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz#19800d4be674379a3cd8c86a8216a2ac6827cadc"
+ integrity sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==
+ dependencies:
+ d3 "^7.8.2"
+ lodash-es "^4.17.21"
+
data-view-buffer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2"
@@ -2422,6 +2951,11 @@ data-view-byte-offset@^1.0.0:
es-errors "^1.3.0"
is-data-view "^1.0.1"
+dayjs@^1.11.7:
+ version "1.11.12"
+ resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.12.tgz#5245226cc7f40a15bf52e0b99fd2a04669ccac1d"
+ integrity sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==
+
debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -2429,6 +2963,20 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
+debug@4, debug@^4.0.0:
+ version "4.3.5"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
+ integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
+ dependencies:
+ ms "2.1.2"
+
+debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
+ integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+ dependencies:
+ ms "2.1.2"
+
debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@@ -2436,12 +2984,12 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
-debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
- version "4.3.4"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
- integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+decode-named-character-reference@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e"
+ integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==
dependencies:
- ms "2.1.2"
+ character-entities "^2.0.0"
decompress-response@^6.0.0:
version "6.0.0"
@@ -2495,6 +3043,13 @@ define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
+delaunator@5:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.1.tgz#39032b08053923e924d6094fe2cde1a99cc51278"
+ integrity sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==
+ dependencies:
+ robust-predicates "^3.0.2"
+
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -2505,6 +3060,11 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
+dequal@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
+ integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
+
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
@@ -2515,6 +3075,11 @@ detect-newline@^3.0.0:
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
+devtools-protocol@0.0.1107588:
+ version "0.0.1107588"
+ resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz#f8cac707840b97cc30b029359341bcbbb0ad8ffa"
+ integrity sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==
+
dezalgo@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81"
@@ -2533,6 +3098,11 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+diff@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531"
+ integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==
+
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@@ -2559,12 +3129,17 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
+dompurify@^3.0.5:
+ version "3.1.6"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.6.tgz#43c714a94c6a7b8801850f82e756685300a027e2"
+ integrity sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==
+
dotenv-expand@10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37"
integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==
-dotenv@16.4.5:
+dotenv@16.4.5, dotenv@^16.3.1:
version "16.4.5"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
@@ -2584,6 +3159,11 @@ electron-to-chromium@^1.4.668:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.734.tgz#6e0083e1a6be06b2df4c849ba1534d86f30a6738"
integrity sha512-pYfGUc+ll8AOzLbLC0lfgwkvCZIV+sKGuFFsSNuF3K3ujrmem8jIjg/t6DNq0J7biTSS1hCt/Hts0nmA3ZyprQ==
+elkjs@^0.9.0:
+ version "0.9.3"
+ resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.9.3.tgz#16711f8ceb09f1b12b99e971b138a8384a529161"
+ integrity sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==
+
emittery@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
@@ -2604,7 +3184,7 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
-end-of-stream@^1.1.0:
+end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -2827,9 +3407,9 @@ eslint-plugin-prettier@^5.1.3:
synckit "^0.8.6"
eslint-plugin-simple-import-sort@^12.0.0:
- version "12.0.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.0.0.tgz#3cfa05d74509bd4dc329a956938823812194dbb6"
- integrity sha512-8o0dVEdAkYap0Cn5kNeklaKcT1nUsa3LITWEuFk3nJifOoD+5JQGoyDUW2W/iPWwBsNBJpyJS9y4je/BgxLcyQ==
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz#8186ad55474d2f5c986a2f1bf70625a981e30d05"
+ integrity sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==
eslint-scope@5.1.1:
version "5.1.1"
@@ -3061,6 +3641,17 @@ external-editor@^3.0.3, external-editor@^3.1.0:
iconv-lite "^0.4.24"
tmp "^0.0.33"
+extract-zip@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
+ integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
+ dependencies:
+ debug "^4.1.1"
+ get-stream "^5.1.0"
+ yauzl "^2.10.0"
+ optionalDependencies:
+ "@types/yauzl" "^2.9.1"
+
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -3111,6 +3702,13 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
+fd-slicer@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
+ integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
+ dependencies:
+ pend "~1.2.0"
+
figures@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
@@ -3280,6 +3878,11 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
+fs-constants@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
+ integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+
fs-extra@^10.0.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
@@ -3585,6 +4188,14 @@ http2-wrapper@^1.0.0-beta.5.2:
quick-lru "^5.1.1"
resolve-alpn "^1.0.0"
+https-proxy-agent@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
+ integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
+ dependencies:
+ agent-base "6"
+ debug "4"
+
human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
@@ -3597,6 +4208,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
+iconv-lite@0.6:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
+ integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3.0.0"
+
ieee754@^1.1.13, ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
@@ -3697,6 +4315,16 @@ internal-slot@^1.0.7:
hasown "^2.0.0"
side-channel "^1.0.4"
+"internmap@1 - 2":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
+ integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
+
+internmap@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
+ integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
+
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
@@ -4415,6 +5043,13 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
+katex@^0.16.9:
+ version "0.16.11"
+ resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.11.tgz#4bc84d5584f996abece5f01c6ad11304276a33f5"
+ integrity sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==
+ dependencies:
+ commander "^8.3.0"
+
keyv@^4.0.0, keyv@^4.5.3:
version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
@@ -4422,11 +5057,26 @@ keyv@^4.0.0, keyv@^4.5.3:
dependencies:
json-buffer "3.0.1"
+khroma@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.1.0.tgz#45f2ce94ce231a437cf5b63c2e886e6eb42bbbb1"
+ integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==
+
kleur@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
+kleur@^4.0.3:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
+ integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
+
+layout-base@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-1.0.2.tgz#1291e296883c322a9dd4c5dd82063721b53e26e2"
+ integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==
+
leven@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
@@ -4469,6 +5119,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
+lodash-es@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
lodash.memoize@4.x:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -4563,6 +5218,31 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"
+mdast-util-from-markdown@^1.3.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0"
+ integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ "@types/unist" "^2.0.0"
+ decode-named-character-reference "^1.0.0"
+ mdast-util-to-string "^3.1.0"
+ micromark "^3.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-decode-string "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ unist-util-stringify-position "^3.0.0"
+ uvu "^0.5.0"
+
+mdast-util-to-string@^3.1.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz#66f7bb6324756741c5f47a53557f0cbf16b6f789"
+ integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -4590,11 +5270,231 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+mermaid@^10.8.0:
+ version "10.9.1"
+ resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.9.1.tgz#5f582c23f3186c46c6aa673e59eeb46d741b2ea6"
+ integrity sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==
+ dependencies:
+ "@braintree/sanitize-url" "^6.0.1"
+ "@types/d3-scale" "^4.0.3"
+ "@types/d3-scale-chromatic" "^3.0.0"
+ cytoscape "^3.28.1"
+ cytoscape-cose-bilkent "^4.1.0"
+ d3 "^7.4.0"
+ d3-sankey "^0.12.3"
+ dagre-d3-es "7.0.10"
+ dayjs "^1.11.7"
+ dompurify "^3.0.5"
+ elkjs "^0.9.0"
+ katex "^0.16.9"
+ khroma "^2.0.0"
+ lodash-es "^4.17.21"
+ mdast-util-from-markdown "^1.3.0"
+ non-layered-tidy-tree-layout "^2.0.2"
+ stylis "^4.1.3"
+ ts-dedent "^2.2.0"
+ uuid "^9.0.0"
+ web-worker "^1.2.0"
+
methods@^1.1.2, methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
+micromark-core-commonmark@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz#1386628df59946b2d39fb2edfd10f3e8e0a75bb8"
+ integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==
+ dependencies:
+ decode-named-character-reference "^1.0.0"
+ micromark-factory-destination "^1.0.0"
+ micromark-factory-label "^1.0.0"
+ micromark-factory-space "^1.0.0"
+ micromark-factory-title "^1.0.0"
+ micromark-factory-whitespace "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-chunked "^1.0.0"
+ micromark-util-classify-character "^1.0.0"
+ micromark-util-html-tag-name "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-resolve-all "^1.0.0"
+ micromark-util-subtokenize "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.1"
+ uvu "^0.5.0"
+
+micromark-factory-destination@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f"
+ integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-label@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz#cc95d5478269085cfa2a7282b3de26eb2e2dec68"
+ integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-factory-space@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf"
+ integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-title@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz#dd0fe951d7a0ac71bdc5ee13e5d1465ad7f50ea1"
+ integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==
+ dependencies:
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-whitespace@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz#798fb7489f4c8abafa7ca77eed6b5745853c9705"
+ integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==
+ dependencies:
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-character@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc"
+ integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-chunked@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz#37a24d33333c8c69a74ba12a14651fd9ea8a368b"
+ integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-classify-character@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz#6a7f8c8838e8a120c8e3c4f2ae97a2bff9190e9d"
+ integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-combine-extensions@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz#192e2b3d6567660a85f735e54d8ea6e3952dbe84"
+ integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==
+ dependencies:
+ micromark-util-chunked "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-decode-numeric-character-reference@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz#b1e6e17009b1f20bc652a521309c5f22c85eb1c6"
+ integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-decode-string@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz#dc12b078cba7a3ff690d0203f95b5d5537f2809c"
+ integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==
+ dependencies:
+ decode-named-character-reference "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-encode@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz#92e4f565fd4ccb19e0dcae1afab9a173bbeb19a5"
+ integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==
+
+micromark-util-html-tag-name@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz#48fd7a25826f29d2f71479d3b4e83e94829b3588"
+ integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==
+
+micromark-util-normalize-identifier@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz#7a73f824eb9f10d442b4d7f120fecb9b38ebf8b7"
+ integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-resolve-all@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz#4652a591ee8c8fa06714c9b54cd6c8e693671188"
+ integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==
+ dependencies:
+ micromark-util-types "^1.0.0"
+
+micromark-util-sanitize-uri@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz#613f738e4400c6eedbc53590c67b197e30d7f90d"
+ integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-encode "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-subtokenize@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz#941c74f93a93eaf687b9054aeb94642b0e92edb1"
+ integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==
+ dependencies:
+ micromark-util-chunked "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-util-symbol@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142"
+ integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==
+
+micromark-util-types@^1.0.0, micromark-util-types@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283"
+ integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==
+
+micromark@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.2.0.tgz#1af9fef3f995ea1ea4ac9c7e2f19c48fd5c006e9"
+ integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==
+ dependencies:
+ "@types/debug" "^4.0.0"
+ debug "^4.0.0"
+ decode-named-character-reference "^1.0.0"
+ micromark-core-commonmark "^1.0.1"
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-chunked "^1.0.0"
+ micromark-util-combine-extensions "^1.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-encode "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-resolve-all "^1.0.0"
+ micromark-util-sanitize-uri "^1.0.0"
+ micromark-util-subtokenize "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.1"
+ uvu "^0.5.0"
+
micromatch@^4.0.0, micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
@@ -4683,6 +5583,16 @@ minipass@^4.2.4:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c"
integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==
+mitt@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd"
+ integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==
+
+mkdirp-classic@^0.5.2:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
+ integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
+
mkdirp@^0.5.4:
version "0.5.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
@@ -4690,6 +5600,11 @@ mkdirp@^0.5.4:
dependencies:
minimist "^1.2.6"
+mri@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
+ integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -4755,6 +5670,13 @@ node-emoji@1.11.0:
dependencies:
lodash "^4.17.21"
+node-fetch@2.6.7:
+ version "2.6.7"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
+ integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
+ dependencies:
+ whatwg-url "^5.0.0"
+
node-fetch@^2.6.1:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
@@ -4772,6 +5694,11 @@ node-releases@^2.0.14:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
+non-layered-tidy-tree-layout@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz#57d35d13c356643fc296a55fb11ac15e74da7804"
+ integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==
+
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@@ -4968,7 +5895,7 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
-parse-json@^5.2.0:
+parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
@@ -5043,6 +5970,11 @@ peek-readable@^5.0.0:
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec"
integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==
+pend@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
+ integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
+
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@@ -5129,18 +6061,32 @@ pretty-format@^29.0.0, pretty-format@^29.7.0:
ansi-styles "^5.0.0"
react-is "^18.0.0"
+prisma-erd-generator@^1.11.2:
+ version "1.11.2"
+ resolved "https://registry.yarnpkg.com/prisma-erd-generator/-/prisma-erd-generator-1.11.2.tgz#75b4321f212d0837e75f98230b03abc3488ff71f"
+ integrity sha512-abo2EBIjqJALfjm8p+uOsQk38DlU3rlLJA9/cOvcLLt8A9bjMkRwlqaZDAD/iXVZcXJRJPgJ98fEviTa+w8oTQ==
+ dependencies:
+ "@mermaid-js/mermaid-cli" "^10.6.1"
+ "@prisma/generator-helper" "^4.0.0 || ^5.0.0"
+ dotenv "^16.3.1"
+
prisma@^5.7.1:
- version "5.12.1"
- resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.12.1.tgz#db4596253bb066afc9f08744642f200a398d8d51"
- integrity sha512-SkMnb6wyIxTv9ACqiHBI2u9gD6y98qXRoCoLEnZsF6yee5Qg828G+ARrESN+lQHdw4maSZFFSBPPDpvSiVTo0Q==
+ version "5.15.0"
+ resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.15.0.tgz#887c295caa1b81b8849d94a2751cc0e0994f86d1"
+ integrity sha512-JA81ACQSCi3a7NUOgonOIkdx8PAVkO+HbUOxmd00Yb8DgIIEpr2V9+Qe/j6MLxIgWtE/OtVQ54rVjfYRbZsCfw==
dependencies:
- "@prisma/engines" "5.12.1"
+ "@prisma/engines" "5.15.0"
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+progress@2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
+ integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
+
prompts@^2.0.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
@@ -5157,7 +6103,7 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"
-proxy-from-env@^1.1.0:
+proxy-from-env@1.1.0, proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
@@ -5180,6 +6126,35 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
+puppeteer-core@19.11.1:
+ version "19.11.1"
+ resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-19.11.1.tgz#4c63d7a0a6cd268ff054ebcac315b646eee32667"
+ integrity sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA==
+ dependencies:
+ "@puppeteer/browsers" "0.5.0"
+ chromium-bidi "0.4.7"
+ cross-fetch "3.1.5"
+ debug "4.3.4"
+ devtools-protocol "0.0.1107588"
+ extract-zip "2.0.1"
+ https-proxy-agent "5.0.1"
+ proxy-from-env "1.1.0"
+ tar-fs "2.1.1"
+ unbzip2-stream "1.4.3"
+ ws "8.13.0"
+
+puppeteer@^19.0.0:
+ version "19.11.1"
+ resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-19.11.1.tgz#bb75d518e87b0b4f6ef9bad1ea7e9d1cdcd18a5d"
+ integrity sha512-39olGaX2djYUdhaQQHDZ0T0GwEp+5f9UB9HmEP0qHfdQHIq0xGQZuAZ5TLnJIc/88SrPLpEflPC+xUqOTv3c5g==
+ dependencies:
+ "@puppeteer/browsers" "0.5.0"
+ cosmiconfig "8.1.3"
+ https-proxy-agent "5.0.1"
+ progress "2.0.3"
+ proxy-from-env "1.1.0"
+ puppeteer-core "19.11.1"
+
pure-rand@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2"
@@ -5249,7 +6224,7 @@ readable-stream@^2.2.2:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.4.0, readable-stream@^3.6.0:
+readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@@ -5384,6 +6359,11 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
+robust-predicates@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771"
+ integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==
+
run-async@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
@@ -5401,6 +6381,11 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
+rw@1:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
+ integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
+
rxjs@7.8.1, rxjs@^7.5.5, rxjs@^7.8.1:
version "7.8.1"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
@@ -5408,6 +6393,13 @@ rxjs@7.8.1, rxjs@^7.5.5, rxjs@^7.8.1:
dependencies:
tslib "^2.1.0"
+sade@^1.7.3:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
+ integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
+ dependencies:
+ mri "^1.1.0"
+
safe-array-concat@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb"
@@ -5437,7 +6429,7 @@ safe-regex-test@^1.0.3:
es-errors "^1.3.0"
is-regex "^1.1.4"
-"safer-buffer@>= 2.1.2 < 3":
+"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -5790,6 +6782,11 @@ strtok3@^7.0.0-alpha.9:
"@tokenizer/token" "^0.3.0"
peek-readable "^5.0.0"
+stylis@^4.1.3:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.2.tgz#8f76b70777dd53eb669c6f58c997bf0a9972e444"
+ integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==
+
superagent@^8.1.2:
version "8.1.2"
resolved "https://registry.yarnpkg.com/superagent/-/superagent-8.1.2.tgz#03cb7da3ec8b32472c9d20f6c2a57c7f3765f30b"
@@ -5863,6 +6860,27 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+tar-fs@2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
+ integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
+ dependencies:
+ chownr "^1.1.1"
+ mkdirp-classic "^0.5.2"
+ pump "^3.0.0"
+ tar-stream "^2.1.4"
+
+tar-stream@^2.1.4:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
+ integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
+ dependencies:
+ bl "^4.0.3"
+ end-of-stream "^1.4.1"
+ fs-constants "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.1.1"
+
terser-webpack-plugin@^5.3.10:
version "5.3.10"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199"
@@ -5898,7 +6916,7 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
-through@^2.3.6:
+through@^2.3.6, through@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
@@ -5962,6 +6980,11 @@ ts-api-utils@^1.0.1, ts-api-utils@^1.3.0:
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1"
integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==
+ts-dedent@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5"
+ integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==
+
ts-jest@^29.1.0:
version "29.1.2"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09"
@@ -6154,11 +7177,26 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
+unbzip2-stream@1.4.3:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
+ integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==
+ dependencies:
+ buffer "^5.2.1"
+ through "^2.3.8"
+
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
+unist-util-stringify-position@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d"
+ integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
universalify@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
@@ -6194,11 +7232,21 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
-uuid@9.0.1, uuid@^9.0.1:
+uuid@9.0.1, uuid@^9.0.0, uuid@^9.0.1:
version "9.0.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
+uvu@^0.5.0:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"
+ integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==
+ dependencies:
+ dequal "^2.0.0"
+ diff "^5.0.0"
+ kleur "^4.0.3"
+ sade "^1.7.3"
+
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
@@ -6258,6 +7306,11 @@ wcwidth@^1.0.1:
dependencies:
defaults "^1.0.3"
+web-worker@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.3.0.tgz#e5f2df5c7fe356755a5fb8f8410d4312627e6776"
+ integrity sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==
+
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@@ -6388,6 +7441,11 @@ write-file-atomic@^4.0.2:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"
+ws@8.13.0:
+ version "8.13.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
+ integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
+
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@@ -6418,6 +7476,19 @@ yargs-parser@21.1.1, yargs-parser@^21.0.1, yargs-parser@^21.1.1:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+yargs@17.7.1:
+ version "17.7.1"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967"
+ integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==
+ dependencies:
+ cliui "^8.0.1"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.3"
+ y18n "^5.0.5"
+ yargs-parser "^21.1.1"
+
yargs@^17.3.1:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
@@ -6431,6 +7502,14 @@ yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.1.1"
+yauzl@^2.10.0:
+ version "2.10.0"
+ resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
+ integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
+ dependencies:
+ buffer-crc32 "~0.2.3"
+ fd-slicer "~1.1.0"
+
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"