shiplocal 0.1.2 → 0.1.4

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.
package/dist/index.js CHANGED
@@ -4071,7 +4071,7 @@ var DEFAULT_TUNNEL_PORT = 3e3;
4071
4071
  // ../shared/dist/protocol.js
4072
4072
  var TUNNEL_WS_PATH = "/tunnel";
4073
4073
  var DEFAULT_TUNNEL_EXPIRY_MS = 2 * 60 * 60 * 1e3;
4074
- var MAX_BODY_BYTES = 10 * 1024 * 1024;
4074
+ var MAX_BODY_BYTES = 50 * 1024 * 1024;
4075
4075
  var headersSchema = external_exports.record(external_exports.union([external_exports.string(), external_exports.array(external_exports.string())]));
4076
4076
  var registerMessageSchema = external_exports.object({
4077
4077
  type: external_exports.literal("register"),
@@ -4153,6 +4153,7 @@ import { WebSocket } from "ws";
4153
4153
 
4154
4154
  // ../tunnel-client/dist/local-proxy.js
4155
4155
  import http from "node:http";
4156
+ var LOOPBACK_HOSTS = ["127.0.0.1", "::1"];
4156
4157
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
4157
4158
  "connection",
4158
4159
  "keep-alive",
@@ -4168,7 +4169,10 @@ var STRIP_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
4168
4169
  "content-encoding",
4169
4170
  "content-length"
4170
4171
  ]);
4171
- function sanitizeRequestHeaders(headers) {
4172
+ function isConnectionRefused(err) {
4173
+ return err instanceof Error && "code" in err && err.code === "ECONNREFUSED";
4174
+ }
4175
+ function sanitizeRequestHeaders(headers, localPort) {
4172
4176
  const result = {};
4173
4177
  for (const [key, value] of Object.entries(headers)) {
4174
4178
  const lower = key.toLowerCase();
@@ -4177,6 +4181,7 @@ function sanitizeRequestHeaders(headers) {
4177
4181
  }
4178
4182
  result[key] = value;
4179
4183
  }
4184
+ result["host"] = `localhost:${String(localPort)}`;
4180
4185
  return result;
4181
4186
  }
4182
4187
  function sanitizeResponseHeaders(headers) {
@@ -4191,16 +4196,14 @@ function sanitizeResponseHeaders(headers) {
4191
4196
  }
4192
4197
  return result;
4193
4198
  }
4194
- async function forwardToLocal(localPort, message) {
4195
- const body = decodeBody(message.body);
4196
- const pathWithQuery = message.query ? `${message.path}?${message.query}` : message.path;
4199
+ function forwardToHost(hostname, localPort, message, body, pathWithQuery) {
4197
4200
  return new Promise((resolve, reject) => {
4198
4201
  const req = http.request({
4199
- hostname: "127.0.0.1",
4202
+ hostname,
4200
4203
  port: localPort,
4201
4204
  method: message.method,
4202
4205
  path: pathWithQuery,
4203
- headers: sanitizeRequestHeaders(message.headers)
4206
+ headers: sanitizeRequestHeaders(message.headers, localPort)
4204
4207
  }, (res) => {
4205
4208
  const chunks = [];
4206
4209
  let totalSize = 0;
@@ -4233,6 +4236,23 @@ async function forwardToLocal(localPort, message) {
4233
4236
  req.end();
4234
4237
  });
4235
4238
  }
4239
+ async function forwardToLocal(localPort, message) {
4240
+ const body = decodeBody(message.body);
4241
+ const pathWithQuery = message.query ? `${message.path}?${message.query}` : message.path;
4242
+ let lastError;
4243
+ for (const hostname of LOOPBACK_HOSTS) {
4244
+ try {
4245
+ return await forwardToHost(hostname, localPort, message, body, pathWithQuery);
4246
+ } catch (err) {
4247
+ if (isConnectionRefused(err)) {
4248
+ lastError = err;
4249
+ continue;
4250
+ }
4251
+ throw err;
4252
+ }
4253
+ }
4254
+ throw lastError ?? new Error("Local server unreachable");
4255
+ }
4236
4256
 
4237
4257
  // ../tunnel-client/dist/client.js
4238
4258
  function toWebSocketUrl(serverUrl) {
@@ -4246,9 +4266,11 @@ function toWebSocketUrl(serverUrl) {
4246
4266
  function formatLocalProxyError(err, localPort) {
4247
4267
  if (err instanceof Error && "code" in err && err.code === "ECONNREFUSED") {
4248
4268
  return [
4249
- `Nothing is running on http://127.0.0.1:${String(localPort)}.`,
4269
+ `Nothing is listening on port ${String(localPort)} (tried 127.0.0.1 and ::1).`,
4250
4270
  "",
4251
4271
  "Start your local server on that port, then refresh this page.",
4272
+ "If your browser works on localhost but the tunnel does not, your dev server may only",
4273
+ "listen on IPv6 \u2014 bind to 0.0.0.0 or 127.0.0.1 (e.g. next dev -H 0.0.0.0).",
4252
4274
  `If your app uses a different port, restart the CLI with that port (e.g. shiplocal ${String(localPort)}).`
4253
4275
  ].join("\n");
4254
4276
  }
@@ -4358,7 +4380,9 @@ function createTunnelClient(options) {
4358
4380
  ws.close();
4359
4381
  }
4360
4382
  }
4361
- const socket = new WebSocket(toWebSocketUrl(options.serverUrl));
4383
+ const socket = new WebSocket(toWebSocketUrl(options.serverUrl), {
4384
+ maxPayload: 64 * 1024 * 1024
4385
+ });
4362
4386
  ws = socket;
4363
4387
  socket.on("open", () => {
4364
4388
  socket.send(JSON.stringify({
@@ -4462,7 +4486,7 @@ async function resolveToken() {
4462
4486
  }
4463
4487
 
4464
4488
  // src/api.ts
4465
- function isConnectionRefused(err) {
4489
+ function isConnectionRefused2(err) {
4466
4490
  if (!(err instanceof Error)) return false;
4467
4491
  const cause = err.cause;
4468
4492
  if (cause instanceof Error && "code" in cause && cause.code === "ECONNREFUSED") {
@@ -4474,7 +4498,7 @@ function isConnectionRefused(err) {
4474
4498
  return err.message.includes("ECONNREFUSED") || err.message.includes("fetch failed");
4475
4499
  }
4476
4500
  function formatServerConnectionError(apiUrl, err) {
4477
- if (isConnectionRefused(err)) {
4501
+ if (isConnectionRefused2(err)) {
4478
4502
  return [
4479
4503
  `Cannot reach ShipLocal server at ${apiUrl}.`,
4480
4504
  "",
@@ -4505,9 +4529,10 @@ async function postJson(path, body, apiUrl) {
4505
4529
 
4506
4530
  // src/local-port.ts
4507
4531
  import net from "node:net";
4508
- function isLocalPortOpen(port, timeoutMs = 2e3) {
4532
+ var LOOPBACK_HOSTS2 = ["127.0.0.1", "::1"];
4533
+ function canConnect(host, port, timeoutMs) {
4509
4534
  return new Promise((resolve) => {
4510
- const socket = net.connect({ port, host: "127.0.0.1" });
4535
+ const socket = net.connect({ port, host });
4511
4536
  const finish = (open) => {
4512
4537
  socket.removeAllListeners();
4513
4538
  socket.destroy();
@@ -4525,10 +4550,18 @@ function isLocalPortOpen(port, timeoutMs = 2e3) {
4525
4550
  });
4526
4551
  });
4527
4552
  }
4553
+ async function isLocalPortOpen(port, timeoutMs = 2e3) {
4554
+ for (const host of LOOPBACK_HOSTS2) {
4555
+ if (await canConnect(host, port, timeoutMs)) {
4556
+ return true;
4557
+ }
4558
+ }
4559
+ return false;
4560
+ }
4528
4561
 
4529
4562
  // src/index.ts
4530
4563
  var program = new Command();
4531
- program.name("shiplocal").description("Share localhost with clients in seconds").version("0.1.2");
4564
+ program.name("shiplocal").description("Share localhost with clients in seconds").version("0.1.4");
4532
4565
  program.command("login").description("Authenticate with ShipLocal Cloud").action(async () => {
4533
4566
  const rl = createInterface({ input, output });
4534
4567
  const apiUrl = await resolveApiUrlAsync();