Mirror: Best-effort discovery of the machine's local network using just Node.js dgram sockets
0
fork

Configure Feed

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

test: Add unit tests for src/network

+783 -3
+3
.github/workflows/ci.yml
··· 40 40 41 41 - name: Build 42 42 run: pnpm run build 43 + 44 + - name: Unit tests 45 + run: pnpm run test:run
+6 -1
package.json
··· 13 13 "dist/" 14 14 ], 15 15 "scripts": { 16 + "test": "vitest test", 17 + "test:run": "vitest test --run", 16 18 "build": "rollup -c ./scripts/rollup.config.mjs", 17 19 "postbuild": "tsc --noEmit ./dist/lan-network.d.ts", 18 20 "check": "tsc --noEmit", 19 21 "clean": "rimraf dist node_modules/.cache", 20 - "prepublishOnly": "run-s clean build check", 22 + "prepublishOnly": "run-s clean build check test:run", 21 23 "prepare": "node ./scripts/prepare.js || true", 22 24 "changeset:version": "changeset version && pnpm install --lockfile-only", 23 25 "changeset:publish": "changeset publish" ··· 72 74 "publishConfig": { 73 75 "access": "public", 74 76 "provenance": true 77 + }, 78 + "dependencies": { 79 + "vitest": "^3.0.6" 75 80 } 76 81 }
+620
pnpm-lock.yaml
··· 7 7 importers: 8 8 9 9 .: 10 + dependencies: 11 + vitest: 12 + specifier: ^3.0.6 13 + version: 3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0) 10 14 devDependencies: 11 15 '@babel/plugin-transform-block-scoping': 12 16 specifier: ^7.25.9 ··· 244 248 '@changesets/write@0.3.2': 245 249 resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} 246 250 251 + '@esbuild/aix-ppc64@0.24.2': 252 + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} 253 + engines: {node: '>=18'} 254 + cpu: [ppc64] 255 + os: [aix] 256 + 257 + '@esbuild/android-arm64@0.24.2': 258 + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} 259 + engines: {node: '>=18'} 260 + cpu: [arm64] 261 + os: [android] 262 + 263 + '@esbuild/android-arm@0.24.2': 264 + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} 265 + engines: {node: '>=18'} 266 + cpu: [arm] 267 + os: [android] 268 + 269 + '@esbuild/android-x64@0.24.2': 270 + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} 271 + engines: {node: '>=18'} 272 + cpu: [x64] 273 + os: [android] 274 + 275 + '@esbuild/darwin-arm64@0.24.2': 276 + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} 277 + engines: {node: '>=18'} 278 + cpu: [arm64] 279 + os: [darwin] 280 + 281 + '@esbuild/darwin-x64@0.24.2': 282 + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} 283 + engines: {node: '>=18'} 284 + cpu: [x64] 285 + os: [darwin] 286 + 287 + '@esbuild/freebsd-arm64@0.24.2': 288 + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} 289 + engines: {node: '>=18'} 290 + cpu: [arm64] 291 + os: [freebsd] 292 + 293 + '@esbuild/freebsd-x64@0.24.2': 294 + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} 295 + engines: {node: '>=18'} 296 + cpu: [x64] 297 + os: [freebsd] 298 + 299 + '@esbuild/linux-arm64@0.24.2': 300 + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} 301 + engines: {node: '>=18'} 302 + cpu: [arm64] 303 + os: [linux] 304 + 305 + '@esbuild/linux-arm@0.24.2': 306 + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} 307 + engines: {node: '>=18'} 308 + cpu: [arm] 309 + os: [linux] 310 + 311 + '@esbuild/linux-ia32@0.24.2': 312 + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} 313 + engines: {node: '>=18'} 314 + cpu: [ia32] 315 + os: [linux] 316 + 317 + '@esbuild/linux-loong64@0.24.2': 318 + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} 319 + engines: {node: '>=18'} 320 + cpu: [loong64] 321 + os: [linux] 322 + 323 + '@esbuild/linux-mips64el@0.24.2': 324 + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} 325 + engines: {node: '>=18'} 326 + cpu: [mips64el] 327 + os: [linux] 328 + 329 + '@esbuild/linux-ppc64@0.24.2': 330 + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} 331 + engines: {node: '>=18'} 332 + cpu: [ppc64] 333 + os: [linux] 334 + 335 + '@esbuild/linux-riscv64@0.24.2': 336 + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} 337 + engines: {node: '>=18'} 338 + cpu: [riscv64] 339 + os: [linux] 340 + 341 + '@esbuild/linux-s390x@0.24.2': 342 + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} 343 + engines: {node: '>=18'} 344 + cpu: [s390x] 345 + os: [linux] 346 + 347 + '@esbuild/linux-x64@0.24.2': 348 + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} 349 + engines: {node: '>=18'} 350 + cpu: [x64] 351 + os: [linux] 352 + 353 + '@esbuild/netbsd-arm64@0.24.2': 354 + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} 355 + engines: {node: '>=18'} 356 + cpu: [arm64] 357 + os: [netbsd] 358 + 359 + '@esbuild/netbsd-x64@0.24.2': 360 + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} 361 + engines: {node: '>=18'} 362 + cpu: [x64] 363 + os: [netbsd] 364 + 365 + '@esbuild/openbsd-arm64@0.24.2': 366 + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} 367 + engines: {node: '>=18'} 368 + cpu: [arm64] 369 + os: [openbsd] 370 + 371 + '@esbuild/openbsd-x64@0.24.2': 372 + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} 373 + engines: {node: '>=18'} 374 + cpu: [x64] 375 + os: [openbsd] 376 + 377 + '@esbuild/sunos-x64@0.24.2': 378 + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} 379 + engines: {node: '>=18'} 380 + cpu: [x64] 381 + os: [sunos] 382 + 383 + '@esbuild/win32-arm64@0.24.2': 384 + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} 385 + engines: {node: '>=18'} 386 + cpu: [arm64] 387 + os: [win32] 388 + 389 + '@esbuild/win32-ia32@0.24.2': 390 + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} 391 + engines: {node: '>=18'} 392 + cpu: [ia32] 393 + os: [win32] 394 + 395 + '@esbuild/win32-x64@0.24.2': 396 + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} 397 + engines: {node: '>=18'} 398 + cpu: [x64] 399 + os: [win32] 400 + 247 401 '@isaacs/cliui@8.0.2': 248 402 resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 249 403 engines: {node: '>=12'} ··· 443 597 '@types/resolve@1.20.2': 444 598 resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} 445 599 600 + '@vitest/expect@3.0.6': 601 + resolution: {integrity: sha512-zBduHf/ja7/QRX4HdP1DSq5XrPgdN+jzLOwaTq/0qZjYfgETNFCKf9nOAp2j3hmom3oTbczuUzrzg9Hafh7hNg==} 602 + 603 + '@vitest/mocker@3.0.6': 604 + resolution: {integrity: sha512-KPztr4/tn7qDGZfqlSPQoF2VgJcKxnDNhmfR3VgZ6Fy1bO8T9Fc1stUiTXtqz0yG24VpD00pZP5f8EOFknjNuQ==} 605 + peerDependencies: 606 + msw: ^2.4.9 607 + vite: ^5.0.0 || ^6.0.0 608 + peerDependenciesMeta: 609 + msw: 610 + optional: true 611 + vite: 612 + optional: true 613 + 614 + '@vitest/pretty-format@3.0.6': 615 + resolution: {integrity: sha512-Zyctv3dbNL+67qtHfRnUE/k8qxduOamRfAL1BurEIQSyOEFffoMvx2pnDSSbKAAVxY0Ej2J/GH2dQKI0W2JyVg==} 616 + 617 + '@vitest/runner@3.0.6': 618 + resolution: {integrity: sha512-JopP4m/jGoaG1+CBqubV/5VMbi7L+NQCJTu1J1Pf6YaUbk7bZtaq5CX7p+8sY64Sjn1UQ1XJparHfcvTTdu9cA==} 619 + 620 + '@vitest/snapshot@3.0.6': 621 + resolution: {integrity: sha512-qKSmxNQwT60kNwwJHMVwavvZsMGXWmngD023OHSgn873pV0lylK7dwBTfYP7e4URy5NiBCHHiQGA9DHkYkqRqg==} 622 + 623 + '@vitest/spy@3.0.6': 624 + resolution: {integrity: sha512-HfOGx/bXtjy24fDlTOpgiAEJbRfFxoX3zIGagCqACkFKKZ/TTOE6gYMKXlqecvxEndKFuNHcHqP081ggZ2yM0Q==} 625 + 626 + '@vitest/utils@3.0.6': 627 + resolution: {integrity: sha512-18ktZpf4GQFTbf9jK543uspU03Q2qya7ZGya5yiZ0Gx0nnnalBvd5ZBislbl2EhLjM8A8rt4OilqKG7QwcGkvQ==} 628 + 446 629 acorn@8.14.0: 447 630 resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 448 631 engines: {node: '>=0.4.0'} ··· 491 674 resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} 492 675 engines: {node: '>= 0.4'} 493 676 677 + assertion-error@2.0.1: 678 + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 679 + engines: {node: '>=12'} 680 + 494 681 async-function@1.0.0: 495 682 resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} 496 683 engines: {node: '>= 0.4'} ··· 524 711 buffer-from@1.1.2: 525 712 resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 526 713 714 + cac@6.7.14: 715 + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 716 + engines: {node: '>=8'} 717 + 527 718 call-bind-apply-helpers@1.0.1: 528 719 resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} 529 720 engines: {node: '>= 0.4'} ··· 539 730 caniuse-lite@1.0.30001696: 540 731 resolution: {integrity: sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==} 541 732 733 + chai@5.2.0: 734 + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} 735 + engines: {node: '>=12'} 736 + 542 737 chalk@2.4.2: 543 738 resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 544 739 engines: {node: '>=4'} ··· 549 744 550 745 chardet@0.7.0: 551 746 resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} 747 + 748 + check-error@2.1.1: 749 + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 750 + engines: {node: '>= 16'} 552 751 553 752 ci-info@3.9.0: 554 753 resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} ··· 629 828 supports-color: 630 829 optional: true 631 830 831 + deep-eql@5.0.2: 832 + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 833 + engines: {node: '>=6'} 834 + 632 835 deepmerge@4.3.1: 633 836 resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 634 837 engines: {node: '>=0.10.0'} ··· 695 898 resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} 696 899 engines: {node: '>= 0.4'} 697 900 901 + es-module-lexer@1.6.0: 902 + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} 903 + 698 904 es-object-atoms@1.1.1: 699 905 resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} 700 906 engines: {node: '>= 0.4'} ··· 707 913 resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} 708 914 engines: {node: '>= 0.4'} 709 915 916 + esbuild@0.24.2: 917 + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} 918 + engines: {node: '>=18'} 919 + hasBin: true 920 + 710 921 escalade@3.2.0: 711 922 resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 712 923 engines: {node: '>=6'} ··· 722 933 723 934 estree-walker@2.0.2: 724 935 resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 936 + 937 + estree-walker@3.0.3: 938 + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 725 939 726 940 eventemitter3@5.0.1: 727 941 resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} ··· 730 944 resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} 731 945 engines: {node: '>=16.17'} 732 946 947 + expect-type@1.1.0: 948 + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} 949 + engines: {node: '>=12.0.0'} 950 + 733 951 extendable-error@0.1.7: 734 952 resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} 735 953 ··· 1082 1300 resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} 1083 1301 engines: {node: '>=18'} 1084 1302 1303 + loupe@3.1.3: 1304 + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} 1305 + 1085 1306 lru-cache@11.0.2: 1086 1307 resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} 1087 1308 engines: {node: 20 || >=22} ··· 1136 1357 1137 1358 ms@2.1.3: 1138 1359 resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 1360 + 1361 + nanoid@3.3.8: 1362 + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} 1363 + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1364 + hasBin: true 1139 1365 1140 1366 nice-try@1.0.5: 1141 1367 resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} ··· 1255 1481 path-type@4.0.0: 1256 1482 resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1257 1483 engines: {node: '>=8'} 1484 + 1485 + pathe@2.0.3: 1486 + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 1487 + 1488 + pathval@2.0.0: 1489 + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} 1490 + engines: {node: '>= 14.16'} 1258 1491 1259 1492 picocolors@1.1.1: 1260 1493 resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} ··· 1289 1522 resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} 1290 1523 engines: {node: '>= 0.4'} 1291 1524 1525 + postcss@8.5.3: 1526 + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} 1527 + engines: {node: ^10 || ^12 || >=14} 1528 + 1292 1529 prettier@2.8.8: 1293 1530 resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} 1294 1531 engines: {node: '>=10.13.0'} ··· 1452 1689 resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} 1453 1690 engines: {node: '>= 0.4'} 1454 1691 1692 + siginfo@2.0.0: 1693 + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 1694 + 1455 1695 signal-exit@4.1.0: 1456 1696 resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1457 1697 engines: {node: '>=14'} ··· 1470 1710 1471 1711 smob@1.5.0: 1472 1712 resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} 1713 + 1714 + source-map-js@1.2.1: 1715 + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 1716 + engines: {node: '>=0.10.0'} 1473 1717 1474 1718 source-map-support@0.5.21: 1475 1719 resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} ··· 1495 1739 1496 1740 sprintf-js@1.0.3: 1497 1741 resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 1742 + 1743 + stackback@0.0.2: 1744 + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 1745 + 1746 + std-env@3.8.0: 1747 + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} 1498 1748 1499 1749 string-argv@0.3.2: 1500 1750 resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} ··· 1561 1811 engines: {node: '>=10'} 1562 1812 hasBin: true 1563 1813 1814 + tinybench@2.9.0: 1815 + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 1816 + 1817 + tinyexec@0.3.2: 1818 + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} 1819 + 1820 + tinypool@1.0.2: 1821 + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} 1822 + engines: {node: ^18.0.0 || >=20.0.0} 1823 + 1824 + tinyrainbow@2.0.0: 1825 + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} 1826 + engines: {node: '>=14.0.0'} 1827 + 1828 + tinyspy@3.0.2: 1829 + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} 1830 + engines: {node: '>=14.0.0'} 1831 + 1564 1832 tmp@0.0.33: 1565 1833 resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} 1566 1834 engines: {node: '>=0.6.0'} ··· 1613 1881 validate-npm-package-license@3.0.4: 1614 1882 resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} 1615 1883 1884 + vite-node@3.0.6: 1885 + resolution: {integrity: sha512-s51RzrTkXKJrhNbUzQRsarjmAae7VmMPAsRT7lppVpIg6mK3zGthP9Hgz0YQQKuNcF+Ii7DfYk3Fxz40jRmePw==} 1886 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 1887 + hasBin: true 1888 + 1889 + vite@6.1.1: 1890 + resolution: {integrity: sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==} 1891 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 1892 + hasBin: true 1893 + peerDependencies: 1894 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 1895 + jiti: '>=1.21.0' 1896 + less: '*' 1897 + lightningcss: ^1.21.0 1898 + sass: '*' 1899 + sass-embedded: '*' 1900 + stylus: '*' 1901 + sugarss: '*' 1902 + terser: ^5.16.0 1903 + tsx: ^4.8.1 1904 + yaml: ^2.4.2 1905 + peerDependenciesMeta: 1906 + '@types/node': 1907 + optional: true 1908 + jiti: 1909 + optional: true 1910 + less: 1911 + optional: true 1912 + lightningcss: 1913 + optional: true 1914 + sass: 1915 + optional: true 1916 + sass-embedded: 1917 + optional: true 1918 + stylus: 1919 + optional: true 1920 + sugarss: 1921 + optional: true 1922 + terser: 1923 + optional: true 1924 + tsx: 1925 + optional: true 1926 + yaml: 1927 + optional: true 1928 + 1929 + vitest@3.0.6: 1930 + resolution: {integrity: sha512-/iL1Sc5VeDZKPDe58oGK4HUFLhw6b5XdY1MYawjuSaDA4sEfYlY9HnS6aCEG26fX+MgUi7MwlduTBHHAI/OvMA==} 1931 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 1932 + hasBin: true 1933 + peerDependencies: 1934 + '@edge-runtime/vm': '*' 1935 + '@types/debug': ^4.1.12 1936 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 1937 + '@vitest/browser': 3.0.6 1938 + '@vitest/ui': 3.0.6 1939 + happy-dom: '*' 1940 + jsdom: '*' 1941 + peerDependenciesMeta: 1942 + '@edge-runtime/vm': 1943 + optional: true 1944 + '@types/debug': 1945 + optional: true 1946 + '@types/node': 1947 + optional: true 1948 + '@vitest/browser': 1949 + optional: true 1950 + '@vitest/ui': 1951 + optional: true 1952 + happy-dom: 1953 + optional: true 1954 + jsdom: 1955 + optional: true 1956 + 1616 1957 webidl-conversions@3.0.1: 1617 1958 resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} 1618 1959 ··· 1642 1983 which@2.0.2: 1643 1984 resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1644 1985 engines: {node: '>= 8'} 1986 + hasBin: true 1987 + 1988 + why-is-node-running@2.3.0: 1989 + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 1990 + engines: {node: '>=8'} 1645 1991 hasBin: true 1646 1992 1647 1993 wrap-ansi@7.0.0: ··· 1989 2335 human-id: 1.0.2 1990 2336 prettier: 2.8.8 1991 2337 2338 + '@esbuild/aix-ppc64@0.24.2': 2339 + optional: true 2340 + 2341 + '@esbuild/android-arm64@0.24.2': 2342 + optional: true 2343 + 2344 + '@esbuild/android-arm@0.24.2': 2345 + optional: true 2346 + 2347 + '@esbuild/android-x64@0.24.2': 2348 + optional: true 2349 + 2350 + '@esbuild/darwin-arm64@0.24.2': 2351 + optional: true 2352 + 2353 + '@esbuild/darwin-x64@0.24.2': 2354 + optional: true 2355 + 2356 + '@esbuild/freebsd-arm64@0.24.2': 2357 + optional: true 2358 + 2359 + '@esbuild/freebsd-x64@0.24.2': 2360 + optional: true 2361 + 2362 + '@esbuild/linux-arm64@0.24.2': 2363 + optional: true 2364 + 2365 + '@esbuild/linux-arm@0.24.2': 2366 + optional: true 2367 + 2368 + '@esbuild/linux-ia32@0.24.2': 2369 + optional: true 2370 + 2371 + '@esbuild/linux-loong64@0.24.2': 2372 + optional: true 2373 + 2374 + '@esbuild/linux-mips64el@0.24.2': 2375 + optional: true 2376 + 2377 + '@esbuild/linux-ppc64@0.24.2': 2378 + optional: true 2379 + 2380 + '@esbuild/linux-riscv64@0.24.2': 2381 + optional: true 2382 + 2383 + '@esbuild/linux-s390x@0.24.2': 2384 + optional: true 2385 + 2386 + '@esbuild/linux-x64@0.24.2': 2387 + optional: true 2388 + 2389 + '@esbuild/netbsd-arm64@0.24.2': 2390 + optional: true 2391 + 2392 + '@esbuild/netbsd-x64@0.24.2': 2393 + optional: true 2394 + 2395 + '@esbuild/openbsd-arm64@0.24.2': 2396 + optional: true 2397 + 2398 + '@esbuild/openbsd-x64@0.24.2': 2399 + optional: true 2400 + 2401 + '@esbuild/sunos-x64@0.24.2': 2402 + optional: true 2403 + 2404 + '@esbuild/win32-arm64@0.24.2': 2405 + optional: true 2406 + 2407 + '@esbuild/win32-ia32@0.24.2': 2408 + optional: true 2409 + 2410 + '@esbuild/win32-x64@0.24.2': 2411 + optional: true 2412 + 1992 2413 '@isaacs/cliui@8.0.2': 1993 2414 dependencies: 1994 2415 string-width: 5.1.2 ··· 2163 2584 2164 2585 '@types/resolve@1.20.2': {} 2165 2586 2587 + '@vitest/expect@3.0.6': 2588 + dependencies: 2589 + '@vitest/spy': 3.0.6 2590 + '@vitest/utils': 3.0.6 2591 + chai: 5.2.0 2592 + tinyrainbow: 2.0.0 2593 + 2594 + '@vitest/mocker@3.0.6(vite@6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0))': 2595 + dependencies: 2596 + '@vitest/spy': 3.0.6 2597 + estree-walker: 3.0.3 2598 + magic-string: 0.30.17 2599 + optionalDependencies: 2600 + vite: 6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0) 2601 + 2602 + '@vitest/pretty-format@3.0.6': 2603 + dependencies: 2604 + tinyrainbow: 2.0.0 2605 + 2606 + '@vitest/runner@3.0.6': 2607 + dependencies: 2608 + '@vitest/utils': 3.0.6 2609 + pathe: 2.0.3 2610 + 2611 + '@vitest/snapshot@3.0.6': 2612 + dependencies: 2613 + '@vitest/pretty-format': 3.0.6 2614 + magic-string: 0.30.17 2615 + pathe: 2.0.3 2616 + 2617 + '@vitest/spy@3.0.6': 2618 + dependencies: 2619 + tinyspy: 3.0.2 2620 + 2621 + '@vitest/utils@3.0.6': 2622 + dependencies: 2623 + '@vitest/pretty-format': 3.0.6 2624 + loupe: 3.1.3 2625 + tinyrainbow: 2.0.0 2626 + 2166 2627 acorn@8.14.0: {} 2167 2628 2168 2629 ansi-colors@4.1.3: {} ··· 2206 2667 get-intrinsic: 1.2.7 2207 2668 is-array-buffer: 3.0.5 2208 2669 2670 + assertion-error@2.0.1: {} 2671 + 2209 2672 async-function@1.0.0: {} 2210 2673 2211 2674 available-typed-arrays@1.0.7: ··· 2239 2702 update-browserslist-db: 1.1.2(browserslist@4.24.4) 2240 2703 2241 2704 buffer-from@1.1.2: {} 2705 + 2706 + cac@6.7.14: {} 2242 2707 2243 2708 call-bind-apply-helpers@1.0.1: 2244 2709 dependencies: ··· 2259 2724 2260 2725 caniuse-lite@1.0.30001696: {} 2261 2726 2727 + chai@5.2.0: 2728 + dependencies: 2729 + assertion-error: 2.0.1 2730 + check-error: 2.1.1 2731 + deep-eql: 5.0.2 2732 + loupe: 3.1.3 2733 + pathval: 2.0.0 2734 + 2262 2735 chalk@2.4.2: 2263 2736 dependencies: 2264 2737 ansi-styles: 3.2.1 ··· 2268 2741 chalk@5.4.1: {} 2269 2742 2270 2743 chardet@0.7.0: {} 2744 + 2745 + check-error@2.1.1: {} 2271 2746 2272 2747 ci-info@3.9.0: {} 2273 2748 ··· 2344 2819 dependencies: 2345 2820 ms: 2.1.3 2346 2821 2822 + deep-eql@5.0.2: {} 2823 + 2347 2824 deepmerge@4.3.1: {} 2348 2825 2349 2826 define-data-property@1.1.4: ··· 2451 2928 2452 2929 es-errors@1.3.0: {} 2453 2930 2931 + es-module-lexer@1.6.0: {} 2932 + 2454 2933 es-object-atoms@1.1.1: 2455 2934 dependencies: 2456 2935 es-errors: 1.3.0 ··· 2468 2947 is-date-object: 1.1.0 2469 2948 is-symbol: 1.1.1 2470 2949 2950 + esbuild@0.24.2: 2951 + optionalDependencies: 2952 + '@esbuild/aix-ppc64': 0.24.2 2953 + '@esbuild/android-arm': 0.24.2 2954 + '@esbuild/android-arm64': 0.24.2 2955 + '@esbuild/android-x64': 0.24.2 2956 + '@esbuild/darwin-arm64': 0.24.2 2957 + '@esbuild/darwin-x64': 0.24.2 2958 + '@esbuild/freebsd-arm64': 0.24.2 2959 + '@esbuild/freebsd-x64': 0.24.2 2960 + '@esbuild/linux-arm': 0.24.2 2961 + '@esbuild/linux-arm64': 0.24.2 2962 + '@esbuild/linux-ia32': 0.24.2 2963 + '@esbuild/linux-loong64': 0.24.2 2964 + '@esbuild/linux-mips64el': 0.24.2 2965 + '@esbuild/linux-ppc64': 0.24.2 2966 + '@esbuild/linux-riscv64': 0.24.2 2967 + '@esbuild/linux-s390x': 0.24.2 2968 + '@esbuild/linux-x64': 0.24.2 2969 + '@esbuild/netbsd-arm64': 0.24.2 2970 + '@esbuild/netbsd-x64': 0.24.2 2971 + '@esbuild/openbsd-arm64': 0.24.2 2972 + '@esbuild/openbsd-x64': 0.24.2 2973 + '@esbuild/sunos-x64': 0.24.2 2974 + '@esbuild/win32-arm64': 0.24.2 2975 + '@esbuild/win32-ia32': 0.24.2 2976 + '@esbuild/win32-x64': 0.24.2 2977 + 2471 2978 escalade@3.2.0: {} 2472 2979 2473 2980 escape-string-regexp@1.0.5: {} ··· 2476 2983 2477 2984 estree-walker@2.0.2: {} 2478 2985 2986 + estree-walker@3.0.3: 2987 + dependencies: 2988 + '@types/estree': 1.0.6 2989 + 2479 2990 eventemitter3@5.0.1: {} 2480 2991 2481 2992 execa@8.0.1: ··· 2489 3000 onetime: 6.0.0 2490 3001 signal-exit: 4.1.0 2491 3002 strip-final-newline: 3.0.0 3003 + 3004 + expect-type@1.1.0: {} 2492 3005 2493 3006 extendable-error@0.1.7: {} 2494 3007 ··· 2864 3377 strip-ansi: 7.1.0 2865 3378 wrap-ansi: 9.0.0 2866 3379 3380 + loupe@3.1.3: {} 3381 + 2867 3382 lru-cache@11.0.2: {} 2868 3383 2869 3384 lru-cache@5.1.1: ··· 2904 3419 mri@1.2.0: {} 2905 3420 2906 3421 ms@2.1.3: {} 3422 + 3423 + nanoid@3.3.8: {} 2907 3424 2908 3425 nice-try@1.0.5: {} 2909 3426 ··· 3013 3530 3014 3531 path-type@4.0.0: {} 3015 3532 3533 + pathe@2.0.3: {} 3534 + 3535 + pathval@2.0.0: {} 3536 + 3016 3537 picocolors@1.1.1: {} 3017 3538 3018 3539 picomatch@2.3.1: {} ··· 3029 3550 3030 3551 possible-typed-array-names@1.0.0: {} 3031 3552 3553 + postcss@8.5.3: 3554 + dependencies: 3555 + nanoid: 3.3.8 3556 + picocolors: 1.1.1 3557 + source-map-js: 1.2.1 3558 + 3032 3559 prettier@2.8.8: {} 3033 3560 3034 3561 prettier@3.4.2: {} ··· 3236 3763 side-channel-map: 1.0.1 3237 3764 side-channel-weakmap: 1.0.2 3238 3765 3766 + siginfo@2.0.0: {} 3767 + 3239 3768 signal-exit@4.1.0: {} 3240 3769 3241 3770 slash@3.0.0: {} ··· 3251 3780 is-fullwidth-code-point: 5.0.0 3252 3781 3253 3782 smob@1.5.0: {} 3783 + 3784 + source-map-js@1.2.1: {} 3254 3785 3255 3786 source-map-support@0.5.21: 3256 3787 dependencies: ··· 3279 3810 spdx-license-ids@3.0.21: {} 3280 3811 3281 3812 sprintf-js@1.0.3: {} 3813 + 3814 + stackback@0.0.2: {} 3815 + 3816 + std-env@3.8.0: {} 3282 3817 3283 3818 string-argv@0.3.2: {} 3284 3819 ··· 3357 3892 commander: 2.20.3 3358 3893 source-map-support: 0.5.21 3359 3894 3895 + tinybench@2.9.0: {} 3896 + 3897 + tinyexec@0.3.2: {} 3898 + 3899 + tinypool@1.0.2: {} 3900 + 3901 + tinyrainbow@2.0.0: {} 3902 + 3903 + tinyspy@3.0.2: {} 3904 + 3360 3905 tmp@0.0.33: 3361 3906 dependencies: 3362 3907 os-tmpdir: 1.0.2 ··· 3424 3969 spdx-correct: 3.2.0 3425 3970 spdx-expression-parse: 3.0.1 3426 3971 3972 + vite-node@3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0): 3973 + dependencies: 3974 + cac: 6.7.14 3975 + debug: 4.4.0 3976 + es-module-lexer: 1.6.0 3977 + pathe: 2.0.3 3978 + vite: 6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0) 3979 + transitivePeerDependencies: 3980 + - '@types/node' 3981 + - jiti 3982 + - less 3983 + - lightningcss 3984 + - sass 3985 + - sass-embedded 3986 + - stylus 3987 + - sugarss 3988 + - supports-color 3989 + - terser 3990 + - tsx 3991 + - yaml 3992 + 3993 + vite@6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0): 3994 + dependencies: 3995 + esbuild: 0.24.2 3996 + postcss: 8.5.3 3997 + rollup: 4.32.1 3998 + optionalDependencies: 3999 + '@types/node': 22.12.0 4000 + fsevents: 2.3.3 4001 + terser: 5.37.0 4002 + yaml: 2.7.0 4003 + 4004 + vitest@3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0): 4005 + dependencies: 4006 + '@vitest/expect': 3.0.6 4007 + '@vitest/mocker': 3.0.6(vite@6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0)) 4008 + '@vitest/pretty-format': 3.0.6 4009 + '@vitest/runner': 3.0.6 4010 + '@vitest/snapshot': 3.0.6 4011 + '@vitest/spy': 3.0.6 4012 + '@vitest/utils': 3.0.6 4013 + chai: 5.2.0 4014 + debug: 4.4.0 4015 + expect-type: 1.1.0 4016 + magic-string: 0.30.17 4017 + pathe: 2.0.3 4018 + std-env: 3.8.0 4019 + tinybench: 2.9.0 4020 + tinyexec: 0.3.2 4021 + tinypool: 1.0.2 4022 + tinyrainbow: 2.0.0 4023 + vite: 6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0) 4024 + vite-node: 3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0) 4025 + why-is-node-running: 2.3.0 4026 + optionalDependencies: 4027 + '@types/node': 22.12.0 4028 + transitivePeerDependencies: 4029 + - jiti 4030 + - less 4031 + - lightningcss 4032 + - msw 4033 + - sass 4034 + - sass-embedded 4035 + - stylus 4036 + - sugarss 4037 + - supports-color 4038 + - terser 4039 + - tsx 4040 + - yaml 4041 + 3427 4042 webidl-conversions@3.0.1: {} 3428 4043 3429 4044 whatwg-url@5.0.0: ··· 3478 4093 which@2.0.2: 3479 4094 dependencies: 3480 4095 isexe: 2.0.0 4096 + 4097 + why-is-node-running@2.3.0: 4098 + dependencies: 4099 + siginfo: 2.0.0 4100 + stackback: 0.0.2 3481 4101 3482 4102 wrap-ansi@7.0.0: 3483 4103 dependencies:
+152
src/__tests__/network.test.ts
··· 1 + import os from 'node:os'; 2 + import { vi, describe, it, expect } from 'vitest'; 3 + import { 4 + parseMacStr, 5 + parseIpStr, 6 + toIpStr, 7 + interfaceAssignments, 8 + matchAssignment, 9 + } from '../network'; 10 + 11 + describe(parseMacStr, () => { 12 + it('parses valid MAC addresses', () => { 13 + expect(parseMacStr('11:22:33:44:55:66')).toEqual([17, 34, 51, 68, 85, 102]); 14 + }); 15 + }); 16 + 17 + describe(parseIpStr, () => { 18 + it('parses valid IP addresses', () => { 19 + expect(parseIpStr('0.0.0.0').toString(16)).toBe('0'); 20 + expect(parseIpStr('1.1.1.1').toString(16)).toBe('1010101'); 21 + expect(parseIpStr('255.255.255.255').toString(16)).toBe('-1'); 22 + expect(parseIpStr('100.1.2.3').toString(16)).toBe('64010203'); 23 + }); 24 + }); 25 + 26 + describe(toIpStr, () => { 27 + it.each([['0.0.0.0'], ['1.1.1.1'], ['255.255.255.255'], ['100.1.2.3']])( 28 + 'stringifies parsed IP (%s)', 29 + addr => { 30 + expect(toIpStr(parseIpStr(addr))).toBe(addr); 31 + } 32 + ); 33 + }); 34 + 35 + describe(interfaceAssignments, () => { 36 + const networkInterfaces = vi 37 + .spyOn(os, 'networkInterfaces') 38 + .mockReturnValue([] as any); 39 + 40 + it('returns sorted list of assignments', () => { 41 + networkInterfaces.mockReturnValueOnce({ 42 + lo0: [ 43 + { 44 + address: '127.0.0.1', 45 + netmask: '255.0.0.0', 46 + family: 'IPv4', 47 + mac: '00:00:00:00:00:00', 48 + internal: true, 49 + cidr: '', 50 + }, 51 + ], 52 + en1: [ 53 + { 54 + address: '10.0.0.10', 55 + netmask: '255.255.255.0', 56 + family: 'IPv4', 57 + mac: '00:00:00:00:00:00', 58 + internal: false, 59 + cidr: '', 60 + }, 61 + ], 62 + tun2: [ 63 + { 64 + address: '100.0.0.11', 65 + netmask: '255.255.255.0', 66 + family: 'IPv4', 67 + mac: '00:00:00:00:00:00', 68 + internal: true, 69 + cidr: '', 70 + }, 71 + ], 72 + }); 73 + expect(interfaceAssignments()).toMatchInlineSnapshot(` 74 + [ 75 + { 76 + "address": "10.0.0.10", 77 + "cidr": "", 78 + "family": "IPv4", 79 + "iname": "en1", 80 + "internal": false, 81 + "mac": "00:00:00:00:00:00", 82 + "netmask": "255.255.255.0", 83 + }, 84 + { 85 + "address": "100.0.0.11", 86 + "cidr": "", 87 + "family": "IPv4", 88 + "iname": "tun2", 89 + "internal": true, 90 + "mac": "00:00:00:00:00:00", 91 + "netmask": "255.255.255.0", 92 + }, 93 + { 94 + "address": "127.0.0.1", 95 + "cidr": "", 96 + "family": "IPv4", 97 + "iname": "lo0", 98 + "internal": true, 99 + "mac": "00:00:00:00:00:00", 100 + "netmask": "255.0.0.0", 101 + }, 102 + ] 103 + `); 104 + }); 105 + }); 106 + 107 + describe(matchAssignment, () => { 108 + it('returns matching assignment by address', () => { 109 + const assignment = { 110 + iname: 'en0', 111 + address: '100.0.0.11', 112 + netmask: '255.255.255.0', 113 + family: 'IPv4', 114 + mac: '00:00:00:00:00:00', 115 + internal: true, 116 + cidr: '', 117 + } as const; 118 + expect(matchAssignment([assignment], '100.0.0.11')).toEqual({ 119 + ...assignment, 120 + gateway: null, 121 + }); 122 + }); 123 + 124 + it('returns matching assignment by gateway', () => { 125 + const assignment = { 126 + iname: 'en0', 127 + address: '100.0.0.11', 128 + netmask: '255.255.255.0', 129 + family: 'IPv4', 130 + mac: '00:00:00:00:00:00', 131 + internal: true, 132 + cidr: '', 133 + } as const; 134 + expect(matchAssignment([assignment], '100.0.0.1')).toEqual({ 135 + ...assignment, 136 + gateway: '100.0.0.1', 137 + }); 138 + }); 139 + 140 + it('returns null otherwise', () => { 141 + const assignment = { 142 + iname: 'en0', 143 + address: '10.0.0.1', 144 + netmask: '255.255.255.0', 145 + family: 'IPv4', 146 + mac: '00:00:00:00:00:00', 147 + internal: true, 148 + cidr: '', 149 + } as const; 150 + expect(matchAssignment([assignment], '100.0.0.1')).toBe(null); 151 + }); 152 + });
+2 -2
src/network.ts
··· 1 - import { networkInterfaces } from 'node:os'; 1 + import os from 'node:os'; 2 2 import type { GatewayAssignment, NetworkAssignment } from './types'; 3 3 4 4 export const parseMacStr = (macStr: string): number[] => ··· 36 36 37 37 export const interfaceAssignments = (): NetworkAssignment[] => { 38 38 const candidates: NetworkAssignment[] = []; 39 - const interfaces = networkInterfaces(); 39 + const interfaces = os.networkInterfaces(); 40 40 for (const iname in interfaces) { 41 41 const assignments = interfaces[iname]; 42 42 if (!assignments) continue;