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

test: Add unit tests for src/network

Changed files
+783 -3
.github
workflows
src
+3
.github/workflows/ci.yml
···
- name: Build
run: pnpm run build
+
+
- name: Unit tests
+
run: pnpm run test:run
+6 -1
package.json
···
"dist/"
],
"scripts": {
+
"test": "vitest test",
+
"test:run": "vitest test --run",
"build": "rollup -c ./scripts/rollup.config.mjs",
"postbuild": "tsc --noEmit ./dist/lan-network.d.ts",
"check": "tsc --noEmit",
"clean": "rimraf dist node_modules/.cache",
-
"prepublishOnly": "run-s clean build check",
+
"prepublishOnly": "run-s clean build check test:run",
"prepare": "node ./scripts/prepare.js || true",
"changeset:version": "changeset version && pnpm install --lockfile-only",
"changeset:publish": "changeset publish"
···
"publishConfig": {
"access": "public",
"provenance": true
+
},
+
"dependencies": {
+
"vitest": "^3.0.6"
}
}
+620
pnpm-lock.yaml
···
importers:
.:
+
dependencies:
+
vitest:
+
specifier: ^3.0.6
+
version: 3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0)
devDependencies:
'@babel/plugin-transform-block-scoping':
specifier: ^7.25.9
···
'@changesets/write@0.3.2':
resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==}
+
'@esbuild/aix-ppc64@0.24.2':
+
resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
+
engines: {node: '>=18'}
+
cpu: [ppc64]
+
os: [aix]
+
+
'@esbuild/android-arm64@0.24.2':
+
resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [android]
+
+
'@esbuild/android-arm@0.24.2':
+
resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
+
engines: {node: '>=18'}
+
cpu: [arm]
+
os: [android]
+
+
'@esbuild/android-x64@0.24.2':
+
resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [android]
+
+
'@esbuild/darwin-arm64@0.24.2':
+
resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [darwin]
+
+
'@esbuild/darwin-x64@0.24.2':
+
resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [darwin]
+
+
'@esbuild/freebsd-arm64@0.24.2':
+
resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [freebsd]
+
+
'@esbuild/freebsd-x64@0.24.2':
+
resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [freebsd]
+
+
'@esbuild/linux-arm64@0.24.2':
+
resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [linux]
+
+
'@esbuild/linux-arm@0.24.2':
+
resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
+
engines: {node: '>=18'}
+
cpu: [arm]
+
os: [linux]
+
+
'@esbuild/linux-ia32@0.24.2':
+
resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
+
engines: {node: '>=18'}
+
cpu: [ia32]
+
os: [linux]
+
+
'@esbuild/linux-loong64@0.24.2':
+
resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
+
engines: {node: '>=18'}
+
cpu: [loong64]
+
os: [linux]
+
+
'@esbuild/linux-mips64el@0.24.2':
+
resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
+
engines: {node: '>=18'}
+
cpu: [mips64el]
+
os: [linux]
+
+
'@esbuild/linux-ppc64@0.24.2':
+
resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
+
engines: {node: '>=18'}
+
cpu: [ppc64]
+
os: [linux]
+
+
'@esbuild/linux-riscv64@0.24.2':
+
resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
+
engines: {node: '>=18'}
+
cpu: [riscv64]
+
os: [linux]
+
+
'@esbuild/linux-s390x@0.24.2':
+
resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
+
engines: {node: '>=18'}
+
cpu: [s390x]
+
os: [linux]
+
+
'@esbuild/linux-x64@0.24.2':
+
resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [linux]
+
+
'@esbuild/netbsd-arm64@0.24.2':
+
resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [netbsd]
+
+
'@esbuild/netbsd-x64@0.24.2':
+
resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [netbsd]
+
+
'@esbuild/openbsd-arm64@0.24.2':
+
resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [openbsd]
+
+
'@esbuild/openbsd-x64@0.24.2':
+
resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [openbsd]
+
+
'@esbuild/sunos-x64@0.24.2':
+
resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [sunos]
+
+
'@esbuild/win32-arm64@0.24.2':
+
resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
+
engines: {node: '>=18'}
+
cpu: [arm64]
+
os: [win32]
+
+
'@esbuild/win32-ia32@0.24.2':
+
resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
+
engines: {node: '>=18'}
+
cpu: [ia32]
+
os: [win32]
+
+
'@esbuild/win32-x64@0.24.2':
+
resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
+
engines: {node: '>=18'}
+
cpu: [x64]
+
os: [win32]
+
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
···
'@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
+
'@vitest/expect@3.0.6':
+
resolution: {integrity: sha512-zBduHf/ja7/QRX4HdP1DSq5XrPgdN+jzLOwaTq/0qZjYfgETNFCKf9nOAp2j3hmom3oTbczuUzrzg9Hafh7hNg==}
+
+
'@vitest/mocker@3.0.6':
+
resolution: {integrity: sha512-KPztr4/tn7qDGZfqlSPQoF2VgJcKxnDNhmfR3VgZ6Fy1bO8T9Fc1stUiTXtqz0yG24VpD00pZP5f8EOFknjNuQ==}
+
peerDependencies:
+
msw: ^2.4.9
+
vite: ^5.0.0 || ^6.0.0
+
peerDependenciesMeta:
+
msw:
+
optional: true
+
vite:
+
optional: true
+
+
'@vitest/pretty-format@3.0.6':
+
resolution: {integrity: sha512-Zyctv3dbNL+67qtHfRnUE/k8qxduOamRfAL1BurEIQSyOEFffoMvx2pnDSSbKAAVxY0Ej2J/GH2dQKI0W2JyVg==}
+
+
'@vitest/runner@3.0.6':
+
resolution: {integrity: sha512-JopP4m/jGoaG1+CBqubV/5VMbi7L+NQCJTu1J1Pf6YaUbk7bZtaq5CX7p+8sY64Sjn1UQ1XJparHfcvTTdu9cA==}
+
+
'@vitest/snapshot@3.0.6':
+
resolution: {integrity: sha512-qKSmxNQwT60kNwwJHMVwavvZsMGXWmngD023OHSgn873pV0lylK7dwBTfYP7e4URy5NiBCHHiQGA9DHkYkqRqg==}
+
+
'@vitest/spy@3.0.6':
+
resolution: {integrity: sha512-HfOGx/bXtjy24fDlTOpgiAEJbRfFxoX3zIGagCqACkFKKZ/TTOE6gYMKXlqecvxEndKFuNHcHqP081ggZ2yM0Q==}
+
+
'@vitest/utils@3.0.6':
+
resolution: {integrity: sha512-18ktZpf4GQFTbf9jK543uspU03Q2qya7ZGya5yiZ0Gx0nnnalBvd5ZBislbl2EhLjM8A8rt4OilqKG7QwcGkvQ==}
+
acorn@8.14.0:
resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
engines: {node: '>=0.4.0'}
···
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
engines: {node: '>= 0.4'}
+
assertion-error@2.0.1:
+
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+
engines: {node: '>=12'}
+
async-function@1.0.0:
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
engines: {node: '>= 0.4'}
···
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
cac@6.7.14:
+
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+
engines: {node: '>=8'}
+
call-bind-apply-helpers@1.0.1:
resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
engines: {node: '>= 0.4'}
···
caniuse-lite@1.0.30001696:
resolution: {integrity: sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==}
+
chai@5.2.0:
+
resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
+
engines: {node: '>=12'}
+
chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
···
chardet@0.7.0:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
+
+
check-error@2.1.1:
+
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
+
engines: {node: '>= 16'}
ci-info@3.9.0:
resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
···
supports-color:
optional: true
+
deep-eql@5.0.2:
+
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
+
engines: {node: '>=6'}
+
deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
···
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
+
es-module-lexer@1.6.0:
+
resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
+
es-object-atoms@1.1.1:
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
engines: {node: '>= 0.4'}
···
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'}
+
esbuild@0.24.2:
+
resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
+
engines: {node: '>=18'}
+
hasBin: true
+
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
···
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+
estree-walker@3.0.3:
+
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
···
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
+
expect-type@1.1.0:
+
resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==}
+
engines: {node: '>=12.0.0'}
+
extendable-error@0.1.7:
resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==}
···
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
engines: {node: '>=18'}
+
loupe@3.1.3:
+
resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
+
lru-cache@11.0.2:
resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==}
engines: {node: 20 || >=22}
···
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+
nanoid@3.3.8:
+
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+
hasBin: true
nice-try@1.0.5:
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
···
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
+
+
pathe@2.0.3:
+
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+
pathval@2.0.0:
+
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
+
engines: {node: '>= 14.16'}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
···
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
+
postcss@8.5.3:
+
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
+
engines: {node: ^10 || ^12 || >=14}
+
prettier@2.8.8:
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
engines: {node: '>=10.13.0'}
···
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
+
siginfo@2.0.0:
+
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
···
smob@1.5.0:
resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==}
+
+
source-map-js@1.2.1:
+
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+
engines: {node: '>=0.10.0'}
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
···
sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+
stackback@0.0.2:
+
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+
std-env@3.8.0:
+
resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
···
engines: {node: '>=10'}
hasBin: true
+
tinybench@2.9.0:
+
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+
tinyexec@0.3.2:
+
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+
tinypool@1.0.2:
+
resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
+
engines: {node: ^18.0.0 || >=20.0.0}
+
+
tinyrainbow@2.0.0:
+
resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
+
engines: {node: '>=14.0.0'}
+
+
tinyspy@3.0.2:
+
resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
+
engines: {node: '>=14.0.0'}
+
tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
···
validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+
vite-node@3.0.6:
+
resolution: {integrity: sha512-s51RzrTkXKJrhNbUzQRsarjmAae7VmMPAsRT7lppVpIg6mK3zGthP9Hgz0YQQKuNcF+Ii7DfYk3Fxz40jRmePw==}
+
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+
hasBin: true
+
+
vite@6.1.1:
+
resolution: {integrity: sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==}
+
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+
hasBin: true
+
peerDependencies:
+
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+
jiti: '>=1.21.0'
+
less: '*'
+
lightningcss: ^1.21.0
+
sass: '*'
+
sass-embedded: '*'
+
stylus: '*'
+
sugarss: '*'
+
terser: ^5.16.0
+
tsx: ^4.8.1
+
yaml: ^2.4.2
+
peerDependenciesMeta:
+
'@types/node':
+
optional: true
+
jiti:
+
optional: true
+
less:
+
optional: true
+
lightningcss:
+
optional: true
+
sass:
+
optional: true
+
sass-embedded:
+
optional: true
+
stylus:
+
optional: true
+
sugarss:
+
optional: true
+
terser:
+
optional: true
+
tsx:
+
optional: true
+
yaml:
+
optional: true
+
+
vitest@3.0.6:
+
resolution: {integrity: sha512-/iL1Sc5VeDZKPDe58oGK4HUFLhw6b5XdY1MYawjuSaDA4sEfYlY9HnS6aCEG26fX+MgUi7MwlduTBHHAI/OvMA==}
+
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+
hasBin: true
+
peerDependencies:
+
'@edge-runtime/vm': '*'
+
'@types/debug': ^4.1.12
+
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+
'@vitest/browser': 3.0.6
+
'@vitest/ui': 3.0.6
+
happy-dom: '*'
+
jsdom: '*'
+
peerDependenciesMeta:
+
'@edge-runtime/vm':
+
optional: true
+
'@types/debug':
+
optional: true
+
'@types/node':
+
optional: true
+
'@vitest/browser':
+
optional: true
+
'@vitest/ui':
+
optional: true
+
happy-dom:
+
optional: true
+
jsdom:
+
optional: true
+
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
···
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
+
hasBin: true
+
+
why-is-node-running@2.3.0:
+
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+
engines: {node: '>=8'}
hasBin: true
wrap-ansi@7.0.0:
···
human-id: 1.0.2
prettier: 2.8.8
+
'@esbuild/aix-ppc64@0.24.2':
+
optional: true
+
+
'@esbuild/android-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/android-arm@0.24.2':
+
optional: true
+
+
'@esbuild/android-x64@0.24.2':
+
optional: true
+
+
'@esbuild/darwin-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/darwin-x64@0.24.2':
+
optional: true
+
+
'@esbuild/freebsd-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/freebsd-x64@0.24.2':
+
optional: true
+
+
'@esbuild/linux-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/linux-arm@0.24.2':
+
optional: true
+
+
'@esbuild/linux-ia32@0.24.2':
+
optional: true
+
+
'@esbuild/linux-loong64@0.24.2':
+
optional: true
+
+
'@esbuild/linux-mips64el@0.24.2':
+
optional: true
+
+
'@esbuild/linux-ppc64@0.24.2':
+
optional: true
+
+
'@esbuild/linux-riscv64@0.24.2':
+
optional: true
+
+
'@esbuild/linux-s390x@0.24.2':
+
optional: true
+
+
'@esbuild/linux-x64@0.24.2':
+
optional: true
+
+
'@esbuild/netbsd-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/netbsd-x64@0.24.2':
+
optional: true
+
+
'@esbuild/openbsd-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/openbsd-x64@0.24.2':
+
optional: true
+
+
'@esbuild/sunos-x64@0.24.2':
+
optional: true
+
+
'@esbuild/win32-arm64@0.24.2':
+
optional: true
+
+
'@esbuild/win32-ia32@0.24.2':
+
optional: true
+
+
'@esbuild/win32-x64@0.24.2':
+
optional: true
+
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
···
'@types/resolve@1.20.2': {}
+
'@vitest/expect@3.0.6':
+
dependencies:
+
'@vitest/spy': 3.0.6
+
'@vitest/utils': 3.0.6
+
chai: 5.2.0
+
tinyrainbow: 2.0.0
+
+
'@vitest/mocker@3.0.6(vite@6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0))':
+
dependencies:
+
'@vitest/spy': 3.0.6
+
estree-walker: 3.0.3
+
magic-string: 0.30.17
+
optionalDependencies:
+
vite: 6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0)
+
+
'@vitest/pretty-format@3.0.6':
+
dependencies:
+
tinyrainbow: 2.0.0
+
+
'@vitest/runner@3.0.6':
+
dependencies:
+
'@vitest/utils': 3.0.6
+
pathe: 2.0.3
+
+
'@vitest/snapshot@3.0.6':
+
dependencies:
+
'@vitest/pretty-format': 3.0.6
+
magic-string: 0.30.17
+
pathe: 2.0.3
+
+
'@vitest/spy@3.0.6':
+
dependencies:
+
tinyspy: 3.0.2
+
+
'@vitest/utils@3.0.6':
+
dependencies:
+
'@vitest/pretty-format': 3.0.6
+
loupe: 3.1.3
+
tinyrainbow: 2.0.0
+
acorn@8.14.0: {}
ansi-colors@4.1.3: {}
···
get-intrinsic: 1.2.7
is-array-buffer: 3.0.5
+
assertion-error@2.0.1: {}
+
async-function@1.0.0: {}
available-typed-arrays@1.0.7:
···
update-browserslist-db: 1.1.2(browserslist@4.24.4)
buffer-from@1.1.2: {}
+
+
cac@6.7.14: {}
call-bind-apply-helpers@1.0.1:
dependencies:
···
caniuse-lite@1.0.30001696: {}
+
chai@5.2.0:
+
dependencies:
+
assertion-error: 2.0.1
+
check-error: 2.1.1
+
deep-eql: 5.0.2
+
loupe: 3.1.3
+
pathval: 2.0.0
+
chalk@2.4.2:
dependencies:
ansi-styles: 3.2.1
···
chalk@5.4.1: {}
chardet@0.7.0: {}
+
+
check-error@2.1.1: {}
ci-info@3.9.0: {}
···
dependencies:
ms: 2.1.3
+
deep-eql@5.0.2: {}
+
deepmerge@4.3.1: {}
define-data-property@1.1.4:
···
es-errors@1.3.0: {}
+
es-module-lexer@1.6.0: {}
+
es-object-atoms@1.1.1:
dependencies:
es-errors: 1.3.0
···
is-date-object: 1.1.0
is-symbol: 1.1.1
+
esbuild@0.24.2:
+
optionalDependencies:
+
'@esbuild/aix-ppc64': 0.24.2
+
'@esbuild/android-arm': 0.24.2
+
'@esbuild/android-arm64': 0.24.2
+
'@esbuild/android-x64': 0.24.2
+
'@esbuild/darwin-arm64': 0.24.2
+
'@esbuild/darwin-x64': 0.24.2
+
'@esbuild/freebsd-arm64': 0.24.2
+
'@esbuild/freebsd-x64': 0.24.2
+
'@esbuild/linux-arm': 0.24.2
+
'@esbuild/linux-arm64': 0.24.2
+
'@esbuild/linux-ia32': 0.24.2
+
'@esbuild/linux-loong64': 0.24.2
+
'@esbuild/linux-mips64el': 0.24.2
+
'@esbuild/linux-ppc64': 0.24.2
+
'@esbuild/linux-riscv64': 0.24.2
+
'@esbuild/linux-s390x': 0.24.2
+
'@esbuild/linux-x64': 0.24.2
+
'@esbuild/netbsd-arm64': 0.24.2
+
'@esbuild/netbsd-x64': 0.24.2
+
'@esbuild/openbsd-arm64': 0.24.2
+
'@esbuild/openbsd-x64': 0.24.2
+
'@esbuild/sunos-x64': 0.24.2
+
'@esbuild/win32-arm64': 0.24.2
+
'@esbuild/win32-ia32': 0.24.2
+
'@esbuild/win32-x64': 0.24.2
+
escalade@3.2.0: {}
escape-string-regexp@1.0.5: {}
···
estree-walker@2.0.2: {}
+
estree-walker@3.0.3:
+
dependencies:
+
'@types/estree': 1.0.6
+
eventemitter3@5.0.1: {}
execa@8.0.1:
···
onetime: 6.0.0
signal-exit: 4.1.0
strip-final-newline: 3.0.0
+
+
expect-type@1.1.0: {}
extendable-error@0.1.7: {}
···
strip-ansi: 7.1.0
wrap-ansi: 9.0.0
+
loupe@3.1.3: {}
+
lru-cache@11.0.2: {}
lru-cache@5.1.1:
···
mri@1.2.0: {}
ms@2.1.3: {}
+
+
nanoid@3.3.8: {}
nice-try@1.0.5: {}
···
path-type@4.0.0: {}
+
pathe@2.0.3: {}
+
+
pathval@2.0.0: {}
+
picocolors@1.1.1: {}
picomatch@2.3.1: {}
···
possible-typed-array-names@1.0.0: {}
+
postcss@8.5.3:
+
dependencies:
+
nanoid: 3.3.8
+
picocolors: 1.1.1
+
source-map-js: 1.2.1
+
prettier@2.8.8: {}
prettier@3.4.2: {}
···
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
+
siginfo@2.0.0: {}
+
signal-exit@4.1.0: {}
slash@3.0.0: {}
···
is-fullwidth-code-point: 5.0.0
smob@1.5.0: {}
+
+
source-map-js@1.2.1: {}
source-map-support@0.5.21:
dependencies:
···
spdx-license-ids@3.0.21: {}
sprintf-js@1.0.3: {}
+
+
stackback@0.0.2: {}
+
+
std-env@3.8.0: {}
string-argv@0.3.2: {}
···
commander: 2.20.3
source-map-support: 0.5.21
+
tinybench@2.9.0: {}
+
+
tinyexec@0.3.2: {}
+
+
tinypool@1.0.2: {}
+
+
tinyrainbow@2.0.0: {}
+
+
tinyspy@3.0.2: {}
+
tmp@0.0.33:
dependencies:
os-tmpdir: 1.0.2
···
spdx-correct: 3.2.0
spdx-expression-parse: 3.0.1
+
vite-node@3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0):
+
dependencies:
+
cac: 6.7.14
+
debug: 4.4.0
+
es-module-lexer: 1.6.0
+
pathe: 2.0.3
+
vite: 6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0)
+
transitivePeerDependencies:
+
- '@types/node'
+
- jiti
+
- less
+
- lightningcss
+
- sass
+
- sass-embedded
+
- stylus
+
- sugarss
+
- supports-color
+
- terser
+
- tsx
+
- yaml
+
+
vite@6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0):
+
dependencies:
+
esbuild: 0.24.2
+
postcss: 8.5.3
+
rollup: 4.32.1
+
optionalDependencies:
+
'@types/node': 22.12.0
+
fsevents: 2.3.3
+
terser: 5.37.0
+
yaml: 2.7.0
+
+
vitest@3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0):
+
dependencies:
+
'@vitest/expect': 3.0.6
+
'@vitest/mocker': 3.0.6(vite@6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0))
+
'@vitest/pretty-format': 3.0.6
+
'@vitest/runner': 3.0.6
+
'@vitest/snapshot': 3.0.6
+
'@vitest/spy': 3.0.6
+
'@vitest/utils': 3.0.6
+
chai: 5.2.0
+
debug: 4.4.0
+
expect-type: 1.1.0
+
magic-string: 0.30.17
+
pathe: 2.0.3
+
std-env: 3.8.0
+
tinybench: 2.9.0
+
tinyexec: 0.3.2
+
tinypool: 1.0.2
+
tinyrainbow: 2.0.0
+
vite: 6.1.1(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0)
+
vite-node: 3.0.6(@types/node@22.12.0)(terser@5.37.0)(yaml@2.7.0)
+
why-is-node-running: 2.3.0
+
optionalDependencies:
+
'@types/node': 22.12.0
+
transitivePeerDependencies:
+
- jiti
+
- less
+
- lightningcss
+
- msw
+
- sass
+
- sass-embedded
+
- stylus
+
- sugarss
+
- supports-color
+
- terser
+
- tsx
+
- yaml
+
webidl-conversions@3.0.1: {}
whatwg-url@5.0.0:
···
which@2.0.2:
dependencies:
isexe: 2.0.0
+
+
why-is-node-running@2.3.0:
+
dependencies:
+
siginfo: 2.0.0
+
stackback: 0.0.2
wrap-ansi@7.0.0:
dependencies:
+152
src/__tests__/network.test.ts
···
+
import os from 'node:os';
+
import { vi, describe, it, expect } from 'vitest';
+
import {
+
parseMacStr,
+
parseIpStr,
+
toIpStr,
+
interfaceAssignments,
+
matchAssignment,
+
} from '../network';
+
+
describe(parseMacStr, () => {
+
it('parses valid MAC addresses', () => {
+
expect(parseMacStr('11:22:33:44:55:66')).toEqual([17, 34, 51, 68, 85, 102]);
+
});
+
});
+
+
describe(parseIpStr, () => {
+
it('parses valid IP addresses', () => {
+
expect(parseIpStr('0.0.0.0').toString(16)).toBe('0');
+
expect(parseIpStr('1.1.1.1').toString(16)).toBe('1010101');
+
expect(parseIpStr('255.255.255.255').toString(16)).toBe('-1');
+
expect(parseIpStr('100.1.2.3').toString(16)).toBe('64010203');
+
});
+
});
+
+
describe(toIpStr, () => {
+
it.each([['0.0.0.0'], ['1.1.1.1'], ['255.255.255.255'], ['100.1.2.3']])(
+
'stringifies parsed IP (%s)',
+
addr => {
+
expect(toIpStr(parseIpStr(addr))).toBe(addr);
+
}
+
);
+
});
+
+
describe(interfaceAssignments, () => {
+
const networkInterfaces = vi
+
.spyOn(os, 'networkInterfaces')
+
.mockReturnValue([] as any);
+
+
it('returns sorted list of assignments', () => {
+
networkInterfaces.mockReturnValueOnce({
+
lo0: [
+
{
+
address: '127.0.0.1',
+
netmask: '255.0.0.0',
+
family: 'IPv4',
+
mac: '00:00:00:00:00:00',
+
internal: true,
+
cidr: '',
+
},
+
],
+
en1: [
+
{
+
address: '10.0.0.10',
+
netmask: '255.255.255.0',
+
family: 'IPv4',
+
mac: '00:00:00:00:00:00',
+
internal: false,
+
cidr: '',
+
},
+
],
+
tun2: [
+
{
+
address: '100.0.0.11',
+
netmask: '255.255.255.0',
+
family: 'IPv4',
+
mac: '00:00:00:00:00:00',
+
internal: true,
+
cidr: '',
+
},
+
],
+
});
+
expect(interfaceAssignments()).toMatchInlineSnapshot(`
+
[
+
{
+
"address": "10.0.0.10",
+
"cidr": "",
+
"family": "IPv4",
+
"iname": "en1",
+
"internal": false,
+
"mac": "00:00:00:00:00:00",
+
"netmask": "255.255.255.0",
+
},
+
{
+
"address": "100.0.0.11",
+
"cidr": "",
+
"family": "IPv4",
+
"iname": "tun2",
+
"internal": true,
+
"mac": "00:00:00:00:00:00",
+
"netmask": "255.255.255.0",
+
},
+
{
+
"address": "127.0.0.1",
+
"cidr": "",
+
"family": "IPv4",
+
"iname": "lo0",
+
"internal": true,
+
"mac": "00:00:00:00:00:00",
+
"netmask": "255.0.0.0",
+
},
+
]
+
`);
+
});
+
});
+
+
describe(matchAssignment, () => {
+
it('returns matching assignment by address', () => {
+
const assignment = {
+
iname: 'en0',
+
address: '100.0.0.11',
+
netmask: '255.255.255.0',
+
family: 'IPv4',
+
mac: '00:00:00:00:00:00',
+
internal: true,
+
cidr: '',
+
} as const;
+
expect(matchAssignment([assignment], '100.0.0.11')).toEqual({
+
...assignment,
+
gateway: null,
+
});
+
});
+
+
it('returns matching assignment by gateway', () => {
+
const assignment = {
+
iname: 'en0',
+
address: '100.0.0.11',
+
netmask: '255.255.255.0',
+
family: 'IPv4',
+
mac: '00:00:00:00:00:00',
+
internal: true,
+
cidr: '',
+
} as const;
+
expect(matchAssignment([assignment], '100.0.0.1')).toEqual({
+
...assignment,
+
gateway: '100.0.0.1',
+
});
+
});
+
+
it('returns null otherwise', () => {
+
const assignment = {
+
iname: 'en0',
+
address: '10.0.0.1',
+
netmask: '255.255.255.0',
+
family: 'IPv4',
+
mac: '00:00:00:00:00:00',
+
internal: true,
+
cidr: '',
+
} as const;
+
expect(matchAssignment([assignment], '100.0.0.1')).toBe(null);
+
});
+
});
+2 -2
src/network.ts
···
-
import { networkInterfaces } from 'node:os';
+
import os from 'node:os';
import type { GatewayAssignment, NetworkAssignment } from './types';
export const parseMacStr = (macStr: string): number[] =>
···
export const interfaceAssignments = (): NetworkAssignment[] => {
const candidates: NetworkAssignment[] = [];
-
const interfaces = networkInterfaces();
+
const interfaces = os.networkInterfaces();
for (const iname in interfaces) {
const assignments = interfaces[iname];
if (!assignments) continue;