portless 0.10.3 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,8 @@ function fixOwnership(...paths) {
7
7
  if (!uid || process.getuid?.() !== 0) return;
8
8
  for (const p of paths) {
9
9
  try {
10
+ const stat = fs.lstatSync(p);
11
+ if (stat.isSymbolicLink()) continue;
10
12
  fs.chownSync(p, parseInt(uid, 10), parseInt(gid || uid, 10));
11
13
  } catch {
12
14
  }
@@ -673,645 +675,15 @@ function checkHostResolution(hostname) {
673
675
  });
674
676
  }
675
677
 
676
- // src/cli-utils.ts
678
+ // src/routes.ts
677
679
  import * as fs3 from "fs";
678
- import * as http3 from "http";
679
- import * as https from "https";
680
- import * as net2 from "net";
681
- import * as os from "os";
682
680
  import * as path2 from "path";
683
- import * as readline from "readline";
684
- import { execSync, spawn } from "child_process";
685
- var isWindows2 = process.platform === "win32";
686
- var FALLBACK_PROXY_PORT = 1355;
687
- var PRIVILEGED_PORT_THRESHOLD = 1024;
688
- var INTERNAL_LAN_IP_ENV = "PORTLESS_INTERNAL_LAN_IP";
689
- var INTERNAL_LAN_IP_FLAG = "--lan-ip-auto";
690
- var SYSTEM_STATE_DIR = isWindows2 ? path2.join(os.tmpdir(), "portless") : "/tmp/portless";
691
- var USER_STATE_DIR = path2.join(os.homedir(), ".portless");
692
- var MIN_APP_PORT = 4e3;
693
- var MAX_APP_PORT = 4999;
694
- var RANDOM_PORT_ATTEMPTS = 50;
695
- var BLOCKED_PORTS = /* @__PURE__ */ new Set([
696
- 0,
697
- 1,
698
- 7,
699
- 9,
700
- 11,
701
- 13,
702
- 15,
703
- 17,
704
- 19,
705
- 20,
706
- 21,
707
- 22,
708
- 23,
709
- 25,
710
- 37,
711
- 42,
712
- 43,
713
- 53,
714
- 69,
715
- 77,
716
- 79,
717
- 87,
718
- 95,
719
- 101,
720
- 102,
721
- 103,
722
- 104,
723
- 109,
724
- 110,
725
- 111,
726
- 113,
727
- 115,
728
- 117,
729
- 119,
730
- 123,
731
- 135,
732
- 137,
733
- 139,
734
- 143,
735
- 161,
736
- 179,
737
- 389,
738
- 427,
739
- 465,
740
- 512,
741
- 513,
742
- 514,
743
- 515,
744
- 526,
745
- 530,
746
- 531,
747
- 532,
748
- 540,
749
- 548,
750
- 554,
751
- 556,
752
- 563,
753
- 587,
754
- 601,
755
- 636,
756
- 989,
757
- 990,
758
- 993,
759
- 995,
760
- 1719,
761
- 1720,
762
- 1723,
763
- 2049,
764
- 3659,
765
- 4045,
766
- 4190,
767
- 5060,
768
- 5061,
769
- 6e3,
770
- 6566,
771
- 6665,
772
- 6666,
773
- 6667,
774
- 6668,
775
- 6669,
776
- 6679,
777
- 6697,
778
- 10080
779
- ]);
780
- var SOCKET_TIMEOUT_MS = 500;
781
- var PID_LOOKUP_TIMEOUT_MS = 5e3;
782
- var WAIT_FOR_PROXY_MAX_ATTEMPTS = 20;
783
- var WAIT_FOR_PROXY_INTERVAL_MS = 250;
784
- var SIGNAL_CODES = {
785
- SIGHUP: 1,
786
- SIGINT: 2,
787
- SIGQUIT: 3,
788
- SIGABRT: 6,
789
- SIGKILL: 9,
790
- SIGTERM: 15
791
- };
792
- function getProtocolPort(tls) {
793
- return tls ? 443 : 80;
794
- }
795
- function getDefaultPort(tls) {
796
- const envPort = process.env.PORTLESS_PORT;
797
- if (envPort) {
798
- const port = parseInt(envPort, 10);
799
- if (!isNaN(port) && port >= 1 && port <= 65535) return port;
800
- }
801
- return tls === void 0 ? FALLBACK_PROXY_PORT : getProtocolPort(tls);
802
- }
803
- function resolveStateDir(port) {
804
- if (process.env.PORTLESS_STATE_DIR) return process.env.PORTLESS_STATE_DIR;
805
- if (isWindows2) return USER_STATE_DIR;
806
- return port < PRIVILEGED_PORT_THRESHOLD ? SYSTEM_STATE_DIR : USER_STATE_DIR;
807
- }
808
- function readPortFromDir(dir) {
809
- try {
810
- const raw = fs3.readFileSync(path2.join(dir, "proxy.port"), "utf-8").trim();
811
- const port = parseInt(raw, 10);
812
- return isNaN(port) ? null : port;
813
- } catch {
814
- return null;
815
- }
816
- }
817
- var TLS_MARKER_FILE = "proxy.tls";
818
- function readTlsMarker(dir) {
819
- try {
820
- return fs3.existsSync(path2.join(dir, TLS_MARKER_FILE));
821
- } catch {
822
- return false;
823
- }
824
- }
825
- function writeTlsMarker(dir, enabled) {
826
- const markerPath = path2.join(dir, TLS_MARKER_FILE);
827
- if (enabled) {
828
- fs3.writeFileSync(markerPath, "1", { mode: 420 });
829
- } else {
830
- try {
831
- fs3.unlinkSync(markerPath);
832
- } catch {
833
- }
834
- }
835
- }
836
- var LAN_MARKER_FILE = "proxy.lan";
837
- function readLanMarker(dir) {
838
- try {
839
- const raw = fs3.readFileSync(path2.join(dir, LAN_MARKER_FILE), "utf-8").trim();
840
- return raw || null;
841
- } catch {
842
- return null;
843
- }
844
- }
845
- function writeLanMarker(dir, ip) {
846
- const markerPath = path2.join(dir, LAN_MARKER_FILE);
847
- if (!ip) {
848
- try {
849
- fs3.unlinkSync(markerPath);
850
- } catch {
851
- }
852
- } else {
853
- fs3.writeFileSync(markerPath, ip, { mode: 420 });
854
- }
855
- }
856
- var DEFAULT_TLD = "localhost";
857
- var RISKY_TLDS = /* @__PURE__ */ new Map([
858
- ["local", "conflicts with mDNS/Bonjour on macOS"],
859
- ["dev", "Google-owned; browsers force HTTPS via preloaded HSTS"],
860
- ["com", "public TLD; DNS requests will leak to the internet"],
861
- ["org", "public TLD; DNS requests will leak to the internet"],
862
- ["net", "public TLD; DNS requests will leak to the internet"],
863
- ["io", "public TLD; DNS requests will leak to the internet"],
864
- ["app", "public TLD; DNS requests will leak to the internet"],
865
- ["edu", "public TLD; DNS requests will leak to the internet"],
866
- ["gov", "public TLD; DNS requests will leak to the internet"],
867
- ["mil", "public TLD; DNS requests will leak to the internet"],
868
- ["int", "public TLD; DNS requests will leak to the internet"]
869
- ]);
870
- function validateTld(tld) {
871
- if (!tld) return "TLD cannot be empty";
872
- if (!/^[a-z0-9]+$/.test(tld)) {
873
- return `Invalid TLD "${tld}": must contain only lowercase letters and digits`;
874
- }
875
- return null;
876
- }
877
- var TLD_FILE = "proxy.tld";
878
- function readTldFromDir(dir) {
879
- try {
880
- const raw = fs3.readFileSync(path2.join(dir, TLD_FILE), "utf-8").trim();
881
- return raw || DEFAULT_TLD;
882
- } catch {
883
- return DEFAULT_TLD;
884
- }
885
- }
886
- function writeTldFile(dir, tld) {
887
- const filePath = path2.join(dir, TLD_FILE);
888
- if (tld === DEFAULT_TLD) {
889
- try {
890
- fs3.unlinkSync(filePath);
891
- } catch {
892
- }
893
- } else {
894
- fs3.writeFileSync(filePath, tld, { mode: 420 });
895
- }
896
- }
897
- function getDefaultTld() {
898
- const val = process.env.PORTLESS_TLD?.trim().toLowerCase();
899
- if (!val) return DEFAULT_TLD;
900
- const err = validateTld(val);
901
- if (err) throw new Error(`PORTLESS_TLD: ${err}`);
902
- return val;
903
- }
904
- function isHttpsEnvDisabled() {
905
- const val = process.env.PORTLESS_HTTPS;
906
- return val === "0" || val === "false";
907
- }
908
- function isWildcardEnvEnabled() {
909
- const val = process.env.PORTLESS_WILDCARD;
910
- return val === "1" || val === "true";
911
- }
912
- function isLanEnvEnabled() {
913
- const val = process.env.PORTLESS_LAN;
914
- return val === "1" || val === "true";
915
- }
916
- function readPersistedProxyState() {
917
- const dirs = [];
918
- if (process.env.PORTLESS_STATE_DIR) {
919
- dirs.push(process.env.PORTLESS_STATE_DIR);
920
- } else {
921
- dirs.push(USER_STATE_DIR, SYSTEM_STATE_DIR);
922
- }
923
- for (const dir of dirs) {
924
- const port = readPortFromDir(dir);
925
- if (port !== null) {
926
- const tls = readTlsMarker(dir);
927
- const tld = readTldFromDir(dir);
928
- const lanIp = readLanMarker(dir);
929
- return { port, tls, tld, lanMode: lanIp !== null || tld === "local" };
930
- }
931
- }
932
- return null;
933
- }
934
- function buildProxyStartConfig(options) {
935
- const effectiveTld = options.lanMode ? "local" : options.tld;
936
- const args = [];
937
- if (options.foreground) {
938
- args.push("--foreground");
939
- }
940
- if (options.includePort && options.proxyPort !== void 0) {
941
- args.push("--port", options.proxyPort.toString());
942
- }
943
- if (options.useHttps) {
944
- if (options.customCertPath && options.customKeyPath) {
945
- args.push("--cert", options.customCertPath, "--key", options.customKeyPath);
946
- } else {
947
- args.push("--https");
948
- }
949
- } else {
950
- args.push("--no-tls");
951
- }
952
- if (options.lanMode) {
953
- args.push("--lan");
954
- if (options.lanIp) {
955
- if (options.lanIpExplicit) {
956
- args.push("--ip", options.lanIp);
957
- } else {
958
- args.push(INTERNAL_LAN_IP_FLAG, options.lanIp);
959
- }
960
- }
961
- } else if (effectiveTld !== DEFAULT_TLD) {
962
- args.push("--tld", effectiveTld);
963
- }
964
- if (options.useWildcard) {
965
- args.push("--wildcard");
966
- }
967
- if (options.skipTrust) {
968
- args.push("--skip-trust");
969
- }
970
- return { effectiveTld, args };
971
- }
972
- async function discoverState() {
973
- if (process.env.PORTLESS_STATE_DIR) {
974
- const dir2 = process.env.PORTLESS_STATE_DIR;
975
- const port = readPortFromDir(dir2) ?? getDefaultPort();
976
- const lanIp = readLanMarker(dir2);
977
- if (await isProxyRunning(port) || await isPortListening(port)) {
978
- const tls = readTlsMarker(dir2);
979
- const tld = readTldFromDir(dir2);
980
- return { dir: dir2, port, tls, tld, lanMode: lanIp !== null || tld === "local", lanIp };
981
- }
982
- return {
983
- dir: dir2,
984
- port,
985
- tls: readTlsMarker(dir2),
986
- tld: readTldFromDir(dir2),
987
- lanMode: lanIp !== null,
988
- lanIp: null
989
- };
990
- }
991
- const userPort = readPortFromDir(USER_STATE_DIR);
992
- if (userPort !== null) {
993
- if (await isProxyRunning(userPort)) {
994
- const tls = readTlsMarker(USER_STATE_DIR);
995
- const tld = readTldFromDir(USER_STATE_DIR);
996
- const lanIp = readLanMarker(USER_STATE_DIR);
997
- return {
998
- dir: USER_STATE_DIR,
999
- port: userPort,
1000
- tls,
1001
- tld,
1002
- lanMode: lanIp !== null || tld === "local",
1003
- lanIp
1004
- };
1005
- }
1006
- }
1007
- const systemPort = readPortFromDir(SYSTEM_STATE_DIR);
1008
- if (systemPort !== null) {
1009
- if (await isProxyRunning(systemPort)) {
1010
- const tls = readTlsMarker(SYSTEM_STATE_DIR);
1011
- const tld = readTldFromDir(SYSTEM_STATE_DIR);
1012
- const lanIp = readLanMarker(SYSTEM_STATE_DIR);
1013
- return {
1014
- dir: SYSTEM_STATE_DIR,
1015
- port: systemPort,
1016
- tls,
1017
- tld,
1018
- lanMode: lanIp !== null || tld === "local",
1019
- lanIp
1020
- };
1021
- }
1022
- }
1023
- const configuredPort = getDefaultPort();
1024
- const probePorts = /* @__PURE__ */ new Set([443, 80, FALLBACK_PROXY_PORT, configuredPort]);
1025
- for (const port of probePorts) {
1026
- if (await isProxyRunning(port)) {
1027
- const dir2 = resolveStateDir(port);
1028
- const tls = readTlsMarker(dir2);
1029
- const tld = readTldFromDir(dir2);
1030
- const lanIp = readLanMarker(dir2);
1031
- return { dir: dir2, port, tls, tld, lanMode: lanIp !== null || tld === "local", lanIp };
1032
- }
1033
- }
1034
- const dir = resolveStateDir(configuredPort);
1035
- return {
1036
- dir,
1037
- port: configuredPort,
1038
- tls: readTlsMarker(dir),
1039
- tld: readTldFromDir(dir),
1040
- lanMode: readLanMarker(dir) !== null,
1041
- lanIp: null
1042
- };
1043
- }
1044
- async function findFreePort(minPort = MIN_APP_PORT, maxPort = MAX_APP_PORT) {
1045
- if (minPort > maxPort) {
1046
- throw new Error(`minPort (${minPort}) must be <= maxPort (${maxPort})`);
1047
- }
1048
- const tryPort = (port) => {
1049
- return new Promise((resolve) => {
1050
- const server = net2.createServer();
1051
- server.listen(port, () => {
1052
- server.close(() => resolve(true));
1053
- });
1054
- server.on("error", () => resolve(false));
1055
- });
1056
- };
1057
- for (let i = 0; i < RANDOM_PORT_ATTEMPTS; i++) {
1058
- const port = minPort + Math.floor(Math.random() * (maxPort - minPort + 1));
1059
- if (!BLOCKED_PORTS.has(port) && await tryPort(port)) {
1060
- return port;
1061
- }
1062
- }
1063
- for (let port = minPort; port <= maxPort; port++) {
1064
- if (!BLOCKED_PORTS.has(port) && await tryPort(port)) {
1065
- return port;
1066
- }
1067
- }
1068
- throw new Error(`No free port found in range ${minPort}-${maxPort}`);
1069
- }
1070
- function isProxyRunning(port, tls = false) {
1071
- return new Promise((resolve) => {
1072
- const requestFn = tls ? https.request : http3.request;
1073
- const req = requestFn(
1074
- {
1075
- hostname: "127.0.0.1",
1076
- port,
1077
- path: "/",
1078
- method: "HEAD",
1079
- timeout: SOCKET_TIMEOUT_MS,
1080
- ...tls ? { rejectUnauthorized: false } : {}
1081
- },
1082
- (res) => {
1083
- res.resume();
1084
- resolve(res.headers[PORTLESS_HEADER.toLowerCase()] === "1");
1085
- }
1086
- );
1087
- req.on("error", () => resolve(false));
1088
- req.on("timeout", () => {
1089
- req.destroy();
1090
- resolve(false);
1091
- });
1092
- req.end();
1093
- });
1094
- }
1095
- function isPortListening(port) {
1096
- return new Promise((resolve) => {
1097
- const socket = net2.createConnection({ host: "127.0.0.1", port });
1098
- let settled = false;
1099
- const finish = (result) => {
1100
- if (settled) return;
1101
- settled = true;
1102
- socket.destroy();
1103
- resolve(result);
1104
- };
1105
- socket.setTimeout(SOCKET_TIMEOUT_MS);
1106
- socket.once("connect", () => finish(true));
1107
- socket.once("error", () => finish(false));
1108
- socket.once("timeout", () => finish(false));
1109
- });
1110
- }
1111
- function parsePidFromNetstat(output, port) {
1112
- for (const line of output.split(/\r?\n/)) {
1113
- if (!line.includes("LISTENING")) continue;
1114
- const parts = line.trim().split(/\s+/);
1115
- if (parts.length < 5) continue;
1116
- const localAddr = parts[1];
1117
- const lastColon = localAddr.lastIndexOf(":");
1118
- if (lastColon === -1) continue;
1119
- const addrPort = parseInt(localAddr.substring(lastColon + 1), 10);
1120
- if (addrPort === port) {
1121
- const pid = parseInt(parts[parts.length - 1], 10);
1122
- if (!isNaN(pid) && pid > 0) return pid;
1123
- }
1124
- }
1125
- return null;
1126
- }
1127
- function findPidOnPort(port) {
1128
- try {
1129
- if (isWindows2) {
1130
- const output2 = execSync("netstat -ano -p tcp", {
1131
- encoding: "utf-8",
1132
- timeout: PID_LOOKUP_TIMEOUT_MS
1133
- });
1134
- return parsePidFromNetstat(output2, port);
1135
- }
1136
- const output = execSync(`lsof -ti tcp:${port} -sTCP:LISTEN`, {
1137
- encoding: "utf-8",
1138
- timeout: PID_LOOKUP_TIMEOUT_MS
1139
- });
1140
- const pid = parseInt(output.trim().split("\n")[0], 10);
1141
- return isNaN(pid) ? null : pid;
1142
- } catch {
1143
- return null;
1144
- }
1145
- }
1146
- async function waitForProxy(port, maxAttempts = WAIT_FOR_PROXY_MAX_ATTEMPTS, intervalMs = WAIT_FOR_PROXY_INTERVAL_MS, tls = false) {
1147
- for (let i = 0; i < maxAttempts; i++) {
1148
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
1149
- if (await isProxyRunning(port, tls)) {
1150
- return true;
1151
- }
1152
- }
1153
- return false;
1154
- }
1155
- function shellEscape(arg) {
1156
- return `'${arg.replace(/'/g, "'\\''")}'`;
1157
- }
1158
- function collectBinPaths(cwd) {
1159
- const dirs = [];
1160
- let dir = cwd;
1161
- for (; ; ) {
1162
- const bin = path2.join(dir, "node_modules", ".bin");
1163
- if (fs3.existsSync(bin)) {
1164
- dirs.push(bin);
1165
- }
1166
- const parent = path2.dirname(dir);
1167
- if (parent === dir) break;
1168
- dir = parent;
1169
- }
1170
- return dirs;
1171
- }
1172
- function augmentedPath(env) {
1173
- const source = env ?? process.env;
1174
- const base = source.PATH ?? source.Path ?? "";
1175
- const bins = collectBinPaths(process.cwd());
1176
- const nodeBin = path2.dirname(process.execPath);
1177
- const allBins = [...bins, nodeBin];
1178
- return allBins.join(path2.delimiter) + path2.delimiter + base;
1179
- }
1180
- function spawnCommand(commandArgs, options) {
1181
- const env = {
1182
- ...options?.env ?? process.env,
1183
- PATH: augmentedPath(options?.env)
1184
- };
1185
- if (isWindows2) {
1186
- for (const key of Object.keys(env)) {
1187
- if (key !== "PATH" && key.toUpperCase() === "PATH") {
1188
- delete env[key];
1189
- }
1190
- }
1191
- }
1192
- const child = isWindows2 ? spawn("cmd.exe", ["/d", "/s", "/c", commandArgs.join(" ")], {
1193
- stdio: "inherit",
1194
- env
1195
- }) : spawn("/bin/sh", ["-c", commandArgs.map(shellEscape).join(" ")], {
1196
- stdio: "inherit",
1197
- env
1198
- });
1199
- let exiting = false;
1200
- const cleanup = () => {
1201
- process.removeListener("SIGINT", onSigInt);
1202
- process.removeListener("SIGTERM", onSigTerm);
1203
- options?.onCleanup?.();
1204
- };
1205
- const handleSignal = (signal) => {
1206
- if (exiting) return;
1207
- exiting = true;
1208
- child.kill(signal);
1209
- cleanup();
1210
- process.exit(128 + (SIGNAL_CODES[signal] || 15));
1211
- };
1212
- const onSigInt = () => handleSignal("SIGINT");
1213
- const onSigTerm = () => handleSignal("SIGTERM");
1214
- process.on("SIGINT", onSigInt);
1215
- process.on("SIGTERM", onSigTerm);
1216
- child.on("error", (err) => {
1217
- if (exiting) return;
1218
- exiting = true;
1219
- console.error(`Failed to run command: ${err.message}`);
1220
- if (err.code === "ENOENT") {
1221
- console.error(`Is "${commandArgs[0]}" installed and in your PATH?`);
1222
- }
1223
- cleanup();
1224
- process.exit(1);
1225
- });
1226
- child.on("exit", (code, signal) => {
1227
- if (exiting) return;
1228
- exiting = true;
1229
- cleanup();
1230
- if (signal) {
1231
- process.exit(128 + (SIGNAL_CODES[signal] || 15));
1232
- }
1233
- process.exit(code ?? 1);
1234
- });
1235
- }
1236
- var FRAMEWORKS_NEEDING_PORT = {
1237
- vite: { strictPort: true },
1238
- vp: { strictPort: true },
1239
- "react-router": { strictPort: true },
1240
- astro: { strictPort: false },
1241
- ng: { strictPort: false },
1242
- "react-native": { strictPort: false },
1243
- expo: { strictPort: false }
1244
- };
1245
- var PACKAGE_RUNNERS = {
1246
- npx: [],
1247
- bunx: [],
1248
- pnpx: [],
1249
- yarn: ["dlx", "exec"],
1250
- pnpm: ["dlx", "exec"]
1251
- };
1252
- function findFrameworkBasename(commandArgs) {
1253
- if (commandArgs.length === 0) return null;
1254
- const first = path2.basename(commandArgs[0]);
1255
- if (FRAMEWORKS_NEEDING_PORT[first]) return first;
1256
- const subcommands = PACKAGE_RUNNERS[first];
1257
- if (!subcommands) return null;
1258
- let i = 1;
1259
- if (subcommands.length > 0) {
1260
- while (i < commandArgs.length && commandArgs[i].startsWith("-")) i++;
1261
- if (i >= commandArgs.length) return null;
1262
- if (!subcommands.includes(commandArgs[i])) {
1263
- const name2 = path2.basename(commandArgs[i]);
1264
- return FRAMEWORKS_NEEDING_PORT[name2] ? name2 : null;
1265
- }
1266
- i++;
1267
- }
1268
- while (i < commandArgs.length && commandArgs[i].startsWith("-")) i++;
1269
- if (i >= commandArgs.length) return null;
1270
- const name = path2.basename(commandArgs[i]);
1271
- return FRAMEWORKS_NEEDING_PORT[name] ? name : null;
1272
- }
1273
- function injectFrameworkFlags(commandArgs, port) {
1274
- const basename2 = findFrameworkBasename(commandArgs);
1275
- if (!basename2) return;
1276
- const framework = FRAMEWORKS_NEEDING_PORT[basename2];
1277
- if (!commandArgs.includes("--port")) {
1278
- commandArgs.push("--port", port.toString());
1279
- if (framework.strictPort) {
1280
- commandArgs.push("--strictPort");
1281
- }
1282
- }
1283
- if (!commandArgs.includes("--host")) {
1284
- const isExpoLan = basename2 === "expo" && isLanEnvEnabled();
1285
- if (isExpoLan) return;
1286
- const hostValue = basename2 === "expo" ? "localhost" : "127.0.0.1";
1287
- commandArgs.push("--host", hostValue);
1288
- }
1289
- }
1290
- function prompt(question) {
1291
- const rl = readline.createInterface({
1292
- input: process.stdin,
1293
- output: process.stdout
1294
- });
1295
- return new Promise((resolve) => {
1296
- rl.on("close", () => resolve(""));
1297
- rl.question(question, (answer) => {
1298
- rl.close();
1299
- resolve(answer.trim().toLowerCase());
1300
- });
1301
- });
1302
- }
1303
-
1304
- // src/routes.ts
1305
- import * as fs4 from "fs";
1306
- import * as path3 from "path";
1307
681
  var STALE_LOCK_THRESHOLD_MS = 1e4;
1308
682
  var LOCK_TIMEOUT_MS = 5e3;
1309
683
  var LOCK_RETRY_BASE_MS = 10;
1310
684
  var LOCK_RETRY_CAP_MS = 500;
1311
685
  var FILE_MODE = 420;
1312
686
  var DIR_MODE = 493;
1313
- var SYSTEM_DIR_MODE = 1023;
1314
- var SYSTEM_FILE_MODE = 438;
1315
687
  function isValidRoute(value) {
1316
688
  return typeof value === "object" && value !== null && typeof value.hostname === "string" && typeof value.port === "number" && typeof value.pid === "number";
1317
689
  }
@@ -1337,27 +709,18 @@ var RouteStore = class _RouteStore {
1337
709
  onWarning;
1338
710
  constructor(dir, options) {
1339
711
  this.dir = dir;
1340
- this.routesPath = path3.join(dir, "routes.json");
1341
- this.lockPath = path3.join(dir, "routes.lock");
1342
- this.pidPath = path3.join(dir, "proxy.pid");
1343
- this.portFilePath = path3.join(dir, "proxy.port");
712
+ this.routesPath = path2.join(dir, "routes.json");
713
+ this.lockPath = path2.join(dir, "routes.lock");
714
+ this.pidPath = path2.join(dir, "proxy.pid");
715
+ this.portFilePath = path2.join(dir, "proxy.port");
1344
716
  this.onWarning = options?.onWarning;
1345
717
  }
1346
- isSystemDir() {
1347
- return this.dir === SYSTEM_STATE_DIR;
1348
- }
1349
- get dirMode() {
1350
- return this.isSystemDir() ? SYSTEM_DIR_MODE : DIR_MODE;
1351
- }
1352
- get fileMode() {
1353
- return this.isSystemDir() ? SYSTEM_FILE_MODE : FILE_MODE;
1354
- }
1355
718
  ensureDir() {
1356
- if (!fs4.existsSync(this.dir)) {
1357
- fs4.mkdirSync(this.dir, { recursive: true, mode: this.dirMode });
719
+ if (!fs3.existsSync(this.dir)) {
720
+ fs3.mkdirSync(this.dir, { recursive: true, mode: DIR_MODE });
1358
721
  }
1359
722
  try {
1360
- fs4.chmodSync(this.dir, this.dirMode);
723
+ fs3.chmodSync(this.dir, DIR_MODE);
1361
724
  } catch {
1362
725
  }
1363
726
  fixOwnership(this.dir);
@@ -1376,14 +739,14 @@ var RouteStore = class _RouteStore {
1376
739
  let delay = LOCK_RETRY_BASE_MS;
1377
740
  while (Date.now() < deadline) {
1378
741
  try {
1379
- fs4.mkdirSync(this.lockPath);
742
+ fs3.mkdirSync(this.lockPath);
1380
743
  return true;
1381
744
  } catch (err) {
1382
745
  if (isErrnoException(err) && err.code === "EEXIST") {
1383
746
  try {
1384
- const stat = fs4.statSync(this.lockPath);
747
+ const stat = fs3.statSync(this.lockPath);
1385
748
  if (Date.now() - stat.mtimeMs > STALE_LOCK_THRESHOLD_MS) {
1386
- fs4.rmSync(this.lockPath, { recursive: true });
749
+ fs3.rmSync(this.lockPath, { recursive: true });
1387
750
  continue;
1388
751
  }
1389
752
  } catch {
@@ -1401,7 +764,7 @@ var RouteStore = class _RouteStore {
1401
764
  }
1402
765
  releaseLock() {
1403
766
  try {
1404
- fs4.rmSync(this.lockPath, { recursive: true });
767
+ fs3.rmSync(this.lockPath, { recursive: true });
1405
768
  } catch {
1406
769
  }
1407
770
  }
@@ -1422,11 +785,11 @@ var RouteStore = class _RouteStore {
1422
785
  * unprotected concurrent writes.
1423
786
  */
1424
787
  loadRoutes(persistCleanup = false) {
1425
- if (!fs4.existsSync(this.routesPath)) {
788
+ if (!fs3.existsSync(this.routesPath)) {
1426
789
  return [];
1427
790
  }
1428
791
  try {
1429
- const raw = fs4.readFileSync(this.routesPath, "utf-8");
792
+ const raw = fs3.readFileSync(this.routesPath, "utf-8");
1430
793
  let parsed;
1431
794
  try {
1432
795
  parsed = JSON.parse(raw);
@@ -1442,8 +805,8 @@ var RouteStore = class _RouteStore {
1442
805
  const alive = routes.filter((r) => r.pid === 0 || this.isProcessAlive(r.pid));
1443
806
  if (persistCleanup && alive.length !== routes.length) {
1444
807
  try {
1445
- fs4.writeFileSync(this.routesPath, JSON.stringify(alive, null, 2), {
1446
- mode: this.fileMode
808
+ fs3.writeFileSync(this.routesPath, JSON.stringify(alive, null, 2), {
809
+ mode: FILE_MODE
1447
810
  });
1448
811
  } catch {
1449
812
  }
@@ -1454,7 +817,7 @@ var RouteStore = class _RouteStore {
1454
817
  }
1455
818
  }
1456
819
  saveRoutes(routes) {
1457
- fs4.writeFileSync(this.routesPath, JSON.stringify(routes, null, 2), { mode: this.fileMode });
820
+ fs3.writeFileSync(this.routesPath, JSON.stringify(routes, null, 2), { mode: FILE_MODE });
1458
821
  fixOwnership(this.routesPath);
1459
822
  }
1460
823
  /**
@@ -1521,45 +884,8 @@ export {
1521
884
  cleanHostsFile,
1522
885
  getManagedHostnames,
1523
886
  checkHostResolution,
1524
- isWindows2 as isWindows,
1525
- FALLBACK_PROXY_PORT,
1526
- PRIVILEGED_PORT_THRESHOLD,
1527
- INTERNAL_LAN_IP_ENV,
1528
- INTERNAL_LAN_IP_FLAG,
1529
- SYSTEM_STATE_DIR,
1530
- USER_STATE_DIR,
1531
- WAIT_FOR_PROXY_MAX_ATTEMPTS,
1532
- WAIT_FOR_PROXY_INTERVAL_MS,
1533
- getDefaultPort,
1534
- resolveStateDir,
1535
- readTlsMarker,
1536
- writeTlsMarker,
1537
- readLanMarker,
1538
- writeLanMarker,
1539
- DEFAULT_TLD,
1540
- RISKY_TLDS,
1541
- validateTld,
1542
- readTldFromDir,
1543
- writeTldFile,
1544
- getDefaultTld,
1545
- isHttpsEnvDisabled,
1546
- isWildcardEnvEnabled,
1547
- isLanEnvEnabled,
1548
- readPersistedProxyState,
1549
- buildProxyStartConfig,
1550
- discoverState,
1551
- findFreePort,
1552
- isProxyRunning,
1553
- isPortListening,
1554
- findPidOnPort,
1555
- waitForProxy,
1556
- spawnCommand,
1557
- injectFrameworkFlags,
1558
- prompt,
1559
887
  FILE_MODE,
1560
888
  DIR_MODE,
1561
- SYSTEM_DIR_MODE,
1562
- SYSTEM_FILE_MODE,
1563
889
  RouteConflictError,
1564
890
  RouteStore
1565
891
  };