eletrotupi / tcc/ commit / aaca724

api: split the suite into a DB-free unit project

The suite was almost entirely integration, so the pure logic could only
be reached through Postgres and every file ran serially against one
shared database. A `unit` Vitest project now runs `*.unit.test.ts` files
with no setup, no database and in parallel, while the existing database
project keeps its global mocks and serial run. Coverage is added as a
report-only config so the unit-versus-integration ratio is visible,
although it is kind of not *that* useful imo
Pedro Lucas Porcellis porcellis@eletrotupi.com · 10 days ago aaca724b6020e9a1b82acb9cc3bb90f81951dc21 Browse files
Parents 92fe16c
Changed files
8
Additions
+834
Deletions
-63
api/.gitignore modified+1
api/.gitignore
1 1
node_modules
2 2
.env
3 3
.env.development
4 4
.env.production
5 5
src/generated/prisma
6 6
orbit.db
7 +
coverage
api/package-lock.json modified+785 -56
api/package-lock.json
1 1
{
2 2
  "name": "orbit-api",
3 3
  "version": "0.0.0",
4 4
  "lockfileVersion": 3,
5 5
  "requires": true,
43 43
        "@types/multer": "^2.1.0",
44 44
        "@types/multer-s3": "^3.0.3",
45 45
        "@types/node": "^25.5.2",
46 46
        "@types/react": "^19.2.17",
47 47
        "@types/supertest": "^6.0.3",
48 +
        "@vitest/coverage-v8": "^3.2.6",
48 49
        "cross-var": "^1.1.0",
49 50
        "dotenv-cli": "^11.0.0",
50 51
        "nodemon": "^3.1.14",
51 52
        "pino-pretty": "^13.1.3",
52 53
        "prisma": "^7.5.0",
54 55
        "tsc-alias": "^1.8.16",
55 56
        "tsx": "^4.21.0",
56 57
        "typescript": "^6.0.2",
57 58
        "vite-tsconfig-paths": "^5.1.4",
58 59
        "vitest": "^3.0.0"
60 +
      }
61 +
    },
62 +
    "node_modules/@ampproject/remapping": {
63 +
      "version": "2.3.0",
64 +
      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
65 +
      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
66 +
      "dev": true,
67 +
      "license": "Apache-2.0",
68 +
      "dependencies": {
69 +
        "@jridgewell/gen-mapping": "^0.3.5",
70 +
        "@jridgewell/trace-mapping": "^0.3.24"
71 +
      },
72 +
      "engines": {
73 +
        "node": ">=6.0.0"
59 74
      }
60 75
    },
61 76
    "node_modules/@aws-crypto/crc32": {
62 77
      "version": "5.2.0",
63 78
      "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
583 598
      "license": "Apache-2.0",
584 599
      "engines": {
585 600
        "node": ">=18.0.0"
586 601
      }
587 602
    },
603 +
    "node_modules/@babel/helper-string-parser": {
604 +
      "version": "7.29.7",
605 +
      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
606 +
      "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
607 +
      "devOptional": true,
608 +
      "license": "MIT",
609 +
      "engines": {
610 +
        "node": ">=6.9.0"
611 +
      }
612 +
    },
613 +
    "node_modules/@babel/helper-validator-identifier": {
614 +
      "version": "7.29.7",
615 +
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
616 +
      "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
617 +
      "devOptional": true,
618 +
      "license": "MIT",
619 +
      "engines": {
620 +
        "node": ">=6.9.0"
621 +
      }
622 +
    },
623 +
    "node_modules/@babel/parser": {
624 +
      "version": "7.29.9",
625 +
      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz",
626 +
      "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
627 +
      "devOptional": true,
628 +
      "license": "MIT",
629 +
      "dependencies": {
630 +
        "@babel/types": "^7.29.8"
631 +
      },
632 +
      "bin": {
633 +
        "parser": "bin/babel-parser.js"
634 +
      },
635 +
      "engines": {
636 +
        "node": ">=6.0.0"
637 +
      }
638 +
    },
588 639
    "node_modules/@babel/runtime": {
589 640
      "version": "7.29.7",
590 641
      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
591 642
      "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
592 643
      "license": "MIT",
593 644
      "engines": {
594 645
        "node": ">=6.9.0"
595 646
      }
596 647
    },
648 +
    "node_modules/@babel/types": {
649 +
      "version": "7.29.8",
650 +
      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
651 +
      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
652 +
      "devOptional": true,
653 +
      "license": "MIT",
654 +
      "dependencies": {
655 +
        "@babel/helper-string-parser": "^7.29.7",
656 +
        "@babel/helper-validator-identifier": "^7.29.7"
657 +
      },
658 +
      "engines": {
659 +
        "node": ">=6.9.0"
660 +
      }
661 +
    },
662 +
    "node_modules/@bcoe/v8-coverage": {
663 +
      "version": "1.0.2",
664 +
      "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
665 +
      "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
666 +
      "dev": true,
667 +
      "license": "MIT",
668 +
      "engines": {
669 +
        "node": ">=18"
670 +
      }
671 +
    },
597 672
    "node_modules/@chevrotain/cst-dts-gen": {
598 673
      "version": "10.5.0",
599 674
      "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.5.0.tgz",
600 675
      "integrity": "sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==",
601 676
      "devOptional": true,
1126 1201
      "version": "1.5.1",
1127 1202
      "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz",
1128 1203
      "integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==",
1129 1204
      "license": "MIT"
1130 1205
    },
1206 +
    "node_modules/@isaacs/cliui": {
1207 +
      "version": "8.0.2",
1208 +
      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
1209 +
      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
1210 +
      "dev": true,
1211 +
      "license": "ISC",
1212 +
      "dependencies": {
1213 +
        "string-width": "^5.1.2",
1214 +
        "string-width-cjs": "npm:string-width@^4.2.0",
1215 +
        "strip-ansi": "^7.0.1",
1216 +
        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
1217 +
        "wrap-ansi": "^8.1.0",
1218 +
        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
1219 +
      },
1220 +
      "engines": {
1221 +
        "node": ">=12"
1222 +
      }
1223 +
    },
1224 +
    "node_modules/@istanbuljs/schema": {
1225 +
      "version": "0.1.6",
1226 +
      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
1227 +
      "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
1228 +
      "dev": true,
1229 +
      "license": "MIT",
1230 +
      "engines": {
1231 +
        "node": ">=8"
1232 +
      }
1233 +
    },
1234 +
    "node_modules/@jridgewell/gen-mapping": {
1235 +
      "version": "0.3.13",
1236 +
      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
1237 +
      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
1238 +
      "dev": true,
1239 +
      "license": "MIT",
1240 +
      "dependencies": {
1241 +
        "@jridgewell/sourcemap-codec": "^1.5.0",
1242 +
        "@jridgewell/trace-mapping": "^0.3.24"
1243 +
      }
1244 +
    },
1245 +
    "node_modules/@jridgewell/resolve-uri": {
1246 +
      "version": "3.1.2",
1247 +
      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
1248 +
      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
1249 +
      "dev": true,
1250 +
      "license": "MIT",
1251 +
      "engines": {
1252 +
        "node": ">=6.0.0"
1253 +
      }
1254 +
    },
1131 1255
    "node_modules/@jridgewell/sourcemap-codec": {
1132 1256
      "version": "1.5.5",
1133 1257
      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
1134 1258
      "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
1135 1259
      "dev": true,
1136 1260
      "license": "MIT"
1261 +
    },
1262 +
    "node_modules/@jridgewell/trace-mapping": {
1263 +
      "version": "0.3.31",
1264 +
      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
1265 +
      "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
1266 +
      "dev": true,
1267 +
      "license": "MIT",
1268 +
      "dependencies": {
1269 +
        "@jridgewell/resolve-uri": "^3.1.0",
1270 +
        "@jridgewell/sourcemap-codec": "^1.4.14"
1271 +
      }
1137 1272
    },
1138 1273
    "node_modules/@mrleebo/prisma-ast": {
1139 1274
      "version": "0.13.1",
1140 1275
      "resolved": "https://registry.npmjs.org/@mrleebo/prisma-ast/-/prisma-ast-0.13.1.tgz",
1141 1276
      "integrity": "sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw==",
1314 1449
    "node_modules/@pinojs/redact": {
1315 1450
      "version": "0.4.0",
1316 1451
      "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
1317 1452
      "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==",
1318 1453
      "license": "MIT"
1454 +
    },
1455 +
    "node_modules/@pkgjs/parseargs": {
1456 +
      "version": "0.11.0",
1457 +
      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
1458 +
      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
1459 +
      "dev": true,
1460 +
      "license": "MIT",
1461 +
      "optional": true,
1462 +
      "engines": {
1463 +
        "node": ">=14"
1464 +
      }
1319 1465
    },
1320 1466
    "node_modules/@prisma/adapter-better-sqlite3": {
1321 1467
      "version": "7.5.0",
1322 1468
      "resolved": "https://registry.npmjs.org/@prisma/adapter-better-sqlite3/-/adapter-better-sqlite3-7.5.0.tgz",
1323 1469
      "integrity": "sha512-ThP6y1cAZW/BdHuuTKzO+j8vzEzXDMZaDPmboJyrkdbJvO9LRiHdnG5LNKAht8YYwjHgQoq7G7NtKbaW7NebVQ==",
2475 2621
      "dependencies": {
2476 2622
        "@types/methods": "^1.1.4",
2477 2623
        "@types/superagent": "^8.1.0"
2478 2624
      }
2479 2625
    },
2626 +
    "node_modules/@vitest/coverage-v8": {
2627 +
      "version": "3.2.6",
2628 +
      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.6.tgz",
2629 +
      "integrity": "sha512-LsAdmUapA0qSN306d8+zOyawM0hFm2m2Hg9IwVNIKBm+qJV8cijiq2c+gxKZcB1HCfIWAy+0qEZDCUQA58A1cw==",
2630 +
      "dev": true,
2631 +
      "license": "MIT",
2632 +
      "dependencies": {
2633 +
        "@ampproject/remapping": "^2.3.0",
2634 +
        "@bcoe/v8-coverage": "^1.0.2",
2635 +
        "ast-v8-to-istanbul": "^0.3.3",
2636 +
        "debug": "^4.4.1",
2637 +
        "istanbul-lib-coverage": "^3.2.2",
2638 +
        "istanbul-lib-report": "^3.0.1",
2639 +
        "istanbul-lib-source-maps": "^5.0.6",
2640 +
        "istanbul-reports": "^3.1.7",
2641 +
        "magic-string": "^0.30.17",
2642 +
        "magicast": "^0.3.5",
2643 +
        "std-env": "^3.9.0",
2644 +
        "test-exclude": "^7.0.1",
2645 +
        "tinyrainbow": "^2.0.0"
2646 +
      },
2647 +
      "funding": {
2648 +
        "url": "https://opencollective.com/vitest"
2649 +
      },
2650 +
      "peerDependencies": {
2651 +
        "@vitest/browser": "3.2.6",
2652 +
        "vitest": "3.2.6"
2653 +
      },
2654 +
      "peerDependenciesMeta": {
2655 +
        "@vitest/browser": {
2656 +
          "optional": true
2657 +
        }
2658 +
      }
2659 +
    },
2480 2660
    "node_modules/@vitest/expect": {
2481 2661
      "version": "3.2.6",
2482 2662
      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz",
2483 2663
      "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==",
2484 2664
      "dev": true,
2519 2699
        "vite": {
2520 2700
          "optional": true
2521 2701
        }
2522 2702
      }
2523 2703
    },
2524 -
    "node_modules/@vitest/mocker/node_modules/estree-walker": {
2525 -
      "version": "3.0.3",
2526 -
      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
2527 -
      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
2528 -
      "dev": true,
2529 -
      "license": "MIT",
2530 -
      "dependencies": {
2531 -
        "@types/estree": "^1.0.0"
2532 -
      }
2533 -
    },
2534 2704
    "node_modules/@vitest/pretty-format": {
2535 -
      "version": "3.2.6",
2536 -
      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz",
2537 -
      "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==",
2705 +
      "version": "3.2.7",
2706 +
      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz",
2707 +
      "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==",
2538 2708
      "dev": true,
2539 2709
      "license": "MIT",
2540 2710
      "dependencies": {
2541 2711
        "tinyrainbow": "^2.0.0"
2542 2712
      },
2572 2742
      },
2573 2743
      "funding": {
2574 2744
        "url": "https://opencollective.com/vitest"
2575 2745
      }
2576 2746
    },
2747 +
    "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": {
2748 +
      "version": "3.2.6",
2749 +
      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz",
2750 +
      "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==",
2751 +
      "dev": true,
2752 +
      "license": "MIT",
2753 +
      "dependencies": {
2754 +
        "tinyrainbow": "^2.0.0"
2755 +
      },
2756 +
      "funding": {
2757 +
        "url": "https://opencollective.com/vitest"
2758 +
      }
2759 +
    },
2577 2760
    "node_modules/@vitest/spy": {
2578 2761
      "version": "3.2.6",
2579 2762
      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz",
2580 2763
      "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==",
2581 2764
      "dev": true,
2600 2783
      },
2601 2784
      "funding": {
2602 2785
        "url": "https://opencollective.com/vitest"
2603 2786
      }
2604 2787
    },
2788 +
    "node_modules/@vitest/utils/node_modules/@vitest/pretty-format": {
2789 +
      "version": "3.2.6",
2790 +
      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz",
2791 +
      "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==",
2792 +
      "dev": true,
2793 +
      "license": "MIT",
2794 +
      "dependencies": {
2795 +
        "tinyrainbow": "^2.0.0"
2796 +
      },
2797 +
      "funding": {
2798 +
        "url": "https://opencollective.com/vitest"
2799 +
      }
2800 +
    },
2605 2801
    "node_modules/abs-svg-path": {
2606 2802
      "version": "0.1.1",
2607 2803
      "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz",
2608 2804
      "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==",
2609 2805
      "license": "MIT"
2619 2815
      },
2620 2816
      "engines": {
2621 2817
        "node": ">= 0.6"
2622 2818
      }
2623 2819
    },
2820 +
    "node_modules/ansi-regex": {
2821 +
      "version": "6.4.0",
2822 +
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz",
2823 +
      "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==",
2824 +
      "dev": true,
2825 +
      "license": "MIT",
2826 +
      "engines": {
2827 +
        "node": ">=12"
2828 +
      },
2829 +
      "funding": {
2830 +
        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
2831 +
      }
2832 +
    },
2833 +
    "node_modules/ansi-styles": {
2834 +
      "version": "6.2.3",
2835 +
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
2836 +
      "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
2837 +
      "dev": true,
2838 +
      "license": "MIT",
2839 +
      "engines": {
2840 +
        "node": ">=12"
2841 +
      },
2842 +
      "funding": {
2843 +
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2844 +
      }
2845 +
    },
2624 2846
    "node_modules/anymatch": {
2625 2847
      "version": "3.1.3",
2626 2848
      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
2627 2849
      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
2628 2850
      "dev": true,
2678 2900
      "dev": true,
2679 2901
      "license": "MIT",
2680 2902
      "engines": {
2681 2903
        "node": ">=12"
2682 2904
      }
2905 +
    },
2906 +
    "node_modules/ast-v8-to-istanbul": {
2907 +
      "version": "0.3.12",
2908 +
      "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz",
2909 +
      "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==",
2910 +
      "dev": true,
2911 +
      "license": "MIT",
2912 +
      "dependencies": {
2913 +
        "@jridgewell/trace-mapping": "^0.3.31",
2914 +
        "estree-walker": "^3.0.3",
2915 +
        "js-tokens": "^10.0.0"
2916 +
      }
2917 +
    },
2918 +
    "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": {
2919 +
      "version": "10.0.0",
2920 +
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz",
2921 +
      "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
2922 +
      "dev": true,
2923 +
      "license": "MIT"
2683 2924
    },
2684 2925
    "node_modules/asynckit": {
2685 2926
      "version": "0.4.0",
2686 2927
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2687 2928
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
3863 4104
      "version": "2.14.1",
3864 4105
      "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
3865 4106
      "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
3866 4107
      "license": "MIT"
3867 4108
    },
4109 +
    "node_modules/brace-expansion": {
4110 +
      "version": "5.0.12",
4111 +
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
4112 +
      "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
4113 +
      "dev": true,
4114 +
      "license": "MIT",
4115 +
      "dependencies": {
4116 +
        "balanced-match": "^4.0.2"
4117 +
      },
4118 +
      "engines": {
4119 +
        "node": "20 || >=22"
4120 +
      }
4121 +
    },
4122 +
    "node_modules/brace-expansion/node_modules/balanced-match": {
4123 +
      "version": "4.0.4",
4124 +
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
4125 +
      "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
4126 +
      "dev": true,
4127 +
      "license": "MIT",
4128 +
      "engines": {
4129 +
        "node": "18 || 20 || >=22"
4130 +
      }
4131 +
    },
3868 4132
    "node_modules/braces": {
3869 4133
      "version": "3.0.3",
3870 4134
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
3871 4135
      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
3872 4136
      "dev": true,
4126 4390
      "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
4127 4391
      "license": "Apache-2.0",
4128 4392
      "engines": {
4129 4393
        "node": ">=0.10.0"
4130 4394
      }
4395 +
    },
4396 +
    "node_modules/color-convert": {
4397 +
      "version": "2.0.1",
4398 +
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
4399 +
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
4400 +
      "dev": true,
4401 +
      "license": "MIT",
4402 +
      "dependencies": {
4403 +
        "color-name": "~1.1.4"
4404 +
      },
4405 +
      "engines": {
4406 +
        "node": ">=7.0.0"
4407 +
      }
4408 +
    },
4409 +
    "node_modules/color-convert/node_modules/color-name": {
4410 +
      "version": "1.1.4",
4411 +
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
4412 +
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
4413 +
      "dev": true,
4414 +
      "license": "MIT"
4131 4415
    },
4132 4416
    "node_modules/color-name": {
4133 4417
      "version": "2.1.0",
4134 4418
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
4135 4419
      "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
4693 4977
      },
4694 4978
      "engines": {
4695 4979
        "node": ">= 0.4"
4696 4980
      }
4697 4981
    },
4982 +
    "node_modules/eastasianwidth": {
4983 +
      "version": "0.2.0",
4984 +
      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
4985 +
      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
4986 +
      "dev": true,
4987 +
      "license": "MIT"
4988 +
    },
4698 4989
    "node_modules/ecdsa-sig-formatter": {
4699 4990
      "version": "1.0.11",
4700 4991
      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
4701 4992
      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
4702 4993
      "license": "Apache-2.0",
4718 5009
      "license": "MIT",
4719 5010
      "dependencies": {
4720 5011
        "@standard-schema/spec": "^1.0.0",
4721 5012
        "fast-check": "^3.23.1"
4722 5013
      }
5014 +
    },
5015 +
    "node_modules/emoji-regex": {
5016 +
      "version": "9.2.2",
5017 +
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
5018 +
      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
5019 +
      "dev": true,
5020 +
      "license": "MIT"
4723 5021
    },
4724 5022
    "node_modules/emoji-regex-xs": {
4725 5023
      "version": "1.0.0",
4726 5024
      "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz",
4727 5025
      "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==",
4853 5151
    "node_modules/escape-html": {
4854 5152
      "version": "1.0.3",
4855 5153
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
4856 5154
      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
4857 5155
      "license": "MIT"
5156 +
    },
5157 +
    "node_modules/estree-walker": {
5158 +
      "version": "3.0.3",
5159 +
      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
5160 +
      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
5161 +
      "dev": true,
5162 +
      "license": "MIT",
5163 +
      "dependencies": {
5164 +
        "@types/estree": "^1.0.0"
5165 +
      }
4858 5166
    },
4859 5167
    "node_modules/esutils": {
4860 5168
      "version": "2.0.3",
4861 5169
      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
4862 5170
      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
5386 5694
      "version": "0.0.0",
5387 5695
      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
5388 5696
      "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
5389 5697
      "license": "MIT"
5390 5698
    },
5699 +
    "node_modules/glob": {
5700 +
      "version": "10.5.0",
5701 +
      "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
5702 +
      "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
5703 +
      "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
5704 +
      "dev": true,
5705 +
      "license": "ISC",
5706 +
      "dependencies": {
5707 +
        "foreground-child": "^3.1.0",
5708 +
        "jackspeak": "^3.1.2",
5709 +
        "minimatch": "^9.0.4",
5710 +
        "minipass": "^7.1.2",
5711 +
        "package-json-from-dist": "^1.0.0",
5712 +
        "path-scurry": "^1.11.1"
5713 +
      },
5714 +
      "bin": {
5715 +
        "glob": "dist/esm/bin.mjs"
5716 +
      },
5717 +
      "funding": {
5718 +
        "url": "https://github.com/sponsors/isaacs"
5719 +
      }
5720 +
    },
5391 5721
    "node_modules/glob-parent": {
5392 5722
      "version": "5.1.2",
5393 5723
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
5394 5724
      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
5395 5725
      "dev": true,
5399 5729
      },
5400 5730
      "engines": {
5401 5731
        "node": ">= 6"
5402 5732
      }
5403 5733
    },
5734 +
    "node_modules/glob/node_modules/brace-expansion": {
5735 +
      "version": "2.1.7",
5736 +
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz",
5737 +
      "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
5738 +
      "dev": true,
5739 +
      "license": "MIT",
5740 +
      "dependencies": {
5741 +
        "balanced-match": "^1.0.0"
5742 +
      }
5743 +
    },
5744 +
    "node_modules/glob/node_modules/minimatch": {
5745 +
      "version": "9.0.9",
5746 +
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
5747 +
      "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
5748 +
      "dev": true,
5749 +
      "license": "ISC",
5750 +
      "dependencies": {
5751 +
        "brace-expansion": "^2.0.2"
5752 +
      },
5753 +
      "engines": {
5754 +
        "node": ">=16 || 14 >=14.17"
5755 +
      },
5756 +
      "funding": {
5757 +
        "url": "https://github.com/sponsors/isaacs"
5758 +
      }
5759 +
    },
5404 5760
    "node_modules/globals": {
5405 5761
      "version": "9.18.0",
5406 5762
      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
5407 5763
      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
5408 5764
      "dev": true,
5574 5930
      "version": "1.1.2",
5575 5931
      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
5576 5932
      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
5577 5933
      "license": "MIT"
5578 5934
    },
5935 +
    "node_modules/html-escaper": {
5936 +
      "version": "2.0.2",
5937 +
      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
5938 +
      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
5939 +
      "dev": true,
5940 +
      "license": "MIT"
5941 +
    },
5579 5942
    "node_modules/http-errors": {
5580 5943
      "version": "2.0.1",
5581 5944
      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
5582 5945
      "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
5583 5946
      "license": "MIT",
5740 6103
      },
5741 6104
      "funding": {
5742 6105
        "url": "https://github.com/sponsors/sindresorhus"
5743 6106
      }
5744 6107
    },
6108 +
    "node_modules/is-fullwidth-code-point": {
6109 +
      "version": "3.0.0",
6110 +
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
6111 +
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
6112 +
      "dev": true,
6113 +
      "license": "MIT",
6114 +
      "engines": {
6115 +
        "node": ">=8"
6116 +
      }
6117 +
    },
5745 6118
    "node_modules/is-glob": {
5746 6119
      "version": "4.0.3",
5747 6120
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
5748 6121
      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
5749 6122
      "dev": true,
5795 6168
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
5796 6169
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
5797 6170
      "devOptional": true,
5798 6171
      "license": "ISC"
5799 6172
    },
6173 +
    "node_modules/istanbul-lib-coverage": {
6174 +
      "version": "3.2.2",
6175 +
      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
6176 +
      "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
6177 +
      "dev": true,
6178 +
      "license": "BSD-3-Clause",
6179 +
      "engines": {
6180 +
        "node": ">=8"
6181 +
      }
6182 +
    },
6183 +
    "node_modules/istanbul-lib-report": {
6184 +
      "version": "3.0.1",
6185 +
      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
6186 +
      "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
6187 +
      "dev": true,
6188 +
      "license": "BSD-3-Clause",
6189 +
      "dependencies": {
6190 +
        "istanbul-lib-coverage": "^3.0.0",
6191 +
        "make-dir": "^4.0.0",
6192 +
        "supports-color": "^7.1.0"
6193 +
      },
6194 +
      "engines": {
6195 +
        "node": ">=10"
6196 +
      }
6197 +
    },
6198 +
    "node_modules/istanbul-lib-report/node_modules/has-flag": {
6199 +
      "version": "4.0.0",
6200 +
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
6201 +
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
6202 +
      "dev": true,
6203 +
      "license": "MIT",
6204 +
      "engines": {
6205 +
        "node": ">=8"
6206 +
      }
6207 +
    },
6208 +
    "node_modules/istanbul-lib-report/node_modules/supports-color": {
6209 +
      "version": "7.2.0",
6210 +
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
6211 +
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
6212 +
      "dev": true,
6213 +
      "license": "MIT",
6214 +
      "dependencies": {
6215 +
        "has-flag": "^4.0.0"
6216 +
      },
6217 +
      "engines": {
6218 +
        "node": ">=8"
6219 +
      }
6220 +
    },
6221 +
    "node_modules/istanbul-lib-source-maps": {
6222 +
      "version": "5.0.6",
6223 +
      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
6224 +
      "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
6225 +
      "dev": true,
6226 +
      "license": "BSD-3-Clause",
6227 +
      "dependencies": {
6228 +
        "@jridgewell/trace-mapping": "^0.3.23",
6229 +
        "debug": "^4.1.1",
6230 +
        "istanbul-lib-coverage": "^3.0.0"
6231 +
      },
6232 +
      "engines": {
6233 +
        "node": ">=10"
6234 +
      }
6235 +
    },
6236 +
    "node_modules/istanbul-reports": {
6237 +
      "version": "3.2.0",
6238 +
      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
6239 +
      "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
6240 +
      "dev": true,
6241 +
      "license": "BSD-3-Clause",
6242 +
      "dependencies": {
6243 +
        "html-escaper": "^2.0.0",
6244 +
        "istanbul-lib-report": "^3.0.0"
6245 +
      },
6246 +
      "engines": {
6247 +
        "node": ">=8"
6248 +
      }
6249 +
    },
6250 +
    "node_modules/jackspeak": {
6251 +
      "version": "3.4.3",
6252 +
      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
6253 +
      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
6254 +
      "dev": true,
6255 +
      "license": "BlueOak-1.0.0",
6256 +
      "dependencies": {
6257 +
        "@isaacs/cliui": "^8.0.2"
6258 +
      },
6259 +
      "funding": {
6260 +
        "url": "https://github.com/sponsors/isaacs"
6261 +
      },
6262 +
      "optionalDependencies": {
6263 +
        "@pkgjs/parseargs": "^0.11.0"
6264 +
      }
6265 +
    },
5800 6266
    "node_modules/jay-peg": {
5801 6267
      "version": "1.1.1",
5802 6268
      "resolved": "https://registry.npmjs.org/jay-peg/-/jay-peg-1.1.1.tgz",
5803 6269
      "integrity": "sha512-D62KEuBxz/ip2gQKOEhk/mx14o7eiFRaU+VNNSP4MOiIkwb/D6B3G1Mfas7C/Fit8EsSV2/IWjZElx/Gs6A4ww==",
5804 6270
      "license": "MIT",
6056 6522
      "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
6057 6523
      "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
6058 6524
      "dev": true,
6059 6525
      "license": "MIT"
6060 6526
    },
6527 +
    "node_modules/lru-cache": {
6528 +
      "version": "10.4.3",
6529 +
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
6530 +
      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
6531 +
      "dev": true,
6532 +
      "license": "ISC"
6533 +
    },
6061 6534
    "node_modules/lru.min": {
6062 6535
      "version": "1.1.4",
6063 6536
      "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz",
6064 6537
      "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==",
6065 6538
      "devOptional": true,
6091 6564
      "license": "MIT",
6092 6565
      "dependencies": {
6093 6566
        "@jridgewell/sourcemap-codec": "^1.5.5"
6094 6567
      }
6095 6568
    },
6569 +
    "node_modules/magicast": {
6570 +
      "version": "0.3.5",
6571 +
      "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
6572 +
      "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
6573 +
      "devOptional": true,
6574 +
      "license": "MIT",
6575 +
      "dependencies": {
6576 +
        "@babel/parser": "^7.25.4",
6577 +
        "@babel/types": "^7.25.4",
6578 +
        "source-map-js": "^1.2.0"
6579 +
      }
6580 +
    },
6581 +
    "node_modules/make-dir": {
6582 +
      "version": "4.0.0",
6583 +
      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
6584 +
      "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
6585 +
      "dev": true,
6586 +
      "license": "MIT",
6587 +
      "dependencies": {
6588 +
        "semver": "^7.5.3"
6589 +
      },
6590 +
      "engines": {
6591 +
        "node": ">=10"
6592 +
      },
6593 +
      "funding": {
6594 +
        "url": "https://github.com/sponsors/sindresorhus"
6595 +
      }
6596 +
    },
6096 6597
    "node_modules/math-intrinsics": {
6097 6598
      "version": "1.1.0",
6098 6599
      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
6099 6600
      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
6100 6601
      "license": "MIT",
6224 6725
      },
6225 6726
      "funding": {
6226 6727
        "url": "https://github.com/sponsors/sindresorhus"
6227 6728
      }
6228 6729
    },
6730 +
    "node_modules/minimatch": {
6731 +
      "version": "10.2.6",
6732 +
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
6733 +
      "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
6734 +
      "dev": true,
6735 +
      "license": "BlueOak-1.0.0",
6736 +
      "dependencies": {
6737 +
        "brace-expansion": "^5.0.8"
6738 +
      },
6739 +
      "engines": {
6740 +
        "node": "18 || 20 || >=22"
6741 +
      },
6742 +
      "funding": {
6743 +
        "url": "https://github.com/sponsors/isaacs"
6744 +
      }
6745 +
    },
6229 6746
    "node_modules/minimist": {
6230 6747
      "version": "1.2.8",
6231 6748
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
6232 6749
      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
6233 6750
      "license": "MIT",
6234 6751
      "funding": {
6235 6752
        "url": "https://github.com/sponsors/ljharb"
6753 +
      }
6754 +
    },
6755 +
    "node_modules/minipass": {
6756 +
      "version": "7.1.3",
6757 +
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
6758 +
      "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
6759 +
      "dev": true,
6760 +
      "license": "BlueOak-1.0.0",
6761 +
      "engines": {
6762 +
        "node": ">=16 || 14 >=14.17"
6236 6763
      }
6237 6764
    },
6238 6765
    "node_modules/mkdirp": {
6239 6766
      "version": "0.5.6",
6240 6767
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
6520 7047
      "funding": {
6521 7048
        "type": "opencollective",
6522 7049
        "url": "https://opencollective.com/nodemon"
6523 7050
      }
6524 7051
    },
6525 -
    "node_modules/nodemon/node_modules/balanced-match": {
6526 -
      "version": "4.0.4",
6527 -
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
6528 -
      "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
6529 -
      "dev": true,
6530 -
      "license": "MIT",
6531 -
      "engines": {
6532 -
        "node": "18 || 20 || >=22"
6533 -
      }
6534 -
    },
6535 -
    "node_modules/nodemon/node_modules/brace-expansion": {
6536 -
      "version": "5.0.5",
6537 -
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
6538 -
      "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
6539 -
      "dev": true,
6540 -
      "license": "MIT",
6541 -
      "dependencies": {
6542 -
        "balanced-match": "^4.0.2"
6543 -
      },
6544 -
      "engines": {
6545 -
        "node": "18 || 20 || >=22"
6546 -
      }
6547 -
    },
6548 7052
    "node_modules/nodemon/node_modules/chokidar": {
6549 7053
      "version": "3.6.0",
6550 7054
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
6551 7055
      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
6552 7056
      "dev": true,
6574 7078
      "version": "1.0.1",
6575 7079
      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
6576 7080
      "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
6577 7081
      "dev": true,
6578 7082
      "license": "ISC"
6579 -
    },
6580 -
    "node_modules/nodemon/node_modules/minimatch": {
6581 -
      "version": "10.2.5",
6582 -
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
6583 -
      "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
6584 -
      "dev": true,
6585 -
      "license": "BlueOak-1.0.0",
6586 -
      "dependencies": {
6587 -
        "brace-expansion": "^5.0.5"
6588 -
      },
6589 -
      "engines": {
6590 -
        "node": "18 || 20 || >=22"
6591 -
      },
6592 -
      "funding": {
6593 -
        "url": "https://github.com/sponsors/isaacs"
6594 -
      }
6595 7083
    },
6596 7084
    "node_modules/nodemon/node_modules/picomatch": {
6597 7085
      "version": "2.3.2",
6598 7086
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
6599 7087
      "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
6752 7240
      "license": "MIT",
6753 7241
      "engines": {
6754 7242
        "node": ">=0.10.0"
6755 7243
      }
6756 7244
    },
7245 +
    "node_modules/package-json-from-dist": {
7246 +
      "version": "1.0.1",
7247 +
      "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
7248 +
      "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
7249 +
      "dev": true,
7250 +
      "license": "BlueOak-1.0.0"
7251 +
    },
6757 7252
    "node_modules/pako": {
6758 7253
      "version": "1.0.11",
6759 7254
      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
6760 7255
      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
6761 7256
      "license": "(MIT AND Zlib)"
6806 7301
      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
6807 7302
      "devOptional": true,
6808 7303
      "license": "MIT",
6809 7304
      "engines": {
6810 7305
        "node": ">=8"
7306 +
      }
7307 +
    },
7308 +
    "node_modules/path-scurry": {
7309 +
      "version": "1.11.1",
7310 +
      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
7311 +
      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
7312 +
      "dev": true,
7313 +
      "license": "BlueOak-1.0.0",
7314 +
      "dependencies": {
7315 +
        "lru-cache": "^10.2.0",
7316 +
        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
7317 +
      },
7318 +
      "engines": {
7319 +
        "node": ">=16 || 14 >=14.18"
7320 +
      },
7321 +
      "funding": {
7322 +
        "url": "https://github.com/sponsors/isaacs"
6811 7323
      }
6812 7324
    },
6813 7325
    "node_modules/path-to-regexp": {
6814 7326
      "version": "8.3.0",
6815 7327
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
8118 8630
    },
8119 8631
    "node_modules/source-map-js": {
8120 8632
      "version": "1.2.1",
8121 8633
      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
8122 8634
      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
8123 -
      "dev": true,
8635 +
      "devOptional": true,
8124 8636
      "license": "BSD-3-Clause",
8125 8637
      "engines": {
8126 8638
        "node": ">=0.10.0"
8127 8639
      }
8128 8640
    },
8219 8731
      "license": "MIT",
8220 8732
      "dependencies": {
8221 8733
        "safe-buffer": "~5.2.0"
8222 8734
      }
8223 8735
    },
8736 +
    "node_modules/string-width": {
8737 +
      "version": "5.1.2",
8738 +
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
8739 +
      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
8740 +
      "dev": true,
8741 +
      "license": "MIT",
8742 +
      "dependencies": {
8743 +
        "eastasianwidth": "^0.2.0",
8744 +
        "emoji-regex": "^9.2.2",
8745 +
        "strip-ansi": "^7.0.1"
8746 +
      },
8747 +
      "engines": {
8748 +
        "node": ">=12"
8749 +
      },
8750 +
      "funding": {
8751 +
        "url": "https://github.com/sponsors/sindresorhus"
8752 +
      }
8753 +
    },
8754 +
    "node_modules/string-width-cjs": {
8755 +
      "name": "string-width",
8756 +
      "version": "4.2.3",
8757 +
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
8758 +
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
8759 +
      "dev": true,
8760 +
      "license": "MIT",
8761 +
      "dependencies": {
8762 +
        "emoji-regex": "^8.0.0",
8763 +
        "is-fullwidth-code-point": "^3.0.0",
8764 +
        "strip-ansi": "^6.0.1"
8765 +
      },
8766 +
      "engines": {
8767 +
        "node": ">=8"
8768 +
      }
8769 +
    },
8770 +
    "node_modules/string-width-cjs/node_modules/ansi-regex": {
8771 +
      "version": "5.0.1",
8772 +
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
8773 +
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
8774 +
      "dev": true,
8775 +
      "license": "MIT",
8776 +
      "engines": {
8777 +
        "node": ">=8"
8778 +
      }
8779 +
    },
8780 +
    "node_modules/string-width-cjs/node_modules/emoji-regex": {
8781 +
      "version": "8.0.0",
8782 +
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
8783 +
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
8784 +
      "dev": true,
8785 +
      "license": "MIT"
8786 +
    },
8787 +
    "node_modules/string-width-cjs/node_modules/strip-ansi": {
8788 +
      "version": "6.0.1",
8789 +
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
8790 +
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
8791 +
      "dev": true,
8792 +
      "license": "MIT",
8793 +
      "dependencies": {
8794 +
        "ansi-regex": "^5.0.1"
8795 +
      },
8796 +
      "engines": {
8797 +
        "node": ">=8"
8798 +
      }
8799 +
    },
8800 +
    "node_modules/strip-ansi": {
8801 +
      "version": "7.2.0",
8802 +
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
8803 +
      "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
8804 +
      "dev": true,
8805 +
      "license": "MIT",
8806 +
      "dependencies": {
8807 +
        "ansi-regex": "^6.2.2"
8808 +
      },
8809 +
      "engines": {
8810 +
        "node": ">=12"
8811 +
      },
8812 +
      "funding": {
8813 +
        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
8814 +
      }
8815 +
    },
8816 +
    "node_modules/strip-ansi-cjs": {
8817 +
      "name": "strip-ansi",
8818 +
      "version": "6.0.1",
8819 +
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
8820 +
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
8821 +
      "dev": true,
8822 +
      "license": "MIT",
8823 +
      "dependencies": {
8824 +
        "ansi-regex": "^5.0.1"
8825 +
      },
8826 +
      "engines": {
8827 +
        "node": ">=8"
8828 +
      }
8829 +
    },
8830 +
    "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
8831 +
      "version": "5.0.1",
8832 +
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
8833 +
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
8834 +
      "dev": true,
8835 +
      "license": "MIT",
8836 +
      "engines": {
8837 +
        "node": ">=8"
8838 +
      }
8839 +
    },
8224 8840
    "node_modules/strip-json-comments": {
8225 8841
      "version": "2.0.1",
8226 8842
      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
8227 8843
      "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
8228 8844
      "license": "MIT",
8348 8964
      },
8349 8965
      "engines": {
8350 8966
        "node": ">=6"
8351 8967
      }
8352 8968
    },
8969 +
    "node_modules/test-exclude": {
8970 +
      "version": "7.0.2",
8971 +
      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz",
8972 +
      "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==",
8973 +
      "dev": true,
8974 +
      "license": "ISC",
8975 +
      "dependencies": {
8976 +
        "@istanbuljs/schema": "^0.1.2",
8977 +
        "glob": "^10.4.1",
8978 +
        "minimatch": "^10.2.2"
8979 +
      },
8980 +
      "engines": {
8981 +
        "node": ">=18"
8982 +
      }
8983 +
    },
8353 8984
    "node_modules/thread-stream": {
8354 8985
      "version": "4.2.0",
8355 8986
      "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.2.0.tgz",
8356 8987
      "integrity": "sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==",
8357 8988
      "license": "MIT",
8427 9058
      "engines": {
8428 9059
        "node": ">=14.0.0"
8429 9060
      }
8430 9061
    },
8431 9062
    "node_modules/tinyspy": {
8432 -
      "version": "4.0.4",
8433 -
      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz",
8434 -
      "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==",
9063 +
      "version": "4.0.6",
9064 +
      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.6.tgz",
9065 +
      "integrity": "sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==",
8435 9066
      "dev": true,
8436 9067
      "license": "MIT",
8437 9068
      "engines": {
8438 9069
        "node": ">=14.0.0"
8439 9070
      }
9014 9645
        "siginfo": "^2.0.0",
9015 9646
        "stackback": "0.0.2"
9016 9647
      },
9017 9648
      "bin": {
9018 9649
        "why-is-node-running": "cli.js"
9650 +
      },
9651 +
      "engines": {
9652 +
        "node": ">=8"
9653 +
      }
9654 +
    },
9655 +
    "node_modules/wrap-ansi": {
9656 +
      "version": "8.1.0",
9657 +
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
9658 +
      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
9659 +
      "dev": true,
9660 +
      "license": "MIT",
9661 +
      "dependencies": {
9662 +
        "ansi-styles": "^6.1.0",
9663 +
        "string-width": "^5.0.1",
9664 +
        "strip-ansi": "^7.0.1"
9665 +
      },
9666 +
      "engines": {
9667 +
        "node": ">=12"
9668 +
      },
9669 +
      "funding": {
9670 +
        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
9671 +
      }
9672 +
    },
9673 +
    "node_modules/wrap-ansi-cjs": {
9674 +
      "name": "wrap-ansi",
9675 +
      "version": "7.0.0",
9676 +
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
9677 +
      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
9678 +
      "dev": true,
9679 +
      "license": "MIT",
9680 +
      "dependencies": {
9681 +
        "ansi-styles": "^4.0.0",
9682 +
        "string-width": "^4.1.0",
9683 +
        "strip-ansi": "^6.0.0"
9684 +
      },
9685 +
      "engines": {
9686 +
        "node": ">=10"
9687 +
      },
9688 +
      "funding": {
9689 +
        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
9690 +
      }
9691 +
    },
9692 +
    "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
9693 +
      "version": "5.0.1",
9694 +
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
9695 +
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
9696 +
      "dev": true,
9697 +
      "license": "MIT",
9698 +
      "engines": {
9699 +
        "node": ">=8"
9700 +
      }
9701 +
    },
9702 +
    "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
9703 +
      "version": "4.3.0",
9704 +
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
9705 +
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
9706 +
      "dev": true,
9707 +
      "license": "MIT",
9708 +
      "dependencies": {
9709 +
        "color-convert": "^2.0.1"
9710 +
      },
9711 +
      "engines": {
9712 +
        "node": ">=8"
9713 +
      },
9714 +
      "funding": {
9715 +
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
9716 +
      }
9717 +
    },
9718 +
    "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
9719 +
      "version": "8.0.0",
9720 +
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
9721 +
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
9722 +
      "dev": true,
9723 +
      "license": "MIT"
9724 +
    },
9725 +
    "node_modules/wrap-ansi-cjs/node_modules/string-width": {
9726 +
      "version": "4.2.3",
9727 +
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
9728 +
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
9729 +
      "dev": true,
9730 +
      "license": "MIT",
9731 +
      "dependencies": {
9732 +
        "emoji-regex": "^8.0.0",
9733 +
        "is-fullwidth-code-point": "^3.0.0",
9734 +
        "strip-ansi": "^6.0.1"
9735 +
      },
9736 +
      "engines": {
9737 +
        "node": ">=8"
9738 +
      }
9739 +
    },
9740 +
    "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
9741 +
      "version": "6.0.1",
9742 +
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
9743 +
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
9744 +
      "dev": true,
9745 +
      "license": "MIT",
9746 +
      "dependencies": {
9747 +
        "ansi-regex": "^5.0.1"
9019 9748
      },
9020 9749
      "engines": {
9021 9750
        "node": ">=8"
9022 9751
      }
9023 9752
    },
9089 9818
        "zod": "^3.25.0 || ^4.0.0"
9090 9819
      }
9091 9820
    }
9092 9821
  }
9093 9822
}
api/package.json modified+3
api/package.json
1 1
{
2 2
  "name": "orbit-api",
3 3
  "version": "0.0.0",
4 4
  "description": "",
5 5
  "license": "GPL-3.0-only",
12 12
    "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
13 13
    "typecheck": "tsc -p tsconfig.test.json --noEmit",
14 14
    "prod": "node dist/index.js",
15 15
    "start": "nodemon src/index.ts",
16 16
    "test": "dotenv -e .env.test -o -- vitest run",
17 +
    "test:unit": "vitest run --project unit",
18 +
    "test:coverage": "dotenv -e .env.test -o -- vitest run --coverage",
17 19
    "test:watch": "dotenv -e .env.test -o -- vitest",
18 20
    "test:setup": "npm run test:setup:db && npm run test:setup:generate && npm run test:setup:migrate",
19 21
    "test:setup:db": "dotenv -e .env.test -o -- node scripts/create-test-db.mjs",
20 22
    "test:setup:generate": "dotenv -e .env.test -o -- npx prisma generate",
21 23
    "test:setup:migrate": "dotenv -e .env.test -o -- npx prisma db push",
57 59
    "@types/multer": "^2.1.0",
58 60
    "@types/multer-s3": "^3.0.3",
59 61
    "@types/node": "^25.5.2",
60 62
    "@types/react": "^19.2.17",
61 63
    "@types/supertest": "^6.0.3",
64 +
    "@vitest/coverage-v8": "^3.2.6",
62 65
    "cross-var": "^1.1.0",
63 66
    "dotenv-cli": "^11.0.0",
64 67
    "nodemon": "^3.1.14",
65 68
    "pino-pretty": "^13.1.3",
66 69
    "prisma": "^7.5.0",
70 73
    "typescript": "^6.0.2",
71 74
    "vite-tsconfig-paths": "^5.1.4",
72 75
    "vitest": "^3.0.0"
73 76
  }
74 77
}
api/tests/auth/activation-code.test.ts → api/tests/auth/activation-code.unit.test.ts
1 1
import { describe, it, expect } from 'vitest'
2 2
import { generateActivationCode } from '@app/services/auth.service'
3 3

4 4
describe('generateActivationCode', () => {
5 5
  it('produces exactly six decimal digits on every draw', () => {
14 14
    const digits = Array.from({ length: 500 }, () => generateActivationCode()).join('')
15 15

16 16
    expect(digits).toContain('9')
17 17
  })
18 18
})
api/tests/auth/password-reset-token.test.ts → api/tests/auth/password-reset-token.unit.test.ts
1 1
import { describe, it, expect } from 'vitest'
2 2
import { generatePasswordResetToken } from '@app/lib/jwt'
3 3

4 4
describe('generatePasswordResetToken', () => {
5 5
  it('produces an opaque 64-character hex token', () => {
12 12
    )
13 13

14 14
    expect(tokens.size).toBe(100)
15 15
  })
16 16
})
api/tests/exports/format.test.ts → api/tests/exports/format.unit.test.ts
1 1
import { describe, it, expect } from 'vitest'
2 2
import { serializeCsv } from '@app/services/export/csv.serializer'
3 3
import { buildManifest } from '@app/services/export/manifest.builder'
4 4
import { profileTable } from '@app/services/export/table.descriptors'
5 5

29 29
    expect(text).toContain('2026-10-04T12:00:00.000Z')
30 30
    expect(text).toContain('`profile.csv` — 0 registros')
31 31
    expect(text).toContain('_id')
32 32
  })
33 33
})
api/tests/serializers/user.test.ts → api/tests/serializers/user.unit.test.ts
1 1
import { describe, it, expect } from 'vitest'
2 2
import { User } from '@prisma/client'
3 3
import { publicUser } from '@app/lib/serializers/user'
4 4

5 5
const row = {
53 53
    ]) {
54 54
      expect(safe).not.toHaveProperty(field)
55 55
    }
56 56
  })
57 57
})
api/vitest.config.ts modified+45 -7
api/vitest.config.ts
1 1
import { defineConfig } from 'vitest/config'
2 2
import tsconfigPaths from 'vite-tsconfig-paths'
3 3

4 +
// Both projects import source through the same `@app/*` alias the app uses
5 +
const appPaths = () => tsconfigPaths({ projects: ['./tsconfig.test.json'] })
6 +

4 7
export default defineConfig({
5 -
  plugins: [tsconfigPaths({ projects: ['./tsconfig.test.json'] })],
6 8
  test: {
7 -
    environment: 'node',
8 -
    setupFiles: ['./tests/setup.ts'],
9 -
    fileParallelism: false,
10 -
    testTimeout: 15_000,
11 -
    typecheck: {
12 -
      tsconfig: './tsconfig.test.json',
9 +
    // Report-only: there is no threshold and CI does not gate on it. The point
10 +
    // is a visible unit-versus-integration ratio, not a build-breaking number.
11 +
    coverage: {
12 +
      provider: 'v8',
13 +
      reporter: ['text', 'html'],
14 +
      include: ['src/**/*.ts'],
15 +
      exclude: ['src/**/*.d.ts'],
13 16
    },
17 +
    projects: [
18 +
      // Pure tests: a single function, no HTTP, no database. No global mocks,
19 +
      // so files run in parallel and need no running stack. The token module
20 +
      // reads its secret at import time and this project runs without dotenv,
21 +
      // so the env carries it.
22 +
      {
23 +
        plugins: [appPaths()],
24 +
        test: {
25 +
          name: 'unit',
26 +
          environment: 'node',
27 +
          include: ['tests/**/*.unit.test.ts'],
28 +
          fileParallelism: true,
29 +
          testTimeout: 15_000,
30 +
          env: { JWT_SECRET: 'unit-test-secret' },
31 +
        },
32 +
      },
33 +

34 +
      // Integration and job tests: real app and database, serial because every
35 +
      // file shares one database. Excludes the unit files so none runs twice.
36 +
      {
37 +
        plugins: [appPaths()],
38 +
        test: {
39 +
          name: 'db',
40 +
          environment: 'node',
41 +
          include: ['tests/**/*.test.ts'],
42 +
          exclude: ['**/node_modules/**', 'tests/**/*.unit.test.ts'],
43 +
          setupFiles: ['./tests/setup.ts'],
44 +
          fileParallelism: false,
45 +
          testTimeout: 15_000,
46 +
          typecheck: {
47 +
            tsconfig: './tsconfig.test.json',
48 +
          },
49 +
        },
50 +
      },
51 +
    ],
14 52
  },
15 53
})