localpreview 0.2.3 → 0.2.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/README.md +39 -2
- package/dist/capture-route.d.ts +1 -0
- package/dist/capture-route.d.ts.map +1 -1
- package/dist/capture-route.js +1 -0
- package/dist/capture-shim.d.ts +5 -1
- package/dist/capture-shim.d.ts.map +1 -1
- package/dist/capture-shim.js +3 -2
- package/dist/cli-ui.d.ts +36 -0
- package/dist/cli-ui.d.ts.map +1 -0
- package/dist/cli-ui.js +351 -0
- package/dist/command.d.ts +1 -0
- package/dist/command.d.ts.map +1 -1
- package/dist/command.js +208 -43
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -3
- package/dist/control-plane.d.ts +11 -1
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +56 -1
- package/dist/errors.d.ts +4 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/local-proxy.d.ts +3 -0
- package/dist/local-proxy.d.ts.map +1 -1
- package/dist/local-proxy.js +87 -9
- package/dist/missing-capture.d.ts +44 -0
- package/dist/missing-capture.d.ts.map +1 -0
- package/dist/missing-capture.js +128 -0
- package/dist/relay-client.d.ts +6 -2
- package/dist/relay-client.d.ts.map +1 -1
- package/dist/relay-client.js +14 -7
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/package.json +3 -2
package/dist/command.js
CHANGED
|
@@ -1,26 +1,52 @@
|
|
|
1
1
|
import { formatCaptureOrigin, parseCaptureHostPort, parseTarget, validateRequestedSubdomain, } from "@localpreview/protocol";
|
|
2
2
|
import { Console, Effect, Layer, Option } from "effect";
|
|
3
|
+
import { adminTokenRequiredMessage, formatStatus, formatWarning, formatListTunnelsOutput, renderCleanHelp, renderConnectHelp, renderGlobalHelp, renderListHelp, removedAdminTokenFlagMessage, } from "./cli-ui.js";
|
|
3
4
|
import { CliConfig, CliConfigLive, LOCAL_CONTROL_PLANE_URL, normalizeControlPlaneUrl } from "./config.js";
|
|
4
5
|
import { ControlPlaneClient, ControlPlaneClientLive, } from "./control-plane.js";
|
|
5
6
|
import { CliUsageError, errorMessage } from "./errors.js";
|
|
6
7
|
import { LocalProxyLive } from "./local-proxy.js";
|
|
7
8
|
import { RelayClient, RelayClientLive } from "./relay-client.js";
|
|
9
|
+
import { CLI_PACKAGE_VERSION } from "./version.js";
|
|
8
10
|
export const runCli = (argv) => {
|
|
9
11
|
const normalized = normalizeCliArgs(argv);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
const helpKind = resolveHelpKind(normalized);
|
|
13
|
+
if (helpKind !== null) {
|
|
14
|
+
return printHelp(helpKind);
|
|
12
15
|
}
|
|
13
16
|
if (isVersionInvocation(normalized)) {
|
|
14
|
-
return Console.log(
|
|
17
|
+
return Console.log(CLI_PACKAGE_VERSION);
|
|
15
18
|
}
|
|
16
19
|
const parsed = parseCommand(normalized);
|
|
17
20
|
if (!parsed.ok) {
|
|
18
21
|
return Effect.fail(new CliUsageError({ message: parsed.message }));
|
|
19
22
|
}
|
|
20
|
-
return runSubcommand(parsed.command);
|
|
23
|
+
return runSubcommand(parsed.command, normalized);
|
|
21
24
|
};
|
|
22
25
|
export const normalizeCliArgs = (argv) => argv[0] === "--" ? argv.slice(1) : argv;
|
|
23
|
-
const
|
|
26
|
+
export const buildConnectOriginalArgv = (argv, legacy) => (legacy ? argv : argv[0] === "connect" ? argv.slice(1) : argv);
|
|
27
|
+
const hasHelpFlag = (argv) => argv.includes("--help") || argv.includes("-h");
|
|
28
|
+
const resolveHelpKind = (argv) => {
|
|
29
|
+
if (argv.length === 0) {
|
|
30
|
+
return "global";
|
|
31
|
+
}
|
|
32
|
+
if (!hasHelpFlag(argv)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const first = argv[0];
|
|
36
|
+
if (first === "clean") {
|
|
37
|
+
return "clean";
|
|
38
|
+
}
|
|
39
|
+
if (first === "list") {
|
|
40
|
+
return "list";
|
|
41
|
+
}
|
|
42
|
+
if (first === "connect") {
|
|
43
|
+
return "connect";
|
|
44
|
+
}
|
|
45
|
+
if (first !== undefined && !first.startsWith("-")) {
|
|
46
|
+
return "connect";
|
|
47
|
+
}
|
|
48
|
+
return "global";
|
|
49
|
+
};
|
|
24
50
|
const isVersionInvocation = (argv) => argv.includes("--version");
|
|
25
51
|
const isLegacyConnectInvocation = (argv) => {
|
|
26
52
|
const first = argv[0];
|
|
@@ -29,21 +55,16 @@ const isLegacyConnectInvocation = (argv) => {
|
|
|
29
55
|
}
|
|
30
56
|
return first !== "connect" && !first.startsWith("-");
|
|
31
57
|
};
|
|
32
|
-
const printHelp = () =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
" localpreview connect 3000 --control-plane https://staging.localpreview.dev",
|
|
43
|
-
" localpreview clean proyecto --force",
|
|
44
|
-
" localpreview clean --all --force",
|
|
45
|
-
" localpreview clean demo --control-plane https://staging.localpreview.dev --admin-token ...",
|
|
46
|
-
].join("\n"));
|
|
58
|
+
const printHelp = (kind) => {
|
|
59
|
+
const text = kind === "global"
|
|
60
|
+
? renderGlobalHelp()
|
|
61
|
+
: kind === "connect"
|
|
62
|
+
? renderConnectHelp()
|
|
63
|
+
: kind === "clean"
|
|
64
|
+
? renderCleanHelp()
|
|
65
|
+
: renderListHelp();
|
|
66
|
+
return Console.log(text);
|
|
67
|
+
};
|
|
47
68
|
const parseCommand = (argv) => {
|
|
48
69
|
if (argv[0] === "clean") {
|
|
49
70
|
const parsed = parseCleanArgs(argv.slice(1));
|
|
@@ -58,6 +79,19 @@ const parseCommand = (argv) => {
|
|
|
58
79
|
ok: true,
|
|
59
80
|
};
|
|
60
81
|
}
|
|
82
|
+
if (argv[0] === "list") {
|
|
83
|
+
const parsed = parseListArgs(argv.slice(1));
|
|
84
|
+
if (!parsed.ok) {
|
|
85
|
+
return parsed;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
command: {
|
|
89
|
+
config: parsed.config,
|
|
90
|
+
kind: "list",
|
|
91
|
+
},
|
|
92
|
+
ok: true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
61
95
|
const legacy = isLegacyConnectInvocation(argv);
|
|
62
96
|
const args = legacy ? argv : argv[0] === "connect" ? argv.slice(1) : argv;
|
|
63
97
|
const parsed = parseConnectArgs(args);
|
|
@@ -152,7 +186,6 @@ const parseConnectArgs = (argv) => {
|
|
|
152
186
|
};
|
|
153
187
|
const parseCleanArgs = (argv) => {
|
|
154
188
|
const rest = [...argv];
|
|
155
|
-
let adminToken;
|
|
156
189
|
let all = false;
|
|
157
190
|
let controlPlane;
|
|
158
191
|
let force = false;
|
|
@@ -165,13 +198,10 @@ const parseCleanArgs = (argv) => {
|
|
|
165
198
|
continue;
|
|
166
199
|
}
|
|
167
200
|
if (arg === "--admin-token") {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
adminToken = value.value;
|
|
173
|
-
index += 1;
|
|
174
|
-
continue;
|
|
201
|
+
return {
|
|
202
|
+
message: removedAdminTokenFlagMessage(),
|
|
203
|
+
ok: false,
|
|
204
|
+
};
|
|
175
205
|
}
|
|
176
206
|
if (arg === "--all") {
|
|
177
207
|
all = true;
|
|
@@ -222,14 +252,13 @@ const parseCleanArgs = (argv) => {
|
|
|
222
252
|
}
|
|
223
253
|
if (!all && subdomain === undefined) {
|
|
224
254
|
return {
|
|
225
|
-
message: "Usage: localpreview clean <subdomain> [--force] [-l|--local] [--control-plane url]
|
|
255
|
+
message: "Usage: localpreview clean <subdomain> [--force] [-l|--local] [--control-plane url]\n localpreview clean --all --force [-l|--local] [--control-plane url]",
|
|
226
256
|
ok: false,
|
|
227
257
|
};
|
|
228
258
|
}
|
|
229
259
|
return {
|
|
230
260
|
config: {
|
|
231
261
|
all,
|
|
232
|
-
adminToken: toOption(adminToken),
|
|
233
262
|
controlPlane: toOption(controlPlane),
|
|
234
263
|
force,
|
|
235
264
|
subdomain: toOption(subdomain),
|
|
@@ -237,6 +266,119 @@ const parseCleanArgs = (argv) => {
|
|
|
237
266
|
ok: true,
|
|
238
267
|
};
|
|
239
268
|
};
|
|
269
|
+
const parseListArgs = (argv) => {
|
|
270
|
+
const rest = [...argv];
|
|
271
|
+
let controlPlane;
|
|
272
|
+
let limit = 100;
|
|
273
|
+
let skip = 0;
|
|
274
|
+
let usedLocalControlPlane = false;
|
|
275
|
+
let usedControlPlaneFlag = false;
|
|
276
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
277
|
+
const arg = rest[index];
|
|
278
|
+
if (arg === undefined) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (arg === "--admin-token") {
|
|
282
|
+
return {
|
|
283
|
+
message: removedAdminTokenFlagMessage(),
|
|
284
|
+
ok: false,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
if (arg === "--limit") {
|
|
288
|
+
const value = readRequiredOptionValue(rest, index, "--limit");
|
|
289
|
+
if (!value.ok) {
|
|
290
|
+
return value;
|
|
291
|
+
}
|
|
292
|
+
const parsedLimit = parsePositiveIntegerOption(value.value, "--limit");
|
|
293
|
+
if (!parsedLimit.ok) {
|
|
294
|
+
return parsedLimit;
|
|
295
|
+
}
|
|
296
|
+
limit = parsedLimit.value;
|
|
297
|
+
index += 1;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (arg === "--skip") {
|
|
301
|
+
const value = readRequiredOptionValue(rest, index, "--skip");
|
|
302
|
+
if (!value.ok) {
|
|
303
|
+
return value;
|
|
304
|
+
}
|
|
305
|
+
const parsedSkip = parseNonNegativeIntegerOption(value.value, "--skip");
|
|
306
|
+
if (!parsedSkip.ok) {
|
|
307
|
+
return parsedSkip;
|
|
308
|
+
}
|
|
309
|
+
skip = parsedSkip.value;
|
|
310
|
+
index += 1;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const controlPlaneFlag = readControlPlaneFlag(rest, index, arg, {
|
|
314
|
+
usedControlPlaneFlag,
|
|
315
|
+
usedLocalControlPlane,
|
|
316
|
+
});
|
|
317
|
+
if (!controlPlaneFlag.ok) {
|
|
318
|
+
return controlPlaneFlag;
|
|
319
|
+
}
|
|
320
|
+
if (controlPlaneFlag.handled) {
|
|
321
|
+
if (controlPlaneFlag.usedLocalControlPlane) {
|
|
322
|
+
usedLocalControlPlane = true;
|
|
323
|
+
}
|
|
324
|
+
if (controlPlaneFlag.usedControlPlaneFlag) {
|
|
325
|
+
usedControlPlaneFlag = true;
|
|
326
|
+
}
|
|
327
|
+
controlPlane = controlPlaneFlag.controlPlane ?? controlPlane;
|
|
328
|
+
index = controlPlaneFlag.nextIndex;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (arg !== undefined && !arg.startsWith("-")) {
|
|
332
|
+
return {
|
|
333
|
+
message: `Unexpected argument: ${arg}`,
|
|
334
|
+
ok: false,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
message: `Unknown option: ${arg}`,
|
|
339
|
+
ok: false,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
config: {
|
|
344
|
+
controlPlane: toOption(controlPlane),
|
|
345
|
+
limit,
|
|
346
|
+
skip,
|
|
347
|
+
},
|
|
348
|
+
ok: true,
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
const parsePositiveIntegerOption = (value, option) => {
|
|
352
|
+
if (!/^\d+$/.test(value)) {
|
|
353
|
+
return {
|
|
354
|
+
message: `${option} must be a positive integer.`,
|
|
355
|
+
ok: false,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
const parsed = Number.parseInt(value, 10);
|
|
359
|
+
if (parsed <= 0) {
|
|
360
|
+
return {
|
|
361
|
+
message: `${option} must be a positive integer.`,
|
|
362
|
+
ok: false,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
ok: true,
|
|
367
|
+
value: parsed,
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
const parseNonNegativeIntegerOption = (value, option) => {
|
|
371
|
+
if (!/^\d+$/.test(value)) {
|
|
372
|
+
return {
|
|
373
|
+
message: `${option} must be a non-negative integer.`,
|
|
374
|
+
ok: false,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
ok: true,
|
|
379
|
+
value: Number.parseInt(value, 10),
|
|
380
|
+
};
|
|
381
|
+
};
|
|
240
382
|
const readControlPlaneFlag = (argv, index, arg, state) => {
|
|
241
383
|
if (arg === "-l" || arg === "--local") {
|
|
242
384
|
if (state.usedControlPlaneFlag) {
|
|
@@ -298,11 +440,13 @@ const readRequiredOptionValue = (argv, index, option) => {
|
|
|
298
440
|
};
|
|
299
441
|
};
|
|
300
442
|
const toOption = (value) => value === undefined ? Option.none() : Option.some(value);
|
|
301
|
-
const runSubcommand = (command) => {
|
|
443
|
+
const runSubcommand = (command, originalArgv) => {
|
|
302
444
|
const controlPlane = Option.getOrUndefined(command.config.controlPlane);
|
|
303
445
|
const effect = command.kind === "connect"
|
|
304
|
-
? runConnect(command.config, command.legacy)
|
|
305
|
-
:
|
|
446
|
+
? runConnect(command.config, command.legacy, originalArgv)
|
|
447
|
+
: command.kind === "clean"
|
|
448
|
+
? runClean(command.config)
|
|
449
|
+
: runList(command.config);
|
|
306
450
|
return effect.pipe(Effect.provide(makeCommandLayer(makeConfigInput(controlPlane))));
|
|
307
451
|
};
|
|
308
452
|
const makeConfigInput = (controlPlaneUrl) => controlPlaneUrl === undefined ? {} : { controlPlaneUrl };
|
|
@@ -312,9 +456,9 @@ const makeCommandLayer = (input) => {
|
|
|
312
456
|
const RelayLive = RelayClientLive.pipe(Layer.provide(Layer.mergeAll(ConfigLive, ProxyLive)));
|
|
313
457
|
return Layer.mergeAll(ConfigLive, ControlPlaneClientLive, ProxyLive, RelayLive);
|
|
314
458
|
};
|
|
315
|
-
const runConnect = (config, legacy) => Effect.scoped(Effect.gen(function* () {
|
|
459
|
+
const runConnect = (config, legacy, originalArgv) => Effect.scoped(Effect.gen(function* () {
|
|
316
460
|
if (legacy) {
|
|
317
|
-
yield* Console.error("
|
|
461
|
+
yield* Console.error(formatWarning("`localpreview <target>` is deprecated. Use `localpreview connect <target>`."));
|
|
318
462
|
}
|
|
319
463
|
const target = parseTarget(config.target);
|
|
320
464
|
if (!target.ok) {
|
|
@@ -325,13 +469,16 @@ const runConnect = (config, legacy) => Effect.scoped(Effect.gen(function* () {
|
|
|
325
469
|
const relay = yield* RelayClient;
|
|
326
470
|
const cliConfig = yield* CliConfig;
|
|
327
471
|
const tunnel = yield* Effect.acquireRelease(controlPlane.createTunnel(cliConfig.controlPlaneUrl, requestedSubdomain === undefined ? {} : { requestedSubdomain }), (tunnel) => closeTunnelBestEffort(controlPlane, cliConfig.controlPlaneUrl, tunnel));
|
|
328
|
-
yield* Console.log(`Tunnel ready: ${tunnel.publicUrl}`);
|
|
329
|
-
yield* Console.log(`Forwarding to ${target.target.protocol}://${target.target.hostname}:${target.target.port}`);
|
|
472
|
+
yield* Console.log(formatStatus(`Tunnel ready: ${tunnel.publicUrl}`));
|
|
473
|
+
yield* Console.log(formatStatus(`Forwarding to ${target.target.protocol}://${target.target.hostname}:${target.target.port}`));
|
|
330
474
|
if (config.captures.length > 0) {
|
|
331
475
|
const origins = config.captures.map((capture) => formatCaptureOrigin(capture)).join(", ");
|
|
332
|
-
yield* Console.error(`
|
|
476
|
+
yield* Console.error(formatWarning(`Captured local backends (${origins}) are exposed through this preview URL. Anyone with the link can reach them.`));
|
|
333
477
|
}
|
|
334
|
-
yield* relay.connectAndServe(tunnel, target.target, config.captures
|
|
478
|
+
yield* relay.connectAndServe(tunnel, target.target, config.captures, {
|
|
479
|
+
legacy,
|
|
480
|
+
originalArgv: buildConnectOriginalArgv(originalArgv, legacy),
|
|
481
|
+
});
|
|
335
482
|
}));
|
|
336
483
|
const validateRequestedName = (value) => Option.match(value, {
|
|
337
484
|
onNone: () => Effect.succeed(undefined),
|
|
@@ -354,10 +501,11 @@ const runClean = (config) => Effect.gen(function* () {
|
|
|
354
501
|
}
|
|
355
502
|
const controlPlane = yield* ControlPlaneClient;
|
|
356
503
|
const cliConfig = yield* CliConfig;
|
|
357
|
-
const adminToken =
|
|
504
|
+
const adminToken = cliConfig.adminToken;
|
|
358
505
|
if (adminToken === undefined || adminToken.length === 0) {
|
|
506
|
+
yield* Console.log(renderGlobalHelp());
|
|
359
507
|
return yield* Effect.fail(new CliUsageError({
|
|
360
|
-
message:
|
|
508
|
+
message: adminTokenRequiredMessage(),
|
|
361
509
|
}));
|
|
362
510
|
}
|
|
363
511
|
if (config.all) {
|
|
@@ -380,7 +528,7 @@ const runClean = (config) => Effect.gen(function* () {
|
|
|
380
528
|
}
|
|
381
529
|
if (subdomain === undefined) {
|
|
382
530
|
return yield* Effect.fail(new CliUsageError({
|
|
383
|
-
message: "Usage: localpreview clean <subdomain> [--force] [-l|--local] [--control-plane url]
|
|
531
|
+
message: "Usage: localpreview clean <subdomain> [--force] [-l|--local] [--control-plane url]",
|
|
384
532
|
}));
|
|
385
533
|
}
|
|
386
534
|
const validation = validateRequestedSubdomain(subdomain);
|
|
@@ -403,6 +551,23 @@ const runClean = (config) => Effect.gen(function* () {
|
|
|
403
551
|
: ` Tunnel ${result.tunnelId} was ${result.relayStopped ? "stopped" : "removed from the store"}.`;
|
|
404
552
|
yield* Console.log(`Subdomain "${result.subdomain}" cleaned.${suffix}`);
|
|
405
553
|
});
|
|
554
|
+
const runList = (config) => Effect.gen(function* () {
|
|
555
|
+
const controlPlane = yield* ControlPlaneClient;
|
|
556
|
+
const cliConfig = yield* CliConfig;
|
|
557
|
+
const adminToken = cliConfig.adminToken;
|
|
558
|
+
if (adminToken === undefined || adminToken.length === 0) {
|
|
559
|
+
yield* Console.log(renderGlobalHelp());
|
|
560
|
+
return yield* Effect.fail(new CliUsageError({
|
|
561
|
+
message: adminTokenRequiredMessage(),
|
|
562
|
+
}));
|
|
563
|
+
}
|
|
564
|
+
const result = yield* controlPlane.listTunnels(cliConfig.controlPlaneUrl, {
|
|
565
|
+
adminToken,
|
|
566
|
+
limit: config.limit,
|
|
567
|
+
skip: config.skip,
|
|
568
|
+
});
|
|
569
|
+
yield* Console.log(formatListTunnelsOutput(result));
|
|
570
|
+
});
|
|
406
571
|
const closeTunnelBestEffort = (controlPlane, controlPlaneUrl, tunnel) => controlPlane
|
|
407
572
|
.closeTunnel(controlPlaneUrl, tunnel)
|
|
408
|
-
.pipe(Effect.catch((error) => Console.error(
|
|
573
|
+
.pipe(Effect.catch((error) => Console.error(formatWarning(errorMessage(error)))));
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from "effect";
|
|
2
2
|
export type CliConfigShape = {
|
|
3
|
-
readonly
|
|
3
|
+
readonly adminToken: string | undefined;
|
|
4
4
|
readonly controlPlaneUrl: string;
|
|
5
5
|
readonly maxInFlightRequests: number;
|
|
6
6
|
readonly relayConnectTimeoutMs: number;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACzC,CAAC;;AAEF,qBAAa,SAAU,SAAQ,cAAyD;CAAG;AAE3F,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAE/D,MAAM,MAAM,8BAA8B,GACtC;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IACE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;CACpB,CAAC;AAEN,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,GAAI,OAAO,MAAM,KAAG,8BA4DxD,CAAC;AA2BF,eAAO,MAAM,aAAa,GAAI,OAAO;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC,KAAG,cAkBH,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC,yCAAmD,CAAC;AAWrD,eAAO,MAAM,aAAa,GAAI,OAAO;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAA4C,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -78,10 +78,9 @@ const isIpv4LoopbackAddress = (hostname) => {
|
|
|
78
78
|
export const makeCliConfig = (input) => {
|
|
79
79
|
const env = input.env ?? process.env;
|
|
80
80
|
const controlPlaneUrl = input.controlPlaneUrl ?? PUBLIC_CONTROL_PLANE_URL;
|
|
81
|
-
const
|
|
82
|
-
(controlPlaneUrl === LOCAL_CONTROL_PLANE_URL ? "local-dev-cleanup-token" : undefined);
|
|
81
|
+
const adminToken = env.LOCALPREVIEW_ADMIN_TOKEN;
|
|
83
82
|
return {
|
|
84
|
-
|
|
83
|
+
adminToken,
|
|
85
84
|
controlPlaneUrl,
|
|
86
85
|
maxInFlightRequests: readNumber(env.LOCALPREVIEW_MAX_IN_FLIGHT_REQUESTS, 100),
|
|
87
86
|
relayConnectTimeoutMs: readNumber(env.LOCALPREVIEW_RELAY_CONNECT_TIMEOUT_MS, 10_000),
|
package/dist/control-plane.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CreateTunnelResponse } from "@localpreview/protocol";
|
|
1
|
+
import { type CreateTunnelResponse, type ListTunnelsResponse } from "@localpreview/protocol";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
import { ControlPlaneError } from "./errors.js";
|
|
4
4
|
export type ControlPlaneClientShape = {
|
|
@@ -15,6 +15,11 @@ export type ControlPlaneClientShape = {
|
|
|
15
15
|
readonly createTunnel: (controlPlaneUrl: string, body: {
|
|
16
16
|
readonly requestedSubdomain?: string;
|
|
17
17
|
}) => Effect.Effect<CreateTunnelResponse, ControlPlaneError>;
|
|
18
|
+
readonly listTunnels: (controlPlaneUrl: string, input: {
|
|
19
|
+
readonly adminToken: string;
|
|
20
|
+
readonly limit: number;
|
|
21
|
+
readonly skip: number;
|
|
22
|
+
}) => Effect.Effect<ListTunnelsResponse, ControlPlaneError>;
|
|
18
23
|
};
|
|
19
24
|
export type CleanSubdomainResponse = {
|
|
20
25
|
readonly cleaned: boolean;
|
|
@@ -55,5 +60,10 @@ export declare const cleanAllSubdomains: (controlPlaneUrl: string, input: {
|
|
|
55
60
|
readonly adminToken: string;
|
|
56
61
|
readonly force: boolean;
|
|
57
62
|
}) => Promise<CleanAllSubdomainsResponse>;
|
|
63
|
+
export declare const listTunnels: (controlPlaneUrl: string, input: {
|
|
64
|
+
readonly adminToken: string;
|
|
65
|
+
readonly limit: number;
|
|
66
|
+
readonly skip: number;
|
|
67
|
+
}) => Promise<ListTunnelsResponse>;
|
|
58
68
|
export {};
|
|
59
69
|
//# sourceMappingURL=control-plane.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"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"}
|
package/dist/control-plane.js
CHANGED
|
@@ -11,11 +11,13 @@ export const ControlPlaneClientLive = Layer.succeed(ControlPlaneClient)({
|
|
|
11
11
|
while: (error) => error.retryable === true,
|
|
12
12
|
})),
|
|
13
13
|
createTunnel: (controlPlaneUrl, body) => createTunnelEffect(controlPlaneUrl, body),
|
|
14
|
+
listTunnels: (controlPlaneUrl, input) => listTunnelsEffect(controlPlaneUrl, input),
|
|
14
15
|
});
|
|
15
16
|
export const createTunnel = (controlPlaneUrl, body) => Effect.runPromise(createTunnelEffect(controlPlaneUrl, body));
|
|
16
17
|
export const closeTunnel = (controlPlaneUrl, tunnel) => Effect.runPromise(closeTunnelEffect(controlPlaneUrl, tunnel));
|
|
17
18
|
export const cleanSubdomain = (controlPlaneUrl, input) => Effect.runPromise(cleanSubdomainEffect(controlPlaneUrl, input));
|
|
18
19
|
export const cleanAllSubdomains = (controlPlaneUrl, input) => Effect.runPromise(cleanAllSubdomainsEffect(controlPlaneUrl, input));
|
|
20
|
+
export const listTunnels = (controlPlaneUrl, input) => Effect.runPromise(listTunnelsEffect(controlPlaneUrl, input));
|
|
19
21
|
const createTunnelEffect = (controlPlaneUrl, body) => Effect.promise(async () => {
|
|
20
22
|
let response;
|
|
21
23
|
try {
|
|
@@ -31,7 +33,7 @@ const createTunnelEffect = (controlPlaneUrl, body) => Effect.promise(async () =>
|
|
|
31
33
|
throw new ControlPlaneError({
|
|
32
34
|
message: [
|
|
33
35
|
`Could not reach localpreview control-plane at ${controlPlaneUrl}.`,
|
|
34
|
-
'Use "-l" or "--local"
|
|
36
|
+
'Use "-l" or "--local" as shorthand for --control-plane http://localhost:3000.',
|
|
35
37
|
].join("\n"),
|
|
36
38
|
retryable: false,
|
|
37
39
|
});
|
|
@@ -136,6 +138,59 @@ const cleanAllSubdomainsEffect = (controlPlaneUrl, input) => Effect.promise(asyn
|
|
|
136
138
|
}
|
|
137
139
|
return json;
|
|
138
140
|
});
|
|
141
|
+
const listTunnelsEffect = (controlPlaneUrl, input) => Effect.promise(async () => {
|
|
142
|
+
let response;
|
|
143
|
+
const url = new URL("/api/tunnels", controlPlaneUrl);
|
|
144
|
+
url.searchParams.set("limit", String(input.limit));
|
|
145
|
+
url.searchParams.set("skip", String(input.skip));
|
|
146
|
+
try {
|
|
147
|
+
response = await fetch(url, {
|
|
148
|
+
headers: {
|
|
149
|
+
[LOCALPREVIEW_ADMIN_TOKEN_HEADER]: input.adminToken,
|
|
150
|
+
},
|
|
151
|
+
method: "GET",
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
throw new ControlPlaneError({
|
|
156
|
+
message: `Could not reach localpreview control-plane at ${controlPlaneUrl}.`,
|
|
157
|
+
retryable: false,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const json = await readJson(response, "Tunnel listing");
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
if (response.status === 404) {
|
|
163
|
+
throw new ControlPlaneError({
|
|
164
|
+
message: [
|
|
165
|
+
"The control-plane does not support tunnel listing yet.",
|
|
166
|
+
"Deploy the updated control-plane, then rerun `localpreview list`.",
|
|
167
|
+
].join(" "),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
throw new ControlPlaneError({
|
|
171
|
+
message: json.error?.message ?? `Tunnel listing failed with HTTP ${response.status}.`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return validateListTunnelsResponse(json);
|
|
175
|
+
});
|
|
176
|
+
const validateListTunnelsResponse = (json) => {
|
|
177
|
+
if (typeof json.total !== "number" ||
|
|
178
|
+
typeof json.skip !== "number" ||
|
|
179
|
+
typeof json.limit !== "number" ||
|
|
180
|
+
!Array.isArray(json.items) ||
|
|
181
|
+
json.counts === undefined ||
|
|
182
|
+
typeof json.counts.tracked !== "number" ||
|
|
183
|
+
typeof json.counts["redis-orphan"] !== "number" ||
|
|
184
|
+
typeof json.counts["sandbox-orphan"] !== "number") {
|
|
185
|
+
throw new ControlPlaneError({
|
|
186
|
+
message: [
|
|
187
|
+
"Tunnel listing returned an invalid response.",
|
|
188
|
+
"This usually means the control-plane is running an older LocalPreview protocol.",
|
|
189
|
+
].join(" "),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return json;
|
|
193
|
+
};
|
|
139
194
|
const requiredCreateTunnelStringFields = [
|
|
140
195
|
"tunnelId",
|
|
141
196
|
"subdomain",
|
package/dist/errors.d.ts
CHANGED
|
@@ -39,6 +39,10 @@ declare const LocalRequestError_base: new <A extends Record<string, any> = {}>(a
|
|
|
39
39
|
readonly _tag: "LocalRequestError";
|
|
40
40
|
} & Readonly<A>;
|
|
41
41
|
export declare class LocalRequestError extends LocalRequestError_base<{
|
|
42
|
+
readonly invalidCapture?: {
|
|
43
|
+
readonly hostname: string;
|
|
44
|
+
readonly port: number;
|
|
45
|
+
};
|
|
42
46
|
readonly message: string;
|
|
43
47
|
readonly requestId: string;
|
|
44
48
|
}> {
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAEA,qBAAa,aAAc,SAAQ,mBAAkC;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;;;;AAEL,qBAAa,cAAe,SAAQ,oBAAmC;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;CAAG;;;;AAEL,qBAAa,oBAAqB,SAAQ,0BAAyC;IACjF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;CAAG;;;;AAEL,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;CAAG;AAEL,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,iBAAiB,GACjB,oBAAoB,GACpB,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,CAAC;AAEtB,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,MAM7C,CAAC"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAEA,qBAAa,aAAc,SAAQ,mBAAkC;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;;;;AAEL,qBAAa,cAAe,SAAQ,oBAAmC;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;CAAG;;;;AAEL,qBAAa,oBAAqB,SAAQ,0BAAyC;IACjF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;CAAG;;;;AAEL,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;CAAG;AAEL,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,iBAAiB,GACjB,oBAAoB,GACpB,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,CAAC;AAEtB,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,MAM7C,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
|
|
3
3
|
import { Console, Effect } from "effect";
|
|
4
4
|
import { runCli } from "./command.js";
|
|
5
|
+
import { formatCliError } from "./cli-ui.js";
|
|
5
6
|
import { errorMessage } from "./errors.js";
|
|
6
7
|
const argv = process.argv.slice(2);
|
|
7
|
-
const program = runCli(argv).pipe(Effect.catch((error) => Console.error(errorMessage(error)).pipe(Effect.andThen(Effect.sync(() => {
|
|
8
|
+
const program = runCli(argv).pipe(Effect.catch((error) => Console.error(formatCliError(errorMessage(error))).pipe(Effect.andThen(Effect.sync(() => {
|
|
8
9
|
process.exitCode =
|
|
9
10
|
typeof error === "object" &&
|
|
10
11
|
error !== null &&
|
package/dist/local-proxy.d.ts
CHANGED
|
@@ -5,6 +5,9 @@ import { CliConfig } from "./config.js";
|
|
|
5
5
|
import { RelayProtocolError } from "./errors.js";
|
|
6
6
|
export type ProxySession = {
|
|
7
7
|
readonly captures: ReadonlyArray<CaptureTarget>;
|
|
8
|
+
readonly legacy: boolean;
|
|
9
|
+
readonly originalArgv: ReadonlyArray<string>;
|
|
10
|
+
readonly reportedMissingCaptures: Set<string>;
|
|
8
11
|
readonly target: TunnelTarget;
|
|
9
12
|
};
|
|
10
13
|
export type LocalProxyShape = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-proxy.d.ts","sourceRoot":"","sources":["../src/local-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,WAAW,EAEhB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAW,OAAO,EAAE,MAAM,EAAS,KAAK,EAAO,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"local-proxy.d.ts","sourceRoot":"","sources":["../src/local-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,WAAW,EAEhB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAW,OAAO,EAAE,MAAM,EAAS,KAAK,EAAO,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AA8BhC,OAAO,EAAE,SAAS,EAAuB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAEL,kBAAkB,EAGnB,MAAM,aAAa,CAAC;AAWrB,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,uBAAuB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,aAAa,EAAE,CACtB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;CAC9C,CAAC;;AAEF,qBAAa,UAAW,SAAQ,eAA4D;CAAG;AAE/F,eAAO,MAAM,cAAc,2CAU1B,CAAC;AA6aF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,EAAE,YAAY,MAAM,KAAG,MAqC5E,CAAC;AA0CF,eAAO,MAAM,0BAA0B,GAAI,SAAS,OAAO,KAAG,WAqB7D,CAAC"}
|