because I got bored of customising my CV for every job
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(server): wire new modules into app.module and update test config

+171 -89
+17 -3
apps/server/package.json
··· 18 18 "e2e:coverage:c8": "E2E_EXTERNAL_URL=http://localhost:3000 npm run test:e2e && npm run e2e:coverage:c8:report", 19 19 "e2e:coverage:c8:stop": "pkill -f 'node dist/main.js' || true", 20 20 "e2e:coverage:all": "node src/scripts/e2e-coverage-all.cjs", 21 + "prepare": "prisma generate || true", 21 22 "prisma:generate": "prisma generate", 22 23 "prisma:migrate": "prisma migrate dev", 23 24 "prisma:deploy": "prisma migrate deploy", ··· 33 34 "@cv/ai-parser": "*", 34 35 "@cv/ai-provider": "*", 35 36 "@cv/auth": "*", 37 + "@cv/cv-renderer": "*", 36 38 "@cv/file-upload": "*", 37 39 "@cv/system": "*", 38 40 "@cv/utils": "*", ··· 48 50 "@nestjs/platform-express": "^10.4.7", 49 51 "@prisma/adapter-pg": "^7.1.0", 50 52 "@prisma/client": "^7.1.0", 53 + "@riotbyte/nest-service-locator": "link:/Users/niels/Developer/riotbyte/nest-service-locator", 54 + "@riotbyte/project-q-core": "link:/Users/niels/Developer/riotbyte/project-q/packages/core", 55 + "@riotbyte/project-q-nestjs": "link:/Users/niels/Developer/riotbyte/project-q/packages/framework/nest", 56 + "@riotbyte/project-q-prisma": "link:/Users/niels/Developer/riotbyte/project-q/packages/transport/prisma", 51 57 "@types/cookie-parser": "^1.4.10", 52 58 "@types/handlebars": "^4.0.40", 53 59 "@types/multer": "^2.0.0", 54 60 "apollo-server-express": "^3.13.0", 55 61 "bcryptjs": "^2.4.3", 62 + "canvas": "^3.1.0", 56 63 "class-transformer": "^0.5.1", 57 64 "class-validator": "^0.14.0", 58 65 "cookie-parser": "^1.4.7", 59 66 "dataloader": "^2.2.3", 67 + "express": "^4.21.2", 60 68 "graphql": "^16.12.0", 61 69 "graphql-scalars": "^1.23.0", 62 70 "graphql-type-json": "^0.3.2", 63 71 "handlebars": "^4.7.8", 64 - "joi": "^17.13.3", 72 + "mammoth": "^1.11.0", 65 73 "multer": "^2.0.2", 66 - "nestjs-zod": "^3.0.0", 74 + "nest-commander": "^3.16.0", 75 + "nestjs-zod": "^5.1.1", 67 76 "passport": "^0.7.0", 68 77 "passport-jwt": "^4.0.1", 69 78 "passport-local": "^1.0.0", 79 + "pdf-parse": "^1.1.4", 80 + "pdf2json": "^3.1.4", 81 + "pdfjs-dist": "^3.11.174", 70 82 "pg": "^8.16.3", 71 83 "reflect-metadata": "^0.2.2", 72 84 "resend": "^6.5.2", 73 85 "rxjs": "^7.8.1", 74 - "zod": "^3.23.8" 86 + "tesseract.js": "^5.1.1", 87 + "zod": "^4.3.6" 75 88 }, 76 89 "devDependencies": { 77 90 "@biomejs/biome": "^2.2.6", ··· 85 98 "@types/node": "^22.7.5", 86 99 "@types/passport-jwt": "^4.0.1", 87 100 "@types/passport-local": "^1.0.38", 101 + "@types/pdf-parse": "^1.1.5", 88 102 "@types/pg": "^8.15.6", 89 103 "@vitest/ui": "^4.0.16", 90 104 "jest": "^29.7.0",
+26
apps/server/prisma/models/queue.prisma
··· 1 + enum MessageStatusEnum { 2 + PENDING 3 + SUCCESS 4 + FAILURE 5 + } 6 + 7 + model MessageStatus { 8 + id String @id @default(uuid()) 9 + name MessageStatusEnum @unique 10 + messages Message[] 11 + } 12 + 13 + model Message { 14 + id String @id @default(uuid()) 15 + messengerId String 16 + name String 17 + envelope String 18 + queue String @default("default") 19 + availableAt DateTime 20 + deliveredAt DateTime? 21 + createdAt DateTime @default(now()) 22 + status MessageStatus @relation(fields: [statusId], references: [id]) 23 + statusId String 24 + 25 + @@index([queue, availableAt]) 26 + }
+2
apps/server/src/main.ts
··· 2 2 import { NestFactory } from "@nestjs/core"; 3 3 import { ExpressAdapter } from "@nestjs/platform-express"; 4 4 import cookieParser from "cookie-parser"; 5 + import express from "express"; 5 6 import { ZodValidationPipe } from "nestjs-zod"; 6 7 import { configureCors } from "./config/cors.configuration"; 7 8 import { DomainExceptionFilter } from "./config/exception-to-http.pipe"; ··· 12 13 const app = await NestFactory.create(AppModule, new ExpressAdapter()); 13 14 const configService = app.get(ConfigService); 14 15 16 + app.use(express.json({ limit: "15mb" })); 15 17 app.use(cookieParser()); 16 18 configureCors(app); 17 19
+20 -6
apps/server/src/modules/app.module.ts
··· 12 12 import { JwtModule } from "@nestjs/jwt"; 13 13 import type { Request, Response } from "express"; 14 14 import { AppConfigModule } from "@/config/config.module"; 15 - import { envValidationSchema } from "@/config/env.validation"; 15 + import { validate } from "@/config/env.validation"; 16 + import { AdminModule } from "./admin/admin.module"; 17 + import { AiCallLogModule } from "./admin/ai-call-log.module"; 16 18 import { AppModule as AppModuleComponent } from "./app/app.module"; 19 + import { ApplicationStatusModule } from "./application/application-status/application-status.module"; 17 20 import { ApplicationModule } from "./application/application.module"; 18 21 import { AuthenticationModule } from "./authentication/authentication.module"; 19 22 import { CurrentUserModule } from "./current-user/current-user.module"; 20 23 import { CVParserModule } from "./cv-parser/cv-parser.module"; 21 24 import { CVTemplateModule } from "./cv-template/cv-template.module"; 25 + import { DataImportModule } from "./data-import/data-import.module"; 22 26 import { SeedModule } from "./database/seed/seed.module"; 23 27 import { EducationModule } from "./education/education.module"; 24 28 import { CompanyModule } from "./job-experience/company/company.module"; ··· 26 30 import { LevelModule } from "./job-experience/level/level.module"; 27 31 import { RoleModule } from "./job-experience/role/role.module"; 28 32 import { SkillModule } from "./job-experience/skill/skill.module"; 33 + import { OnboardingModule } from "./onboarding/onboarding.module"; 29 34 import { OrganizationModule } from "./organization/organization.module"; 35 + import { ProfileModule } from "./profile/profile.module"; 36 + import { UserAiSettingsModule } from "./user-settings/user-ai-settings.module"; 37 + import { ProjectQMessengerModule } from "./messenger/messenger.module"; 38 + import { JobTypeModule } from "./vacancies/job-type/job-type.module"; 30 39 import { VacancyModule } from "./vacancies/vacancy.module"; 31 40 32 41 @Module({ 33 42 imports: [ 34 43 ConfigModule.forRoot({ 35 44 isGlobal: true, 36 - validationSchema: envValidationSchema, 37 - validationOptions: { 38 - abortEarly: false, // Show all validation errors at once 39 - allowUnknown: true, // Allow unknown environment variables 40 - }, 45 + validate, 41 46 }), 42 47 JwtModule.registerAsync({ 43 48 global: true, ··· 60 65 res, 61 66 }), 62 67 }), 68 + AiCallLogModule, 63 69 AppConfigModule, 64 70 BaseModule, 65 71 DatabaseModule, ··· 77 83 LevelModule, 78 84 EmploymentModule, 79 85 OrganizationModule, 86 + JobTypeModule, 80 87 VacancyModule, 88 + ApplicationStatusModule, 81 89 ApplicationModule, 82 90 CVParserModule, 83 91 CVTemplateModule, 92 + DataImportModule, 93 + ProjectQMessengerModule, 84 94 EducationModule, 85 95 SeedModule, 96 + UserAiSettingsModule, 97 + OnboardingModule, 98 + ProfileModule, 99 + AdminModule, 86 100 ], 87 101 providers: [], 88 102 })
+6 -2
apps/server/test/auth-integration.e2e-spec.ts
··· 89 89 .expect(200); 90 90 91 91 expect(response.body.errors).toBeDefined(); 92 - expect(response.body.errors[0].message).toContain("No authentication token provided"); 92 + expect(response.body.errors[0].message).toContain( 93 + "No authentication token provided", 94 + ); 93 95 }); 94 96 95 97 it("should fail login with invalid credentials", async () => { ··· 262 264 .expect(200); 263 265 264 266 expect(response.body.errors).toBeDefined(); 265 - expect(response.body.errors[0].message).toContain("No authentication token provided"); 267 + expect(response.body.errors[0].message).toContain( 268 + "No authentication token provided", 269 + ); 266 270 }); 267 271 }); 268 272 });
+3 -1
apps/server/test/auth.e2e-spec.ts
··· 118 118 .expect(200); 119 119 120 120 expect(response.body.errors).toBeDefined(); 121 - expect(response.body.errors[0].message).toContain("No authentication token provided"); 121 + expect(response.body.errors[0].message).toContain( 122 + "No authentication token provided", 123 + ); 122 124 }); 123 125 124 126 it("should fail login with invalid credentials", async () => {
+1 -1
apps/server/test/coverage-unit/lcov-report/index.html
··· 86 86 <div class='footer quiet pad2 space-top1 center small'> 87 87 Code coverage generated by 88 88 <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> 89 - at 2026-01-10T20:21:56.043Z 89 + at 2026-02-25T18:54:50.277Z 90 90 </div> 91 91 <script src="prettify.js"></script> 92 92 <script>
+29 -15
apps/server/test/cv-upload-integration.e2e-spec.ts
··· 43 43 .send(TEST_USER) 44 44 .timeout(10000); 45 45 46 - if (registerResponse.status === 201 && registerResponse.body.accessToken) { 46 + if ( 47 + registerResponse.status === 201 && 48 + registerResponse.body.accessToken 49 + ) { 47 50 accessToken = registerResponse.body.accessToken; 48 51 console.log(`✅ Test user registered`); 49 52 } else if (registerResponse.status === 409) { ··· 187 190 console.log( 188 191 ` Education: ${response.body.data.education?.length || 0}`, 189 192 ); 190 - console.log( 191 - ` Skills: ${response.body.data.skills?.length || 0}`, 192 - ); 193 + console.log(` Skills: ${response.body.data.skills?.length || 0}`); 193 194 194 195 if (duration < 30) { 195 196 console.log(` 🚀 Excellent performance!`); ··· 204 205 // Only test one file if both exist 205 206 break; 206 207 } catch (error) { 207 - if (error instanceof Error && "code" in error && error.code === "ENOENT") { 208 + if ( 209 + error instanceof Error && 210 + "code" in error && 211 + error.code === "ENOENT" 212 + ) { 208 213 console.log(` ⚠️ Skipping ${fileName}: not found`); 209 214 } else { 210 215 throw error; ··· 235 240 236 241 console.log(`\n⏱️ Results:`); 237 242 console.log(` Duration: ${duration.toFixed(1)}s`); 238 - console.log(` Name: ${response.body.data.personalInfo.name || "N/A"}`); 243 + console.log( 244 + ` Name: ${response.body.data.personalInfo.name || "N/A"}`, 245 + ); 239 246 console.log( 240 247 ` Job Experiences: ${response.body.data.jobExperiences?.length || 0}`, 241 248 ); 242 249 243 250 expect(response.body.success).toBe(true); 244 251 } catch (error) { 245 - if (error instanceof Error && "code" in error && error.code === "ENOENT") { 252 + if ( 253 + error instanceof Error && 254 + "code" in error && 255 + error.code === "ENOENT" 256 + ) { 246 257 console.log(` ⚠️ Skipping ${fileName}: not found`); 247 258 } else { 248 259 throw error; ··· 272 283 273 284 describe("Performance Benchmarks", () => { 274 285 it("should provide parsing statistics for all test files", async () => { 275 - const results: Array<{ file: string; duration: number; success: boolean }> = 276 - []; 286 + const results: Array<{ 287 + file: string; 288 + duration: number; 289 + success: boolean; 290 + }> = []; 277 291 278 - const testFiles = [ 279 - "test-cv-tiny.md", 280 - "test-cv.txt", 281 - "test-cv.md", 282 - ]; 292 + const testFiles = ["test-cv-tiny.md", "test-cv.txt", "test-cv.md"]; 283 293 284 294 for (const fileName of testFiles) { 285 295 const filePath = join(__dirname, "../../../", fileName); ··· 301 311 success: response.status === 201, 302 312 }); 303 313 } catch (error) { 304 - if (error instanceof Error && "code" in error && error.code === "ENOENT") { 314 + if ( 315 + error instanceof Error && 316 + "code" in error && 317 + error.code === "ENOENT" 318 + ) { 305 319 console.log(` ⚠️ Skipping ${fileName}: not found`); 306 320 } else { 307 321 results.push({ file: fileName, duration: 0, success: false });
+8 -19
apps/server/test/cv-upload.e2e-spec.ts
··· 102 102 console.log(` Name: ${data.personalInfo.name}`); 103 103 console.log(` Job Experiences: ${data.jobExperiences.length}`); 104 104 console.log(` Education: ${data.education.length}`); 105 - console.log( 106 - ` Skills: ${data.skills?.length || 0}`, 107 - ); 105 + console.log(` Skills: ${data.skills?.length || 0}`); 108 106 109 107 // Performance assertions 110 108 if (duration < 30) { ··· 150 148 151 149 describe("PDF File Upload", () => { 152 150 it("should parse a PDF CV successfully", async () => { 153 - const pdfPath = join( 154 - __dirname, 155 - "../../../test-files/sample-cv.pdf", 156 - ); 151 + const pdfPath = join(__dirname, "../../../test-files/sample-cv.pdf"); 157 152 158 153 // Skip if test PDF doesn't exist 159 154 try { ··· 174 169 175 170 console.log(`\n⏱️ PDF Parsing: ${duration.toFixed(1)}s`); 176 171 } catch (error) { 177 - console.log(` ⚠️ Skipping PDF test: test-files/sample-cv.pdf not found`); 172 + console.log( 173 + ` ⚠️ Skipping PDF test: test-files/sample-cv.pdf not found`, 174 + ); 178 175 } 179 176 }, 360000); 180 177 }); ··· 215 212 const results: Array<{ file: string; duration: number }> = []; 216 213 217 214 // Test with multiple file sizes 218 - const testFiles = [ 219 - "test-cv-tiny.md", 220 - "test-cv.txt", 221 - "test-cv.md", 222 - ]; 215 + const testFiles = ["test-cv-tiny.md", "test-cv.txt", "test-cv.md"]; 223 216 224 217 for (const fileName of testFiles) { 225 218 const filePath = join(__dirname, "../../../", fileName); ··· 296 289 console.log( 297 290 ` Name: ${response.body.data.personalInfo.name || "N/A"}`, 298 291 ); 299 - console.log( 300 - ` Jobs: ${response.body.data.jobExperiences.length}`, 301 - ); 302 - console.log( 303 - ` Education: ${response.body.data.education.length}`, 304 - ); 292 + console.log(` Jobs: ${response.body.data.jobExperiences.length}`); 293 + console.log(` Education: ${response.body.data.education.length}`); 305 294 306 295 expect(response.body.success).toBe(true); 307 296 } catch {
+15 -3
apps/server/test/cv-upload.integration.ts
··· 267 267 // Test one file and break 268 268 break; 269 269 } catch (error) { 270 - if (error instanceof Error && "code" in error && error.code === "ENOENT") { 270 + if ( 271 + error instanceof Error && 272 + "code" in error && 273 + error.code === "ENOENT" 274 + ) { 271 275 console.log(` ⚠️ Skipping ${fileName}: not found`); 272 276 continue; 273 277 } ··· 317 321 318 322 expect(result.success).toBe(true); 319 323 } catch (error) { 320 - if (error instanceof Error && "code" in error && error.code === "ENOENT") { 324 + if ( 325 + error instanceof Error && 326 + "code" in error && 327 + error.code === "ENOENT" 328 + ) { 321 329 console.log(` ⚠️ Skipping ${fileName}: not found`); 322 330 } else { 323 331 throw error; ··· 376 384 success: response.ok, 377 385 }); 378 386 } catch (error) { 379 - if (error instanceof Error && "code" in error && error.code === "ENOENT") { 387 + if ( 388 + error instanceof Error && 389 + "code" in error && 390 + error.code === "ENOENT" 391 + ) { 380 392 console.log(` ⚠️ Skipping ${fileName}: not found`); 381 393 } 382 394 }
+1
apps/server/tsconfig.json
··· 6 6 "types": ["node"], 7 7 "experimentalDecorators": true, 8 8 "emitDecoratorMetadata": true, 9 + "preserveSymlinks": true, 9 10 "paths": { 10 11 "@/*": ["./src/*"], 11 12 "@cv/auth": ["../../packages/auth/src"],
+6 -1
apps/server/vitest.config.ts
··· 7 7 testTimeout: 60000, // 60 seconds default 8 8 hookTimeout: 60000, 9 9 include: ["**/*.{test,spec,integration}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], 10 - exclude: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/__tests__/**/*.spec.ts"], // Exclude Jest tests 10 + exclude: [ 11 + "**/node_modules/**", 12 + "**/dist/**", 13 + "**/build/**", 14 + "**/__tests__/**/*.spec.ts", 15 + ], // Exclude Jest tests 11 16 }, 12 17 });
+37 -38
pnpm-lock.yaml
··· 282 282 specifier: ^7.1.0 283 283 version: 7.2.0(prisma@7.2.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3) 284 284 '@riotbyte/nest-service-locator': 285 - specifier: ^0.2.0 286 - version: 0.2.0(@nestjs/platform-express@10.4.20)(class-transformer@0.5.1)(class-validator@0.14.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) 285 + specifier: link:/Users/niels/Developer/riotbyte/nest-service-locator 286 + version: link:../../../../riotbyte/nest-service-locator 287 287 '@riotbyte/project-q-core': 288 288 specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/core 289 289 version: link:../../../../riotbyte/project-q/packages/core 290 290 '@riotbyte/project-q-nestjs': 291 291 specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/framework/nest 292 292 version: link:../../../../riotbyte/project-q/packages/framework/nest 293 - '@riotbyte/project-q-transport-postgres': 294 - specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/transport/postgres 295 - version: link:../../../../riotbyte/project-q/packages/transport/postgres 293 + '@riotbyte/project-q-prisma': 294 + specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/transport/prisma 295 + version: link:../../../../riotbyte/project-q/packages/transport/prisma 296 296 '@types/cookie-parser': 297 297 specifier: ^1.4.10 298 298 version: 1.4.10(@types/express@5.0.6) ··· 443 443 version: 6.3.4 444 444 ts-jest: 445 445 specifier: ^29.1.2 446 - version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)))(typescript@5.9.3) 446 + version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3))(typescript@5.9.3) 447 447 ts-node: 448 448 specifier: ^10.9.2 449 449 version: 10.9.2(@types/node@22.19.3)(typescript@5.9.3) ··· 462 462 463 463 apps/worker: 464 464 dependencies: 465 + '@cv/system': 466 + specifier: '*' 467 + version: link:../../packages/system 465 468 '@nestjs/common': 466 469 specifier: ^10.4.7 467 470 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) 471 + '@nestjs/config': 472 + specifier: ^3.2.0 473 + version: 3.3.0(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) 468 474 '@nestjs/core': 469 475 specifier: ^10.4.7 470 476 version: 10.4.20(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) 477 + '@nestjs/event-emitter': 478 + specifier: ^3.0.1 479 + version: 3.0.1(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20) 480 + '@riotbyte/nest-service-locator': 481 + specifier: link:/Users/niels/Developer/riotbyte/nest-service-locator 482 + version: link:../../../../riotbyte/nest-service-locator 471 483 '@riotbyte/project-q-core': 472 484 specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/core 473 485 version: link:../../../../riotbyte/project-q/packages/core 474 - '@riotbyte/project-q-transport-postgres': 475 - specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/transport/postgres 476 - version: link:../../../../riotbyte/project-q/packages/transport/postgres 477 - pg: 478 - specifier: ^8.16.3 479 - version: 8.16.3 486 + '@riotbyte/project-q-nestjs': 487 + specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/framework/nest 488 + version: link:../../../../riotbyte/project-q/packages/framework/nest 489 + '@riotbyte/project-q-prisma': 490 + specifier: link:/Users/niels/Developer/riotbyte/project-q/packages/transport/prisma 491 + version: link:../../../../riotbyte/project-q/packages/transport/prisma 492 + eventemitter2: 493 + specifier: ^6.4.9 494 + version: 6.4.9 495 + nest-commander: 496 + specifier: ^3.16.0 497 + version: 3.16.0(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.20)(@types/inquirer@8.2.12)(typescript@5.9.3) 480 498 playwright: 481 499 specifier: ^1.52.0 482 500 version: 1.58.2 ··· 489 507 rxjs: 490 508 specifier: ^7.8.1 491 509 version: 7.8.2 510 + zod: 511 + specifier: ^4.3.6 512 + version: 4.3.6 492 513 devDependencies: 493 514 '@cv/tsconfig': 494 515 specifier: '*' ··· 496 517 '@types/node': 497 518 specifier: ^22.7.5 498 519 version: 22.19.3 499 - '@types/pg': 500 - specifier: ^8.15.6 501 - version: 8.16.0 502 520 nodemon: 503 521 specifier: ^3.1.7 504 522 version: 3.1.11 ··· 535 553 version: 29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)) 536 554 ts-jest: 537 555 specifier: ^29.1.1 538 - version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)))(typescript@5.9.3) 556 + version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3))(typescript@5.9.3) 539 557 typescript: 540 558 specifier: ^5.3.3 541 559 version: 5.9.3 ··· 566 584 version: 29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)) 567 585 ts-jest: 568 586 specifier: ^29.1.2 569 - version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)))(typescript@5.9.3) 587 + version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3))(typescript@5.9.3) 570 588 typescript: 571 589 specifier: ^5.3.3 572 590 version: 5.9.3 ··· 688 706 version: 29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)) 689 707 ts-jest: 690 708 specifier: ^29.1.1 691 - version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)))(typescript@5.9.3) 709 + version: 29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3))(typescript@5.9.3) 692 710 typescript: 693 711 specifier: ^5.3.3 694 712 version: 5.9.3 ··· 2980 2998 '@repeaterjs/repeater@3.0.6': 2981 2999 resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} 2982 3000 2983 - '@riotbyte/nest-service-locator@0.2.0': 2984 - resolution: {integrity: sha512-8dt0MC1Xm7Q7DjpgFAq4seF+SvT8oXy2GDQ/lbQWUYnXELBy+4fmRnOXOASPVfuKvcfVMUj5s/zoIcFwW01adw==} 2985 - engines: {node: '>= 18.0.0'} 2986 - 2987 3001 '@rolldown/pluginutils@1.0.0-beta.27': 2988 3002 resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} 2989 3003 ··· 10953 10967 10954 10968 '@repeaterjs/repeater@3.0.6': {} 10955 10969 10956 - '@riotbyte/nest-service-locator@0.2.0(@nestjs/platform-express@10.4.20)(class-transformer@0.5.1)(class-validator@0.14.3)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)': 10957 - dependencies: 10958 - '@nestjs/common': 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) 10959 - '@nestjs/core': 10.4.20(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) 10960 - transitivePeerDependencies: 10961 - - '@nestjs/microservices' 10962 - - '@nestjs/platform-express' 10963 - - '@nestjs/websockets' 10964 - - class-transformer 10965 - - class-validator 10966 - - encoding 10967 - - reflect-metadata 10968 - - rxjs 10969 - - supports-color 10970 - 10971 10970 '@rolldown/pluginutils@1.0.0-beta.27': {} 10972 10971 10973 10972 '@rollup/pluginutils@5.3.0(rollup@4.54.0)': ··· 16704 16703 16705 16704 trough@2.2.0: {} 16706 16705 16707 - ts-jest@29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.19.3)(typescript@5.9.3)))(typescript@5.9.3): 16706 + ts-jest@29.4.6(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.3))(typescript@5.9.3): 16708 16707 dependencies: 16709 16708 bs-logger: 0.2.6 16710 16709 fast-json-stable-stringify: 2.1.0