unplugin-cloudflare-tunnel 0.0.0-alpha-1 → 0.0.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/api.d.ts CHANGED
@@ -1 +1,50 @@
1
- export { };
1
+ import * as z from "zod/mini";
2
+
3
+ //#region src/api.d.ts
4
+ declare const CloudflareErrorSchema: z.ZodMiniObject<{
5
+ code: z.ZodMiniNumber<number>;
6
+ message: z.ZodMiniString<string>;
7
+ }, z.core.$strip>;
8
+ declare const CloudflareApiResponseSchema: z.ZodMiniObject<{
9
+ success: z.ZodMiniBoolean<boolean>;
10
+ errors: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniObject<{
11
+ code: z.ZodMiniNumber<number>;
12
+ message: z.ZodMiniString<string>;
13
+ }, z.core.$strip>>>;
14
+ messages: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
15
+ result: z.ZodMiniUnknown;
16
+ }, z.core.$strip>;
17
+ declare const AccountSchema: z.ZodMiniObject<{
18
+ id: z.ZodMiniString<string>;
19
+ name: z.ZodMiniString<string>;
20
+ }, z.core.$strip>;
21
+ declare const ZoneSchema: z.ZodMiniObject<{
22
+ id: z.ZodMiniString<string>;
23
+ name: z.ZodMiniString<string>;
24
+ }, z.core.$strip>;
25
+ declare const TunnelSchema: z.ZodMiniObject<{
26
+ id: z.ZodMiniString<string>;
27
+ name: z.ZodMiniString<string>;
28
+ account_tag: z.ZodMiniString<string>;
29
+ created_at: z.ZodMiniString<string>;
30
+ connections: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnknown>>;
31
+ }, z.core.$strip>;
32
+ declare const DNSRecordSchema: z.ZodMiniObject<{
33
+ id: z.ZodMiniString<string>;
34
+ type: z.ZodMiniString<string>;
35
+ name: z.ZodMiniString<string>;
36
+ content: z.ZodMiniString<string>;
37
+ proxied: z.ZodMiniBoolean<boolean>;
38
+ comment: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
39
+ }, z.core.$strip>;
40
+ declare function normalizeAddress(address: string | {
41
+ address?: string;
42
+ port?: number;
43
+ } | null | undefined): {
44
+ host: string;
45
+ port?: number;
46
+ };
47
+ declare function ensureCloudflaredBinary(binPath: string): Promise<void>;
48
+ declare function getLocalTarget(host: string, port: number): string;
49
+ //#endregion
50
+ export { AccountSchema, CloudflareApiResponseSchema, CloudflareErrorSchema, DNSRecordSchema, TunnelSchema, ZoneSchema, ensureCloudflaredBinary, getLocalTarget, normalizeAddress };
package/dist/api.js CHANGED
@@ -1 +1,59 @@
1
- export { };
1
+ import * as z from "zod/mini";
2
+ import NodeFS from "node:fs/promises";
3
+ import { install } from "cloudflared";
4
+
5
+ //#region src/api.ts
6
+ const CloudflareErrorSchema = z.object({
7
+ code: z.number(),
8
+ message: z.string()
9
+ });
10
+ const CloudflareApiResponseSchema = z.object({
11
+ success: z.boolean(),
12
+ errors: z.optional(z.array(CloudflareErrorSchema)),
13
+ messages: z.optional(z.array(z.string())),
14
+ result: z.unknown()
15
+ });
16
+ const AccountSchema = z.object({
17
+ id: z.string(),
18
+ name: z.string()
19
+ });
20
+ const ZoneSchema = z.object({
21
+ id: z.string(),
22
+ name: z.string()
23
+ });
24
+ const TunnelSchema = z.object({
25
+ id: z.string(),
26
+ name: z.string(),
27
+ account_tag: z.string(),
28
+ created_at: z.string(),
29
+ connections: z.optional(z.array(z.unknown()))
30
+ });
31
+ const DNSRecordSchema = z.object({
32
+ id: z.string(),
33
+ type: z.string(),
34
+ name: z.string(),
35
+ content: z.string(),
36
+ proxied: z.boolean(),
37
+ comment: z.nullish(z.string())
38
+ });
39
+ function normalizeAddress(address) {
40
+ if (address && typeof address === "object") return {
41
+ host: "address" in address && address.address ? address.address : "localhost",
42
+ port: "port" in address && typeof address.port === "number" ? address.port : void 0
43
+ };
44
+ return { host: "localhost" };
45
+ }
46
+ async function ensureCloudflaredBinary(binPath) {
47
+ try {
48
+ await NodeFS.access(binPath);
49
+ } catch {
50
+ console.log("[unplugin-cloudflare-tunnel] Installing cloudflared binary...");
51
+ await install(binPath);
52
+ }
53
+ }
54
+ function getLocalTarget(host, port) {
55
+ return `http://${host.includes(":") ? `[${host}]` : host}:${port}`;
56
+ }
57
+
58
+ //#endregion
59
+ export { AccountSchema, CloudflareApiResponseSchema, CloudflareErrorSchema, DNSRecordSchema, TunnelSchema, ZoneSchema, ensureCloudflaredBinary, getLocalTarget, normalizeAddress };
package/dist/esbuild.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/esbuild.d.ts
4
4
 
package/dist/esbuild.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/esbuild.ts
4
4
  /**
package/dist/farm.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/farm.d.ts
4
4
 
package/dist/farm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/farm.ts
4
4
  /**
@@ -1,40 +1,40 @@
1
- import { z } from "zod";
2
1
  import { UnpluginInstance } from "unplugin";
2
+ import * as z from "zod/mini";
3
3
 
4
4
  //#region src/index.d.ts
5
5
 
6
- declare const CloudflareApiResponseSchema: z.ZodType<{
7
- success: boolean;
8
- errors?: Array<{
9
- code: number;
10
- message: string;
11
- }>;
12
- messages?: Array<string>;
13
- result: unknown;
14
- }>;
15
- declare const AccountSchema: z.ZodType<{
16
- id: string;
17
- name: string;
18
- }>;
19
- declare const ZoneSchema: z.ZodType<{
20
- id: string;
21
- name: string;
22
- }>;
23
- declare const TunnelSchema: z.ZodType<{
24
- id: string;
25
- name: string;
26
- account_tag: string;
27
- created_at: string;
28
- connections?: Array<unknown>;
29
- }>;
30
- declare const DNSRecordSchema: z.ZodType<{
31
- id: string;
32
- type: string;
33
- name: string;
34
- content: string;
35
- proxied: boolean;
36
- comment?: string | null;
37
- }>;
6
+ declare const CloudflareApiResponseSchema: z.ZodMiniObject<{
7
+ success: z.ZodMiniBoolean<boolean>;
8
+ errors: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniObject<{
9
+ code: z.ZodMiniNumber<number>;
10
+ message: z.ZodMiniString<string>;
11
+ }, z.core.$strip>>>;
12
+ messages: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
13
+ result: z.ZodMiniUnknown;
14
+ }, z.core.$strip>;
15
+ declare const AccountSchema: z.ZodMiniObject<{
16
+ id: z.ZodMiniString<string>;
17
+ name: z.ZodMiniString<string>;
18
+ }, z.core.$strip>;
19
+ declare const ZoneSchema: z.ZodMiniObject<{
20
+ id: z.ZodMiniString<string>;
21
+ name: z.ZodMiniString<string>;
22
+ }, z.core.$strip>;
23
+ declare const TunnelSchema: z.ZodMiniObject<{
24
+ id: z.ZodMiniString<string>;
25
+ name: z.ZodMiniString<string>;
26
+ account_tag: z.ZodMiniString<string>;
27
+ created_at: z.ZodMiniString<string>;
28
+ connections: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnknown>>;
29
+ }, z.core.$strip>;
30
+ declare const DNSRecordSchema: z.ZodMiniObject<{
31
+ id: z.ZodMiniString<string>;
32
+ type: z.ZodMiniString<string>;
33
+ name: z.ZodMiniString<string>;
34
+ content: z.ZodMiniString<string>;
35
+ proxied: z.ZodMiniBoolean<boolean>;
36
+ comment: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
37
+ }, z.core.$strip>;
38
38
  type CloudflareApiResponse<T = unknown> = z.infer<typeof CloudflareApiResponseSchema> & {
39
39
  result: T;
40
40
  };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as DNSRecord, i as CloudflareTunnelOptions, n as CloudflareApiResponse, o as Tunnel, r as CloudflareTunnel, s as Zone, t as Account } from "./index-BjNI6nQt.js";
1
+ import { a as DNSRecord, i as CloudflareTunnelOptions, n as CloudflareApiResponse, o as Tunnel, r as CloudflareTunnel, s as Zone, t as Account } from "./index-BK_mUExr.js";
2
2
  export { Account, CloudflareApiResponse, CloudflareTunnel, CloudflareTunnel as default, CloudflareTunnelOptions, DNSRecord, Tunnel, Zone };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as src_default, t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { n as src_default, t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  export { CloudflareTunnel, src_default as default };
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/rolldown.d.ts
4
4
 
package/dist/rolldown.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/rolldown.ts
4
4
  /**
package/dist/rollup.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/rollup.d.ts
4
4
 
package/dist/rollup.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/rollup.ts
4
4
  /**
package/dist/rspack.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/rspack.d.ts
4
4
 
package/dist/rspack.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/rspack.ts
4
4
  /**
@@ -1,19 +1,53 @@
1
- import { bin, install } from "cloudflared";
2
- import fs from "node:fs/promises";
3
- import { exec, spawn } from "node:child_process";
4
- import { z } from "zod";
5
1
  import { createUnplugin } from "unplugin";
2
+ import * as z from "zod/mini";
3
+ import NodeFS from "node:fs/promises";
4
+ import { bin, install } from "cloudflared";
5
+ import * as NodeChildProcess from "node:child_process";
6
6
 
7
7
  //#region src/index.ts
8
+ const PLUGIN_NAME = "unplugin-cloudflare-tunnel";
8
9
  const INFO_LOG_REGEX = /^.*Z INF .*/;
10
+ const LOG_LEVEL_RANK = {
11
+ debug: 10,
12
+ info: 20,
13
+ warn: 30,
14
+ error: 40,
15
+ fatal: 50
16
+ };
17
+ function shouldLog(threshold, level) {
18
+ return LOG_LEVEL_RANK[level] >= LOG_LEVEL_RANK[threshold];
19
+ }
20
+ function supportsColor() {
21
+ if (!process.stdout.isTTY) return false;
22
+ if (process.env.NO_COLOR !== void 0) return false;
23
+ if (process.env.TERM === "dumb") return false;
24
+ if (process.env.FORCE_COLOR === "0") return false;
25
+ return true;
26
+ }
27
+ const ANSI = {
28
+ reset: "\x1B[0m",
29
+ dim: "\x1B[2m",
30
+ bold: "\x1B[1m",
31
+ blue: "\x1B[34m",
32
+ yellow: "\x1B[33m"
33
+ };
34
+ const ANSI_ESCAPE = String.fromCharCode(27);
35
+ const ANSI_STYLE_SEQUENCE_REGEX = new RegExp(`${ANSI_ESCAPE}\\[[0-9;]*m`, "g");
36
+ function stripAnsi(text) {
37
+ return text.replace(ANSI_STYLE_SEQUENCE_REGEX, "");
38
+ }
39
+ function colorize(text, ansi) {
40
+ if (!supportsColor()) return text;
41
+ return `${ansi}${text}${ANSI.reset}`;
42
+ }
9
43
  const CloudflareErrorSchema = z.object({
10
44
  code: z.number(),
11
45
  message: z.string()
12
46
  });
13
47
  const CloudflareApiResponseSchema = z.object({
14
48
  success: z.boolean(),
15
- errors: z.array(CloudflareErrorSchema).optional(),
16
- messages: z.array(z.string()).optional(),
49
+ errors: z.optional(z.array(CloudflareErrorSchema)),
50
+ messages: z.optional(z.array(z.string())),
17
51
  result: z.unknown()
18
52
  });
19
53
  const AccountSchema = z.object({
@@ -29,7 +63,7 @@ const TunnelSchema = z.object({
29
63
  name: z.string(),
30
64
  account_tag: z.string(),
31
65
  created_at: z.string(),
32
- connections: z.array(z.unknown()).optional()
66
+ connections: z.optional(z.array(z.unknown()))
33
67
  });
34
68
  const DNSRecordSchema = z.object({
35
69
  id: z.string(),
@@ -37,14 +71,14 @@ const DNSRecordSchema = z.object({
37
71
  name: z.string(),
38
72
  content: z.string(),
39
73
  proxied: z.boolean(),
40
- comment: z.string().nullish()
74
+ comment: z.nullish(z.string())
41
75
  });
42
76
  const unpluginFactory = (options = {}) => {
43
77
  const { enabled = true } = options;
44
78
  if (enabled === false) {
45
79
  const VIRTUAL_MODULE_ID_STUB = "virtual:unplugin-cloudflare-tunnel";
46
80
  return {
47
- name: "unplugin-cloudflare-tunnel",
81
+ name: PLUGIN_NAME,
48
82
  enforce: "pre",
49
83
  resolveId(id) {
50
84
  if (id === VIRTUAL_MODULE_ID_STUB) return "\0" + VIRTUAL_MODULE_ID_STUB;
@@ -95,8 +129,79 @@ const unpluginFactory = (options = {}) => {
95
129
  cleanupConfig = namedOptions.cleanup || {};
96
130
  }
97
131
  const { port: userProvidedPort, logFile, logLevel, debug = false } = options;
98
- const debugLog = (...args) => {
99
- if (debug) console.log("[cloudflare-tunnel:debug]", ...args);
132
+ const effectivePluginLogLevel = logLevel ?? (debug ? "debug" : "info");
133
+ const pluginLog = {
134
+ debug: (...args) => {
135
+ if (debug || effectivePluginLogLevel === "debug") console.log("[cloudflare-tunnel:debug]", ...args);
136
+ },
137
+ info: (message) => {
138
+ if (shouldLog(effectivePluginLogLevel, "info")) console.log(`[unplugin-cloudflare-tunnel] ${message}`);
139
+ },
140
+ warn: (message) => {
141
+ if (shouldLog(effectivePluginLogLevel, "warn")) console.warn(`[unplugin-cloudflare-tunnel] ${message}`);
142
+ },
143
+ error: (message) => {
144
+ if (shouldLog(effectivePluginLogLevel, "error")) console.error(`[unplugin-cloudflare-tunnel] ${message}`);
145
+ }
146
+ };
147
+ const debugLog = pluginLog.debug;
148
+ const makeLocalDisplay = (localTarget) => {
149
+ if (!localTarget) return localTarget;
150
+ return localTarget.replace("http://[::1]:", "http://localhost:").replace("http://127.0.0.1:", "http://localhost:");
151
+ };
152
+ const announceConnecting = () => {
153
+ if (globalState.__tunnelConnectingAnnounced) return;
154
+ globalState.__tunnelConnectingAnnounced = true;
155
+ const message = isQuickMode ? "cf tunnel connecting…" : hostname ? `cf tunnel connecting… (${hostname})` : "cf tunnel connecting…";
156
+ console.log("");
157
+ console.log(colorize(message, ANSI.bold));
158
+ };
159
+ const announceTunnel = (params) => {
160
+ if (!params.url) return;
161
+ if (globalState.__lastAnnouncedTunnelKey === params.key) return;
162
+ globalState.__lastAnnouncedTunnelKey = params.key;
163
+ const cols = process.stdout.columns ?? 80;
164
+ const maxWidth = Math.max(10, cols - 2);
165
+ const headerText = "unplugin-cloudflare-tunnel";
166
+ const header = (() => {
167
+ return `${colorize("[", ANSI.yellow)}${headerText}${colorize("]", ANSI.yellow)}`;
168
+ })();
169
+ const urlLine = colorize(params.url, ANSI.blue + ANSI.bold);
170
+ const localLine = params.localTarget ? makeLocalDisplay(params.localTarget) : "";
171
+ const headerPlainLen = stripAnsi(header).length;
172
+ const contentPlainLen = Math.max(stripAnsi(urlLine).length, localLine.length, 10, 5);
173
+ const width = Math.min(90, maxWidth, Math.max(44, headerPlainLen, contentPlainLen + 4));
174
+ const rule = "─".repeat(width);
175
+ const center = (text) => {
176
+ const plainLen = stripAnsi(text).length;
177
+ const pad = Math.max(0, Math.floor((width - plainLen) / 2));
178
+ return `${" ".repeat(pad)}${text}`;
179
+ };
180
+ if (cols < 70) {
181
+ const out$1 = [];
182
+ out$1.push("");
183
+ out$1.push(`${header} ${colorize("Tunnel URL", ANSI.bold)} ${urlLine}`);
184
+ if (localLine) out$1.push(`${header} ${colorize("Local", ANSI.dim + ANSI.bold)} ${localLine}`);
185
+ out$1.push("");
186
+ console.log(out$1.join("\n"));
187
+ return;
188
+ }
189
+ const out = [];
190
+ out.push("");
191
+ out.push(center(header));
192
+ out.push(rule);
193
+ out.push(center(colorize("Tunnel URL", ANSI.bold)));
194
+ out.push(center(urlLine));
195
+ out.push(center(urlLine));
196
+ out.push(center(urlLine));
197
+ if (localLine) {
198
+ out.push("");
199
+ out.push(center(colorize("Local", ANSI.dim + ANSI.bold)));
200
+ out.push(center(localLine));
201
+ }
202
+ out.push(rule);
203
+ out.push("");
204
+ console.log(out.join("\n"));
100
205
  };
101
206
  if (!isQuickMode && (!hostname || typeof hostname !== "string")) throw new Error("[unplugin-cloudflare-tunnel] hostname is required and must be a valid string in named tunnel mode");
102
207
  let tunnelUrl = hostname ? `https://${hostname}` : "";
@@ -252,7 +357,7 @@ const unpluginFactory = (options = {}) => {
252
357
  if (logFile) cloudflaredArgs.push("--logfile", logFile);
253
358
  cloudflaredArgs.push("--url", localTarget);
254
359
  debugLog("Spawning quick tunnel:", bin, cloudflaredArgs);
255
- const child$1 = spawn(bin, cloudflaredArgs, {
360
+ const child$1 = NodeChildProcess.spawn(bin, cloudflaredArgs, {
256
361
  stdio: [
257
362
  "ignore",
258
363
  "pipe",
@@ -262,7 +367,7 @@ const unpluginFactory = (options = {}) => {
262
367
  windowsHide: true,
263
368
  shell: process.platform === "win32"
264
369
  });
265
- console.log(`[unplugin-cloudflare-tunnel] Quick tunnel process spawned with PID: ${child$1.pid}`);
370
+ debugLog(`[unplugin-cloudflare-tunnel] Quick tunnel process spawned with PID: ${child$1.pid}`);
266
371
  return new Promise((resolve, reject) => {
267
372
  let urlFound = false;
268
373
  const timeout = setTimeout(() => {
@@ -310,17 +415,17 @@ const unpluginFactory = (options = {}) => {
310
415
  globalState.shuttingDown = true;
311
416
  globalState.tunnelUrl = void 0;
312
417
  try {
313
- console.log(`[unplugin-cloudflare-tunnel] 🛑 Terminating cloudflared process (PID: ${child.pid}) with ${signal}...`);
314
- if (!child.kill(signal) && process.platform === "win32") exec(`taskkill /pid ${child.pid} /T /F`, () => {});
418
+ debugLog(`[unplugin-cloudflare-tunnel] Terminating cloudflared process (PID: ${child.pid}) with ${signal}...`);
419
+ if (!child.kill(signal) && process.platform === "win32") NodeChildProcess.exec(`taskkill /pid ${child.pid} /T /F`, () => {});
315
420
  if (signal === "SIGTERM") setTimeout(() => {
316
421
  if (child && !child.killed) {
317
- console.log("[unplugin-cloudflare-tunnel] 🛑 Force killing cloudflared process...");
318
- if (process.platform === "win32") exec(`taskkill /pid ${child.pid} /T /F`, () => {});
422
+ debugLog("[unplugin-cloudflare-tunnel] Force killing cloudflared process...");
423
+ if (process.platform === "win32") NodeChildProcess.exec(`taskkill /pid ${child.pid} /T /F`, () => {});
319
424
  else child.kill("SIGKILL");
320
425
  }
321
426
  }, 2e3);
322
427
  } catch (error) {
323
- console.log(`[unplugin-cloudflare-tunnel] Note: Error killing cloudflared: ${error}`);
428
+ debugLog(`[unplugin-cloudflare-tunnel] Note: Error killing cloudflared: ${error}`);
324
429
  }
325
430
  };
326
431
  let exitHandlersRegistered = globalState.exitHandlersRegistered ?? false;
@@ -359,9 +464,27 @@ const unpluginFactory = (options = {}) => {
359
464
  const generateDnsComment = () => {
360
465
  return `unplugin-cloudflare-tunnel:${tunnelName}`;
361
466
  };
467
+ const registerListeningHandler = (handler) => {
468
+ const httpServer = server.httpServer;
469
+ if (!httpServer) return;
470
+ const invokeHandler = () => {
471
+ try {
472
+ const maybePromise = handler();
473
+ if (maybePromise && typeof maybePromise.then === "function") maybePromise.catch((error) => {
474
+ console.error(`[unplugin-cloudflare-tunnel] ❌ Dev server listening hook failed: ${error.message}`);
475
+ });
476
+ } catch (error) {
477
+ console.error(`[unplugin-cloudflare-tunnel] ❌ Dev server listening hook failed: ${error.message}`);
478
+ }
479
+ };
480
+ httpServer.on("listening", invokeHandler);
481
+ if (httpServer.listening) invokeHandler();
482
+ };
362
483
  try {
363
484
  const { host: serverHost, port: detectedPort } = normalizeAddress(server.httpServer?.address());
364
- const port = userProvidedPort || detectedPort || server.config.server.port || 5173;
485
+ const configPortValue = server.config?.server?.port;
486
+ const resolvedConfigPort = typeof configPortValue === "string" ? Number.parseInt(configPortValue, 10) : configPortValue;
487
+ const port = userProvidedPort || detectedPort || (typeof resolvedConfigPort === "number" && !Number.isNaN(resolvedConfigPort) ? resolvedConfigPort : void 0) || 5173;
365
488
  const newConfigHash = JSON.stringify({
366
489
  isQuickMode,
367
490
  hostname,
@@ -372,13 +495,13 @@ const unpluginFactory = (options = {}) => {
372
495
  });
373
496
  if (globalState.child && !globalState.child.killed && globalState.configHash === newConfigHash) {
374
497
  tunnelUrl = await globalState.tunnelUrl ?? "";
375
- console.log("[unplugin-cloudflare-tunnel] Config unchanged – re-using existing tunnel");
498
+ debugLog("[unplugin-cloudflare-tunnel] Config unchanged – re-using existing tunnel");
376
499
  globalState.shuttingDown = false;
377
500
  registerExitHandler();
378
501
  return;
379
502
  }
380
503
  if (globalState.child && !globalState.child.killed) {
381
- console.log("[unplugin-cloudflare-tunnel] Config changed – terminating previous tunnel...");
504
+ debugLog("[unplugin-cloudflare-tunnel] Config changed – terminating previous tunnel...");
382
505
  try {
383
506
  globalState.child.kill("SIGTERM");
384
507
  } catch (_) {}
@@ -387,7 +510,7 @@ const unpluginFactory = (options = {}) => {
387
510
  delete globalState.configHash;
388
511
  globalState.shuttingDown = false;
389
512
  if (isQuickMode) {
390
- console.log("[unplugin-cloudflare-tunnel] Starting quick tunnel mode...");
513
+ debugLog("[unplugin-cloudflare-tunnel] Starting quick tunnel mode...");
391
514
  debugLog("Quick tunnel mode - no API token or hostname required");
392
515
  await ensureCloudflaredBinary(bin);
393
516
  const localTarget$1 = getLocalTarget(serverHost, port);
@@ -399,20 +522,33 @@ const unpluginFactory = (options = {}) => {
399
522
  globalState.child = child;
400
523
  globalState.configHash = newConfigHash;
401
524
  registerExitHandler();
402
- console.log(`🌐 Quick tunnel ready at: ${url}`);
403
- server.httpServer?.on("listening", async () => {
525
+ registerListeningHandler(() => {
526
+ const { host: actualServerHost, port: actualPort } = normalizeAddress(server.httpServer?.address());
527
+ const actualLocalTarget = getLocalTarget(actualServerHost, actualPort ?? port);
528
+ announceTunnel({
529
+ key: `quick:${url}:${actualPort ?? port}`,
530
+ url,
531
+ localTarget: actualLocalTarget
532
+ });
533
+ });
534
+ registerListeningHandler(async () => {
404
535
  try {
405
536
  const { host: actualServerHost, port: actualPort } = normalizeAddress(server.httpServer?.address());
406
537
  if (actualPort !== port) {
407
- console.log(`[unplugin-cloudflare-tunnel] ⚠️ Port conflict detected - server is using port ${actualPort} instead of ${port}`);
408
- console.log(`[unplugin-cloudflare-tunnel] 🔄 Quick tunnel needs to be restarted for new port...`);
538
+ pluginLog.warn(`Port conflict detected - server is using port ${actualPort} instead of ${port}`);
539
+ pluginLog.info("Restarting quick tunnel for the new port...");
409
540
  killCloudflared("SIGTERM");
410
541
  await new Promise((resolve) => setTimeout(resolve, 1e3));
411
- const { child: newChild, url: newUrl } = await spawnQuickTunnel(getLocalTarget(actualServerHost, actualPort ?? port));
542
+ const newLocalTarget = getLocalTarget(actualServerHost, actualPort ?? port);
543
+ const { child: newChild, url: newUrl } = await spawnQuickTunnel(newLocalTarget);
412
544
  tunnelUrl = newUrl;
413
545
  child = newChild;
414
546
  globalState.child = child;
415
- console.log(`🌐 Quick tunnel updated for port ${actualPort}: ${newUrl}`);
547
+ announceTunnel({
548
+ key: `quick:${newUrl}:${actualPort ?? port}`,
549
+ url: newUrl,
550
+ localTarget: newLocalTarget
551
+ });
416
552
  globalState.configHash = JSON.stringify({
417
553
  isQuickMode,
418
554
  hostname,
@@ -435,10 +571,10 @@ const unpluginFactory = (options = {}) => {
435
571
  throw error;
436
572
  }
437
573
  }
438
- console.log("[unplugin-cloudflare-tunnel] Starting named tunnel mode...");
574
+ debugLog("[unplugin-cloudflare-tunnel] Starting named tunnel mode...");
439
575
  const apiToken = providedApiToken || process.env.CLOUDFLARE_API_KEY;
440
576
  if (!apiToken) throw new Error("[unplugin-cloudflare-tunnel] API token is required. Provide it via 'apiToken' option or set the CLOUDFLARE_API_KEY environment variable. Get your token at: https://dash.cloudflare.com/profile/api-tokens");
441
- console.log(`[unplugin-cloudflare-tunnel] Using port ${port}${userProvidedPort === port ? " (user-provided)" : " (from bundler config)"}`);
577
+ debugLog(`[unplugin-cloudflare-tunnel] Using port ${port}${userProvidedPort === port ? " (user-provided)" : " (from bundler config)"}`);
442
578
  await ensureCloudflaredBinary(bin);
443
579
  const accounts = await cf(apiToken, "GET", "/accounts", void 0, z.array(AccountSchema));
444
580
  const accountId = forcedAccount || accounts[0]?.id;
@@ -462,7 +598,7 @@ const unpluginFactory = (options = {}) => {
462
598
  const { autoCleanup = true } = cleanupConfig;
463
599
  let tunnel = (await cf(apiToken, "GET", `/accounts/${accountId}/cfd_tunnel?name=${tunnelName}`, void 0, z.array(TunnelSchema)))[0];
464
600
  if (!tunnel) {
465
- console.log(`[unplugin-cloudflare-tunnel] Creating tunnel '${tunnelName}'...`);
601
+ pluginLog.info(`Creating tunnel '${tunnelName}'...`);
466
602
  tunnel = await cf(apiToken, "POST", `/accounts/${accountId}/cfd_tunnel`, {
467
603
  name: tunnelName,
468
604
  config_src: "cloudflare"
@@ -470,13 +606,13 @@ const unpluginFactory = (options = {}) => {
470
606
  }
471
607
  const tunnelId = tunnel.id;
472
608
  if (autoCleanup) {
473
- console.log(`[unplugin-cloudflare-tunnel] 🧹 Running resource cleanup for tunnel '${tunnelName}'...`);
609
+ debugLog(`[unplugin-cloudflare-tunnel] Running resource cleanup for tunnel '${tunnelName}'...`);
474
610
  const dnsCleanup = await cleanupMismatchedDnsRecords(apiToken, zoneId, generateDnsComment(), hostname, tunnelId);
475
- if (dnsCleanup.found.length > 0) console.log(`[unplugin-cloudflare-tunnel] 📊 DNS cleanup: ${dnsCleanup.found.length} mismatched, ${dnsCleanup.deleted.length} deleted`);
611
+ if (dnsCleanup.found.length > 0) pluginLog.warn(`DNS cleanup: ${dnsCleanup.found.length} mismatched, ${dnsCleanup.deleted.length} deleted`);
476
612
  const mismatchedSslCerts = await findMismatchedSslCertificates(apiToken, zoneId, tunnelName, hostname);
477
613
  if (mismatchedSslCerts.length > 0) {
478
614
  for (const cert of mismatchedSslCerts) await cf(apiToken, "DELETE", `/zones/${zoneId}/ssl/certificate_packs/${cert.id}`);
479
- console.log(`[unplugin-cloudflare-tunnel] 📊 SSL cleanup: ${mismatchedSslCerts.length} deleted`);
615
+ pluginLog.warn(`SSL cleanup: ${mismatchedSslCerts.length} deleted`);
480
616
  }
481
617
  } else debugLog("← Cleanup skipped", cleanupConfig);
482
618
  const localTarget = getLocalTarget(serverHost, port);
@@ -549,7 +685,7 @@ const unpluginFactory = (options = {}) => {
549
685
  debugLog("← Total TLS", totalTls);
550
686
  const existingHostnameCert = certContainingHost(hostname);
551
687
  if (totalTls.status !== "on" && !existingHostnameCert) {
552
- console.log(`[unplugin-cloudflare-tunnel] Requesting edge certificate for ${hostname}...`);
688
+ pluginLog.info(`Requesting edge certificate for ${hostname}...`);
553
689
  const tagHostname = generateSslTagHostname();
554
690
  const certificateHosts = [hostname, tagHostname];
555
691
  debugLog(`Adding tag hostname to certificate: ${tagHostname}`);
@@ -574,7 +710,7 @@ const unpluginFactory = (options = {}) => {
574
710
  if (logFile) cloudflaredArgs.push("--logfile", logFile);
575
711
  debugLog("Spawning cloudflared", bin, cloudflaredArgs);
576
712
  cloudflaredArgs.push("run", "--token", token);
577
- child = spawn(bin, cloudflaredArgs, {
713
+ child = NodeChildProcess.spawn(bin, cloudflaredArgs, {
578
714
  stdio: [
579
715
  "ignore",
580
716
  "pipe",
@@ -584,18 +720,37 @@ const unpluginFactory = (options = {}) => {
584
720
  windowsHide: true,
585
721
  shell: process.platform === "win32"
586
722
  });
587
- console.log(`[unplugin-cloudflare-tunnel] Process spawned with PID: ${child.pid}`);
723
+ debugLog(`[unplugin-cloudflare-tunnel] Process spawned with PID: ${child.pid}`);
588
724
  globalState.child = child;
589
725
  globalState.configHash = newConfigHash;
590
726
  registerExitHandler();
591
727
  let tunnelReady = false;
728
+ const logCloudflaredLines = (kind, text) => {
729
+ if (globalState.shuttingDown && !debug) return;
730
+ const isVerbose = effectiveLogLevel === "debug" || effectiveLogLevel === "info";
731
+ const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
732
+ if (isVerbose) {
733
+ for (const line of lines) {
734
+ const prefix = kind === "stdout" ? "[cloudflared stdout]" : "[cloudflared stderr]";
735
+ if (kind === "stdout") console.log(`${prefix} ${line}`);
736
+ else console.error(`${prefix} ${line}`);
737
+ }
738
+ return;
739
+ }
740
+ for (const line of lines) {
741
+ if (INFO_LOG_REGEX.test(line)) continue;
742
+ const prefix = kind === "stdout" ? "[cloudflared stdout]" : "[cloudflared stderr]";
743
+ if (kind === "stdout") console.log(`${prefix} ${line}`);
744
+ else console.error(`${prefix} ${line}`);
745
+ }
746
+ };
592
747
  child.stdout?.on("data", (data) => {
593
748
  const output = data.toString();
594
- if (!globalState.shuttingDown || debug) console.log(`[cloudflared stdout] ${output.trim()}`);
749
+ logCloudflaredLines("stdout", output);
595
750
  if (output.includes("Connection") && output.includes("registered")) {
596
751
  if (!tunnelReady) {
597
752
  tunnelReady = true;
598
- console.log(`🌐 Cloudflare tunnel started for https://${hostname}`);
753
+ pluginLog.info(`Tunnel connected for https://${hostname}`);
599
754
  }
600
755
  }
601
756
  });
@@ -605,10 +760,7 @@ const unpluginFactory = (options = {}) => {
605
760
  if (logLevel === "debug") console.log(`[cloudflared debug] ${error}`);
606
761
  return;
607
762
  }
608
- if (!globalState.shuttingDown || debug) console.error(`[cloudflared stderr] ${error}`);
609
- if (error.toLowerCase().includes("error") || error.toLowerCase().includes("failed") || error.toLowerCase().includes("fatal")) {
610
- if (!globalState.shuttingDown || debug) console.error(`[unplugin-cloudflare-tunnel] ⚠️ ${error}`);
611
- }
763
+ logCloudflaredLines("stderr", error);
612
764
  });
613
765
  child.on("error", (error) => {
614
766
  console.error(`[unplugin-cloudflare-tunnel] ❌ Failed to start tunnel process: ${error.message}`);
@@ -620,25 +772,31 @@ const unpluginFactory = (options = {}) => {
620
772
  if (signal) console.error(`[unplugin-cloudflare-tunnel] Process terminated by signal: ${signal}`);
621
773
  } else if (code === 0) console.log(`[unplugin-cloudflare-tunnel] ✅ Tunnel process exited cleanly`);
622
774
  });
623
- setTimeout(() => {
624
- if (!tunnelReady) console.log(`🌐 Cloudflare tunnel starting for https://${hostname}`);
625
- }, 3e3);
775
+ registerListeningHandler(() => {
776
+ const { host: actualServerHost, port: actualPort } = normalizeAddress(server.httpServer?.address());
777
+ const actualLocalTarget = getLocalTarget(actualServerHost, actualPort ?? port);
778
+ announceTunnel({
779
+ key: `named:${hostname}:${actualPort ?? port}`,
780
+ url: `https://${hostname}`,
781
+ localTarget: actualLocalTarget
782
+ });
783
+ });
626
784
  server.httpServer?.once("close", () => {
627
785
  killCloudflared("SIGTERM");
628
786
  });
629
- server.httpServer?.on("listening", async () => {
787
+ registerListeningHandler(async () => {
630
788
  try {
631
789
  const { host: actualServerHost, port: actualPort } = normalizeAddress(server.httpServer?.address());
632
790
  if (actualPort !== port) {
633
- console.log(`[unplugin-cloudflare-tunnel] ⚠️ Port conflict detected - server is using port ${actualPort} instead of ${port}`);
634
- console.log(`[unplugin-cloudflare-tunnel] 🔄 Updating tunnel configuration...`);
791
+ pluginLog.warn(`Port conflict detected - server is using port ${actualPort} instead of ${port}`);
792
+ pluginLog.info("Updating tunnel configuration...");
635
793
  const newLocalTarget = getLocalTarget(actualServerHost, actualPort ?? port);
636
794
  debugLog("← Updating local target to", newLocalTarget);
637
795
  await cf(apiToken, "PUT", `/accounts/${accountId}/cfd_tunnel/${tunnelId}/configurations`, { config: { ingress: [{
638
796
  hostname,
639
797
  service: newLocalTarget
640
798
  }, { service: "http_status:404" }] } });
641
- console.log(`[unplugin-cloudflare-tunnel] ✅ Tunnel configuration updated to use port ${actualPort}`);
799
+ pluginLog.info(`Tunnel configuration updated to use port ${actualPort}`);
642
800
  globalState.configHash = JSON.stringify({
643
801
  hostname,
644
802
  port: actualPort,
@@ -652,27 +810,121 @@ const unpluginFactory = (options = {}) => {
652
810
  }
653
811
  });
654
812
  } catch (error) {
655
- console.error(`[unplugin-cloudflare-tunnel] Setup failed: ${error.message}`);
656
- if (error.message.includes("API token")) {
657
- console.error(`[unplugin-cloudflare-tunnel] 💡 Check your API token at: https://dash.cloudflare.com/profile/api-tokens`);
658
- console.error(`[unplugin-cloudflare-tunnel] 💡 Required permissions: Zone:Zone:Read, Zone:DNS:Edit, Account:Cloudflare Tunnel:Edit`);
659
- } else if (error.message.includes("Zone") && error.message.includes("not found")) console.error(`[unplugin-cloudflare-tunnel] 💡 Make sure '${hostname}' domain is added to your Cloudflare account`);
660
- else if (error.message.includes("cloudflared")) console.error(`[unplugin-cloudflare-tunnel] 💡 Try deleting node_modules and reinstalling to get a fresh cloudflared binary`);
813
+ if (error instanceof Error) {
814
+ console.error(`[unplugin-cloudflare-tunnel] ❌ Setup failed: ${error.message}`);
815
+ if (error.message.includes("API token")) {
816
+ console.error(`[unplugin-cloudflare-tunnel] 💡 Check your API token at: https://dash.cloudflare.com/profile/api-tokens`);
817
+ console.error(`[unplugin-cloudflare-tunnel] 💡 Required permissions: Zone:Zone:Read, Zone:DNS:Edit, Account:Cloudflare Tunnel:Edit`);
818
+ } else if (error.message.includes("Zone") && error.message.includes("not found")) console.error(`[unplugin-cloudflare-tunnel] 💡 Make sure '${hostname}' domain is added to your Cloudflare account`);
819
+ else if (error.message.includes("cloudflared")) console.error(`[unplugin-cloudflare-tunnel] 💡 Try deleting node_modules and reinstalling to get a fresh cloudflared binary`);
820
+ }
661
821
  throw error;
662
822
  }
663
823
  };
824
+ const ensureWebpackAllowedHosts = (devServerOptions, bundler) => {
825
+ if (!devServerOptions) return;
826
+ const hostToAllow = isQuickMode ? ".trycloudflare.com" : hostname;
827
+ if (!hostToAllow) return;
828
+ const label = bundler === "webpack" ? "Webpack" : "Rspack";
829
+ const normalizeArray = (values) => {
830
+ const unique = Array.from(new Set(values.filter(Boolean)));
831
+ devServerOptions.allowedHosts = unique;
832
+ return unique;
833
+ };
834
+ let modified = false;
835
+ const current = devServerOptions.allowedHosts;
836
+ if (current === "all") return;
837
+ if (typeof current === "undefined" || current === "auto") {
838
+ normalizeArray(["localhost", hostToAllow]);
839
+ modified = true;
840
+ } else if (typeof current === "string") {
841
+ if (current !== hostToAllow) {
842
+ normalizeArray([current, hostToAllow]);
843
+ modified = true;
844
+ }
845
+ } else if (Array.isArray(current)) {
846
+ if (!current.includes(hostToAllow)) {
847
+ current.push(hostToAllow);
848
+ modified = true;
849
+ }
850
+ }
851
+ if (modified) debugLog(`[unplugin-cloudflare-tunnel] Configured ${label} devServer.allowedHosts to include ${hostToAllow}`);
852
+ };
853
+ const setupWebpackLikeDevServerIntegration = (compiler, bundler) => {
854
+ if ((compiler?.options?.mode ?? process.env.NODE_ENV) === "production") return;
855
+ const optionsContainer = compiler.options;
856
+ if (!optionsContainer.devServer) optionsContainer.devServer = {};
857
+ const devServerOptions = optionsContainer.devServer;
858
+ ensureWebpackAllowedHosts(devServerOptions, bundler);
859
+ let lastHttpServer;
860
+ let missingServerWarned = false;
861
+ const runConfiguration = (devServerInstance) => {
862
+ if (!devServerInstance) {
863
+ if (!missingServerWarned) {
864
+ console.warn(`[unplugin-cloudflare-tunnel] ${bundler} dev server instance unavailable; skipping tunnel setup`);
865
+ missingServerWarned = true;
866
+ }
867
+ return;
868
+ }
869
+ const httpServer = [
870
+ devServerInstance.server,
871
+ devServerInstance.httpServer,
872
+ devServerInstance.listeningApp,
873
+ devServerInstance.server?.server
874
+ ].find((candidate) => candidate);
875
+ if (!httpServer) {
876
+ if (!missingServerWarned) {
877
+ console.warn(`[unplugin-cloudflare-tunnel] Unable to locate HTTP server from ${bundler} dev server; tunnel will not start`);
878
+ missingServerWarned = true;
879
+ }
880
+ return;
881
+ }
882
+ if (lastHttpServer === httpServer) return;
883
+ lastHttpServer = httpServer;
884
+ httpServer.once("close", () => {
885
+ if (lastHttpServer === httpServer) lastHttpServer = void 0;
886
+ });
887
+ const configuredPromise = configureServer({
888
+ httpServer,
889
+ config: { server: { port: devServerInstance.options?.port ?? devServerOptions?.port } }
890
+ });
891
+ globalState.tunnelUrl = configuredPromise.then(() => tunnelUrl).catch(() => "");
892
+ configuredPromise.catch(() => {});
893
+ };
894
+ const scheduleConfiguration = (devServerInstance) => {
895
+ const httpServer = devServerInstance?.server || devServerInstance?.httpServer || devServerInstance?.listeningApp;
896
+ if (httpServer && typeof httpServer.once === "function") if (httpServer.listening) runConfiguration(devServerInstance);
897
+ else httpServer.once("listening", () => runConfiguration(devServerInstance));
898
+ else runConfiguration(devServerInstance);
899
+ };
900
+ const originalSetupMiddlewares = devServerOptions.setupMiddlewares;
901
+ devServerOptions.setupMiddlewares = function(middlewares, devServer) {
902
+ scheduleConfiguration(devServer);
903
+ if (typeof originalSetupMiddlewares === "function") return originalSetupMiddlewares.call(this, middlewares, devServer);
904
+ return middlewares;
905
+ };
906
+ const originalOnListening = devServerOptions.onListening;
907
+ devServerOptions.onListening = function(devServer) {
908
+ scheduleConfiguration(devServer);
909
+ if (typeof originalOnListening === "function") return originalOnListening.call(this, devServer);
910
+ };
911
+ };
664
912
  return {
665
- name: "unplugin-cloudflare-tunnel",
913
+ name: PLUGIN_NAME,
666
914
  enforce: "pre",
667
- resolveId(id) {
668
- if (id === VIRTUAL_MODULE_ID) return "\0" + VIRTUAL_MODULE_ID;
915
+ resolveId: (id) => {
916
+ if (id === VIRTUAL_MODULE_ID) {
917
+ debugLog("resolveId called for", id);
918
+ return "\0" + VIRTUAL_MODULE_ID;
919
+ }
669
920
  },
670
- async load(id) {
921
+ load: async (id) => {
671
922
  const url = await globalState.tunnelUrl;
672
923
  if (id === "\0" + VIRTUAL_MODULE_ID) return `export function getTunnelUrl() { return ${JSON.stringify(url || "")}; }`;
673
924
  },
674
925
  vite: {
675
- config(config) {
926
+ config: (config) => {
927
+ announceConnecting();
676
928
  if (!config.server) config.server = {};
677
929
  if (isQuickMode) {
678
930
  config.server.allowedHosts = [".trycloudflare.com"];
@@ -680,15 +932,15 @@ const unpluginFactory = (options = {}) => {
680
932
  }
681
933
  if (!config.server.allowedHosts) {
682
934
  config.server.allowedHosts = [hostname];
683
- console.log(`[unplugin-cloudflare-tunnel] Configured Vite to allow requests from ${hostname}`);
935
+ debugLog(`[unplugin-cloudflare-tunnel] Configured Vite to allow requests from ${hostname}`);
684
936
  } else if (Array.isArray(config.server.allowedHosts)) {
685
937
  if (!config.server.allowedHosts.includes(hostname)) {
686
938
  config.server.allowedHosts.push(hostname);
687
- console.log(`[unplugin-cloudflare-tunnel] Added ${hostname} to allowed hosts`);
939
+ debugLog(`[unplugin-cloudflare-tunnel] Added ${hostname} to allowed hosts`);
688
940
  }
689
941
  }
690
942
  },
691
- configureServer(server) {
943
+ configureServer: (server) => {
692
944
  const configuredPromise = configureServer(server);
693
945
  globalState.tunnelUrl = configuredPromise.then(() => tunnelUrl).catch(() => "");
694
946
  return async () => {
@@ -696,6 +948,12 @@ const unpluginFactory = (options = {}) => {
696
948
  };
697
949
  }
698
950
  },
951
+ rspack: (compiler) => {
952
+ setupWebpackLikeDevServerIntegration(compiler, "rspack");
953
+ },
954
+ webpack: (compiler) => {
955
+ setupWebpackLikeDevServerIntegration(compiler, "webpack");
956
+ },
699
957
  closeBundle() {
700
958
  killCloudflared("SIGTERM");
701
959
  delete globalState.child;
@@ -713,7 +971,7 @@ function normalizeAddress(address) {
713
971
  }
714
972
  async function ensureCloudflaredBinary(binPath) {
715
973
  try {
716
- await fs.access(binPath);
974
+ await NodeFS.access(binPath);
717
975
  } catch {
718
976
  console.log("[unplugin-cloudflare-tunnel] Installing cloudflared binary...");
719
977
  await install(binPath);
package/dist/vite.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/vite.d.ts
4
4
 
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/vite.ts
4
4
  /**
package/dist/webpack.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CloudflareTunnel } from "./index-BjNI6nQt.js";
1
+ import { r as CloudflareTunnel } from "./index-BK_mUExr.js";
2
2
 
3
3
  //#region src/webpack.d.ts
4
4
 
package/dist/webpack.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as CloudflareTunnel } from "./src-BC4MyCER.js";
1
+ import { t as CloudflareTunnel } from "./src-CVRdCQUT.js";
2
2
 
3
3
  //#region src/webpack.ts
4
4
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unplugin-cloudflare-tunnel",
3
- "version": "0.0.0-alpha-1",
4
- "packageManager": "bun@1.3.1",
3
+ "version": "0.0.1",
4
+ "packageManager": "bun@1.3.5",
5
5
  "description": "A plugin that automatically creates and manages Cloudflare tunnels for local development",
6
6
  "type": "module",
7
7
  "imports": {
@@ -51,28 +51,27 @@
51
51
  "dependencies": {
52
52
  "cloudflared": "^0.7.1",
53
53
  "unplugin": "^2.3.10",
54
- "unplugin-utils": "^0.3.1",
55
- "zod": "^4.1.12"
54
+ "zod": "^4.2.1"
56
55
  },
57
56
  "devDependencies": {
58
57
  "@arethetypeswrong/core": "^0.18.2",
59
- "@biomejs/biome": "^2.3.2",
60
- "@changesets/changelog-github": "^0.5.1",
61
- "@changesets/cli": "^2.29.7",
58
+ "@biomejs/biome": "^2.3.10",
59
+ "@changesets/changelog-github": "^0.5.2",
60
+ "@changesets/cli": "^2.29.8",
62
61
  "@rspack/core": "^1.5.7",
63
- "@sxzz/test-utils": "^0.5.12",
62
+ "@sxzz/test-utils": "^0.5.15",
64
63
  "@total-typescript/ts-reset": "^0.6.1",
65
- "@types/bun": "^1.3.1",
66
- "@types/node": "^24.9.1",
67
- "execa": "^9.6.0",
68
- "publint": "^0.3.15",
64
+ "@types/bun": "^1.3.5",
65
+ "@types/node": "^25.0.3",
66
+ "execa": "^9.6.1",
67
+ "publint": "^0.3.16",
69
68
  "rollup": "^4.52.3",
70
- "tsdown": "^0.15.10",
71
- "tsx": "^4.20.6",
69
+ "tsdown": "^0.15.12",
70
+ "tsx": "^4.21.0",
72
71
  "typescript": "^5.9.3",
73
- "unplugin-unused": "^0.5.4",
72
+ "unplugin-unused": "^0.5.6",
74
73
  "vite": "^7.1.12",
75
- "vitest": "^4.0.3",
74
+ "vitest": "^4.0.16",
76
75
  "webpack-dev-server": "^5.2.2"
77
76
  },
78
77
  "peerDependencies": {
@@ -111,7 +110,7 @@
111
110
  }
112
111
  },
113
112
  "engines": {
114
- "node": ">=20.19.0"
113
+ "node": ">=20.0"
115
114
  },
116
115
  "keywords": [
117
116
  "unplugin",
@@ -126,6 +125,7 @@
126
125
  ],
127
126
  "license": "MIT",
128
127
  "repository": "o-az/unplugin-cloudflare-tunnel",
128
+ "readme": "https://github.com/o-az/unplugin-cloudflare-tunnel/blob/main/.github/README.md",
129
129
  "author": "Omar A <gh@omar.mov>",
130
130
  "publishConfig": {
131
131
  "access": "public"