@cloudflare/vite-plugin 1.36.4 → 1.37.1
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.d.mts +5 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +266 -129
- package/dist/index.mjs.map +1 -1
- package/dist/{package-DVvoeaWx.mjs → package-THM8qmxs.mjs} +2 -2
- package/dist/{package-DVvoeaWx.mjs.map → package-THM8qmxs.mjs.map} +1 -1
- package/dist/workers/runner-worker/module-runner.js +1 -1
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -1503,7 +1503,7 @@ async function assertWranglerVersion() {
|
|
|
1503
1503
|
* The default compatibility date to use when the user omits one.
|
|
1504
1504
|
* This value is injected at build time and remains fixed for each release.
|
|
1505
1505
|
*/
|
|
1506
|
-
const DEFAULT_COMPAT_DATE = "2026-05-
|
|
1506
|
+
const DEFAULT_COMPAT_DATE = "2026-05-15";
|
|
1507
1507
|
|
|
1508
1508
|
//#endregion
|
|
1509
1509
|
//#region ../../node_modules/.pnpm/@remix-run+node-fetch-server@0.8.0/node_modules/@remix-run/node-fetch-server/dist/node-fetch-server.js
|
|
@@ -1997,7 +1997,7 @@ var MetricsRegistry = class {
|
|
|
1997
1997
|
};
|
|
1998
1998
|
|
|
1999
1999
|
//#endregion
|
|
2000
|
-
//#region ../workers-utils/dist/chunk-
|
|
2000
|
+
//#region ../workers-utils/dist/chunk-GMTGAG26.mjs
|
|
2001
2001
|
var UserError = class extends Error {
|
|
2002
2002
|
static {
|
|
2003
2003
|
__name(this, "UserError");
|
|
@@ -4394,8 +4394,15 @@ function findRedirectedWranglerConfig(cwd, userConfigPath) {
|
|
|
4394
4394
|
};
|
|
4395
4395
|
}
|
|
4396
4396
|
__name(findRedirectedWranglerConfig, "findRedirectedWranglerConfig");
|
|
4397
|
+
function isRedirectedConfig(config) {
|
|
4398
|
+
return config.configPath !== void 0 && config.configPath !== config.userConfigPath;
|
|
4399
|
+
}
|
|
4400
|
+
__name(isRedirectedConfig, "isRedirectedConfig");
|
|
4397
4401
|
function isRedirectedRawConfig(rawConfig, configPath, userConfigPath) {
|
|
4398
|
-
return
|
|
4402
|
+
return isRedirectedConfig({
|
|
4403
|
+
configPath,
|
|
4404
|
+
userConfigPath
|
|
4405
|
+
});
|
|
4399
4406
|
}
|
|
4400
4407
|
__name(isRedirectedRawConfig, "isRedirectedRawConfig");
|
|
4401
4408
|
function configFormat(configPath) {
|
|
@@ -30887,9 +30894,9 @@ function normalizeAndValidateConfig(rawConfig, configPath, userConfigPath, args,
|
|
|
30887
30894
|
if (useServiceEnvironments) diagnostics.warnings.push("Service environments are deprecated, and will be removed in the future. DO NOT USE IN PRODUCTION.");
|
|
30888
30895
|
const isDispatchNamespace = typeof args["dispatch-namespace"] === "string" && args["dispatch-namespace"].trim() !== "";
|
|
30889
30896
|
const topLevelEnv = normalizeAndValidateEnvironment(diagnostics, configPath, rawConfig, isDispatchNamespace, preserveOriginalMain);
|
|
30890
|
-
const
|
|
30897
|
+
const isRedirectedConfig2 = isRedirectedRawConfig(rawConfig, configPath, userConfigPath);
|
|
30891
30898
|
const definedEnvironments = Object.keys(rawConfig.env ?? {});
|
|
30892
|
-
if (
|
|
30899
|
+
if (isRedirectedConfig2 && definedEnvironments.length > 0) diagnostics.errors.push(dedent`
|
|
30893
30900
|
Redirected configurations cannot include environments but the following have been found:\n${definedEnvironments.map((env$1) => ` - ${env$1}`).join("\n")}
|
|
30894
30901
|
|
|
30895
30902
|
|
|
@@ -30900,7 +30907,7 @@ function normalizeAndValidateConfig(rawConfig, configPath, userConfigPath, args,
|
|
|
30900
30907
|
const envName = args.env ?? getCloudflareEnv();
|
|
30901
30908
|
assert(envName === void 0 || typeof envName === "string");
|
|
30902
30909
|
let activeEnv = topLevelEnv;
|
|
30903
|
-
if (envName) if (
|
|
30910
|
+
if (envName) if (isRedirectedConfig2) {
|
|
30904
30911
|
if (!isPagesConfig(rawConfig) && rawConfig.targetEnvironment && rawConfig.targetEnvironment !== envName) {
|
|
30905
30912
|
const via = args.env !== void 0 ? "via the `--env/-e` CLI argument" : "via the CLOUDFLARE_ENV environment variable";
|
|
30906
30913
|
throw new Error(dedent`
|
|
@@ -30932,9 +30939,9 @@ Consider adding an environment configuration section to the ${configFileName(con
|
|
|
30932
30939
|
const config = {
|
|
30933
30940
|
configPath,
|
|
30934
30941
|
userConfigPath,
|
|
30935
|
-
topLevelName:
|
|
30936
|
-
definedEnvironments:
|
|
30937
|
-
targetEnvironment:
|
|
30942
|
+
topLevelName: isRedirectedConfig2 ? rawConfig.topLevelName : rawConfig.name,
|
|
30943
|
+
definedEnvironments: isRedirectedConfig2 ? rawConfig.definedEnvironments : definedEnvironments,
|
|
30944
|
+
targetEnvironment: isRedirectedConfig2 ? rawConfig.targetEnvironment : envName,
|
|
30938
30945
|
pages_build_output_dir: normalizeAndValidatePagesBuildOutputDir(configPath, rawConfig.pages_build_output_dir),
|
|
30939
30946
|
legacy_env: !useServiceEnvironments,
|
|
30940
30947
|
send_metrics: rawConfig.send_metrics,
|
|
@@ -31263,7 +31270,7 @@ var validateStreamingTailConsumers = /* @__PURE__ */ __name((diagnostics, field,
|
|
|
31263
31270
|
}, "validateStreamingTailConsumers");
|
|
31264
31271
|
function normalizeAndValidateEnvironment(diagnostics, configPath, rawEnv, isDispatchNamespace, preserveOriginalMain, envName = "top level", topLevelEnv, useServiceEnvironments, rawConfig) {
|
|
31265
31272
|
deprecated(diagnostics, rawEnv, "node_compat", `The "node_compat" field is no longer supported as of Wrangler v4. Instead, use the \`nodejs_compat\` compatibility flag. This includes the functionality from legacy \`node_compat\` polyfills and natively implemented Node.js APIs. See https://developers.cloudflare.com/workers/runtime-apis/nodejs for more information.`, true, "Removed", "error");
|
|
31266
|
-
experimental(diagnostics, rawEnv, "unsafe");
|
|
31273
|
+
if (topLevelEnv === void 0 || rawConfig?.unsafe === void 0) experimental(diagnostics, rawEnv, "unsafe");
|
|
31267
31274
|
const route = normalizeAndValidateRoute(diagnostics, topLevelEnv, rawEnv);
|
|
31268
31275
|
const account_id = inheritableInWranglerEnvironments(diagnostics, useServiceEnvironments, topLevelEnv, mutateEmptyStringAccountIDValue(diagnostics, rawEnv), "account_id", isString$2, void 0, void 0);
|
|
31269
31276
|
const routes = validateRoutes(diagnostics, topLevelEnv, rawEnv);
|
|
@@ -31426,9 +31433,11 @@ var validateDefines = /* @__PURE__ */ __name((envName) => (diagnostics, field, v
|
|
|
31426
31433
|
if (configDefines.length > 0) {
|
|
31427
31434
|
if (typeof value === "object" && value !== null) {
|
|
31428
31435
|
const configEnvDefines = config === void 0 ? [] : Object.keys(value);
|
|
31429
|
-
|
|
31430
|
-
|
|
31431
|
-
|
|
31436
|
+
const missingDefines = configDefines.filter((varName) => !(varName in value));
|
|
31437
|
+
if (missingDefines.length > 0) diagnostics.warnings.push(`The following define entries exist at the top level, but not on "${fieldPath}".
|
|
31438
|
+
This is probably not what you want, since "define" configuration is not inherited by environments.
|
|
31439
|
+
Please add these entries to "env.${envName}.define":
|
|
31440
|
+
` + missingDefines.map((varName) => `- ${varName}`).join("\n"));
|
|
31432
31441
|
for (const varName of configEnvDefines) if (!configDefines.includes(varName)) diagnostics.warnings.push(`"${varName}" exists on "env.${envName}", but not on the top level.
|
|
31433
31442
|
This is not what you probably want, since "define" configuration within environments can only override existing top level "define" configuration
|
|
31434
31443
|
Please remove "${fieldPath}.${varName}", or add "define.${varName}".`);
|
|
@@ -31452,9 +31461,11 @@ var validateVars = /* @__PURE__ */ __name((envName) => (diagnostics, field, valu
|
|
|
31452
31461
|
const configVars = Object.keys(config?.vars ?? {});
|
|
31453
31462
|
if (configVars.length > 0) {
|
|
31454
31463
|
if (typeof value === "object" && value !== null) {
|
|
31455
|
-
|
|
31456
|
-
|
|
31457
|
-
|
|
31464
|
+
const missingVars = configVars.filter((varName) => !(varName in value));
|
|
31465
|
+
if (missingVars.length > 0) diagnostics.warnings.push(`The following vars exist at the top level, but not on "${fieldPath}".
|
|
31466
|
+
This is probably not what you want, since "vars" configuration is not inherited by environments.
|
|
31467
|
+
Please add these vars to "env.${envName}.vars":
|
|
31468
|
+
` + missingVars.map((varName) => `- ${varName}`).join("\n"));
|
|
31458
31469
|
}
|
|
31459
31470
|
}
|
|
31460
31471
|
return isValid2;
|
|
@@ -33475,27 +33486,36 @@ function startTunnel(options) {
|
|
|
33475
33486
|
const timeoutMs = options.timeoutMs ?? TUNNEL_STARTUP_TIMEOUT_MS;
|
|
33476
33487
|
const reminderIntervalMs = options.reminderIntervalMs ?? DEFAULT_TUNNEL_REMINDER_INTERVAL_MS;
|
|
33477
33488
|
const defaultExpiryMs = options.expiryMs ?? DEFAULT_TUNNEL_EXPIRY_MS;
|
|
33489
|
+
const isNamedTunnel = options.token !== void 0;
|
|
33478
33490
|
const timeFormatter = new Intl.DateTimeFormat(void 0, { timeStyle: "short" });
|
|
33479
|
-
const readyPromise = spawnCloudflared([
|
|
33491
|
+
const readyPromise = spawnCloudflared(isNamedTunnel ? [
|
|
33492
|
+
"tunnel",
|
|
33493
|
+
"--no-autoupdate",
|
|
33494
|
+
"run"
|
|
33495
|
+
] : [
|
|
33480
33496
|
"tunnel",
|
|
33481
33497
|
"--no-autoupdate",
|
|
33482
33498
|
"--url",
|
|
33483
33499
|
options.origin.href
|
|
33484
33500
|
], {
|
|
33485
33501
|
stdio: "pipe",
|
|
33502
|
+
env: options.token ? { TUNNEL_TOKEN: options.token } : void 0,
|
|
33486
33503
|
skipVersionCheck: true,
|
|
33487
33504
|
logger
|
|
33488
33505
|
}).then((process2) => {
|
|
33489
33506
|
cloudflaredProcess = process2;
|
|
33490
33507
|
if (disposed) terminateCloudflared(process2);
|
|
33491
33508
|
return process2;
|
|
33492
|
-
}).then((process2) =>
|
|
33493
|
-
|
|
33494
|
-
|
|
33495
|
-
|
|
33509
|
+
}).then((process2) => {
|
|
33510
|
+
if (isNamedTunnel) return { mode: "named" };
|
|
33511
|
+
return waitForQuickTunnelReady(process2, timeoutMs, {
|
|
33512
|
+
logger,
|
|
33513
|
+
origin: options.origin
|
|
33514
|
+
});
|
|
33515
|
+
}).then((result) => {
|
|
33496
33516
|
expiresAt = Date.now() + defaultExpiryMs;
|
|
33497
33517
|
scheduleExpiryTimeout();
|
|
33498
|
-
scheduleReminder(result.publicUrl.origin);
|
|
33518
|
+
scheduleReminder(result.mode === "quick" ? result.publicUrl.origin : void 0);
|
|
33499
33519
|
return result;
|
|
33500
33520
|
});
|
|
33501
33521
|
function disposeTunnel() {
|
|
@@ -33521,7 +33541,7 @@ function startTunnel(options) {
|
|
|
33521
33541
|
if (disposed) return;
|
|
33522
33542
|
const remainingMs = expiresAt - Date.now();
|
|
33523
33543
|
if (remainingMs <= 0) return;
|
|
33524
|
-
logger?.log(`The tunnel is still open at ${publicURL}. It expires in ${formatTunnelDuration(remainingMs)}. ${options.extendHint ?? ""}`);
|
|
33544
|
+
logger?.log(`${publicURL ? `The tunnel is still open at ${publicURL}.` : "The tunnel is still open."} It expires in ${formatTunnelDuration(remainingMs)}. ${options.extendHint ?? ""}`);
|
|
33525
33545
|
}, reminderIntervalMs);
|
|
33526
33546
|
reminderInterval.unref?.();
|
|
33527
33547
|
}
|
|
@@ -33555,6 +33575,7 @@ function startTunnel(options) {
|
|
|
33555
33575
|
__name(extendExpiry, "extendExpiry");
|
|
33556
33576
|
return {
|
|
33557
33577
|
ready: /* @__PURE__ */ __name(() => readyPromise, "ready"),
|
|
33578
|
+
isOpen: /* @__PURE__ */ __name(() => !disposed, "isOpen"),
|
|
33558
33579
|
dispose: disposeTunnel,
|
|
33559
33580
|
extendExpiry
|
|
33560
33581
|
};
|
|
@@ -33600,7 +33621,10 @@ function waitForQuickTunnelReady(cloudflared, timeoutMs, options) {
|
|
|
33600
33621
|
if (match && !resolved) {
|
|
33601
33622
|
resolved = true;
|
|
33602
33623
|
clearTimeout(timeoutId);
|
|
33603
|
-
resolve$4({
|
|
33624
|
+
resolve$4({
|
|
33625
|
+
mode: "quick",
|
|
33626
|
+
publicUrl: new URL(match[0])
|
|
33627
|
+
});
|
|
33604
33628
|
}
|
|
33605
33629
|
});
|
|
33606
33630
|
cloudflared.on("error", (error) => {
|
|
@@ -33808,53 +33832,84 @@ var require_picocolors = /* @__PURE__ */ __commonJS$1({ "../../node_modules/.pnp
|
|
|
33808
33832
|
//#endregion
|
|
33809
33833
|
//#region src/plugins/tunnel.ts
|
|
33810
33834
|
var import_picocolors$5 = /* @__PURE__ */ __toESM$1(require_picocolors(), 1);
|
|
33811
|
-
|
|
33812
|
-
"
|
|
33813
|
-
|
|
33814
|
-
|
|
33815
|
-
|
|
33816
|
-
|
|
33817
|
-
|
|
33818
|
-
|
|
33819
|
-
|
|
33820
|
-
|
|
33821
|
-
|
|
33835
|
+
function createPublicExposureWarning(mode, name, shortcutPressed) {
|
|
33836
|
+
const intro = name === void 0 ? import_picocolors$5.default.dim("Once connected, this tunnel will be ") + "publicly accessible" + import_picocolors$5.default.dim(". Anyone who can reach it can:") : import_picocolors$5.default.dim("Once connected, this tunnel may be reachable from the Internet. Anyone who can reach it can:");
|
|
33837
|
+
const concerns = [
|
|
33838
|
+
"Call ungated endpoints",
|
|
33839
|
+
"Trigger logic that uses remote bindings",
|
|
33840
|
+
"Reach internal services if your Worker proxies requests"
|
|
33841
|
+
];
|
|
33842
|
+
const hints = [name === void 0 ? "Consider using a named tunnel with Cloudflare Access to restrict access." : "Consider using Cloudflare Access to restrict access."];
|
|
33843
|
+
if (mode === "dev") {
|
|
33844
|
+
concerns.push("Request module source and other dev-server assets", "Access HMR messages, including absolute file system paths", "Observe file-change cadence and parts of the live module graph");
|
|
33845
|
+
hints.unshift("If you only need to share a running build, use vite preview to avoid HMR and other dev-server exposure.");
|
|
33846
|
+
}
|
|
33847
|
+
const lines = [
|
|
33848
|
+
intro,
|
|
33849
|
+
...concerns.map((concern) => import_picocolors$5.default.dim(`• ${concern}`)),
|
|
33822
33850
|
"",
|
|
33823
|
-
import_picocolors$5.default.dim(
|
|
33851
|
+
...hints.map((guidance) => import_picocolors$5.default.dim(guidance)),
|
|
33824
33852
|
""
|
|
33825
|
-
]
|
|
33853
|
+
];
|
|
33854
|
+
if (shortcutPressed) lines.push("Press t + enter again to close the tunnel.", "");
|
|
33855
|
+
const spacing = " ";
|
|
33856
|
+
return lines.map((line) => spacing + line).join("\n");
|
|
33826
33857
|
}
|
|
33827
|
-
const DEV_PUBLIC_EXPOSURE_WARNING = createPublicExposureWarning([
|
|
33828
|
-
...COMMON_PUBLIC_EXPOSURE_CONCERNS,
|
|
33829
|
-
"Request module source and other dev-server assets",
|
|
33830
|
-
"Access HMR messages, including absolute file system paths",
|
|
33831
|
-
"Observe file-change cadence and parts of the live module graph"
|
|
33832
|
-
], `If you only need to share a running build, use vite preview to avoid HMR and other dev-server exposure. ${COMMON_PUBLIC_EXPOSURE_GUIDANCE}`);
|
|
33833
|
-
const PREVIEW_PUBLIC_EXPOSURE_WARNING = createPublicExposureWarning(COMMON_PUBLIC_EXPOSURE_CONCERNS, COMMON_PUBLIC_EXPOSURE_GUIDANCE);
|
|
33834
33858
|
const QUICK_TUNNEL_SSE_WARNING = "Quick tunnels do not support Server-Sent Events (SSE). Use a named Cloudflare Tunnel if you need SSE over a public URL.";
|
|
33835
33859
|
const QUICK_TUNNEL_ALLOWED_HOST = ".trycloudflare.com";
|
|
33836
33860
|
var TunnelManager = class {
|
|
33837
33861
|
#logger;
|
|
33838
33862
|
#origin;
|
|
33839
|
-
#
|
|
33863
|
+
#publicUrls;
|
|
33864
|
+
#requestedTunnel;
|
|
33840
33865
|
#tunnel;
|
|
33866
|
+
#abortController;
|
|
33841
33867
|
#hasWarnedAboutSse = false;
|
|
33842
33868
|
constructor(logger) {
|
|
33843
33869
|
this.#logger = logger;
|
|
33844
33870
|
}
|
|
33845
|
-
isStarted(origin) {
|
|
33846
|
-
return this.#origin === origin && this.#
|
|
33871
|
+
isStarted(origin, name) {
|
|
33872
|
+
return this.#origin === origin && this.#requestedTunnel === name;
|
|
33873
|
+
}
|
|
33874
|
+
isOpen() {
|
|
33875
|
+
if (!this.#tunnel) return this.#origin !== void 0;
|
|
33876
|
+
const isOpen = this.#tunnel.isOpen();
|
|
33877
|
+
if (!isOpen) {
|
|
33878
|
+
this.#tunnel = void 0;
|
|
33879
|
+
this.dispose();
|
|
33880
|
+
}
|
|
33881
|
+
return isOpen;
|
|
33847
33882
|
}
|
|
33848
|
-
async startTunnel(
|
|
33883
|
+
async startTunnel(options) {
|
|
33849
33884
|
try {
|
|
33850
|
-
if (this.#origin === origin && this.#tunnel) return await this.#waitForPublicUrl(this.#tunnel);
|
|
33851
|
-
this.#logger.info(import_picocolors$5.default.dim("\n ➜ Starting tunnel (usually takes a few seconds)...\n"));
|
|
33852
33885
|
if (this.#tunnel) this.dispose();
|
|
33853
|
-
|
|
33854
|
-
this.#
|
|
33886
|
+
const abortController = new AbortController();
|
|
33887
|
+
this.#abortController = abortController;
|
|
33888
|
+
this.#origin = options.origin;
|
|
33889
|
+
this.#requestedTunnel = options.name;
|
|
33890
|
+
this.#logger.info(import_picocolors$5.default.dim("\n ➜ Starting tunnel (usually takes a few seconds)...\n"));
|
|
33891
|
+
this.#logger.warn(createPublicExposureWarning(options.mode, options.name, options.shortcutPressed ?? false));
|
|
33892
|
+
const namedTunnel = options.name !== void 0 ? await wrangler.unstable_resolveNamedTunnel(options.name, new URL(options.origin), {
|
|
33893
|
+
accountId: options.accountId,
|
|
33894
|
+
complianceRegion: options.complianceRegion
|
|
33895
|
+
}) : void 0;
|
|
33896
|
+
if (abortController.signal.aborted) return null;
|
|
33897
|
+
if (namedTunnel) this.#publicUrls = namedTunnel.hostnames.map((hostname) => `https://${hostname}`);
|
|
33898
|
+
if (options.mode === "preview") {
|
|
33899
|
+
if (namedTunnel) {
|
|
33900
|
+
const allowedUrls = getAllowedTunnelUrls(this.#publicUrls ?? [], options.allowedHosts);
|
|
33901
|
+
if (allowedUrls.length === 0) {
|
|
33902
|
+
const suggestedAllowedHosts = getSuggestedAllowedHosts(namedTunnel.hostnames);
|
|
33903
|
+
throw new Error("The resolved tunnel hostnames are not allowed by Vite preview host validation.\n\nAdd at least one of these hosts to `preview.allowedHosts` in your Vite config.\nYou can use exact hostnames or a domain suffix:\n" + suggestedAllowedHosts.map((hostname) => ` - ${hostname}`).join("\n") + "\n");
|
|
33904
|
+
}
|
|
33905
|
+
this.#publicUrls = allowedUrls;
|
|
33906
|
+
} else if (!isQuickTunnelAllowed(options.allowedHosts)) throw new Error(`Quick tunnel hostnames are not allowed by Vite preview host validation.
|
|
33907
|
+
Add \`${QUICK_TUNNEL_ALLOWED_HOST}\` to \`preview.allowedHosts\` in your Vite config.\n`);
|
|
33908
|
+
}
|
|
33855
33909
|
const tunnel = startTunnel({
|
|
33856
|
-
origin: new URL(origin),
|
|
33857
|
-
|
|
33910
|
+
origin: new URL(options.origin),
|
|
33911
|
+
token: namedTunnel?.token,
|
|
33912
|
+
extendHint: "Press a + enter to extend by 1 hour.",
|
|
33858
33913
|
logger: {
|
|
33859
33914
|
log: (message) => this.#logger.info(message),
|
|
33860
33915
|
warn: (message) => this.#logger.warn(message),
|
|
@@ -33862,47 +33917,54 @@ var TunnelManager = class {
|
|
|
33862
33917
|
}
|
|
33863
33918
|
});
|
|
33864
33919
|
this.#tunnel = tunnel;
|
|
33865
|
-
return await this.#
|
|
33920
|
+
return await this.#waitForPublicUrls(tunnel);
|
|
33866
33921
|
} catch (error) {
|
|
33867
|
-
|
|
33922
|
+
this.#origin = void 0;
|
|
33923
|
+
this.#publicUrls = void 0;
|
|
33924
|
+
this.#requestedTunnel = void 0;
|
|
33925
|
+
throw error;
|
|
33868
33926
|
}
|
|
33869
33927
|
}
|
|
33870
|
-
async #
|
|
33928
|
+
async #waitForPublicUrls(tunnel) {
|
|
33871
33929
|
try {
|
|
33872
|
-
const
|
|
33930
|
+
const result = await tunnel.ready();
|
|
33873
33931
|
if (this.#tunnel !== tunnel) {
|
|
33874
|
-
debuglog("Tunnel was restarted before it finished starting. Ignoring this tunnel's public URL:", publicUrl);
|
|
33932
|
+
debuglog("Tunnel was restarted before it finished starting. Ignoring this tunnel's public URL:", result.mode === "quick" ? result.publicUrl : this.#publicUrls);
|
|
33875
33933
|
return null;
|
|
33876
33934
|
}
|
|
33935
|
+
if (result.mode === "named") return this.#publicUrls ?? null;
|
|
33936
|
+
const { publicUrl } = result;
|
|
33877
33937
|
debuglog("Tunnel is ready with public URL:", publicUrl);
|
|
33878
|
-
this.#
|
|
33879
|
-
return
|
|
33938
|
+
this.#publicUrls = [publicUrl.toString()];
|
|
33939
|
+
return this.#publicUrls;
|
|
33880
33940
|
} catch (error) {
|
|
33881
33941
|
if (this.#tunnel !== tunnel) return null;
|
|
33882
|
-
this.#publicUrl = void 0;
|
|
33883
33942
|
this.#tunnel = void 0;
|
|
33884
33943
|
throw error;
|
|
33885
33944
|
}
|
|
33886
33945
|
}
|
|
33887
|
-
get
|
|
33888
|
-
return this.#
|
|
33946
|
+
get publicUrls() {
|
|
33947
|
+
return this.#publicUrls;
|
|
33889
33948
|
}
|
|
33890
33949
|
extendExpiry() {
|
|
33891
33950
|
this.#tunnel?.extendExpiry();
|
|
33892
33951
|
}
|
|
33893
33952
|
warnIfQuickTunnelSseResponse(contentType) {
|
|
33894
|
-
if (this.#hasWarnedAboutSse || !this.#tunnel || contentType === null || !contentType.toLowerCase().startsWith("text/event-stream")) return;
|
|
33953
|
+
if (this.#hasWarnedAboutSse || this.#requestedTunnel !== void 0 || !this.#tunnel || contentType === null || !contentType.toLowerCase().startsWith("text/event-stream")) return;
|
|
33895
33954
|
this.#hasWarnedAboutSse = true;
|
|
33896
33955
|
this.#logger.warn(QUICK_TUNNEL_SSE_WARNING);
|
|
33897
33956
|
}
|
|
33898
33957
|
dispose() {
|
|
33899
33958
|
const tunnel = this.#tunnel;
|
|
33959
|
+
this.#abortController?.abort();
|
|
33900
33960
|
this.#origin = void 0;
|
|
33901
|
-
this.#
|
|
33961
|
+
this.#publicUrls = void 0;
|
|
33962
|
+
this.#requestedTunnel = void 0;
|
|
33902
33963
|
this.#tunnel = void 0;
|
|
33903
33964
|
this.#hasWarnedAboutSse = false;
|
|
33904
33965
|
debuglog("Disposing tunnel...");
|
|
33905
33966
|
if (tunnel) tunnel.dispose();
|
|
33967
|
+
this.#logger.info(" ➜ Tunnel closed");
|
|
33906
33968
|
}
|
|
33907
33969
|
disposeOnExit() {
|
|
33908
33970
|
try {
|
|
@@ -33922,6 +33984,19 @@ function warnIfQuickTunnelSseResponse(contentType) {
|
|
|
33922
33984
|
function extendTunnelExpiry() {
|
|
33923
33985
|
tunnelManager?.extendExpiry();
|
|
33924
33986
|
}
|
|
33987
|
+
function isTunnelOpen() {
|
|
33988
|
+
return tunnelManager?.isOpen() ?? false;
|
|
33989
|
+
}
|
|
33990
|
+
async function toggleTunnel(server, ctx) {
|
|
33991
|
+
if (!tunnelManager) return;
|
|
33992
|
+
if (tunnelManager.isOpen()) {
|
|
33993
|
+
ctx.clearTunnelHostnames();
|
|
33994
|
+
tunnelManager.dispose();
|
|
33995
|
+
return;
|
|
33996
|
+
}
|
|
33997
|
+
if ("restart" in server) await setupDevTunnel(server, ctx, tunnelManager, true);
|
|
33998
|
+
else await setupPreviewTunnel(server, ctx, tunnelManager, true);
|
|
33999
|
+
}
|
|
33925
34000
|
/**
|
|
33926
34001
|
* Resolve the dev tunnel origin from the running server.
|
|
33927
34002
|
*
|
|
@@ -33952,8 +34027,8 @@ async function resolveDevTunnelOrigin(server) {
|
|
|
33952
34027
|
async function resolvePreviewTunnelOrigin(server) {
|
|
33953
34028
|
const { preview } = server.config;
|
|
33954
34029
|
const host = typeof preview.host === "string" ? preview.host : void 0;
|
|
33955
|
-
let resolvedPort;
|
|
33956
|
-
if (preview.port === 0) resolvedPort = await getPorts({
|
|
34030
|
+
let resolvedPort = preview.port;
|
|
34031
|
+
if (!server.httpServer.listening) if (preview.port === 0) resolvedPort = await getPorts({
|
|
33957
34032
|
port: 0,
|
|
33958
34033
|
host
|
|
33959
34034
|
});
|
|
@@ -33978,18 +34053,28 @@ async function resolvePreviewTunnelOrigin(server) {
|
|
|
33978
34053
|
secure: !!preview.https
|
|
33979
34054
|
}));
|
|
33980
34055
|
}
|
|
33981
|
-
async function setupDevTunnel(server, ctx, manager) {
|
|
34056
|
+
async function setupDevTunnel(server, ctx, manager, shortcutPressed) {
|
|
33982
34057
|
const origin = await resolveDevTunnelOrigin(server);
|
|
33983
|
-
|
|
34058
|
+
const tunnel = ctx.resolvedPluginConfig.tunnel;
|
|
34059
|
+
if (manager.isStarted(origin, tunnel.name)) {
|
|
33984
34060
|
debuglog("Tunnel is already started on", origin);
|
|
33985
34061
|
return;
|
|
33986
34062
|
}
|
|
33987
|
-
const
|
|
33988
|
-
|
|
34063
|
+
const publicUrls = await manager.startTunnel({
|
|
34064
|
+
mode: "dev",
|
|
34065
|
+
origin,
|
|
34066
|
+
shortcutPressed,
|
|
34067
|
+
name: tunnel.name,
|
|
34068
|
+
accountId: ctx.entryWorkerConfig?.account_id,
|
|
34069
|
+
complianceRegion: ctx.entryWorkerConfig?.compliance_region,
|
|
34070
|
+
allowedHosts: true
|
|
34071
|
+
});
|
|
34072
|
+
if (!publicUrls) return;
|
|
33989
34073
|
const allowedHosts = server.config.server.allowedHosts;
|
|
33990
|
-
const tunnelHostnames =
|
|
34074
|
+
const tunnelHostnames = publicUrls.map((url) => new URL(url).hostname);
|
|
33991
34075
|
ctx.replaceTunnelHostnames(tunnelHostnames);
|
|
33992
34076
|
if (allowedHosts !== true && tunnelHostnames.some((hostname) => !allowedHosts.includes(hostname))) await server.restart();
|
|
34077
|
+
if (shortcutPressed) server.printUrls();
|
|
33993
34078
|
}
|
|
33994
34079
|
/**
|
|
33995
34080
|
* Start a preview tunnel on the resolved preview origin.
|
|
@@ -33997,7 +34082,7 @@ async function setupDevTunnel(server, ctx, manager) {
|
|
|
33997
34082
|
* We write the resolved port back to preview config so the server binds the
|
|
33998
34083
|
* same port that the tunnel is sharing.
|
|
33999
34084
|
*/
|
|
34000
|
-
async function setupPreviewTunnel(server, manager) {
|
|
34085
|
+
async function setupPreviewTunnel(server, ctx, manager, shortcutPressed) {
|
|
34001
34086
|
const { preview } = server.config;
|
|
34002
34087
|
const originalPort = preview.port;
|
|
34003
34088
|
const resolvedOrigin = await resolvePreviewTunnelOrigin(server);
|
|
@@ -34005,17 +34090,58 @@ async function setupPreviewTunnel(server, manager) {
|
|
|
34005
34090
|
preview.port = resolvedPort;
|
|
34006
34091
|
preview.strictPort = true;
|
|
34007
34092
|
if (originalPort !== 0 && resolvedPort !== originalPort) server.config.logger.info(import_picocolors$5.default.dim(`Port ${originalPort} is in use, using ${resolvedPort} instead for preview tunnel sharing.\n`));
|
|
34008
|
-
|
|
34009
|
-
|
|
34010
|
-
|
|
34093
|
+
const tunnel = ctx.resolvedPluginConfig.tunnel;
|
|
34094
|
+
const origin = resolvedOrigin.toString();
|
|
34095
|
+
if (manager.isStarted(origin, tunnel.name)) {
|
|
34096
|
+
debuglog("Tunnel is already started on", origin);
|
|
34097
|
+
return;
|
|
34098
|
+
}
|
|
34099
|
+
if (!await manager.startTunnel({
|
|
34100
|
+
mode: "preview",
|
|
34101
|
+
origin,
|
|
34102
|
+
shortcutPressed,
|
|
34103
|
+
name: tunnel.name,
|
|
34104
|
+
allowedHosts: preview?.allowedHosts,
|
|
34105
|
+
accountId: ctx.allWorkerConfigs[0]?.account_id,
|
|
34106
|
+
complianceRegion: ctx.allWorkerConfigs[0]?.compliance_region
|
|
34107
|
+
})) return;
|
|
34108
|
+
if (shortcutPressed) server.printUrls();
|
|
34109
|
+
}
|
|
34110
|
+
function patchPrintUrls(server) {
|
|
34011
34111
|
const serverPrintUrls = server.printUrls.bind(server);
|
|
34012
34112
|
server.printUrls = () => {
|
|
34013
34113
|
serverPrintUrls();
|
|
34014
|
-
const
|
|
34015
|
-
if (!
|
|
34016
|
-
server.config.logger.info(`${import_picocolors$5.default.green(" ➜")} ${import_picocolors$5.default.bold("Tunnel:")} ${import_picocolors$5.default.cyan(
|
|
34017
|
-
server.config.logger.
|
|
34018
|
-
|
|
34114
|
+
const publicUrls = tunnelManager?.publicUrls;
|
|
34115
|
+
if (!publicUrls || publicUrls.length === 0) return;
|
|
34116
|
+
for (let i$1 = 0; i$1 < publicUrls.length; i$1++) if (i$1 === 0) server.config.logger.info(`${import_picocolors$5.default.green(" ➜")} ${import_picocolors$5.default.bold("Tunnel:")} ${import_picocolors$5.default.cyan(publicUrls[i$1])}`);
|
|
34117
|
+
else server.config.logger.info(` ${import_picocolors$5.default.cyan(publicUrls[i$1])}`);
|
|
34118
|
+
server.config.logger.info("");
|
|
34119
|
+
};
|
|
34120
|
+
}
|
|
34121
|
+
function isQuickTunnelAllowed(allowedHosts) {
|
|
34122
|
+
if (allowedHosts === void 0) return false;
|
|
34123
|
+
if (allowedHosts === true) return true;
|
|
34124
|
+
return allowedHosts.some((allowedHost) => allowedHost.toLowerCase() === QUICK_TUNNEL_ALLOWED_HOST);
|
|
34125
|
+
}
|
|
34126
|
+
function getAllowedTunnelUrls(publicUrls, allowedHosts) {
|
|
34127
|
+
if (allowedHosts === void 0) return [];
|
|
34128
|
+
if (allowedHosts === true) return publicUrls;
|
|
34129
|
+
return publicUrls.filter((publicUrl) => {
|
|
34130
|
+
const hostname = new URL(publicUrl).hostname.toLowerCase();
|
|
34131
|
+
return allowedHosts.some((allowedHost) => {
|
|
34132
|
+
const normalizedAllowedHost = allowedHost.toLowerCase();
|
|
34133
|
+
if (normalizedAllowedHost.startsWith(".")) return hostname === normalizedAllowedHost.slice(1) || hostname.endsWith(normalizedAllowedHost);
|
|
34134
|
+
return hostname === normalizedAllowedHost;
|
|
34135
|
+
});
|
|
34136
|
+
});
|
|
34137
|
+
}
|
|
34138
|
+
function getSuggestedAllowedHosts(hostnames) {
|
|
34139
|
+
const suggestions = new Set(hostnames);
|
|
34140
|
+
for (const hostname of hostnames) {
|
|
34141
|
+
const segments = hostname.split(".");
|
|
34142
|
+
if (segments.length > 2) suggestions.add(`.${segments.slice(1).join(".")}`);
|
|
34143
|
+
}
|
|
34144
|
+
return Array.from(suggestions);
|
|
34019
34145
|
}
|
|
34020
34146
|
const tunnelPlugin = createPlugin("tunnel", (ctx) => {
|
|
34021
34147
|
function stopTunnel() {
|
|
@@ -34028,12 +34154,9 @@ const tunnelPlugin = createPlugin("tunnel", (ctx) => {
|
|
|
34028
34154
|
},
|
|
34029
34155
|
configureServer(server) {
|
|
34030
34156
|
assertIsNotPreview(ctx);
|
|
34031
|
-
if (!ctx.resolvedPluginConfig.tunnel) {
|
|
34032
|
-
stopTunnel();
|
|
34033
|
-
return;
|
|
34034
|
-
}
|
|
34035
34157
|
tunnelManager ??= new TunnelManager(server.config.logger);
|
|
34036
|
-
patchPrintUrls(server
|
|
34158
|
+
patchPrintUrls(server);
|
|
34159
|
+
if (!ctx.resolvedPluginConfig.tunnel.autoStart) return;
|
|
34037
34160
|
const serverListen = server.listen.bind(server);
|
|
34038
34161
|
server.listen = async (...args) => {
|
|
34039
34162
|
const result = await serverListen(...args);
|
|
@@ -34050,13 +34173,9 @@ const tunnelPlugin = createPlugin("tunnel", (ctx) => {
|
|
|
34050
34173
|
},
|
|
34051
34174
|
async configurePreviewServer(server) {
|
|
34052
34175
|
assertIsPreview(ctx);
|
|
34053
|
-
if (!ctx.resolvedPluginConfig.tunnel) {
|
|
34054
|
-
stopTunnel();
|
|
34055
|
-
return;
|
|
34056
|
-
}
|
|
34057
34176
|
tunnelManager ??= new TunnelManager(server.config.logger);
|
|
34058
|
-
patchPrintUrls(server
|
|
34059
|
-
await setupPreviewTunnel(server, tunnelManager);
|
|
34177
|
+
patchPrintUrls(server);
|
|
34178
|
+
if (ctx.resolvedPluginConfig.tunnel.autoStart) await setupPreviewTunnel(server, ctx, tunnelManager);
|
|
34060
34179
|
const closePreviewServer = server.close.bind(server);
|
|
34061
34180
|
server.close = async () => {
|
|
34062
34181
|
const closePromise = closePreviewServer();
|
|
@@ -34102,7 +34221,8 @@ function createRequestHandler(handler) {
|
|
|
34102
34221
|
let request$2;
|
|
34103
34222
|
try {
|
|
34104
34223
|
if (req.originalUrl) req.url = req.originalUrl;
|
|
34105
|
-
|
|
34224
|
+
const protocol = getForwardedProto(req);
|
|
34225
|
+
request$2 = createRequest(req, res, protocol ? { protocol } : void 0);
|
|
34106
34226
|
let response = await handler(toMiniflareRequest(request$2), req);
|
|
34107
34227
|
if (req.httpVersionMajor === 2) {
|
|
34108
34228
|
response = new Response$1(response.body, response);
|
|
@@ -34135,6 +34255,20 @@ function toMiniflareRequest(request$2) {
|
|
|
34135
34255
|
});
|
|
34136
34256
|
}
|
|
34137
34257
|
const isRolldown = "rolldownVersion" in vite;
|
|
34258
|
+
/**
|
|
34259
|
+
* Parses the `X-Forwarded-Proto` header from an incoming Node.js request.
|
|
34260
|
+
*
|
|
34261
|
+
* If multiple proxies are in the chain, the header may be a comma-separated
|
|
34262
|
+
* list — the left-most value is the original client-facing protocol.
|
|
34263
|
+
* Returns `undefined` if the header is missing or holds an unsupported value.
|
|
34264
|
+
*/
|
|
34265
|
+
function getForwardedProto(req) {
|
|
34266
|
+
const raw = req.headers["x-forwarded-proto"];
|
|
34267
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
34268
|
+
if (!value) return;
|
|
34269
|
+
const first = value.split(",")[0]?.trim().toLowerCase();
|
|
34270
|
+
if (first === "http" || first === "https") return `${first}:`;
|
|
34271
|
+
}
|
|
34138
34272
|
|
|
34139
34273
|
//#endregion
|
|
34140
34274
|
//#region src/export-types.ts
|
|
@@ -41274,7 +41408,10 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
|
|
|
41274
41408
|
const shared = {
|
|
41275
41409
|
persistState: pluginConfig.persistState ?? true,
|
|
41276
41410
|
inspectorPort: pluginConfig.inspectorPort,
|
|
41277
|
-
tunnel: pluginConfig.tunnel
|
|
41411
|
+
tunnel: typeof pluginConfig.tunnel === "boolean" ? { autoStart: pluginConfig.tunnel } : {
|
|
41412
|
+
autoStart: pluginConfig.tunnel?.autoStart ?? false,
|
|
41413
|
+
name: pluginConfig.tunnel?.name
|
|
41414
|
+
},
|
|
41278
41415
|
experimental: { headersAndRedirectsDevModeSupport: pluginConfig.experimental?.headersAndRedirectsDevModeSupport }
|
|
41279
41416
|
};
|
|
41280
41417
|
const root = userConfig.root ? nodePath.resolve(userConfig.root) : process.cwd();
|
|
@@ -48520,10 +48657,7 @@ function validateWorkerEnvironmentOptions(resolvedPluginConfig, resolvedViteConf
|
|
|
48520
48657
|
const configPlugin = createPlugin("config", (ctx) => {
|
|
48521
48658
|
return {
|
|
48522
48659
|
config(userConfig, env$1) {
|
|
48523
|
-
if (ctx.resolvedPluginConfig.type === "preview") return {
|
|
48524
|
-
appType: "custom",
|
|
48525
|
-
preview: { allowedHosts: getAllowedHosts(ctx.resolvedPluginConfig.tunnel ? [QUICK_TUNNEL_ALLOWED_HOST] : [], userConfig.preview?.allowedHosts ?? userConfig.server?.allowedHosts) }
|
|
48526
|
-
};
|
|
48660
|
+
if (ctx.resolvedPluginConfig.type === "preview") return { appType: "custom" };
|
|
48527
48661
|
if (!ctx.hasShownWorkerConfigWarnings) {
|
|
48528
48662
|
ctx.setHasShownWorkerConfigWarnings(true);
|
|
48529
48663
|
const workerConfigWarnings = getWarningForWorkersConfigs(ctx.resolvedPluginConfig.rawConfigs);
|
|
@@ -52760,7 +52894,8 @@ function handleWebSocket(httpServer, miniflare, entryWorkerName) {
|
|
|
52760
52894
|
httpServer.on("upgrade", async (request$2, socket, head) => {
|
|
52761
52895
|
socket.on("error", () => socket.destroy());
|
|
52762
52896
|
const rawHost = request$2.headers.host ?? UNKNOWN_HOST;
|
|
52763
|
-
const
|
|
52897
|
+
const protocol = getForwardedProto(request$2) ?? "http:";
|
|
52898
|
+
const base = /^https?:\/\//i.test(rawHost) ? rawHost : `${protocol}//${rawHost}`;
|
|
52764
52899
|
const url = new URL(request$2.url ?? "", base);
|
|
52765
52900
|
const isViteRequest = request$2.headers["sec-websocket-protocol"]?.startsWith("vite");
|
|
52766
52901
|
const isSandboxRequest = hasSandboxOrigin(url.origin);
|
|
@@ -53740,22 +53875,16 @@ const shortcutsPlugin = createPlugin("shortcuts", (ctx) => {
|
|
|
53740
53875
|
async configureServer(viteDevServer) {
|
|
53741
53876
|
if (!isCustomShortcutsSupported) return;
|
|
53742
53877
|
assertIsNotPreview(ctx);
|
|
53743
|
-
|
|
53744
|
-
addExplorerShortcut(viteDevServer);
|
|
53745
|
-
if (ctx.resolvedPluginConfig.tunnel) addTunnelShortcut(viteDevServer);
|
|
53878
|
+
addShortcuts(viteDevServer, ctx);
|
|
53746
53879
|
},
|
|
53747
53880
|
async configurePreviewServer(vitePreviewServer) {
|
|
53748
53881
|
if (!isCustomShortcutsSupported) return;
|
|
53749
53882
|
assertIsPreview(ctx);
|
|
53750
|
-
|
|
53751
|
-
addExplorerShortcut(vitePreviewServer);
|
|
53752
|
-
if (ctx.resolvedPluginConfig.tunnel) addTunnelShortcut(vitePreviewServer);
|
|
53883
|
+
addShortcuts(vitePreviewServer, ctx);
|
|
53753
53884
|
}
|
|
53754
53885
|
};
|
|
53755
53886
|
});
|
|
53756
|
-
function
|
|
53757
|
-
const workerConfigs = ctx.allWorkerConfigs;
|
|
53758
|
-
if (workerConfigs.length === 0) return;
|
|
53887
|
+
function addShortcuts(server, ctx) {
|
|
53759
53888
|
if (!process.stdin.isTTY) return;
|
|
53760
53889
|
const registryPath = getDefaultDevRegistryPath();
|
|
53761
53890
|
const printBindingsShortcut = {
|
|
@@ -53763,6 +53892,7 @@ function addBindingsShortcut(server, ctx) {
|
|
|
53763
53892
|
description: "list configured Cloudflare bindings",
|
|
53764
53893
|
action: (viteServer) => {
|
|
53765
53894
|
viteServer.config.logger.info("");
|
|
53895
|
+
const workerConfigs = ctx.allWorkerConfigs;
|
|
53766
53896
|
for (const workerConfig of workerConfigs) {
|
|
53767
53897
|
const bindings = wrangler.unstable_convertConfigBindingsToStartWorkerBindings(workerConfig);
|
|
53768
53898
|
wrangler.unstable_printBindings(bindings, workerConfig.tail_consumers, workerConfig.streaming_tail_consumers, workerConfig.containers, {
|
|
@@ -53775,15 +53905,6 @@ function addBindingsShortcut(server, ctx) {
|
|
|
53775
53905
|
}
|
|
53776
53906
|
}
|
|
53777
53907
|
};
|
|
53778
|
-
const bindCLIShortcuts = server.bindCLIShortcuts.bind(server);
|
|
53779
|
-
server.bindCLIShortcuts = (options) => {
|
|
53780
|
-
if (server.httpServer && process.stdin.isTTY && !process.env.CI && options?.print) server.config.logger.info(import_picocolors.default.dim(import_picocolors.default.green(" ➜")) + import_picocolors.default.dim(" press ") + import_picocolors.default.bold(`${printBindingsShortcut.key} + enter`) + import_picocolors.default.dim(` to ${printBindingsShortcut.description}`));
|
|
53781
|
-
bindCLIShortcuts(options);
|
|
53782
|
-
};
|
|
53783
|
-
server.bindCLIShortcuts({ customShortcuts: [printBindingsShortcut] });
|
|
53784
|
-
}
|
|
53785
|
-
function addExplorerShortcut(server) {
|
|
53786
|
-
if (!process.stdin.isTTY) return;
|
|
53787
53908
|
const openExplorerShortcut = {
|
|
53788
53909
|
key: "e",
|
|
53789
53910
|
description: "open local explorer",
|
|
@@ -53799,22 +53920,38 @@ function addExplorerShortcut(server) {
|
|
|
53799
53920
|
});
|
|
53800
53921
|
}
|
|
53801
53922
|
};
|
|
53802
|
-
const
|
|
53803
|
-
server.bindCLIShortcuts = (options) => {
|
|
53804
|
-
if (server.httpServer && process.stdin.isTTY && !process.env.CI && options?.print) server.config.logger.info(import_picocolors.default.dim(import_picocolors.default.green(" ➜")) + import_picocolors.default.dim(" press ") + import_picocolors.default.bold(`${openExplorerShortcut.key} + enter`) + import_picocolors.default.dim(` to ${openExplorerShortcut.description}`));
|
|
53805
|
-
bindCLIShortcuts(options);
|
|
53806
|
-
};
|
|
53807
|
-
server.bindCLIShortcuts({ customShortcuts: [openExplorerShortcut] });
|
|
53808
|
-
}
|
|
53809
|
-
function addTunnelShortcut(server) {
|
|
53810
|
-
if (!process.stdin.isTTY) return;
|
|
53811
|
-
server.bindCLIShortcuts({ customShortcuts: [{
|
|
53923
|
+
const toggleTunnelShortcut = {
|
|
53812
53924
|
key: "t",
|
|
53925
|
+
description: "start or close tunnel",
|
|
53926
|
+
action: () => {
|
|
53927
|
+
toggleTunnel(server, ctx).catch((error) => {
|
|
53928
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
53929
|
+
server.config.logger.error(import_picocolors.default.red(`Error: ${message}`));
|
|
53930
|
+
});
|
|
53931
|
+
}
|
|
53932
|
+
};
|
|
53933
|
+
const extendTunnelExpiryShortcut = {
|
|
53934
|
+
key: "a",
|
|
53813
53935
|
description: "extend tunnel by 1 hour",
|
|
53814
53936
|
action: () => {
|
|
53815
53937
|
extendTunnelExpiry();
|
|
53816
53938
|
}
|
|
53817
|
-
}
|
|
53939
|
+
};
|
|
53940
|
+
const bindCLIShortcuts = server.bindCLIShortcuts.bind(server);
|
|
53941
|
+
server.bindCLIShortcuts = (options) => {
|
|
53942
|
+
if (server.httpServer && process.stdin.isTTY && !process.env.CI && options?.print) {
|
|
53943
|
+
if (ctx.allWorkerConfigs.length > 0) server.config.logger.info(import_picocolors.default.dim(import_picocolors.default.green(" ➜")) + import_picocolors.default.dim(" press ") + import_picocolors.default.bold(`${printBindingsShortcut.key} + enter`) + import_picocolors.default.dim(` to ${printBindingsShortcut.description}`));
|
|
53944
|
+
server.config.logger.info(import_picocolors.default.dim(import_picocolors.default.green(" ➜")) + import_picocolors.default.dim(" press ") + import_picocolors.default.bold(`${openExplorerShortcut.key} + enter`) + import_picocolors.default.dim(` to ${openExplorerShortcut.description}`));
|
|
53945
|
+
server.config.logger.info(import_picocolors.default.dim(import_picocolors.default.green(" ➜")) + import_picocolors.default.dim(" press ") + import_picocolors.default.bold(`${toggleTunnelShortcut.key} + enter`) + import_picocolors.default.dim(` to ${isTunnelOpen() ? "close tunnel" : "start tunnel"}`));
|
|
53946
|
+
}
|
|
53947
|
+
bindCLIShortcuts(options);
|
|
53948
|
+
};
|
|
53949
|
+
server.bindCLIShortcuts({ customShortcuts: [
|
|
53950
|
+
printBindingsShortcut,
|
|
53951
|
+
openExplorerShortcut,
|
|
53952
|
+
toggleTunnelShortcut,
|
|
53953
|
+
extendTunnelExpiryShortcut
|
|
53954
|
+
] });
|
|
53818
53955
|
}
|
|
53819
53956
|
|
|
53820
53957
|
//#endregion
|