From bc9ee2f97a06e012a3dc1164ce801027ec0ec6d7 Mon Sep 17 00:00:00 2001 From: Luna Simons Date: Sun, 28 Jan 2024 23:05:21 +0100 Subject: [PATCH] feat: queue processing (#26) * feat: added bull queue lessons processing * ci: who uses these anyways :troll: * feat: added redis unix socket support --- .env.example | 5 + .github/workflows/node-ci.yaml | 3 +- default.nix | 4 +- module.nix | 8 ++ package.json | 2 + src/app.module.ts | 14 ++- src/lessons/lessons.controller.ts | 41 +++---- src/lessons/lessons.module.ts | 14 ++- src/lessons/lessons.processor.ts | 67 ++++++++++++ yarn.lock | 170 +++++++++++++++++++++++++++++- 10 files changed, 302 insertions(+), 26 deletions(-) create mode 100644 src/lessons/lessons.processor.ts diff --git a/.env.example b/.env.example index 7964f22..5bf150b 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,11 @@ UNTIS_USERNAME= UNTIS_PASSWORD= UNTIS_BASEURL= +BULL_REDIS_HOST=localhost +BULL_REDIS_PORT=6379 +# or +#BULL_REDIS_PATH=/run/redis/redis.sock + #MAINTENANCE_TITLE= #MAINTENANCE_DESCRIPTION= #MAINTENANCE_LOCATION= diff --git a/.github/workflows/node-ci.yaml b/.github/workflows/node-ci.yaml index 4e87615..ce97bef 100644 --- a/.github/workflows/node-ci.yaml +++ b/.github/workflows/node-ci.yaml @@ -6,8 +6,7 @@ jobs: strategy: matrix: node-version: [16.x, 18.x] - os: [ubuntu-latest, windows-latest, macos-latest] - runs-on: ${{matrix.os}} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 diff --git a/default.nix b/default.nix index 551622e..a6d8139 100644 --- a/default.nix +++ b/default.nix @@ -13,7 +13,7 @@ mkYarnPackage rec { offlineCache = fetchYarnDeps { yarnLock = src + "/yarn.lock"; - hash = "sha256-NHghkf5Nziyz3M7E4941sV5JFqY7RYMTlZqYsQPZLpU="; + hash = "sha256-mToEmc4cNd2fsyT/DUkzMiO4BYUDw6aexbcXOVfB2ds="; }; nativeBuildInputs = [makeWrapper]; @@ -30,6 +30,8 @@ mkYarnPackage rec { --add-flags "$out/libexec/untis-ics-sync/deps/untis-ics-sync/dist/main.js" ''; + dontStrip = true; + meta = with lib; { description = "Serves a calendar API (ICS) for events provided from Untis"; homepage = "https://github.com/bddvlpr/untis-ics-sync"; diff --git a/module.nix b/module.nix index bdff6d0..2a1a065 100644 --- a/module.nix +++ b/module.nix @@ -40,12 +40,20 @@ in { serviceConfig = { Restart = "on-failure"; ExecStart = "${lib.getExe cfg.package}"; + Environment = [ + "BULL_REDIS_PATH=${config.services.redis.servers.untis-ics-sync.unixSocket}" + ]; EnvironmentFile = cfg.envFile; User = cfg.user; Group = cfg.group; }; }; + services.redis.servers.untis-ics-sync = { + enable = true; + user = cfg.user; + }; + users = { users.untis-ics-sync = lib.mkIf (cfg.user == "untis-ics-sync") { isSystemUser = true; diff --git a/package.json b/package.json index 2f7cf0c..679025b 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { + "@nestjs/bull": "^10.0.1", "@nestjs/cache-manager": "^2.1.0", "@nestjs/common": "^9.0.0", "@nestjs/config": "^3.0.1", @@ -27,6 +28,7 @@ "@nestjs/platform-express": "^9.0.0", "@nestjs/swagger": "^7.1.10", "@willsoto/nestjs-prometheus": "^6.0.0", + "bull": "^4.11.5", "cache-manager": "^5.2.3", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", diff --git a/src/app.module.ts b/src/app.module.ts index 5bdf90f..da9ea00 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,15 +1,27 @@ import { Module } from '@nestjs/common'; import { UntisModule } from './untis/untis.module'; import { ClassesModule } from './classes/classes.module'; -import { ConfigModule } from '@nestjs/config'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { SubjectsModule } from './subjects/subjects.module'; import { LessonsModule } from './lessons/lessons.module'; import { HolidaysModule } from './holidays/holidays.module'; import { MetricsModule } from './metrics/metrics.module'; +import { BullModule } from '@nestjs/bull'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), + BullModule.forRootAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: (configService: ConfigService) => ({ + redis: { + host: configService.get('BULL_REDIS_HOST'), + port: configService.get('BULL_REDIS_PORT'), + path: configService.get('BULL_REDIS_PATH'), + }, + }), + }), UntisModule, ClassesModule, SubjectsModule, diff --git a/src/lessons/lessons.controller.ts b/src/lessons/lessons.controller.ts index 1f5726b..d58f1ea 100644 --- a/src/lessons/lessons.controller.ts +++ b/src/lessons/lessons.controller.ts @@ -1,3 +1,4 @@ +import { InjectQueue } from '@nestjs/bull'; import { Controller, DefaultValuePipe, @@ -17,17 +18,16 @@ import { ApiQuery, ApiTags, } from '@nestjs/swagger'; -import { UntisService } from 'src/untis/untis.service'; +import { Queue } from 'bull'; import { GetLessonDto } from './dto/get-lesson.dto'; -import { LessonsService } from './lessons.service'; +import { FetchData, FetchIcsData } from './lessons.processor'; @ApiTags('lessons') @Controller('lessons') export class LessonsController { constructor( private readonly configService: ConfigService, - private readonly untisService: UntisService, - private readonly lessonsService: LessonsService, + @InjectQueue('lessons-queue') private readonly lessonsQueue: Queue, ) {} @ApiOkResponse({ @@ -39,11 +39,13 @@ export class LessonsController { }) @Get(':classId') async getLessonsForClass(@Param('classId', ParseIntPipe) classId: number) { - const lessons = await this.untisService.fetchTimetable( - this.configService.get('LESSONS_TIMETABLE_BEFORE', 7), - this.configService.get('LESSONS_TIMETABLE_AFTER', 7), + const job = this.lessonsQueue.add('fetch', { + before: this.configService.get('LESSONS_TIMETABLE_BEFORE', 7), + after: this.configService.get('LESSONS_TIMETABLE_AFTER', 14), classId, - ); + } as FetchData); + + const lessons = (await job).finished(); if (!lessons) throw new HttpException( 'No lessons found, does class exist?', @@ -76,22 +78,23 @@ export class LessonsController { @Query('offset', new DefaultValuePipe(0), ParseIntPipe) offset?: number, ) { - const lessons = await this.untisService.fetchTimetable( - this.configService.get('LESSONS_TIMETABLE_BEFORE', 7), - this.configService.get('LESSONS_TIMETABLE_AFTER', 7), + const job = this.lessonsQueue.add('fetch-ics', { + before: this.configService.get('LESSONS_TIMETABLE_BEFORE', 7), + after: this.configService.get('LESSONS_TIMETABLE_AFTER', 14), classId, - ); - if (!lessons) + includedSubjects, + excludedSubjects, + alarms, + offset, + } as FetchIcsData); + + const ics = await (await job).finished(); + if (!ics) throw new HttpException( 'No lessons found, does class exist?', HttpStatus.NOT_FOUND, ); - return this.lessonsService.convertToEvents(lessons, { - includedSubjects, - excludedSubjects, - alarms, - offset, - }); + return ics; } } diff --git a/src/lessons/lessons.module.ts b/src/lessons/lessons.module.ts index 85d2074..d13ea7b 100644 --- a/src/lessons/lessons.module.ts +++ b/src/lessons/lessons.module.ts @@ -2,10 +2,20 @@ import { Module } from '@nestjs/common'; import { LessonsService } from './lessons.service'; import { LessonsController } from './lessons.controller'; import { UntisModule } from 'src/untis/untis.module'; +import { BullModule } from '@nestjs/bull'; +import { LessonsProcessor } from './lessons.processor'; @Module({ - providers: [LessonsService], + providers: [LessonsService, LessonsProcessor], controllers: [LessonsController], - imports: [UntisModule], + imports: [ + UntisModule, + BullModule.registerQueue({ + name: 'lessons-queue', + settings: { + stalledInterval: 5, + }, + }), + ], }) export class LessonsModule {} diff --git a/src/lessons/lessons.processor.ts b/src/lessons/lessons.processor.ts new file mode 100644 index 0000000..65148ef --- /dev/null +++ b/src/lessons/lessons.processor.ts @@ -0,0 +1,67 @@ +import { Process, Processor } from '@nestjs/bull'; +import { Job } from 'bull'; +import { UntisService } from 'src/untis/untis.service'; +import { LessonsService } from './lessons.service'; + +export interface FetchData { + before: number; + after: number; + classId: number; +} + +export interface FetchIcsData { + before: number; + after: number; + classId: number; + includedSubjects?: number[]; + excludedSubjects?: number[]; + alarms?: number[]; + offset?: number; +} + +@Processor('lessons-queue') +export class LessonsProcessor { + constructor( + private readonly untisService: UntisService, + private readonly lessonsService: LessonsService, + ) {} + + @Process('fetch') + async handleFetch(job: Job) { + const { before, after, classId } = job.data; + const lessons = await this.untisService.fetchTimetable( + before, + after, + classId, + ); + await job.progress(100); + return lessons; + } + + @Process('fetch-ics') + async handleFetchIcs(job: Job) { + const { + before, + after, + classId, + includedSubjects, + excludedSubjects, + alarms, + offset, + } = job.data; + const lessons = await this.untisService.fetchTimetable( + before, + after, + classId, + ); + await job.progress(50); + const ics = await this.lessonsService.convertToEvents(lessons, { + includedSubjects, + excludedSubjects, + alarms, + offset, + }); + await job.progress(100); + return ics; + } +} diff --git a/yarn.lock b/yarn.lock index 334dc09..79ddc86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -406,6 +406,11 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.0.tgz#04ad39d82176c7da1591c81e78b993cffd8348d8" integrity sha512-9S9QrXY2K0L4AGDcSgTi9vgiCcG8VcBv4Mp7/1hDPYoswIy6Z6KO5blYto82BT8M0MZNRWmCFLpCs3HlpYGGdw== +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -667,6 +672,51 @@ resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe" integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA== +"@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz#44d752c1a2dc113f15f781b7cc4f53a307e3fa38" + integrity sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ== + +"@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz#f954f34355712212a8e06c465bc06c40852c6bb3" + integrity sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw== + +"@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz#45c63037f045c2b15c44f80f0393fa24f9655367" + integrity sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg== + +"@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz#35707efeafe6d22b3f373caf9e8775e8920d1399" + integrity sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA== + +"@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz#091b1218b66c341f532611477ef89e83f25fae4f" + integrity sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA== + +"@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz#0f164b726869f71da3c594171df5ebc1c4b0a407" + integrity sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ== + +"@nestjs/bull-shared@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@nestjs/bull-shared/-/bull-shared-10.0.1.tgz#381656aebbb6a03a94e9568e434977bcc373e91c" + integrity sha512-8Td36l2i5x9+iQWjPB5Bd5+6u5Eangb5DclNcwrdwKqvd28xE92MSW97P4JV52C2kxrTjZwx8ck/wObAwtpQPw== + dependencies: + tslib "2.6.0" + +"@nestjs/bull@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@nestjs/bull/-/bull-10.0.1.tgz#592073d148a98f3e0b2268a81dc023db29ef9b66" + integrity sha512-1GcJ8BkHDgQdBMZ7SqAqgUHiFnISXmpGvewFeTc8wf87JLk2PweiKv9j9/KQKU+NI237pCe82XB0bXzTnsdxSw== + dependencies: + "@nestjs/bull-shared" "^10.0.1" + tslib "2.6.0" + "@nestjs/cache-manager@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@nestjs/cache-manager/-/cache-manager-2.1.0.tgz#e4dadc4ba9c02c059db4dac5e0b5513466e2895a" @@ -1679,6 +1729,19 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +bull@^4.11.5: + version "4.11.5" + resolved "https://registry.yarnpkg.com/bull/-/bull-4.11.5.tgz#59b51d631467fa83c1a3437b7fcf262005bea529" + integrity sha512-9jazyvBBYr55IRDkfJh/mJjWiq8NJUMoCC5zTuBX4JhkZvVXegnwsaIa1jr3x9xwSxGvWEhwQ9lt1jlCT5j6pQ== + dependencies: + cron-parser "^4.2.1" + get-port "^5.1.1" + ioredis "^5.3.2" + lodash "^4.17.21" + msgpackr "^1.5.2" + semver "^7.5.2" + uuid "^8.3.0" + busboy@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -1839,6 +1902,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== +cluster-key-slot@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1989,6 +2057,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== +cron-parser@^4.2.1: + version "4.9.0" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.9.0.tgz#0340694af3e46a0894978c6f52a6dbb5c0f11ad5" + integrity sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q== + dependencies: + luxon "^3.2.1" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2055,6 +2130,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -2630,6 +2710,11 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-port@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== + get-stream@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -2898,6 +2983,21 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +ioredis@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -3532,6 +3632,16 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -3574,6 +3684,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +luxon@^3.2.1: + version "3.4.4" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" + integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== + macos-release@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.5.1.tgz#bccac4a8f7b93163a8d163b8ebf385b3c5f55bf9" @@ -3728,6 +3843,27 @@ ms@2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +msgpackr-extract@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz#e05ec1bb4453ddf020551bcd5daaf0092a2c279d" + integrity sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A== + dependencies: + node-gyp-build-optional-packages "5.0.7" + optionalDependencies: + "@msgpackr-extract/msgpackr-extract-darwin-arm64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-darwin-x64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-arm" "3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-arm64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.2" + +msgpackr@^1.5.2: + version "1.10.0" + resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.10.0.tgz#adbca9c951f06647a808f76bc00a519cf6f7fbe4" + integrity sha512-rVQ5YAQDoZKZLX+h8tNq7FiHrPJoeGHViz3U4wIcykhAEpwF/nH2Vbk8dQxmpX5JavkI8C7pt4bnkJ02ZmRoUw== + optionalDependencies: + msgpackr-extract "^3.0.2" + multer@1.4.4-lts.1: version "1.4.4-lts.1" resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4-lts.1.tgz#24100f701a4611211cfae94ae16ea39bb314e04d" @@ -3790,6 +3926,11 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +node-gyp-build-optional-packages@5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz#5d2632bbde0ab2f6e22f1bbac2199b07244ae0b3" + integrity sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4187,6 +4328,18 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== + dependencies: + redis-errors "^1.0.0" + reflect-metadata@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" @@ -4308,7 +4461,7 @@ schema-utils@^3.1.1, schema-utils@^3.1.2: ajv "^6.12.5" ajv-keywords "^3.5.2" -semver@7.x, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@7.x, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -4454,6 +4607,11 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" @@ -4755,6 +4913,11 @@ tslib@2.5.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +tslib@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -4869,6 +5032,11 @@ uuid@9.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + 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"