shiplocal 0.1.3 → 0.1.5
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 +59 -11
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4109,6 +4109,10 @@ var errorMessageSchema = external_exports.object({
|
|
|
4109
4109
|
type: external_exports.literal("error"),
|
|
4110
4110
|
message: external_exports.string()
|
|
4111
4111
|
});
|
|
4112
|
+
var terminatedMessageSchema = external_exports.object({
|
|
4113
|
+
type: external_exports.literal("terminated"),
|
|
4114
|
+
message: external_exports.string()
|
|
4115
|
+
});
|
|
4112
4116
|
var tunnelMessageSchema = external_exports.discriminatedUnion("type", [
|
|
4113
4117
|
registerMessageSchema,
|
|
4114
4118
|
registeredMessageSchema,
|
|
@@ -4116,7 +4120,8 @@ var tunnelMessageSchema = external_exports.discriminatedUnion("type", [
|
|
|
4116
4120
|
pongMessageSchema,
|
|
4117
4121
|
tunnelRequestMessageSchema,
|
|
4118
4122
|
tunnelResponseMessageSchema,
|
|
4119
|
-
errorMessageSchema
|
|
4123
|
+
errorMessageSchema,
|
|
4124
|
+
terminatedMessageSchema
|
|
4120
4125
|
]);
|
|
4121
4126
|
function parseTunnelMessage(data) {
|
|
4122
4127
|
const parsed = typeof data === "string" ? JSON.parse(data) : data;
|
|
@@ -4153,6 +4158,7 @@ import { WebSocket } from "ws";
|
|
|
4153
4158
|
|
|
4154
4159
|
// ../tunnel-client/dist/local-proxy.js
|
|
4155
4160
|
import http from "node:http";
|
|
4161
|
+
var LOOPBACK_HOSTS = ["127.0.0.1", "::1"];
|
|
4156
4162
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
4157
4163
|
"connection",
|
|
4158
4164
|
"keep-alive",
|
|
@@ -4168,6 +4174,9 @@ var STRIP_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
|
|
|
4168
4174
|
"content-encoding",
|
|
4169
4175
|
"content-length"
|
|
4170
4176
|
]);
|
|
4177
|
+
function isConnectionRefused(err) {
|
|
4178
|
+
return err instanceof Error && "code" in err && err.code === "ECONNREFUSED";
|
|
4179
|
+
}
|
|
4171
4180
|
function sanitizeRequestHeaders(headers, localPort) {
|
|
4172
4181
|
const result = {};
|
|
4173
4182
|
for (const [key, value] of Object.entries(headers)) {
|
|
@@ -4192,12 +4201,10 @@ function sanitizeResponseHeaders(headers) {
|
|
|
4192
4201
|
}
|
|
4193
4202
|
return result;
|
|
4194
4203
|
}
|
|
4195
|
-
|
|
4196
|
-
const body = decodeBody(message.body);
|
|
4197
|
-
const pathWithQuery = message.query ? `${message.path}?${message.query}` : message.path;
|
|
4204
|
+
function forwardToHost(hostname, localPort, message, body, pathWithQuery) {
|
|
4198
4205
|
return new Promise((resolve, reject) => {
|
|
4199
4206
|
const req = http.request({
|
|
4200
|
-
hostname
|
|
4207
|
+
hostname,
|
|
4201
4208
|
port: localPort,
|
|
4202
4209
|
method: message.method,
|
|
4203
4210
|
path: pathWithQuery,
|
|
@@ -4234,6 +4241,23 @@ async function forwardToLocal(localPort, message) {
|
|
|
4234
4241
|
req.end();
|
|
4235
4242
|
});
|
|
4236
4243
|
}
|
|
4244
|
+
async function forwardToLocal(localPort, message) {
|
|
4245
|
+
const body = decodeBody(message.body);
|
|
4246
|
+
const pathWithQuery = message.query ? `${message.path}?${message.query}` : message.path;
|
|
4247
|
+
let lastError;
|
|
4248
|
+
for (const hostname of LOOPBACK_HOSTS) {
|
|
4249
|
+
try {
|
|
4250
|
+
return await forwardToHost(hostname, localPort, message, body, pathWithQuery);
|
|
4251
|
+
} catch (err) {
|
|
4252
|
+
if (isConnectionRefused(err)) {
|
|
4253
|
+
lastError = err;
|
|
4254
|
+
continue;
|
|
4255
|
+
}
|
|
4256
|
+
throw err;
|
|
4257
|
+
}
|
|
4258
|
+
}
|
|
4259
|
+
throw lastError ?? new Error("Local server unreachable");
|
|
4260
|
+
}
|
|
4237
4261
|
|
|
4238
4262
|
// ../tunnel-client/dist/client.js
|
|
4239
4263
|
function toWebSocketUrl(serverUrl) {
|
|
@@ -4247,9 +4271,11 @@ function toWebSocketUrl(serverUrl) {
|
|
|
4247
4271
|
function formatLocalProxyError(err, localPort) {
|
|
4248
4272
|
if (err instanceof Error && "code" in err && err.code === "ECONNREFUSED") {
|
|
4249
4273
|
return [
|
|
4250
|
-
`Nothing is
|
|
4274
|
+
`Nothing is listening on port ${String(localPort)} (tried 127.0.0.1 and ::1).`,
|
|
4251
4275
|
"",
|
|
4252
4276
|
"Start your local server on that port, then refresh this page.",
|
|
4277
|
+
"If your browser works on localhost but the tunnel does not, your dev server may only",
|
|
4278
|
+
"listen on IPv6 \u2014 bind to 0.0.0.0 or 127.0.0.1 (e.g. next dev -H 0.0.0.0).",
|
|
4253
4279
|
`If your app uses a different port, restart the CLI with that port (e.g. shiplocal ${String(localPort)}).`
|
|
4254
4280
|
].join("\n");
|
|
4255
4281
|
}
|
|
@@ -4328,6 +4354,13 @@ function createTunnelClient(options) {
|
|
|
4328
4354
|
}
|
|
4329
4355
|
return;
|
|
4330
4356
|
}
|
|
4357
|
+
if (message.type === "terminated") {
|
|
4358
|
+
intentionalClose = true;
|
|
4359
|
+
publicUrl = null;
|
|
4360
|
+
options.onTerminated?.(message.message);
|
|
4361
|
+
ws?.close();
|
|
4362
|
+
return;
|
|
4363
|
+
}
|
|
4331
4364
|
if (message.type === "ping") {
|
|
4332
4365
|
ws?.send(JSON.stringify({ type: "pong" }));
|
|
4333
4366
|
return;
|
|
@@ -4465,7 +4498,7 @@ async function resolveToken() {
|
|
|
4465
4498
|
}
|
|
4466
4499
|
|
|
4467
4500
|
// src/api.ts
|
|
4468
|
-
function
|
|
4501
|
+
function isConnectionRefused2(err) {
|
|
4469
4502
|
if (!(err instanceof Error)) return false;
|
|
4470
4503
|
const cause = err.cause;
|
|
4471
4504
|
if (cause instanceof Error && "code" in cause && cause.code === "ECONNREFUSED") {
|
|
@@ -4477,7 +4510,7 @@ function isConnectionRefused(err) {
|
|
|
4477
4510
|
return err.message.includes("ECONNREFUSED") || err.message.includes("fetch failed");
|
|
4478
4511
|
}
|
|
4479
4512
|
function formatServerConnectionError(apiUrl, err) {
|
|
4480
|
-
if (
|
|
4513
|
+
if (isConnectionRefused2(err)) {
|
|
4481
4514
|
return [
|
|
4482
4515
|
`Cannot reach ShipLocal server at ${apiUrl}.`,
|
|
4483
4516
|
"",
|
|
@@ -4508,9 +4541,10 @@ async function postJson(path, body, apiUrl) {
|
|
|
4508
4541
|
|
|
4509
4542
|
// src/local-port.ts
|
|
4510
4543
|
import net from "node:net";
|
|
4511
|
-
|
|
4544
|
+
var LOOPBACK_HOSTS2 = ["127.0.0.1", "::1"];
|
|
4545
|
+
function canConnect(host, port, timeoutMs) {
|
|
4512
4546
|
return new Promise((resolve) => {
|
|
4513
|
-
const socket = net.connect({ port, host
|
|
4547
|
+
const socket = net.connect({ port, host });
|
|
4514
4548
|
const finish = (open) => {
|
|
4515
4549
|
socket.removeAllListeners();
|
|
4516
4550
|
socket.destroy();
|
|
@@ -4528,10 +4562,18 @@ function isLocalPortOpen(port, timeoutMs = 2e3) {
|
|
|
4528
4562
|
});
|
|
4529
4563
|
});
|
|
4530
4564
|
}
|
|
4565
|
+
async function isLocalPortOpen(port, timeoutMs = 2e3) {
|
|
4566
|
+
for (const host of LOOPBACK_HOSTS2) {
|
|
4567
|
+
if (await canConnect(host, port, timeoutMs)) {
|
|
4568
|
+
return true;
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4571
|
+
return false;
|
|
4572
|
+
}
|
|
4531
4573
|
|
|
4532
4574
|
// src/index.ts
|
|
4533
4575
|
var program = new Command();
|
|
4534
|
-
program.name("shiplocal").description("Share localhost with clients in seconds").version("0.1.
|
|
4576
|
+
program.name("shiplocal").description("Share localhost with clients in seconds").version("0.1.5");
|
|
4535
4577
|
program.command("login").description("Authenticate with ShipLocal Cloud").action(async () => {
|
|
4536
4578
|
const rl = createInterface({ input, output });
|
|
4537
4579
|
const apiUrl = await resolveApiUrlAsync();
|
|
@@ -4612,6 +4654,12 @@ program.argument("[port]", "Local port to expose", String(DEFAULT_TUNNEL_PORT)).
|
|
|
4612
4654
|
},
|
|
4613
4655
|
onReconnecting: (attempt) => {
|
|
4614
4656
|
console.log(`Reconnecting\u2026 (attempt ${String(attempt)})`);
|
|
4657
|
+
},
|
|
4658
|
+
onTerminated: (message) => {
|
|
4659
|
+
console.log("");
|
|
4660
|
+
console.log(message);
|
|
4661
|
+
console.log("Run shiplocal again to start a new tunnel.");
|
|
4662
|
+
console.log("");
|
|
4615
4663
|
}
|
|
4616
4664
|
});
|
|
4617
4665
|
const shutdown = () => {
|