first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

63
node_modules/lan-network/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,63 @@
# lan-network
## 0.2.0
### Minor Changes
- Add `noProbe` and `noDhcp` options
Submitted by [@kitten](https://github.com/kitten) (See [#18](https://github.com/kitten/lan-network/pull/18))
## 0.1.8
### Patch Changes
- Deprioritize `bridge*` interfaces as internal networks
Submitted by [@kitten](https://github.com/kitten) (See [#15](https://github.com/kitten/lan-network/pull/15))
- Update rollup config for reduced output and exclude sources from sourcemaps
Submitted by [@kitten](https://github.com/kitten) (See [#17](https://github.com/kitten/lan-network/pull/17))
## 0.1.7
### Patch Changes
- Compare subnet-masked addresses before accepting DHCP discover message
Submitted by [@hyoban](https://github.com/hyoban) (See [#12](https://github.com/kitten/lan-network/pull/12))
## 0.1.6
### Patch Changes
- ⚠️ Fix probing and fallback methods for Windows
Submitted by [@kitten](https://github.com/kitten) (See [#9](https://github.com/kitten/lan-network/pull/9))
## 0.1.5
### Patch Changes
- When matching a probed route, ignore internal interfaces. The probed route will match a VPN (virtual) interface when using it to tunnel all traffic, but is unlikely to be considered the local network by users
Submitted by [@kitten](https://github.com/kitten) (See [#7](https://github.com/kitten/lan-network/pull/7))
## 0.1.3
### Patch Changes
- Move vitest to devDependencies
Submitted by [@kitten](https://github.com/kitten) (See [#5](https://github.com/kitten/lan-network/pull/5))
## 0.1.2
### Patch Changes
- Add CLI for testing
Submitted by [@kitten](https://github.com/kitten) (See [#3](https://github.com/kitten/lan-network/pull/3))
## 0.1.1
### Patch Changes
- Bind to assignment IP for DHCP discovery
Submitted by [@kitten](https://github.com/kitten) (See [#1](https://github.com/kitten/lan-network/pull/1))
## 0.1.0
Initial Release.

21
node_modules/lan-network/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Phil Pluckthun,
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

22
node_modules/lan-network/README.md generated vendored Normal file
View File

@@ -0,0 +1,22 @@
# lan-network
**Best-effort discovery of the machine's default gateway and local network IPv4 address exclusively with UDP sockets.**
This utility attempts to determine the interface and IPv4 address of a machine
on the local network. It'll attempt to determine the default gateway and
return the corresponding network interface assignment, both when the network
is online and offline.
The LAN Network it attempts to pick is the one that the machine uses to connect
to the internet. Determining it is useful to pick the machine's IP address that
is generally used to connect to it from other devices on the network.
`lanNetwork()` makes three separate attempts to guess the local network:
1. Create a socket to a publicly routed IP, and return the assignment matching the socket's local address
2. Broadcast DHCP discovery packets on all routable network assignments and listen for replies
3. Highest priority assignment
`lanNetworkSync()` does the same synchronously by spawning a child process
and blocking until a result is determined. Using this method is generally
not recommended.

258
node_modules/lan-network/dist/chunks/index-chunk.js generated vendored Normal file
View File

@@ -0,0 +1,258 @@
var e = require("child_process");
var t = require("node:crypto");
var r = require("node:dgram");
var s = require("node:os");
var n = require("dgram");
const o = {
iname: "lo0",
address: "127.0.0.1",
netmask: "255.0.0.0",
family: "IPv4",
mac: "00:00:00:00:00:00",
internal: !0,
cidr: "127.0.0.1/8",
gateway: null
};
const parseMacStr = e => e.split(":").slice(0, 16).map((e => parseInt(e, 16)));
const parseIpStr = e => {
const t = e.split(".").slice(0, 4).map((e => parseInt(e, 10)));
return t[3] | t[2] << 8 | t[1] << 16 | t[0] << 24;
};
const getSubnetPriority = e => {
if (e.startsWith("192.")) {
return 5;
} else if (e.startsWith("172.")) {
return 4;
} else if (e.startsWith("10.")) {
return 3;
} else if (e.startsWith("100.")) {
return 2;
} else if (e.startsWith("127.")) {
return 1;
} else {
return 0;
}
};
const isInternal = e => {
if (e.internal) {
return !0;
}
const t = parseMacStr(e.mac);
if (t.every((e => !e))) {
return !0;
} else if (0 === t[0] && 21 === t[1] && 93 === t[2]) {
return !0;
} else if (e.iname.includes("vEthernet") || /^bridge\d+$/.test(e.iname)) {
return !0;
} else {
return !1;
}
};
const interfaceAssignments = () => {
const e = [];
const t = s.networkInterfaces();
for (const r in t) {
const s = t[r];
if (!s) {
continue;
}
for (const t of s) {
if ("IPv4" !== t.family) {
continue;
}
e.push({
...t,
iname: r
});
}
}
return e.sort(((e, t) => {
const r = getSubnetPriority(e.address);
const s = getSubnetPriority(t.address);
return +isInternal(e) - +isInternal(t) || s - r || parseIpStr(t.address) - parseIpStr(e.address);
}));
};
const matchAssignment = (e, t) => {
const r = parseIpStr(t);
for (const s of e) {
const e = parseIpStr(s.address);
if (r === e) {
return {
...s,
gateway: null
};
}
const n = parseIpStr(s.netmask);
if ((r & n) == (e & n)) {
return {
...s,
gateway: t
};
}
}
return null;
};
class DHCPTimeoutError extends TypeError {
code="ETIMEDOUT";
}
const dhcpDiscover = e => new Promise(((s, n) => {
const o = (e => (e => {
const t = 255;
let r = "";
r += `${(e >>> 24 & t).toString(10)}.`;
r += `${(e >>> 16 & t).toString(10)}.`;
r += `${(e >>> 8 & t).toString(10)}.`;
r += (e & t).toString(10);
return r;
})(parseIpStr(e.address) | ~parseIpStr(e.netmask)))(e);
const c = (e => {
const r = new Uint8Array(16);
r.set(parseMacStr(e));
const s = new Uint8Array(244);
const n = t.randomBytes(4);
s[0] = 1;
s[1] = 1;
s[2] = 6;
s[3] = 0;
s.set(n, 4);
s[10] = 128;
s.set(r, 28);
s.set([ 99, 130, 83, 99 ], 236);
s.set([ 53, 1, 1, 255 ], 240);
return s;
})(e.mac);
const a = setTimeout((() => {
n(new DHCPTimeoutError("Received no reply to DHCPDISCOVER in 250ms"));
}), 250);
const i = r.createSocket({
type: "udp4",
reuseAddr: !0
}, ((t, r) => {
if (!((e, t, r) => {
const s = parseIpStr(e);
const n = parseIpStr(t);
const o = parseIpStr(r);
return (s & o) == (n & o);
})(r.address, e.address, e.netmask)) {
return;
}
clearTimeout(a);
s(r.address);
i.close();
i.unref();
}));
i.on("error", (e => {
clearTimeout(a);
n(e);
i.close();
i.unref();
}));
i.bind(68, (() => {
i.setBroadcast(!0);
i.setSendBufferSize(c.length);
i.send(c, 0, c.length, 67, o, (e => {
if (e) {
n(e);
}
}));
}));
}));
class DefaultRouteError extends TypeError {
code="ECONNABORT";
}
const probeDefaultRoute = () => new Promise(((e, t) => {
const r = n.createSocket({
type: "udp4",
reuseAddr: !0
});
r.on("error", (e => {
t(e);
r.close();
r.unref();
}));
r.connect(53, "1.1.1.1", (() => {
const s = r.address();
if (s && "address" in s && "0.0.0.0" !== s.address) {
e(s.address);
} else {
t(new DefaultRouteError("No route to host"));
}
r.close();
r.unref();
}));
}));
exports.DEFAULT_ASSIGNMENT = o;
exports.dhcpDiscover = dhcpDiscover;
exports.interfaceAssignments = interfaceAssignments;
exports.lanNetwork = async function lanNetwork(e) {
const t = interfaceAssignments();
if (!t.length) {
return o;
}
let r;
if (!e?.noProbe) {
try {
const e = await probeDefaultRoute();
if ((r = matchAssignment(t, e)) && !isInternal(r)) {
return r;
}
} catch {}
}
if (!e?.noDhcp) {
const e = await Promise.allSettled(t.map((e => dhcpDiscover(e))));
for (const s of e) {
if ("fulfilled" === s.status && s.value) {
if (r = matchAssignment(t, s.value)) {
return r;
}
}
}
}
return {
...t[0],
gateway: null
};
};
exports.lanNetworkSync = function lanNetworkSync(t) {
const r = require.resolve("lan-network/subprocess");
const {error: s, status: n, stdout: c} = e.spawnSync(process.execPath, [ r, t?.noProbe ? "--no-probe" : null, t?.noDhcp ? "--no-dhcp" : null ].filter((e => !!e)), {
shell: !1,
timeout: 500,
encoding: "utf8",
windowsVerbatimArguments: !1,
windowsHide: !0
});
if (n || s) {
return o;
} else if (!n && "string" == typeof c) {
const e = JSON.parse(c.trim());
return "object" == typeof e && e && "address" in e ? e : o;
} else {
return o;
}
};
exports.matchAssignment = matchAssignment;
exports.probeDefaultRoute = probeDefaultRoute;
//# sourceMappingURL=index-chunk.js.map

File diff suppressed because one or more lines are too long

1
node_modules/lan-network/dist/lan-network-cli.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
#!/usr/bin/env node

119
node_modules/lan-network/dist/lan-network-cli.js generated vendored Executable file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/env node
var e = require("./chunks/index-chunk.js");
!function cli() {
let t = "default";
e: for (let e = 1; e < process.argv.length; e++) {
const o = process.argv[e].trim().toLowerCase();
switch (o) {
case "-h":
case "--help":
t = "help";
break e;
case "-d":
case "--dhcp":
t = "dhcp";
break;
case "-p":
case "--probe":
t = "probe";
break;
case "-f":
case "--fallback":
t = "fallback";
break;
default:
if (o.startsWith("-")) {
throw new TypeError(`Invalid flag: ${o}`);
}
}
}
switch (t) {
case "help":
return function help() {
const e = [ "Discover the machine's default gateway and local network IP (test utility)", "", "Usage", " $ lan-network", " $ lan-network --default", "", "Modes", " --probe Discover gateway via UDP4 socket to publicly routed address", " --dhcp Discover gateway via DHCPv4 discover broadcast", " --fallback Return highest-priority IPv4 network interface assignment", " --default Try the three above modes in order", " --help Print help output" ].join("\n");
console.log(e);
}();
case "dhcp":
return async function dhcp() {
const t = e.interfaceAssignments();
if (!t.length) {
console.error("No available network interface assignments");
process.exit(1);
}
const o = await Promise.allSettled(t.map((t => e.dhcpDiscover(t))));
let s = null;
for (const r of o) {
if ("fulfilled" === r.status && r.value) {
if (s = e.matchAssignment(t, r.value)) {
break;
}
}
}
if (s && s !== e.DEFAULT_ASSIGNMENT) {
console.log(JSON.stringify(s, null, 2));
process.exit(0);
} else {
console.error("No DHCP router was discoverable");
process.exit(1);
}
}();
case "probe":
return async function probe() {
const t = e.interfaceAssignments();
if (!t.length) {
console.error("No available network interface assignments");
process.exit(1);
}
try {
const o = await e.probeDefaultRoute();
const s = e.matchAssignment(t, o);
if (s && s !== e.DEFAULT_ASSIGNMENT) {
console.log(JSON.stringify(s, null, 2));
process.exit(0);
} else {
console.error("No default gateway or route");
process.exit(1);
}
} catch (e) {
console.error("No default gateway or route");
console.error(e);
process.exit(1);
}
}();
case "fallback":
return async function fallback() {
const t = e.interfaceAssignments();
if (!t.length) {
console.error("No available network interface assignments");
process.exit(1);
}
const o = {
...t[0],
gateway: null
};
console.log(JSON.stringify(o, null, 2));
process.exit(0);
}();
case "default":
(async function main() {
const t = await e.lanNetwork();
if (t !== e.DEFAULT_ASSIGNMENT) {
console.log(JSON.stringify(t, null, 2));
process.exit(0);
} else {
console.error("No default gateway, route, or DHCP router");
process.exit(1);
}
})();
}
}();
//# sourceMappingURL=lan-network-cli.js.map

1
node_modules/lan-network/dist/lan-network-cli.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"lan-network-cli.js","sources":["../src/cli.ts"],"sourcesContent":null,"names":["cli","mode","parseArgs","i","process","argv","length","arg","trim","toLowerCase","startsWith","TypeError","help","output","join","console","log","async","dhcp","assignments","interfaceAssignments","error","exit","discoveries","Promise","allSettled","map","assignment","dhcpDiscover","discovery","status","value","matchAssignment","DEFAULT_ASSIGNMENT","JSON","stringify","probe","defaultRoute","probeDefaultRoute","fallback","gateway","main","lanNetwork"],"mappings":";;;CA4GA,SAASA;EACP,IAAIC,IAAa;EACjBC,GAAW,KAAK,IAAIC,IAAI,GAAGA,IAAIC,QAAQC,KAAKC,QAAQH,KAAK;IACvD,MAAMI,IAAMH,QAAQC,KAAKF,GAAGK,OAAOC;IACnC,QAAQF;KACN,KAAK;KACL,KAAK;MACHN,IAAO;MACP,MAAMC;;KACR,KAAK;KACL,KAAK;MACHD,IAAO;MACP;;KACF,KAAK;KACL,KAAK;MACHA,IAAO;MACP;;KACF,KAAK;KACL,KAAK;MACHA,IAAO;MACP;;KACF;MACE,IAAIM,EAAIG,WAAW;QAAM,MAAM,IAAIC,UAAU,iBAAiBJ;;;AAEpE;EACA,QAAQN;GACN,KAAK;IACH,OAzHN,SAASW;MACP,MAAMC,IAAS,EACb,8EACA,IACA,SACA,mBACA,6BACA,IACA,SACA,6EACA,gEACA,2EACA,oDACA,oCACAC,KAAK;MACPC,QAAQC,IAAIH;AACd,KAyGaD;;GACT,KAAK;IACH,OAzGNK,eAAeC;MACb,MAAMC,IAAcC,EAAAA;MACpB,KAAKD,EAAYb,QAAQ;QACvBS,QAAQM,MAAM;QACdjB,QAAQkB,KAAK;AACf;MACA,MAAMC,UAAoBC,QAAQC,WAChCN,EAAYO,KAAIC,KAEPC,EAAAA,aAAaD;MAGxB,IAAIA,IAAuC;MAC3C,KAAK,MAAME,KAAaN;QAEtB,IAAyB,gBAArBM,EAAUC,UAA0BD,EAAUE;UAEhD,IAAKJ,IAAaK,EAAAA,gBAAgBb,GADhBU,EAAUE;YAE1B;;;;MAIN,IAAIJ,KAAcA,MAAeM,sBAAoB;QACnDlB,QAAQC,IAAIkB,KAAKC,UAAUR,GAAY,MAAM;QAC7CvB,QAAQkB,KAAK;AACf,aAAO;QACLP,QAAQM,MAAM;QACdjB,QAAQkB,KAAK;AACf;AACF,KA4EaJ;;GACT,KAAK;IACH,OA5END,eAAemB;MACb,MAAMjB,IAAcC,EAAAA;MACpB,KAAKD,EAAYb,QAAQ;QACvBS,QAAQM,MAAM;QACdjB,QAAQkB,KAAK;AACf;MACA;QACE,MAAMe,UAAqBC;QAC3B,MAAMX,IAAaK,EAAAA,gBAAgBb,GAAakB;QAChD,IAAIV,KAAcA,MAAeM,sBAAoB;UACnDlB,QAAQC,IAAIkB,KAAKC,UAAUR,GAAY,MAAM;UAC7CvB,QAAQkB,KAAK;AACf,eAAO;UACLP,QAAQM,MAAM;UACdjB,QAAQkB,KAAK;AACf;AACD,QAAC,OAAOD;QACPN,QAAQM,MAAM;QACdN,QAAQM,MAAMA;QACdjB,QAAQkB,KAAK;AACf;AACF,KAuDac;;GACT,KAAK;IACH,OAvDNnB,eAAesB;MACb,MAAMpB,IAAcC,EAAAA;MACpB,KAAKD,EAAYb,QAAQ;QACvBS,QAAQM,MAAM;QACdjB,QAAQkB,KAAK;AACf;MACA,MAAMK,IAAa;WAAKR,EAAY;QAAIqB,SAAS;;MACjDzB,QAAQC,IAAIkB,KAAKC,UAAUR,GAAY,MAAM;MAC7CvB,QAAQkB,KAAK;AACf,KA8CaiB;;GACT,KAAK;KA7CTtB,eAAewB;MACb,MAAMd,UAAmBe;MACzB,IAAIf,MAAeM,EAAAA,oBAAoB;QACrClB,QAAQC,IAAIkB,KAAKC,UAAUR,GAAY,MAAM;QAC7CvB,QAAQkB,KAAK;AACf,aAAO;QACLP,QAAQM,MAAM;QACdjB,QAAQkB,KAAK;AACf;AACF,MAqCamB;;AAEb,CAEAzC"}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,11 @@
var s = require("./chunks/index-chunk.js");
!async function output() {
const n = await s.lanNetwork({
noProbe: process.argv.includes("--no-probe"),
noDhcp: process.argv.includes("--no-dhcp")
});
process.stdout.write(JSON.stringify(n));
process.exit(0);
}();
//# sourceMappingURL=lan-network-subprocess.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"lan-network-subprocess.js","sources":["../src/subprocess.ts"],"sourcesContent":null,"names":["async","output","assignment","lanNetwork","noProbe","process","argv","includes","noDhcp","stdout","write","JSON","stringify","exit"],"mappings":";;CAEAA,eAAeC;EACb,MAAMC,UAAmBC,aAAW;IAClCC,SAASC,QAAQC,KAAKC,SAAS;IAC/BC,QAAQH,QAAQC,KAAKC,SAAS;;EAEhCF,QAAQI,OAAOC,MAAMC,KAAKC,UAAUV;EACpCG,QAAQQ,KAAK;AACf,CAEAZ"}

21
node_modules/lan-network/dist/lan-network.d.ts generated vendored Normal file
View File

@@ -0,0 +1,21 @@
interface NetworkAssignment {
iname: string;
address: string;
netmask: string;
mac: string;
internal: boolean;
cidr: string | null;
family: 'IPv4';
}
interface GatewayAssignment extends NetworkAssignment {
gateway: string | null;
}
interface NetworkOptions {
noProbe?: boolean;
noDhcp?: boolean;
}
declare function lanNetwork(opts?: NetworkOptions): Promise<GatewayAssignment>;
declare function lanNetworkSync(opts?: NetworkOptions): GatewayAssignment;
export { type NetworkOptions, lanNetwork, lanNetworkSync };

12
node_modules/lan-network/dist/lan-network.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
Object.defineProperty(exports, "__esModule", {
value: !0
});
require("child_process");
var e = require("./chunks/index-chunk.js");
exports.lanNetwork = e.lanNetwork;
exports.lanNetworkSync = e.lanNetworkSync;
//# sourceMappingURL=lan-network.js.map

1
node_modules/lan-network/dist/lan-network.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"lan-network.js","sources":[],"sourcesContent":null,"names":[],"mappings":";;;;;;;;;;"}

84
node_modules/lan-network/package.json generated vendored Normal file
View File

@@ -0,0 +1,84 @@
{
"name": "lan-network",
"version": "0.2.0",
"description": "Best-effort discovery of the machine's default gateway and local network IP exclusively with UDP sockets.",
"author": "Phil Pluckthun <phil@kitten.sh>",
"source": "./src/index.ts",
"main": "./dist/lan-network",
"types": "./dist/lan-network.d.ts",
"files": [
"LICENSE.md",
"README.md",
"CHANGELOG.md",
"dist/"
],
"bin": {
"lan-network": "./dist/lan-network-cli.js"
},
"exports": {
".": {
"types": "./dist/lan-network.d.ts",
"require": "./dist/lan-network.js",
"source": "./src/index.ts"
},
"./subprocess": {
"types": "./dist/lan-network-subprocess.d.ts",
"require": "./dist/lan-network-subprocess.js",
"source": "./src/subprocess.ts"
},
"./cli": {
"types": "./dist/lan-network-cli.d.ts",
"require": "./dist/lan-network-cli.js",
"source": "./src/cli.ts"
},
"./package.json": "./package.json"
},
"prettier": {
"singleQuote": true,
"arrowParens": "avoid",
"trailingComma": "es5"
},
"lint-staged": {
"*.{js,ts,json,md}": "prettier --write"
},
"keywords": [],
"license": "MIT",
"repository": "https://github.com/kitten/lan-network",
"bugs": {
"url": "https://github.com/kitten/lan-network/issues"
},
"devDependencies": {
"@babel/plugin-transform-typescript": "^7.26.7",
"@changesets/cli": "^2.29.6",
"@changesets/get-github-info": "^0.6.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-terser": "^0.4.4",
"@types/node": "^22.12.0",
"dotenv": "^16.4.7",
"lint-staged": "^15.4.3",
"npm-run-all": "^4.1.5",
"prettier": "^3.4.2",
"rimraf": "^6.0.1",
"rollup": "^4.32.1",
"rollup-plugin-cjs-check": "^1.0.3",
"rollup-plugin-dts": "^6.1.1",
"typescript": "^5.7.3",
"vitest": "^3.0.6"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"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",
"changeset:version": "changeset version && pnpm install --lockfile-only",
"changeset:publish": "changeset publish"
}
}