wrangler 4.90.1 → 4.91.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.
@@ -30381,7 +30381,9 @@ function normalizeAndValidateEnvironment(diagnostics, configPath, rawEnv, isDisp
30381
30381
  "Removed",
30382
30382
  "error"
30383
30383
  );
30384
- experimental(diagnostics, rawEnv, "unsafe");
30384
+ if (topLevelEnv === void 0 || rawConfig?.unsafe === void 0) {
30385
+ experimental(diagnostics, rawEnv, "unsafe");
30386
+ }
30385
30387
  const route = normalizeAndValidateRoute(diagnostics, topLevelEnv, rawEnv);
30386
30388
  const account_id = inheritableInWranglerEnvironments(
30387
30389
  diagnostics,
@@ -32262,17 +32264,14 @@ function startTunnel(options) {
32262
32264
  const timeoutMs = options.timeoutMs ?? TUNNEL_STARTUP_TIMEOUT_MS;
32263
32265
  const reminderIntervalMs = options.reminderIntervalMs ?? DEFAULT_TUNNEL_REMINDER_INTERVAL_MS;
32264
32266
  const defaultExpiryMs = options.expiryMs ?? DEFAULT_TUNNEL_EXPIRY_MS;
32267
+ const isNamedTunnel = options.token !== void 0;
32265
32268
  const timeFormatter = new Intl.DateTimeFormat(void 0, {
32266
32269
  timeStyle: "short"
32267
32270
  });
32268
- const cloudflaredArgs = [
32269
- "tunnel",
32270
- "--no-autoupdate",
32271
- "--url",
32272
- options.origin.href
32273
- ];
32271
+ const cloudflaredArgs = isNamedTunnel ? ["tunnel", "--no-autoupdate", "run"] : ["tunnel", "--no-autoupdate", "--url", options.origin.href];
32274
32272
  const cloudflaredPromise = spawnCloudflared(cloudflaredArgs, {
32275
32273
  stdio: "pipe",
32274
+ env: options.token ? { TUNNEL_TOKEN: options.token } : void 0,
32276
32275
  skipVersionCheck: true,
32277
32276
  logger: logger4
32278
32277
  }).then((process22) => {
@@ -32282,15 +32281,20 @@ function startTunnel(options) {
32282
32281
  }
32283
32282
  return process22;
32284
32283
  });
32285
- const readyPromise = cloudflaredPromise.then(
32286
- (process22) => waitForQuickTunnelReady(process22, timeoutMs, {
32284
+ const readyPromise = cloudflaredPromise.then((process22) => {
32285
+ if (isNamedTunnel) {
32286
+ return { mode: "named" };
32287
+ }
32288
+ return waitForQuickTunnelReady(process22, timeoutMs, {
32287
32289
  logger: logger4,
32288
32290
  origin: options.origin
32289
- })
32290
- ).then((result) => {
32291
+ });
32292
+ }).then((result) => {
32291
32293
  expiresAt = Date.now() + defaultExpiryMs;
32292
32294
  scheduleExpiryTimeout();
32293
- scheduleReminder(result.publicUrl.origin);
32295
+ scheduleReminder(
32296
+ result.mode === "quick" ? result.publicUrl.origin : void 0
32297
+ );
32294
32298
  return result;
32295
32299
  });
32296
32300
  function disposeTunnel() {
@@ -32325,7 +32329,7 @@ function startTunnel(options) {
32325
32329
  return;
32326
32330
  }
32327
32331
  logger4?.log(
32328
- `The tunnel is still open at ${publicURL}. It expires in ${formatTunnelDuration(remainingMs)}. ${options.extendHint ?? ""}`
32332
+ `${publicURL ? `The tunnel is still open at ${publicURL}.` : "The tunnel is still open."} It expires in ${formatTunnelDuration(remainingMs)}. ${options.extendHint ?? ""}`
32329
32333
  );
32330
32334
  }, reminderIntervalMs);
32331
32335
  reminderInterval.unref?.();
@@ -32381,6 +32385,7 @@ function startTunnel(options) {
32381
32385
  __name2(extendExpiry, "extendExpiry");
32382
32386
  return {
32383
32387
  ready: /* @__PURE__ */ __name2(() => readyPromise, "ready"),
32388
+ isOpen: /* @__PURE__ */ __name2(() => !disposed, "isOpen"),
32384
32389
  dispose: disposeTunnel,
32385
32390
  extendExpiry
32386
32391
  };
@@ -32439,7 +32444,7 @@ function waitForQuickTunnelReady(cloudflared, timeoutMs, options) {
32439
32444
  if (match3 && !resolved) {
32440
32445
  resolved = true;
32441
32446
  clearTimeout(timeoutId);
32442
- resolve32({ publicUrl: new URL(match3[0]) });
32447
+ resolve32({ mode: "quick", publicUrl: new URL(match3[0]) });
32443
32448
  }
32444
32449
  });
32445
32450
  }
@@ -38028,14 +38033,16 @@ var init_dist = __esm({
38028
38033
  if (configDefines.length > 0) {
38029
38034
  if (typeof value === "object" && value !== null) {
38030
38035
  const configEnvDefines = config === void 0 ? [] : Object.keys(value);
38031
- for (const varName of configDefines) {
38032
- if (!(varName in value)) {
38033
- diagnostics.warnings.push(
38034
- `"define.${varName}" exists at the top level, but not on "${fieldPath}".
38035
- This is not what you probably want, since "define" configuration is not inherited by environments.
38036
- Please add "define.${varName}" to "env.${envName}".`
38037
- );
38038
- }
38036
+ const missingDefines = configDefines.filter(
38037
+ (varName) => !(varName in value)
38038
+ );
38039
+ if (missingDefines.length > 0) {
38040
+ diagnostics.warnings.push(
38041
+ `The following define entries exist at the top level, but not on "${fieldPath}".
38042
+ This is probably not what you want, since "define" configuration is not inherited by environments.
38043
+ Please add these entries to "env.${envName}.define":
38044
+ ` + missingDefines.map((varName) => `- ${varName}`).join("\n")
38045
+ );
38039
38046
  }
38040
38047
  for (const varName of configEnvDefines) {
38041
38048
  if (!configDefines.includes(varName)) {
@@ -38076,14 +38083,14 @@ Please remove "${fieldPath}.${varName}", or add "define.${varName}".`
38076
38083
  const configVars = Object.keys(config?.vars ?? {});
38077
38084
  if (configVars.length > 0) {
38078
38085
  if (typeof value === "object" && value !== null) {
38079
- for (const varName of configVars) {
38080
- if (!(varName in value)) {
38081
- diagnostics.warnings.push(
38082
- `"vars.${varName}" exists at the top level, but not on "${fieldPath}".
38083
- This is not what you probably want, since "vars" configuration is not inherited by environments.
38084
- Please add "vars.${varName}" to "env.${envName}".`
38085
- );
38086
- }
38086
+ const missingVars = configVars.filter((varName) => !(varName in value));
38087
+ if (missingVars.length > 0) {
38088
+ diagnostics.warnings.push(
38089
+ `The following vars exist at the top level, but not on "${fieldPath}".
38090
+ This is probably not what you want, since "vars" configuration is not inherited by environments.
38091
+ Please add these vars to "env.${envName}.vars":
38092
+ ` + missingVars.map((varName) => `- ${varName}`).join("\n")
38093
+ );
38087
38094
  }
38088
38095
  }
38089
38096
  }
@@ -46851,18 +46858,18 @@ var require_async = __commonJS({
46851
46858
  ];
46852
46859
  }, "defaultPaths");
46853
46860
  var defaultIsFile = /* @__PURE__ */ __name(function isFile2(file3, cb2) {
46854
- fs33.stat(file3, function(err, stat9) {
46861
+ fs33.stat(file3, function(err, stat10) {
46855
46862
  if (!err) {
46856
- return cb2(null, stat9.isFile() || stat9.isFIFO());
46863
+ return cb2(null, stat10.isFile() || stat10.isFIFO());
46857
46864
  }
46858
46865
  if (err.code === "ENOENT" || err.code === "ENOTDIR") return cb2(null, false);
46859
46866
  return cb2(err);
46860
46867
  });
46861
46868
  }, "isFile");
46862
46869
  var defaultIsDir = /* @__PURE__ */ __name(function isDirectory3(dir2, cb2) {
46863
- fs33.stat(dir2, function(err, stat9) {
46870
+ fs33.stat(dir2, function(err, stat10) {
46864
46871
  if (!err) {
46865
- return cb2(null, stat9.isDirectory());
46872
+ return cb2(null, stat10.isDirectory());
46866
46873
  }
46867
46874
  if (err.code === "ENOENT" || err.code === "ENOTDIR") return cb2(null, false);
46868
46875
  return cb2(err);
@@ -47353,21 +47360,21 @@ var require_sync = __commonJS({
47353
47360
  }, "defaultPaths");
47354
47361
  var defaultIsFile = /* @__PURE__ */ __name(function isFile2(file3) {
47355
47362
  try {
47356
- var stat9 = fs33.statSync(file3, { throwIfNoEntry: false });
47363
+ var stat10 = fs33.statSync(file3, { throwIfNoEntry: false });
47357
47364
  } catch (e10) {
47358
47365
  if (e10 && (e10.code === "ENOENT" || e10.code === "ENOTDIR")) return false;
47359
47366
  throw e10;
47360
47367
  }
47361
- return !!stat9 && (stat9.isFile() || stat9.isFIFO());
47368
+ return !!stat10 && (stat10.isFile() || stat10.isFIFO());
47362
47369
  }, "isFile");
47363
47370
  var defaultIsDir = /* @__PURE__ */ __name(function isDirectory3(dir2) {
47364
47371
  try {
47365
- var stat9 = fs33.statSync(dir2, { throwIfNoEntry: false });
47372
+ var stat10 = fs33.statSync(dir2, { throwIfNoEntry: false });
47366
47373
  } catch (e10) {
47367
47374
  if (e10 && (e10.code === "ENOENT" || e10.code === "ENOTDIR")) return false;
47368
47375
  throw e10;
47369
47376
  }
47370
- return !!stat9 && stat9.isDirectory();
47377
+ return !!stat10 && stat10.isDirectory();
47371
47378
  }, "isDirectory");
47372
47379
  var defaultRealpathSync = /* @__PURE__ */ __name(function realpathSync4(x6) {
47373
47380
  try {
@@ -49650,7 +49657,40 @@ function getDebugFilepath() {
49650
49657
  const filepath = dir2.endsWith(".log") ? dir2 : path3__namespace.default.join(dir2, `wrangler-${date}.log`);
49651
49658
  return path3__namespace.default.resolve(filepath);
49652
49659
  }
49660
+ async function cleanupOldLogFiles(logsDir) {
49661
+ if (!fs29.existsSync(logsDir)) {
49662
+ return;
49663
+ }
49664
+ const maxAgeDays = 30;
49665
+ const cutoffMs = maxAgeDays * 24 * 60 * 60 * 1e3;
49666
+ try {
49667
+ const files = await fs9.readdir(logsDir);
49668
+ const now = Date.now();
49669
+ for (const f7 of files.filter(
49670
+ (filename) => filename.startsWith("wrangler-") && filename.endsWith(".log")
49671
+ )) {
49672
+ const filePath = path3__namespace.default.join(logsDir, f7);
49673
+ try {
49674
+ const fileStat = await fs9.stat(filePath);
49675
+ if (now - fileStat.mtimeMs > cutoffMs) {
49676
+ await fs9.unlink(filePath);
49677
+ }
49678
+ } catch {
49679
+ }
49680
+ }
49681
+ } catch {
49682
+ }
49683
+ }
49684
+ function tryCleanupLogs() {
49685
+ const debugFileDir = getDebugFileDir();
49686
+ if (hasStartedLogCleanup || debugFileDir.endsWith(".log")) {
49687
+ return;
49688
+ }
49689
+ hasStartedLogCleanup = true;
49690
+ void cleanupOldLogFiles(debugFileDir);
49691
+ }
49653
49692
  async function appendToDebugLogFile(messageLevel, message) {
49693
+ tryCleanupLogs();
49654
49694
  const entry = `
49655
49695
  --- ${(/* @__PURE__ */ new Date()).toISOString()} ${messageLevel}
49656
49696
  ${util4.stripVTControlCharacters(message)}
@@ -49684,7 +49724,7 @@ ${util4.stripVTControlCharacters(message)}
49684
49724
  }
49685
49725
  });
49686
49726
  }
49687
- var import_signal_exit, getDebugFileDir, debugLogFilepath, mutex, hasLoggedLocation, hasLoggedError, hasSeenErrorMessage;
49727
+ var import_signal_exit, getDebugFileDir, debugLogFilepath, mutex, hasStartedLogCleanup, hasLoggedLocation, hasLoggedError, hasSeenErrorMessage;
49688
49728
  var init_log_file = __esm({
49689
49729
  "src/utils/log-file.ts"() {
49690
49730
  init_import_meta_url();
@@ -49700,8 +49740,11 @@ var init_log_file = __esm({
49700
49740
  }
49701
49741
  });
49702
49742
  __name(getDebugFilepath, "getDebugFilepath");
49743
+ __name(cleanupOldLogFiles, "cleanupOldLogFiles");
49703
49744
  debugLogFilepath = getDebugFilepath();
49704
49745
  mutex = new miniflare.Mutex();
49746
+ hasStartedLogCleanup = false;
49747
+ __name(tryCleanupLogs, "tryCleanupLogs");
49705
49748
  hasLoggedLocation = false;
49706
49749
  hasLoggedError = false;
49707
49750
  hasSeenErrorMessage = false;
@@ -49723,6 +49766,13 @@ function getLoggerLevel() {
49723
49766
  }
49724
49767
  return "log";
49725
49768
  }
49769
+ function shouldLogToDisk(isTestEnvironment = typeof vitest !== "undefined") {
49770
+ if (isTestEnvironment) {
49771
+ return false;
49772
+ }
49773
+ const setting = process.env.WRANGLER_WRITE_LOGS?.toLowerCase();
49774
+ return setting !== "false" && setting !== "0";
49775
+ }
49726
49776
  function consoleMethodToLoggerLevel(method) {
49727
49777
  if (method in LOGGER_LEVELS) {
49728
49778
  return method;
@@ -49776,6 +49826,7 @@ var init_logger = __esm({
49776
49826
  __name(getLoggerLevel, "getLoggerLevel");
49777
49827
  overrideLoggerLevel = new async_hooks.AsyncLocalStorage();
49778
49828
  runWithLogLevel = /* @__PURE__ */ __name((overrideLogLevel, cb2) => overrideLoggerLevel.run({ logLevel: overrideLogLevel }, cb2), "runWithLogLevel");
49829
+ __name(shouldLogToDisk, "shouldLogToDisk");
49779
49830
  __name(consoleMethodToLoggerLevel, "consoleMethodToLoggerLevel");
49780
49831
  Logger = class _Logger {
49781
49832
  static {
@@ -49865,8 +49916,7 @@ var init_logger = __esm({
49865
49916
  }
49866
49917
  doLog(messageLevel, args) {
49867
49918
  const message = Array.isArray(args) ? this.formatMessage(messageLevel, util4.format(...args)) : args;
49868
- const inUnitTests = typeof vitest !== "undefined";
49869
- if (!inUnitTests) {
49919
+ if (shouldLogToDisk()) {
49870
49920
  void appendToDebugLogFile(messageLevel, message);
49871
49921
  }
49872
49922
  if (LOGGER_LEVELS[this.loggerLevel] >= LOGGER_LEVELS[messageLevel]) {
@@ -53968,16 +54018,16 @@ var require_windows = __commonJS({
53968
54018
  return false;
53969
54019
  }
53970
54020
  __name(checkPathExt, "checkPathExt");
53971
- function checkStat(stat9, path85, options) {
53972
- if (!stat9.isSymbolicLink() && !stat9.isFile()) {
54021
+ function checkStat(stat10, path85, options) {
54022
+ if (!stat10.isSymbolicLink() && !stat10.isFile()) {
53973
54023
  return false;
53974
54024
  }
53975
54025
  return checkPathExt(path85, options);
53976
54026
  }
53977
54027
  __name(checkStat, "checkStat");
53978
54028
  function isexe(path85, options, cb2) {
53979
- fs33.stat(path85, function(er2, stat9) {
53980
- cb2(er2, er2 ? false : checkStat(stat9, path85, options));
54029
+ fs33.stat(path85, function(er2, stat10) {
54030
+ cb2(er2, er2 ? false : checkStat(stat10, path85, options));
53981
54031
  });
53982
54032
  }
53983
54033
  __name(isexe, "isexe");
@@ -53996,8 +54046,8 @@ var require_mode = __commonJS({
53996
54046
  isexe.sync = sync;
53997
54047
  var fs33 = __require("fs");
53998
54048
  function isexe(path85, options, cb2) {
53999
- fs33.stat(path85, function(er2, stat9) {
54000
- cb2(er2, er2 ? false : checkStat(stat9, options));
54049
+ fs33.stat(path85, function(er2, stat10) {
54050
+ cb2(er2, er2 ? false : checkStat(stat10, options));
54001
54051
  });
54002
54052
  }
54003
54053
  __name(isexe, "isexe");
@@ -54005,14 +54055,14 @@ var require_mode = __commonJS({
54005
54055
  return checkStat(fs33.statSync(path85), options);
54006
54056
  }
54007
54057
  __name(sync, "sync");
54008
- function checkStat(stat9, options) {
54009
- return stat9.isFile() && checkMode(stat9, options);
54058
+ function checkStat(stat10, options) {
54059
+ return stat10.isFile() && checkMode(stat10, options);
54010
54060
  }
54011
54061
  __name(checkStat, "checkStat");
54012
- function checkMode(stat9, options) {
54013
- var mod = stat9.mode;
54014
- var uid = stat9.uid;
54015
- var gid = stat9.gid;
54062
+ function checkMode(stat10, options) {
54063
+ var mod = stat10.mode;
54064
+ var uid = stat10.uid;
54065
+ var gid = stat10.gid;
54016
54066
  var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
54017
54067
  var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
54018
54068
  var u8 = parseInt("100", 8);
@@ -55818,7 +55868,7 @@ var name, version;
55818
55868
  var init_package = __esm({
55819
55869
  "package.json"() {
55820
55870
  name = "wrangler";
55821
- version = "4.90.1";
55871
+ version = "4.91.0";
55822
55872
  }
55823
55873
  });
55824
55874
  function getWranglerVersion() {
@@ -135822,8 +135872,8 @@ var init_esm6 = __esm({
135822
135872
  }
135823
135873
  return this._userIgnored(path85, stats);
135824
135874
  }
135825
- _isntIgnored(path85, stat9) {
135826
- return !this._isIgnored(path85, stat9);
135875
+ _isntIgnored(path85, stat10) {
135876
+ return !this._isIgnored(path85, stat10);
135827
135877
  }
135828
135878
  /**
135829
135879
  * Provides a set of common helpers and properties relating to symlink handling.
@@ -139547,7 +139597,8 @@ function getInstanceTypeUsage(instanceType) {
139547
139597
  function inferInstanceType(config) {
139548
139598
  for (const [instanceType, configuration] of Object.entries(instanceTypes)) {
139549
139599
  if (config.vcpu === configuration.vcpu && config.memory_mib === configuration.memory_mib && config.disk?.size_mb === configuration.disk_mb) {
139550
- return instanceType;
139600
+ const canonical = instanceType in LEGACY_TO_CANONICAL ? LEGACY_TO_CANONICAL[instanceType] : void 0;
139601
+ return canonical ?? instanceType;
139551
139602
  }
139552
139603
  }
139553
139604
  }
@@ -139565,11 +139616,12 @@ function cleanForInstanceType(app) {
139565
139616
  delete app.configuration.vcpu;
139566
139617
  return app;
139567
139618
  }
139568
- var instanceTypes, instanceTypeNames;
139619
+ var instanceTypes, instanceTypeNames, LEGACY_TO_CANONICAL;
139569
139620
  var init_instance_type = __esm({
139570
139621
  "src/cloudchamber/instance-type/instance-type.ts"() {
139571
139622
  init_import_meta_url();
139572
139623
  init_interactive();
139624
+ init_containers_shared();
139573
139625
  init_dist();
139574
139626
  instanceTypes = {
139575
139627
  // lite is the default instance type when REQUIRE_INSTANCE_TYPE is set
@@ -139618,6 +139670,10 @@ var init_instance_type = __esm({
139618
139670
  __name(promptForInstanceType, "promptForInstanceType");
139619
139671
  __name(checkInstanceType, "checkInstanceType");
139620
139672
  __name(getInstanceTypeUsage, "getInstanceTypeUsage");
139673
+ LEGACY_TO_CANONICAL = {
139674
+ dev: "lite" /* LITE */,
139675
+ standard: "standard-1" /* STANDARD_1 */
139676
+ };
139621
139677
  __name(inferInstanceType, "inferInstanceType");
139622
139678
  __name(cleanForInstanceType, "cleanForInstanceType");
139623
139679
  }
@@ -179982,8 +180038,8 @@ function getLayerRoutePathString(isArray, lrp) {
179982
180038
  return lrp && lrp.toString();
179983
180039
  }
179984
180040
  function preventDuplicateSegments(originalUrl, reconstructedRoute, layerPath) {
179985
- const normalizeURL = stripUrlQueryAndFragment(originalUrl || "");
179986
- const originalUrlSplit = _optionalChain([normalizeURL, "optionalAccess", (_14) => _14.split, "call", (_15) => _15("/"), "access", (_16) => _16.filter, "call", (_17) => _17((v7) => !!v7)]);
180041
+ const normalizeURL2 = stripUrlQueryAndFragment(originalUrl || "");
180042
+ const originalUrlSplit = _optionalChain([normalizeURL2, "optionalAccess", (_14) => _14.split, "call", (_15) => _15("/"), "access", (_16) => _16.filter, "call", (_17) => _17((v7) => !!v7)]);
179987
180043
  let tempCounter = 0;
179988
180044
  const currentOffset = _optionalChain([reconstructedRoute, "optionalAccess", (_18) => _18.split, "call", (_19) => _19("/"), "access", (_20) => _20.filter, "call", (_21) => _21((v7) => !!v7), "access", (_22) => _22.length]) || 0;
179989
180045
  const result = _optionalChain([
@@ -233995,8 +234051,8 @@ async function locatePath(paths, {
233995
234051
  const statFunction = allowSymlinks ? fs29.promises.stat : fs29.promises.lstat;
233996
234052
  return pLocate(paths, async (path_) => {
233997
234053
  try {
233998
- const stat9 = await statFunction(path3__namespace.default.resolve(cwd2, path_));
233999
- return matchType(type, stat9);
234054
+ const stat10 = await statFunction(path3__namespace.default.resolve(cwd2, path_));
234055
+ return matchType(type, stat10);
234000
234056
  } catch {
234001
234057
  return false;
234002
234058
  }
@@ -234012,7 +234068,7 @@ var init_locate_path = __esm({
234012
234068
  file: "isFile"
234013
234069
  };
234014
234070
  __name(checkType, "checkType");
234015
- matchType = /* @__PURE__ */ __name((type, stat9) => stat9[typeMappings[type]](), "matchType");
234071
+ matchType = /* @__PURE__ */ __name((type, stat10) => stat10[typeMappings[type]](), "matchType");
234016
234072
  toPath = /* @__PURE__ */ __name((urlOrPath) => urlOrPath instanceof URL ? Url.fileURLToPath(urlOrPath) : urlOrPath, "toPath");
234017
234073
  __name(locatePath, "locatePath");
234018
234074
  }
@@ -247848,6 +247904,7 @@ ${JSON.stringify(defaultRoutesJSONSpec, null, 2)}`
247848
247904
  tsconfig: void 0,
247849
247905
  minify: void 0,
247850
247906
  legacyEnv: void 0,
247907
+ tunnelName: void 0,
247851
247908
  env: void 0,
247852
247909
  envFile: void 0,
247853
247910
  ip,
@@ -285502,6 +285559,8 @@ function getBindingValue(binding) {
285502
285559
  switch (binding.type) {
285503
285560
  case "plain_text":
285504
285561
  return `"${binding.text}"`;
285562
+ case "json":
285563
+ return JSON.stringify(binding.json);
285505
285564
  case "secret_text":
285506
285565
  return "********";
285507
285566
  case "kv_namespace":
@@ -285551,10 +285610,7 @@ function extractConfigBindings(config) {
285551
285610
  const env6 = {};
285552
285611
  const vars = previews?.vars ?? {};
285553
285612
  for (const [name2, value] of Object.entries(vars)) {
285554
- env6[name2] = {
285555
- type: "plain_text",
285556
- text: typeof value === "string" ? value : JSON.stringify(value)
285557
- };
285613
+ env6[name2] = typeof value === "string" ? { type: "plain_text", text: value } : { type: "json", json: value };
285558
285614
  }
285559
285615
  for (const kv of previews?.kv_namespaces ?? []) {
285560
285616
  env6[kv.binding] = { type: "kv_namespace", namespace_id: kv.id };
@@ -285570,10 +285626,14 @@ function extractConfigBindings(config) {
285570
285626
  env6[r22.binding] = { type: "r2_bucket", bucket_name: r22.bucket_name };
285571
285627
  }
285572
285628
  for (const service of previews?.services ?? []) {
285629
+ const crossAccountGrant = service.cross_account_grant;
285573
285630
  env6[service.binding] = {
285574
285631
  type: "service",
285575
285632
  service: service.service,
285576
- entrypoint: service.entrypoint
285633
+ entrypoint: service.entrypoint,
285634
+ ...crossAccountGrant !== void 0 && {
285635
+ cross_account_grant: crossAccountGrant
285636
+ }
285577
285637
  };
285578
285638
  }
285579
285639
  for (const doBinding of previews?.durable_objects?.bindings ?? []) {
@@ -285700,6 +285760,10 @@ function extractConfigBindings(config) {
285700
285760
  if (config.assets?.binding) {
285701
285761
  env6[config.assets.binding] = { type: "assets" };
285702
285762
  }
285763
+ for (const binding of previews?.unsafe?.bindings ?? []) {
285764
+ const { name: name2, type, ...rest } = binding;
285765
+ env6[name2] = { type, ...rest };
285766
+ }
285703
285767
  return env6;
285704
285768
  }
285705
285769
  function assemblePreviewScriptSettings(config) {
@@ -294061,13 +294125,13 @@ function validateBulkPutFile(filename) {
294061
294125
  telemetryMessage: "r2 object bulk put entry file not found"
294062
294126
  });
294063
294127
  }
294064
- const stat9 = fs29__namespace.default.statSync(entry.file, { throwIfNoEntry: false });
294065
- if (!stat9?.isFile()) {
294128
+ const stat10 = fs29__namespace.default.statSync(entry.file, { throwIfNoEntry: false });
294129
+ if (!stat10?.isFile()) {
294066
294130
  throw new UserError(`The path "${entry.file}" is not a file.`, {
294067
294131
  telemetryMessage: "r2 object bulk put entry path not file"
294068
294132
  });
294069
294133
  }
294070
- if (stat9.size > MAX_UPLOAD_SIZE_BYTES) {
294134
+ if (stat10.size > MAX_UPLOAD_SIZE_BYTES) {
294071
294135
  throw new UserError(
294072
294136
  `The file "${entry.file}" exceeds the maximum upload size of ${prettyBytes(
294073
294137
  MAX_UPLOAD_SIZE_BYTES,
@@ -294076,7 +294140,7 @@ function validateBulkPutFile(filename) {
294076
294140
  { telemetryMessage: "r2 object bulk put entry file too large" }
294077
294141
  );
294078
294142
  }
294079
- entry.size = stat9.size;
294143
+ entry.size = stat10.size;
294080
294144
  }
294081
294145
  return entries2;
294082
294146
  }
@@ -296860,6 +296924,119 @@ async function getTunnelToken(sdk, accountId, tunnelId) {
296860
296924
  return String(response);
296861
296925
  });
296862
296926
  }
296927
+ async function resolveNamedTunnel(name2, origin, options) {
296928
+ let accountId = options.accountId;
296929
+ if (!accountId) {
296930
+ accountId = await requireAuth({
296931
+ account_id: options.accountId,
296932
+ compliance_region: options.complianceRegion
296933
+ });
296934
+ }
296935
+ const sdk = createCloudflareClient({
296936
+ compliance_region: options.complianceRegion
296937
+ });
296938
+ const tunnel = await withTunnelErrorHandling(async () => {
296939
+ for await (const item of sdk.zeroTrust.tunnels.cloudflared.list({
296940
+ account_id: accountId,
296941
+ name: name2,
296942
+ is_deleted: false
296943
+ })) {
296944
+ if (item.name === name2) {
296945
+ return normalizeTunnelResponse(item);
296946
+ }
296947
+ }
296948
+ return null;
296949
+ });
296950
+ if (!tunnel) {
296951
+ throw new UserError(
296952
+ `No Cloudflare Tunnel named "${name2}" was found in this account. Use "wrangler tunnel list" to see available tunnels.`,
296953
+ { telemetryMessage: "tunnel resolve named missing tunnel" }
296954
+ );
296955
+ }
296956
+ const tunnelId = tunnel.id;
296957
+ if (!tunnelId) {
296958
+ throw new FatalError(
296959
+ `Tunnel "${name2}" was found but has no ID. This is unexpected.`,
296960
+ { telemetryMessage: "tunnel resolve named missing tunnel id" }
296961
+ );
296962
+ }
296963
+ const configuration = await withTunnelErrorHandling(
296964
+ () => sdk.zeroTrust.tunnels.cloudflared.configurations.get(tunnelId, {
296965
+ account_id: accountId
296966
+ })
296967
+ );
296968
+ const hostnames = getMatchingIngressHostnames(
296969
+ origin,
296970
+ configuration.config?.ingress ?? []
296971
+ );
296972
+ if (hostnames.length === 0) {
296973
+ throw new UserError(
296974
+ createMissingIngressMessage(
296975
+ name2,
296976
+ origin,
296977
+ `https://dash.cloudflare.com/${accountId}/tunnels/${tunnelId}`,
296978
+ configuration.config?.ingress ?? []
296979
+ ),
296980
+ { telemetryMessage: "tunnel resolve named ingress mismatch" }
296981
+ );
296982
+ }
296983
+ const token = await getTunnelToken(sdk, accountId, tunnelId);
296984
+ return { hostnames, token };
296985
+ }
296986
+ function getMatchingIngressHostnames(origin, ingressConfig) {
296987
+ const hostnames = /* @__PURE__ */ new Set();
296988
+ const originUrl = normalizeURL(origin);
296989
+ for (const ingress of ingressConfig) {
296990
+ try {
296991
+ const serviceUrl = normalizeURL(ingress.service);
296992
+ if (ingress.hostname && serviceUrl.toString() === originUrl.toString()) {
296993
+ hostnames.add(ingress.hostname);
296994
+ }
296995
+ } catch {
296996
+ }
296997
+ }
296998
+ return [...hostnames];
296999
+ }
297000
+ function normalizeURL(url4) {
297001
+ const normalizedUrl = new URL(url4);
297002
+ if (LOCAL_TUNNEL_HOSTNAMES.has(normalizedUrl.hostname)) {
297003
+ normalizedUrl.hostname = "localhost";
297004
+ }
297005
+ if (!normalizedUrl.port) {
297006
+ switch (normalizedUrl.protocol) {
297007
+ case "http:":
297008
+ normalizedUrl.port = "80";
297009
+ break;
297010
+ case "https:":
297011
+ normalizedUrl.port = "443";
297012
+ break;
297013
+ }
297014
+ }
297015
+ return normalizedUrl;
297016
+ }
297017
+ function createMissingIngressMessage(name2, origin, dashboardUrl, ingress) {
297018
+ if (ingress.length === 0) {
297019
+ return [
297020
+ `Tunnel "${name2}" has no routes configured.`,
297021
+ "",
297022
+ `Add a route for ${origin} in the Cloudflare dashboard:`,
297023
+ dashboardUrl,
297024
+ ""
297025
+ ].join("\n");
297026
+ }
297027
+ return [
297028
+ `Tunnel "${name2}" has no route for ${origin}`,
297029
+ "",
297030
+ "Resolved routes:",
297031
+ ...ingress.map(
297032
+ ({ hostname: hostname2, service }) => ` - ${hostname2 ?? "(no hostname)"} -> ${service}`
297033
+ ),
297034
+ "",
297035
+ "Update your local server settings or the tunnel routes in the Cloudflare dashboard:",
297036
+ dashboardUrl,
297037
+ ""
297038
+ ].join("\n");
297039
+ }
296863
297040
  function normalizeTunnelResponse(response) {
296864
297041
  return response;
296865
297042
  }
@@ -296902,12 +297079,21 @@ async function resolveTunnelId(sdk, accountId, input) {
296902
297079
  }
296903
297080
  return tunnelId;
296904
297081
  }
296905
- var TUNNEL_PERMISSION_ERROR_MESSAGE, TUNNEL_ID_REGEX;
297082
+ var LOCAL_TUNNEL_HOSTNAMES, TUNNEL_PERMISSION_ERROR_MESSAGE, TUNNEL_ID_REGEX;
296906
297083
  var init_client12 = __esm({
296907
297084
  "src/tunnel/client.ts"() {
296908
297085
  init_import_meta_url();
296909
297086
  init_dist();
296910
297087
  init_cloudflare();
297088
+ init_internal();
297089
+ init_user3();
297090
+ LOCAL_TUNNEL_HOSTNAMES = /* @__PURE__ */ new Set([
297091
+ "localhost",
297092
+ "127.0.0.1",
297093
+ "::1",
297094
+ "0.0.0.0",
297095
+ "::"
297096
+ ]);
296911
297097
  TUNNEL_PERMISSION_ERROR_MESSAGE = `
296912
297098
  Cloudflare Tunnel commands require API token authentication with tunnel permissions.
296913
297099
 
@@ -296930,6 +297116,10 @@ Then run your tunnel command again.
296930
297116
  __name(listTunnels, "listTunnels");
296931
297117
  __name(deleteTunnel, "deleteTunnel");
296932
297118
  __name(getTunnelToken, "getTunnelToken");
297119
+ __name(resolveNamedTunnel, "resolveNamedTunnel");
297120
+ __name(getMatchingIngressHostnames, "getMatchingIngressHostnames");
297121
+ __name(normalizeURL, "normalizeURL");
297122
+ __name(createMissingIngressMessage, "createMissingIngressMessage");
296933
297123
  __name(normalizeTunnelResponse, "normalizeTunnelResponse");
296934
297124
  TUNNEL_ID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
296935
297125
  __name(isTunnelId, "isTunnelId");
@@ -315072,8 +315262,12 @@ var init_dev2 = __esm({
315072
315262
  type: "boolean"
315073
315263
  },
315074
315264
  tunnel: {
315075
- describe: "Expose your local dev server via a Cloudflare Quick Tunnel (https://try.cloudflare.com)",
315265
+ describe: "Expose your local dev server via a Cloudflare Tunnel. Use `--tunnel` for a Quick Tunnel and `--tunnel-name` with `--tunnel` for a named tunnel.",
315076
315266
  type: "boolean"
315267
+ },
315268
+ "tunnel-name": {
315269
+ describe: "Use an existing named Cloudflare Tunnel when `--tunnel` is enabled.",
315270
+ type: "string"
315077
315271
  }
315078
315272
  },
315079
315273
  async validateArgs(args) {
@@ -317002,7 +317196,7 @@ var init_ProxyController = __esm({
317002
317196
  logger.debug("[ProxyWorker]", ...message.args);
317003
317197
  break;
317004
317198
  case "sseResponseDetected":
317005
- if (this.latestConfig?.dev?.tunnel) {
317199
+ if (this.latestConfig?.dev?.tunnel?.enabled && this.latestConfig.dev.tunnel.name === void 0) {
317006
317200
  logger.once.warn(
317007
317201
  "Quick tunnels do not support Server-Sent Events (SSE). Use a named Cloudflare Tunnel if you need SSE over a public URL."
317008
317202
  );
@@ -319069,6 +319263,13 @@ function cli_hotkeys_default(options, render2 = true) {
319069
319263
  \u2570\u2500\u2500${"\u2500".repeat(maxLineLength)}\u2500\u2500\u256F`;
319070
319264
  }
319071
319265
  __name(formatInstructions, "formatInstructions");
319266
+ function isKeyMatch(input, key) {
319267
+ if (input === key) {
319268
+ return true;
319269
+ }
319270
+ return /^[a-z]$/.test(key) && input === `shift+${key}`;
319271
+ }
319272
+ __name(isKeyMatch, "isKeyMatch");
319072
319273
  const unregisterKeyPress = onKeyPress(async (key) => {
319073
319274
  const entries2 = [];
319074
319275
  if (key.name) {
@@ -319088,7 +319289,7 @@ function cli_hotkeys_default(options, render2 = true) {
319088
319289
  if (unwrapHook(disabled)) {
319089
319290
  continue;
319090
319291
  }
319091
- if (keys.includes(char)) {
319292
+ if (keys.some((registeredKey) => isKeyMatch(char, registeredKey))) {
319092
319293
  try {
319093
319294
  await handler();
319094
319295
  } catch {
@@ -319122,7 +319323,7 @@ var init_cli_hotkeys = __esm({
319122
319323
  }
319123
319324
  });
319124
319325
  function registerDevHotKeys(devEnvs, args, options = {}) {
319125
- const { render: render2 = true, getTunnel: getTunnel2 } = options;
319326
+ const { render: render2 = true, tunnelManager } = options;
319126
319327
  const primaryDevEnv = devEnvs[0];
319127
319328
  const unregisterHotKeys = cli_hotkeys_default(
319128
319329
  [
@@ -319196,7 +319397,7 @@ function registerDevHotKeys(devEnvs, args, options = {}) {
319196
319397
  {
319197
319398
  keys: ["l"],
319198
319399
  // Remote mode is not supported when using tunnels
319199
- disabled: /* @__PURE__ */ __name(() => args.forceLocal || args.tunnel, "disabled"),
319400
+ disabled: /* @__PURE__ */ __name(() => args.forceLocal || !!tunnelManager?.isOpen(), "disabled"),
319200
319401
  handler: /* @__PURE__ */ __name(async () => {
319201
319402
  await primaryDevEnv.config.patch({
319202
319403
  dev: {
@@ -319207,16 +319408,29 @@ function registerDevHotKeys(devEnvs, args, options = {}) {
319207
319408
  }, "handler")
319208
319409
  },
319209
319410
  {
319210
- // We remind users about the tunnel hotkey every 10mins
319211
- // Hiding this hotkey to reduce noise on startup
319212
319411
  keys: ["t"],
319213
- disabled: /* @__PURE__ */ __name(() => !args.tunnel, "disabled"),
319412
+ label: /* @__PURE__ */ __name(() => tunnelManager?.isOpen() ? "close tunnel" : "start tunnel", "label"),
319413
+ disabled: /* @__PURE__ */ __name(() => primaryDevEnv.config.latestConfig?.dev?.remote === true, "disabled"),
319214
319414
  handler: /* @__PURE__ */ __name(async () => {
319215
- const tunnel = getTunnel2?.();
319216
- if (!tunnel) {
319217
- return;
319415
+ try {
319416
+ if (!tunnelManager?.isOpen()) {
319417
+ await tunnelManager?.start(true);
319418
+ return;
319419
+ }
319420
+ await tunnelManager.stop();
319421
+ } catch (error2) {
319422
+ logger.error(
319423
+ error2 instanceof Error ? error2.message : String(error2)
319424
+ );
319218
319425
  }
319219
- tunnel.extendExpiry();
319426
+ }, "handler")
319427
+ },
319428
+ {
319429
+ keys: ["a"],
319430
+ label: "extend tunnel by 1 hour",
319431
+ disabled: /* @__PURE__ */ __name(() => !tunnelManager?.isOpen(), "disabled"),
319432
+ handler: /* @__PURE__ */ __name(async () => {
319433
+ tunnelManager?.getTunnel()?.extendExpiry();
319220
319434
  }, "handler")
319221
319435
  },
319222
319436
  {
@@ -319264,6 +319478,126 @@ var init_hotkeys = __esm({
319264
319478
  __name(registerDevHotKeys, "registerDevHotKeys");
319265
319479
  }
319266
319480
  });
319481
+
319482
+ // src/tunnel/dev.ts
319483
+ var TunnelManager;
319484
+ var init_dev3 = __esm({
319485
+ "src/tunnel/dev.ts"() {
319486
+ init_import_meta_url();
319487
+ init_colors();
319488
+ init_dist();
319489
+ init_source();
319490
+ init_start_dev();
319491
+ init_logger();
319492
+ init_client12();
319493
+ TunnelManager = class {
319494
+ static {
319495
+ __name(this, "TunnelManager");
319496
+ }
319497
+ primaryDevEnv;
319498
+ args;
319499
+ tunnel;
319500
+ constructor(primaryDevEnv, args) {
319501
+ this.primaryDevEnv = primaryDevEnv;
319502
+ this.args = args;
319503
+ }
319504
+ getTunnel() {
319505
+ return this.tunnel;
319506
+ }
319507
+ isOpen() {
319508
+ return this.tunnel !== void 0;
319509
+ }
319510
+ async start(shortcutPressed = false) {
319511
+ if (this.tunnel) {
319512
+ return;
319513
+ }
319514
+ logger.log(dim("\u2394 Starting tunnel (usually takes a few seconds)..."));
319515
+ const origin = this.getTunnelOrigin();
319516
+ const tunnelConfig = this.getCurrentTunnelConfig();
319517
+ const isQuickTunnel = tunnelConfig?.name === void 0;
319518
+ logger.warn(
319519
+ (isQuickTunnel ? source_default.dim("Once connected, this tunnel will be ") + "publicly accessible" : source_default.dim(
319520
+ "Once connected, this tunnel may be reachable from the Internet"
319521
+ )) + source_default.dim(". Anyone who can reach it can:\n") + source_default.dim(
319522
+ "- Call ungated endpoints\n- Trigger logic that uses remote bindings\n- Reach internal services if your Worker proxies requests\n\n" + (isQuickTunnel ? "Consider using a named tunnel with Cloudflare Access to restrict access.\n" : "Consider using Cloudflare Access to restrict access.\n")
319523
+ ) + (shortcutPressed ? "\nPress [t] again to close the tunnel." : "")
319524
+ );
319525
+ const namedTunnel = tunnelConfig?.name !== void 0 ? await resolveNamedTunnel(tunnelConfig.name, origin, {
319526
+ accountId: this.args.accountId,
319527
+ complianceRegion: this.primaryDevEnv.config.latestConfig?.complianceRegion
319528
+ }) : void 0;
319529
+ const nextTunnel = startTunnel({
319530
+ origin,
319531
+ token: namedTunnel?.token,
319532
+ extendHint: "Press [a] to extend by 1 hour.",
319533
+ logger
319534
+ });
319535
+ this.tunnel = nextTunnel;
319536
+ try {
319537
+ const result = await nextTunnel.ready();
319538
+ if (this.tunnel !== nextTunnel) {
319539
+ return;
319540
+ }
319541
+ await this.syncTunnelState(true);
319542
+ this.logTunnelDetails(result, namedTunnel);
319543
+ } catch (error2) {
319544
+ if (this.tunnel === nextTunnel) {
319545
+ this.tunnel = void 0;
319546
+ await this.syncTunnelState(false);
319547
+ }
319548
+ throw error2;
319549
+ }
319550
+ }
319551
+ async stop() {
319552
+ if (!this.tunnel) {
319553
+ return;
319554
+ }
319555
+ logger.log(dim("\u2394 Closing tunnel..."));
319556
+ this.tunnel.dispose();
319557
+ this.tunnel = void 0;
319558
+ await this.syncTunnelState(false);
319559
+ logger.log("\u2B23 Tunnel closed");
319560
+ }
319561
+ getCurrentTunnelConfig() {
319562
+ return this.primaryDevEnv.config.latestConfig?.dev?.tunnel;
319563
+ }
319564
+ getTunnelOrigin() {
319565
+ const config = this.primaryDevEnv.config.latestConfig;
319566
+ const protocol = config?.dev?.server?.secure ? "https" : "http";
319567
+ const hostname2 = config?.dev?.server?.hostname ?? "localhost";
319568
+ const port = config?.dev?.server?.port ?? 8787;
319569
+ return new URL(`${protocol}://${formatHostname(hostname2)}:${port}`);
319570
+ }
319571
+ async syncTunnelState(enabled) {
319572
+ const latestDevConfig = this.primaryDevEnv.config.latestConfig?.dev;
319573
+ if (!latestDevConfig?.tunnel || latestDevConfig.tunnel.enabled === enabled) {
319574
+ return;
319575
+ }
319576
+ await this.primaryDevEnv.config.patch({
319577
+ dev: {
319578
+ ...latestDevConfig,
319579
+ tunnel: {
319580
+ ...latestDevConfig.tunnel,
319581
+ enabled
319582
+ }
319583
+ }
319584
+ });
319585
+ }
319586
+ logTunnelDetails(result, namedTunnel) {
319587
+ const publicUrls = result.mode === "quick" ? [result.publicUrl.toString()] : namedTunnel ? namedTunnel.hostnames.map((hostname2) => `https://${hostname2}`) : [];
319588
+ if (publicUrls.length === 1) {
319589
+ logger.log(
319590
+ `\u2B23 Sharing via Cloudflare Tunnel: ${source_default.green(publicUrls[0])}`
319591
+ );
319592
+ } else if (publicUrls.length > 1) {
319593
+ logger.log(
319594
+ "\u2B23 Sharing via Cloudflare Tunnel:\n" + publicUrls.map((url4) => ` ${source_default.green(url4)}`).join("\n")
319595
+ );
319596
+ }
319597
+ }
319598
+ };
319599
+ }
319600
+ });
319267
319601
  function constructRedirects({
319268
319602
  redirects,
319269
319603
  redirectsFile,
@@ -321545,7 +321879,7 @@ var init_assets6 = __esm({
321545
321879
  });
321546
321880
  async function startDev(args) {
321547
321881
  let devEnv;
321548
- let tunnel;
321882
+ let tunnelManager;
321549
321883
  let unregisterHotKeys;
321550
321884
  try {
321551
321885
  if (args.logLevel) {
@@ -321562,7 +321896,10 @@ async function startDev(args) {
321562
321896
  unregisterHotKeys = registerDevHotKeys(
321563
321897
  Array.isArray(devEnv) ? devEnv : [devEnv],
321564
321898
  args,
321565
- { getTunnel: /* @__PURE__ */ __name(() => tunnel, "getTunnel"), render: false }
321899
+ {
321900
+ tunnelManager,
321901
+ render: false
321902
+ }
321566
321903
  );
321567
321904
  }
321568
321905
  }
@@ -321610,21 +321947,19 @@ async function startDev(args) {
321610
321947
  })
321611
321948
  )
321612
321949
  );
321613
- if (isInteractive3() && args.showInteractiveDevSession !== false) {
321614
- unregisterHotKeys = registerDevHotKeys(devEnv, args, {
321615
- getTunnel: /* @__PURE__ */ __name(() => tunnel, "getTunnel")
321616
- });
321617
- }
321618
321950
  } else {
321619
321951
  devEnv = new exports.unstable_DevEnv();
321620
321952
  await setupDevEnv(devEnv, args.config, authHook, args);
321621
- if (isInteractive3() && args.showInteractiveDevSession !== false) {
321622
- unregisterHotKeys = registerDevHotKeys([devEnv], args, {
321623
- getTunnel: /* @__PURE__ */ __name(() => tunnel, "getTunnel")
321624
- });
321625
- }
321626
321953
  }
321627
- const [primaryDevEnv, ...secondary] = Array.isArray(devEnv) ? devEnv : [devEnv];
321954
+ const devEnvs = Array.isArray(devEnv) ? devEnv : [devEnv];
321955
+ const [primaryDevEnv, ...secondary] = devEnvs;
321956
+ tunnelManager = new TunnelManager(primaryDevEnv, args);
321957
+ primaryDevEnv.on("teardown", () => {
321958
+ tunnelManager?.getTunnel()?.dispose();
321959
+ });
321960
+ if (isInteractive3() && args.showInteractiveDevSession !== false) {
321961
+ unregisterHotKeys = registerDevHotKeys(devEnvs, args, { tunnelManager });
321962
+ }
321628
321963
  void primaryDevEnv.proxy.ready.promise.then(({ url: url4 }) => {
321629
321964
  if (args.onReady) {
321630
321965
  args.onReady(url4.hostname, parseInt(url4.port));
@@ -321645,32 +321980,7 @@ async function startDev(args) {
321645
321980
  maybePrintScheduledWorkerWarning(hasCrons, !!args.testScheduled, url4);
321646
321981
  });
321647
321982
  if (args.tunnel) {
321648
- const config = primaryDevEnv.config.latestConfig;
321649
- const protocol = config?.dev?.server?.secure ? "https" : "http";
321650
- const hostname2 = config?.dev?.server?.hostname ?? "localhost";
321651
- const port = config?.dev?.server?.port ?? 8787;
321652
- const origin = new URL(
321653
- `${protocol}://${formatHostname(hostname2)}:${port}`
321654
- );
321655
- logger.log(dim("\u2394 Starting tunnel (usually takes a few seconds)..."));
321656
- tunnel = startTunnel({
321657
- origin,
321658
- extendHint: "Press [t] to extend by 1 hour.",
321659
- logger
321660
- });
321661
- primaryDevEnv.on("teardown", () => {
321662
- tunnel?.dispose();
321663
- });
321664
- const { publicUrl } = await tunnel.ready();
321665
- logger.log(
321666
- `\u2B23 Sharing via Cloudflare Tunnel: ${source_default.green(publicUrl.origin)}
321667
- `
321668
- );
321669
- logger.warn(
321670
- source_default.dim("This URL is ") + "publicly accessible" + source_default.dim(". Anyone with it can:\n") + source_default.dim(
321671
- "- Call ungated endpoints\n- Trigger logic that uses remote bindings\n- Reach internal services if your Worker proxies requests\n\nConsider using a named tunnel with Cloudflare Access to restrict access."
321672
- )
321673
- );
321983
+ await tunnelManager.start();
321674
321984
  }
321675
321985
  return {
321676
321986
  devEnv: primaryDevEnv,
@@ -321684,7 +321994,7 @@ async function startDev(args) {
321684
321994
  unregisterHotKeys?.();
321685
321995
  })(),
321686
321996
  (async () => {
321687
- tunnel?.dispose();
321997
+ tunnelManager?.getTunnel()?.dispose();
321688
321998
  })()
321689
321999
  ]);
321690
322000
  throw e10;
@@ -321763,7 +322073,10 @@ async function setupDevEnv(devEnv, configPath, auth, args) {
321763
322073
  // initialise with a random id
321764
322074
  containerBuildId: generateContainerBuildId(),
321765
322075
  generateTypes: args.types,
321766
- tunnel: args.tunnel
322076
+ tunnel: {
322077
+ enabled: args.tunnel ?? false,
322078
+ name: args.tunnelName
322079
+ }
321767
322080
  },
321768
322081
  legacy: {
321769
322082
  site: /* @__PURE__ */ __name((configParam) => {
@@ -321832,7 +322145,6 @@ var init_start_dev = __esm({
321832
322145
  init_colors();
321833
322146
  init_containers_shared();
321834
322147
  init_dist();
321835
- init_source();
321836
322148
  init_esm2();
321837
322149
  init_api4();
321838
322150
  init_MultiworkerRuntimeController();
@@ -321843,6 +322155,7 @@ var init_start_dev = __esm({
321843
322155
  init_is_interactive();
321844
322156
  init_logger();
321845
322157
  init_sites2();
322158
+ init_dev3();
321846
322159
  init_user3();
321847
322160
  init_collectKeyValues();
321848
322161
  __name(startDev, "startDev");
@@ -321967,7 +322280,8 @@ unstable_dev()'s behaviour will likely change in future releases`
321967
322280
  dockerPath,
321968
322281
  containerEngine: options?.experimental?.containerEngine,
321969
322282
  types: false,
321970
- tunnel: void 0
322283
+ tunnel: void 0,
322284
+ tunnelName: void 0
321971
322285
  };
321972
322286
  const devServer = await run(
321973
322287
  {
@@ -322013,7 +322327,7 @@ function parseRequestInput(readyAddress, readyPort, input = "/", init4, protocol
322013
322327
  return [url4, forward];
322014
322328
  }
322015
322329
  var import_undici31;
322016
- var init_dev3 = __esm({
322330
+ var init_dev4 = __esm({
322017
322331
  "src/api/dev.ts"() {
322018
322332
  init_import_meta_url();
322019
322333
  init_dist();
@@ -322372,7 +322686,7 @@ var init_integrations6 = __esm({
322372
322686
  var init_api4 = __esm({
322373
322687
  "src/api/index.ts"() {
322374
322688
  init_import_meta_url();
322375
- init_dev3();
322689
+ init_dev4();
322376
322690
  init_pages4();
322377
322691
  init_generate_types();
322378
322692
  init_mtls_certificate();
@@ -322489,6 +322803,7 @@ init_esm();
322489
322803
  init_api4();
322490
322804
  init_src3();
322491
322805
  init_print_bindings();
322806
+ init_client12();
322492
322807
  init_splitter();
322493
322808
  init_dist();
322494
322809
  init_dist();
@@ -323178,5 +323493,6 @@ exports.unstable_getVarsForDev = getVarsForDev;
323178
323493
  exports.unstable_getWorkerNameFromProject = getWorkerNameFromProject;
323179
323494
  exports.unstable_printBindings = printBindings;
323180
323495
  exports.unstable_readConfig = readConfig;
323496
+ exports.unstable_resolveNamedTunnel = resolveNamedTunnel;
323181
323497
  exports.unstable_splitSqlQuery = splitSqlQuery;
323182
323498
  exports.unstable_startWorker = startWorker;