### Install Cloudflared with PNPM Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Installs the cloudflared CLI globally using PNPM. ```sh pnpm i -g cloudflared ``` -------------------------------- ### Install Cloudflared with NPM Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Installs the cloudflared CLI globally using NPM. ```sh npm i -g cloudflared ``` -------------------------------- ### Install Cloudflared with Yarn Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Installs the cloudflared CLI globally using Yarn. ```sh yarn global add cloudflared ``` -------------------------------- ### Manage Cloudflared Binary Path and Installation Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Checks if the cloudflared binary exists at the specified path and installs it if not. It then spawns the cloudflared process to display its version. ```javascript import { bin, install } from "cloudflared"; import fs from "node:fs"; import { spawn } from "node:child_process"; if (!fs.existsSync(bin)) { // install cloudflared binary await install(bin); } // run cloudflared spawn(bin, ["--version"], { stdio: "inherit" }); ``` -------------------------------- ### Binary Management: install(to, version?) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Downloads the platform-appropriate `cloudflared` binary from GitHub releases to the specified path. Defaults to the version set by `CLOUDFLARED_VERSION` env var, or "latest". Returns a Promise resolving to the installed binary path. ```APIDOC ## install(to, version?) ### Description Downloads the platform-appropriate `cloudflared` binary from GitHub releases to the specified path. Defaults to the version set by `CLOUDFLARED_VERSION` env var, or "latest". Returns a Promise resolving to the installed binary path. ### Parameters - **to** (string) - The path where the binary should be installed. - **version** (string, optional) - The specific version of `cloudflared` to install. Defaults to "latest" or the version specified by `CLOUDFLARED_VERSION` environment variable. ### Usage ```ts import { install, bin } from "cloudflared"; // Install the latest version const path1 = await install(bin); console.log("Latest installed at:", path1); // Install a specific version const path2 = await install("/usr/local/bin/cloudflared", "2024.1.5"); console.log("Specific version installed at:", path2); // Install with CLOUDFLARED_VERSION env var // CLOUDFLARED_VERSION=2023.8.2 node script.js // → installs 2023.8.2 automatically via postinstall ``` ``` -------------------------------- ### service.install Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Installs `cloudflared` as a persistent background service. Requires root on Linux. ```APIDOC ## `service.install(token?)` — Install cloudflared as a system service Installs `cloudflared` as a persistent background service (launchd on macOS, systemd or SysV on Linux). Pass a tunnel token to run a named tunnel, or omit it to use a config file. **Requires root on Linux.** ```ts import { service, AlreadyInstalledError } from "cloudflared"; try { // Install with a named tunnel token service.install(process.env.CLOUDFLARED_TOKEN); console.log("Service installed successfully"); } catch (err) { if (err instanceof AlreadyInstalledError) { console.log("Service is already installed"); } else { console.error("Install failed:", err.message); } } ``` ``` -------------------------------- ### Cloudflared Service Status Example Output Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Example output from running the service.js script, showing that the service is running and detailing its ingress rules and metrics server. ```sh ❯ node examples/service.js Cloudflared Service Example. Service is running. - http://localhost:12345 -> sub.example.com - http_status:404 -> undefined metrics server: 127.0.0.1:49177/metrics ``` -------------------------------- ### Check and Install cloudflared Binary Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Ensures the cloudflared binary is available, installing it if necessary. The `bin` constant provides the path to the executable. ```typescript import fs from "node:fs"; import { spawn } from "node:child_process"; import { bin, install } from "cloudflared"; // Check and install the binary if missing if (!fs.existsSync(bin)) { console.log("Installing cloudflared..."); const installedPath = await install(bin); console.log("Installed to:", installedPath); // Output: Installed to: /path/to/node_modules/cloudflared/bin/cloudflared } // Run the binary directly spawn(bin, ["--version"], { stdio: "inherit" }); // Output: cloudflared version 2024.8.2 (built 2024-08-02T00:00:00Z) ``` -------------------------------- ### Download and Install cloudflared Binary Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Downloads the cloudflared binary from GitHub releases to a specified path. Supports installing the latest or a specific version. The `CLOUDFLARED_VERSION` environment variable can also dictate the version. ```typescript import { install, bin } from "cloudflared"; // Install the latest version const path1 = await install(bin); console.log("Latest installed at:", path1); // Install a specific version const path2 = await install("/usr/local/bin/cloudflared", "2024.1.5"); console.log("Specific version installed at:", path2); // Install with CLOUDFLARED_VERSION env var // CLOUDFLARED_VERSION=2023.8.2 node script.js // → installs 2023.8.2 automatically via postinstall ``` -------------------------------- ### Cloudflared Tunnel Execution Example Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Example output from running the tunnel.js script, showing the generated tunnel URL, connection details, and the process exit code. ```sh ❯ node examples/tunnel.js Cloudflared Tunnel Example. LINK: https://mailto-davis-wilderness-facts.trycloudflare.com CONN: { id: 'df1b8330-44ea-4ecb-bb93-8a32400f6d1c', ip: '198.41.200.193', location: 'tpe01' } tunnel process exited with code 0 ``` -------------------------------- ### cloudflared bin Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Manage the cloudflared binary from the command line. Provides install, remove, and list operations. ```APIDOC ## `cloudflared bin` — Manage the binary from the command line ### Description The `bin` subcommand provides install/remove/list operations for the `cloudflared` binary outside of the JavaScript API. ### Usage - Print binary path: ```sh cloudflared bin ``` - Install latest cloudflared binary: ```sh cloudflared bin install ``` - Install a specific version: ```sh cloudflared bin install 2024.1.5 ``` - List the 30 most recent releases: ```sh cloudflared bin list ``` - Remove the installed binary: ```sh cloudflared bin remove ``` - Pass any cloudflared command through (auto-installs binary if missing): ```sh cloudflared tunnel --hello-world cloudflared tunnel --url http://localhost:3000 cloudflared --version ``` ``` -------------------------------- ### Install cloudflared as a System Service Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Installs cloudflared as a persistent background service. Pass a tunnel token to run a named tunnel, or omit it to use a config file. Requires root on Linux. Handles AlreadyInstalledError if the service is already present. ```typescript import { service, AlreadyInstalledError } from "cloudflared"; try { // Install with a named tunnel token service.install(process.env.CLOUDFLARED_TOKEN); console.log("Service installed successfully"); } catch (err) { if (err instanceof AlreadyInstalledError) { console.log("Service is already installed"); } else { console.error("Install failed:", err.message); } } ``` -------------------------------- ### Manage cloudflared Binary via CLI Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt The `bin` subcommand manages the cloudflared binary from the command line, including installation, listing versions, and removal. It can also pass commands through to the cloudflared executable. ```bash # Print binary path cloudflared bin ``` ```bash # Install latest cloudflared binary cloudflared bin install ``` ```bash # Install a specific version cloudflared bin install 2024.1.5 ``` ```bash # List the 30 most recent releases cloudflared bin list ``` ```bash # Remove the installed binary cloudflared bin remove ``` ```bash # Pass any cloudflared command through (auto-installs binary if missing) cloudflared tunnel --hello-world ``` ```bash cloudflared tunnel --url http://localhost:3000 ``` ```bash cloudflared --version ``` -------------------------------- ### service.exists Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Checks if the `cloudflared` service is installed on the system. ```APIDOC ## `service.exists()` — Check if the service is installed Returns `true` if the `cloudflared` service plist (macOS) or unit file (Linux) exists on disk. Use this to guard install/uninstall calls. ```ts import { service } from "cloudflared"; if (service.exists()) { console.log("cloudflared service is installed"); } else { console.log("cloudflared service is NOT installed"); } // Typical guard pattern if (!service.exists()) { service.install(process.env.CLOUDFLARED_TOKEN); } ``` ``` -------------------------------- ### Cloudflared Binary Management CLI Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Provides commands to manage the cloudflared binary, including printing its path, removing it, installing specific versions, listing releases, and displaying help. ```sh ❯ cloudflared bin --help cloudflared bin : Prints the path to the binary cloudflared bin remove : Removes the binary cloudflared bin install [version] : Installs the binary cloudflared bin list : Lists 30 latest releases cloudflared bin help : Prints this help message Examples: cloudflared bin install : Installs the latest version of cloudflared cloudflared bin install 2023.4.1 : Installs cloudflared 2023.4.1 You can find releases at https://github.com/cloudflare/cloudflared/releases ``` -------------------------------- ### Error Classes Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Provides typed error handling for install and service flows with specific error classes. ```APIDOC ## Error Classes ### `UnsupportedError`, `AlreadyInstalledError`, `NotInstalledError` — Typed error handling ### Description The library exports three error classes for predictable error handling in install/service flows. ### Usage - Binary install error handling: ```ts import { install, bin, UnsupportedError } from "cloudflared"; try { await install(bin, "2024.1.5"); } catch (err) { if (err instanceof UnsupportedError) { console.error("Platform or architecture not supported:", err.message); // e.g., "Unsupported platform: freebsd" } } ``` - Service lifecycle error handling: ```ts import { service, AlreadyInstalledError, NotInstalledError } from "cloudflared"; try { service.install(process.env.TOKEN); } catch (err) { if (err instanceof AlreadyInstalledError) { console.log("Already running — skipping install"); } else if (err instanceof NotInstalledError) { console.log("Not found — nothing to uninstall"); } else { throw err; } } ``` ``` -------------------------------- ### Tunnel Class: Tunnel.quick(url?, options?) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Static factory that spawns `cloudflared tunnel --url ` (or `--hello-world` if no URL is given). Returns a `Tunnel` instance immediately; listen for the "url" event to get the public HTTPS address. No Cloudflare account or token is needed. ```APIDOC ## Tunnel.quick(url?, options?) ### Description Static factory that spawns `cloudflared tunnel --url ` (or `--hello-world` if no URL is given). Returns a `Tunnel` instance immediately; listen for the "url" event to get the public HTTPS address. No Cloudflare account or token is needed. ### Parameters - **url** (string, optional) - The local URL to expose through the tunnel. If not provided, `--hello-world` is used. - **options** (object, optional) - Additional options for the tunnel. ### Events - **url**: Emitted when the public URL for the tunnel is available. - **connected**: Emitted when the first edge connection to the tunnel is established. - **disconnected**: Emitted when an edge connection is lost. - **stdout**: Emitted with data from the tunnel's standard output. - **stderr**: Emitted with data from the tunnel's standard error. - **exit**: Emitted when the tunnel process exits, with the exit code. - **error**: Emitted when an error occurs. ### Usage ```ts import fs from "node:fs"; import { Tunnel, bin, install } from "cloudflared"; if (!fs.existsSync(bin)) { await install(bin); } // Expose a local HTTP server at port 3000 const tunnel = Tunnel.quick("http://localhost:3000"); // Wait for the public URL const url = await new Promise((resolve) => tunnel.once("url", resolve)); console.log("Public URL:", url); // Output: Public URL: https://random-words-here.trycloudflare.com // Wait for the first edge connection to be established const conn = await new Promise((resolve) => tunnel.once("connected", resolve)); console.log("Edge connection:", conn); // Output: Edge connection: { id: 'df1b8330-...', ip: '198.41.200.193', location: 'tpe01' } // Gracefully stop the tunnel after 30 seconds setTimeout(tunnel.stop, 30_000); tunnel.on("exit", (code) => { console.log("Tunnel exited with code:", code); // Output: Tunnel exited with code: 0 }); ``` ``` -------------------------------- ### Create a Quick Tunnel Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Spawns a `cloudflared tunnel` command to expose a local URL publicly. Listens for the 'url' event to get the public HTTPS address. No Cloudflare account or token is required. ```typescript import fs from "node:fs"; import { Tunnel, bin, install } from "cloudflared"; if (!fs.existsSync(bin)) { await install(bin); } // Expose a local HTTP server at port 3000 const tunnel = Tunnel.quick("http://localhost:3000"); // Wait for the public URL const url = await new Promise((resolve) => tunnel.once("url", resolve)); console.log("Public URL:", url); // Output: Public URL: https://random-words-here.trycloudflare.com // Wait for the first edge connection to be established const conn = await new Promise((resolve) => tunnel.once("connected", resolve)); console.log("Edge connection:", conn); // Output: Edge connection: { id: 'df1b8330-...', ip: '198.41.200.193', location: 'tpe01' } // Gracefully stop the tunnel after 30 seconds setTimeout(tunnel.stop, 30_000); tunnel.on("exit", (code) => { console.log("Tunnel exited with code:", code); // Output: Tunnel exited with code: 0 }); ``` -------------------------------- ### service.clean() Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Removes stale log files for a previously uninstalled service on macOS. Throws AlreadyInstalledError if the service is still installed. This function is specific to macOS. ```APIDOC ## `service.clean()` — Remove stale service log files ### Description Removes leftover log files from a previously uninstalled service on macOS. Throws `AlreadyInstalledError` if the service is still installed. macOS only. ### Method ```ts service.clean(); ``` ### Throws - `AlreadyInstalledError`: If the service is still installed. ### Example ```ts import { service, AlreadyInstalledError } from "cloudflared"; try { service.clean(); console.log("Stale log files removed"); } catch (err) { if (err instanceof AlreadyInstalledError) { console.log("Cannot clean: service is still installed"); } } ``` ``` -------------------------------- ### Check if the cloudflared Service is Installed Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Returns true if the cloudflared service configuration file exists on disk. Use this to guard install/uninstall calls. This is a typical pattern to prevent errors when managing the service. ```typescript import { service } from "cloudflared"; if (service.exists()) { console.log("cloudflared service is installed"); } else { console.log("cloudflared service is NOT installed"); } // Typical guard pattern if (!service.exists()) { service.install(process.env.CLOUDFLARED_TOKEN); } ``` -------------------------------- ### Typed Error Handling for Install/Service Flows Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Handles predictable errors during binary installation and service lifecycle management using exported error classes. Catches specific errors like UnsupportedError, AlreadyInstalledError, and NotInstalledError. ```typescript import { install, bin, service, UnsupportedError, AlreadyInstalledError, NotInstalledError, } from "cloudflared"; // Binary install error try { await install(bin, "2024.1.5"); } catch (err) { if (err instanceof UnsupportedError) { console.error("Platform or architecture not supported:", err.message); // e.g., "Unsupported platform: freebsd" } } ``` ```typescript // Service lifecycle errors try { service.install(process.env.TOKEN); } catch (err) { if (err instanceof AlreadyInstalledError) { console.log("Already running — skipping install"); } else if (err instanceof NotInstalledError) { console.log("Not found — nothing to uninstall"); } else { throw err; } } ``` -------------------------------- ### Uninstall the cloudflared System Service Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Stops and removes the cloudflared system service and cleans up log files. Throws NotInstalledError if the service is not currently installed. Requires root on Linux. ```typescript import { service, NotInstalledError } from "cloudflared"; try { service.uninstall(); console.log("Service uninstalled"); } catch (err) { if (err instanceof NotInstalledError) { console.log("Service was not installed"); } else { console.error("Uninstall failed:", err.message); } } ``` -------------------------------- ### Remove Stale Service Log Files (macOS) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Removes leftover log files from a previously uninstalled service on macOS. Throws AlreadyInstalledError if the service is still installed. This function is macOS-specific. ```typescript import { service, AlreadyInstalledError } from "cloudflared"; try { service.clean(); console.log("Stale log files removed"); } catch (err) { if (err instanceof AlreadyInstalledError) { console.log("Cannot clean: service is still installed"); } } ``` -------------------------------- ### Create and Manage a Cloudflared Tunnel Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Demonstrates creating a quick hello-world tunnel, listening for 'url' and 'connected' events, logging the tunnel URL and connection details, and stopping the tunnel after 15 seconds. It also logs the exit code of the tunnel process. ```javascript import { Tunnel } from "cloudflared"; console.log("Cloudflared Tunnel Example."); main(); async function main() { // run: cloudflared tunnel --hello-world const tunnel = Tunnel.quick(); // show the url const url = new Promise((resolve) => tunnel.once("url", resolve)); console.log("LINK:", await url); // wait for connection to be established const conn = new Promise((resolve) => tunnel.once("connected", resolve)); console.log("CONN:", await conn); // stop the tunnel after 15 seconds setTimeout(tunnel.stop, 15_000); tunnel.on("exit", (code) => { console.log("tunnel process exited with code", code); }); } ``` -------------------------------- ### Binary Management: use(executable) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Overrides the `bin` path used by all tunnel and service operations within the current process. Useful when you bundle or ship your own `cloudflared` binary. ```APIDOC ## use(executable) ### Description Overrides the `bin` path used by all tunnel and service operations within the current process. Useful when you bundle or ship your own `cloudflared` binary. ### Parameters - **executable** (string) - The path to the custom `cloudflared` executable. ### Usage ```ts import { use, bin, Tunnel } from "cloudflared"; console.log("Default bin:", bin); // Output: /path/to/node_modules/cloudflared/bin/cloudflared // Point to a custom binary use("/opt/custom/cloudflared"); console.log("New bin:", bin); // Output: /opt/custom/cloudflared // All subsequent Tunnel/service calls now use the custom binary const tunnel = Tunnel.quick("http://localhost:3000"); ``` ``` -------------------------------- ### Binary Management: bin Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt `bin` is a mutable string constant holding the resolved path to the `cloudflared` binary. It respects the `CLOUDFLARED_BIN` environment variable, falling back to a default path inside the package's `bin/` directory. ```APIDOC ## bin ### Description `bin` is a mutable string constant holding the resolved path to the `cloudflared` binary. It respects the `CLOUDFLARED_BIN` environment variable, falling back to a default path inside the package's `bin/` directory. ### Usage ```ts import fs from "node:fs"; import { spawn } from "node:child_process"; import { bin, install } from "cloudflared"; // Check and install the binary if missing if (!fs.existsSync(bin)) { console.log("Installing cloudflared..."); const installedPath = await install(bin); console.log("Installed to:", installedPath); // Output: Installed to: /path/to/node_modules/cloudflared/bin/cloudflared } // Run the binary directly spawn(bin, ["--version"], { stdio: "inherit" }); // Output: cloudflared version 2024.8.2 (built 2024-08-02T00:00:00Z) ``` ``` -------------------------------- ### new Tunnel(options) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Creates a tunnel instance using raw arguments or a configuration object. This constructor provides full access to `cloudflared` tunnel subcommands. ```APIDOC ## new Tunnel(options) ### Description The base `Tunnel` constructor accepts either a `TunnelOptions` record (converted automatically to CLI flags) or a raw `string[]` array of arguments passed directly to `cloudflared`. This provides full access to any `cloudflared` tunnel subcommand. ### Parameters #### Path Parameters - **options** (TunnelOptions | string[]) - Required - Either a `TunnelOptions` object or a raw string array of arguments for `cloudflared`. ### Example ```ts import { Tunnel } from "cloudflared"; // Using a TunnelOptions object — keys become CLI flags const tunnel1 = new Tunnel({ "--url": "http://localhost:4000", "--loglevel": "warn", }); // Using a raw string array for full control const tunnel2 = new Tunnel(["tunnel", "--url", "http://localhost:5000", "--no-autoupdate"]); tunnel2.on("url", (url) => console.log("URL:", url)); tunnel2.on("exit", (code, signal) => { console.log(`Exited: code=${code} signal=${signal}`); }); ``` ``` -------------------------------- ### service.uninstall Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Uninstalls the `cloudflared` system service. Requires root on Linux. ```APIDOC ## `service.uninstall()` — Uninstall the cloudflared system service Stops and removes the `cloudflared` system service and cleans up log files. Throws `NotInstalledError` if the service is not currently installed. **Requires root on Linux.** ```ts import { service, NotInstalledError } from "cloudflared"; try { service.uninstall(); console.log("Service uninstalled"); } catch (err) { if (err instanceof NotInstalledError) { console.log("Service was not installed"); } else { console.error("Uninstall failed:", err.message); } } ``` ``` -------------------------------- ### service.current Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Inspects the running service state, providing live information about the tunnel. ```APIDOC ## `service.current()` — Inspect the running service state Parses the service log files (or systemd journal) and returns live information about the running tunnel: tunnel ID, connector ID, active edge connections, metrics server address, and the parsed ingress configuration. ```ts import { service } from "cloudflared"; if (!service.exists()) { throw new Error("Service not running"); } const info = service.current(); console.log("Tunnel ID:", info.tunnelID); // Output: Tunnel ID: abc12345-1234-1234-1234-abc123456789 console.log("Connector ID:", info.connectorID); // Output: Connector ID: def67890-... console.log("Metrics server:", info.metrics); // Output: Metrics server: 127.0.0.1:49177/metrics for (const conn of info.connections) { if (conn.id) { console.log(` Edge: ${conn.location} @ ${conn.ip} (${conn.id})`); } } // Output: // Edge: tpe01 @ 198.41.200.193 (df1b8330-...) for (const rule of info.config.ingress ?? []) { console.log(` Route: ${rule.hostname ?? "(catch-all)"} → ${rule.service}`); } // Output: // Route: sub.example.com → http://localhost:12345 // Route: (catch-all) → http_status:404 ``` ``` -------------------------------- ### Tunnel.withToken(token, options?) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Creates an authenticated tunnel using a Cloudflare account token. This method is suitable for tunnels managed via the Cloudflare dashboard, running `cloudflared tunnel run --token `. ```APIDOC ## Tunnel.withToken(token, options?) ### Description Static factory for named Cloudflare Tunnels managed via the Cloudflare dashboard. Runs `cloudflared tunnel run --token `. The tunnel name, routing, and ingress rules are configured in the Cloudflare dashboard. ### Parameters #### Path Parameters - **token** (string) - Required - The Cloudflare account token. - **options** (object) - Optional - Options for the tunnel. ### Example ```ts import { Tunnel } from "cloudflared"; const token = process.env.CLOUDFLARED_TOKEN; if (!token) throw new Error("CLOUDFLARED_TOKEN is required"); const tunnel = Tunnel.withToken(token); tunnel.on("url", (url) => { console.log("Tunnel hostname:", url); }); process.on("SIGINT", () => { tunnel.stop(); }); ``` ``` -------------------------------- ### Create Tunnel with Raw Arguments Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt The `Tunnel` constructor accepts either a `TunnelOptions` object or a raw string array for direct CLI argument passing. This provides full control over `cloudflared` tunnel subcommands. ```typescript import { Tunnel } from "cloudflared"; // Using a TunnelOptions object — keys become CLI flags const tunnel1 = new Tunnel({ "--url": "http://localhost:4000", "--loglevel": "warn", }); // Using a raw string array for full control const tunnel2 = new Tunnel(["tunnel", "--url", "http://localhost:5000", "--no-autoupdate"]); tunnel2.on("url", (url) => console.log("URL:", url)); tunnel2.on("stdout", (data) => process.stdout.write(data)); tunnel2.on("stderr", (data) => process.stderr.write(data)); tunnel2.on("exit", (code, signal) => { console.log(`Exited: code=${code} signal=${signal}`); }); // Access the underlying ChildProcess console.log("PID:", tunnel2.process.pid); ``` -------------------------------- ### Parse and Emit Tunnel Configuration Updates Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Use ConfigHandler to parse 'Updated to new configuration' log lines and emit typed 'config' events. This is useful for tracking routing changes in named tunnels. Ensure CLOUDFLARED_TOKEN is set in the environment. ```typescript import { Tunnel, ConfigHandler, type TunnelConfig } from "cloudflared"; const tunnel = Tunnel.withToken(process.env.CLOUDFLARED_TOKEN!); // Generic parameter T constrains the config shape const handler = new ConfigHandler(tunnel); handler.on("config", ({ config, version }) => { console.log("Config version:", version); // Output: Config version: 1 for (const rule of config.ingress) { console.log(` Route: ${rule.hostname ?? "(catch-all)"} → ${rule.service}`); } // Output: // Route: app.example.com → http://localhost:8080 // Route: (catch-all) → http_status:404 }); handler.on("error", (err) => { console.error("Config parse error:", err.message); }); ``` -------------------------------- ### Read cloudflared Service Log Files Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Returns the raw contents of the stdout (log) or stderr (err) log files written by the cloudflared service. This is for macOS and Linux SysV systems. On Linux with systemd, use service.journal() instead. ```typescript import { service } from "cloudflared"; // macOS / Linux SysV only const stdout = service.log(); console.log("Service stdout log:", stdout || "(empty)"); const stderr = service.err(); console.log("Last 500 chars of stderr:", stderr.slice(-500)); ``` -------------------------------- ### service.journal Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Reads systemd journal entries for the cloudflared service. ```APIDOC ## `service.journal(n?)` — Read systemd journal entries Returns the last `n` log entries (default 300) from the systemd journal for `cloudflared.service`. Only available on Linux systems running systemd. ```ts import { service } from "cloudflared"; // Linux with systemd only const recentLogs = service.journal(50); console.log("Last 50 journal entries:\n", recentLogs); // Output: INF Registered tunnel connection connIndex=0 ... ``` ``` -------------------------------- ### Inspect the Running cloudflared Service State Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Parses service log files to return live information about the running tunnel, including tunnel ID, connector ID, active edge connections, metrics server address, and the parsed ingress configuration. Ensure the service exists before calling. ```typescript import { service } from "cloudflared"; if (!service.exists()) { throw new Error("Service not running"); } const info = service.current(); console.log("Tunnel ID:", info.tunnelID); // Output: Tunnel ID: abc12345-1234-1234-1234-abc123456789 console.log("Connector ID:", info.connectorID); // Output: Connector ID: def67890-... console.log("Metrics server:", info.metrics); // Output: Metrics server: 127.0.0.1:49177/metrics for (const conn of info.connections) { if (conn.id) { console.log(` Edge: ${conn.location} @ ${conn.ip} (${conn.id})`); } } // Output: // Edge: tpe01 @ 198.41.200.193 (df1b8330-... for (const rule of info.config.ingress ?? []) { console.log(` Route: ${rule.hostname ?? "(catch-all)"} → ${rule.service}`); } // Output: // Route: sub.example.com → http://localhost:12345 // Route: (catch-all) → http_status:404 ``` -------------------------------- ### ConfigHandler Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Parses and emits tunnel configuration updates. Useful for tracking routing changes in named tunnels. ```APIDOC ## `new ConfigHandler(tunnel)` — Parse and emit tunnel configuration updates A built-in output handler subclass that parses `cloudflared`'s `Updated to new configuration` log lines and emits typed `"config"` events with the parsed JSON ingress rules. Useful for tracking routing changes in named tunnels. ```ts import { Tunnel, ConfigHandler, type TunnelConfig } from "cloudflared"; const tunnel = Tunnel.withToken(process.env.CLOUDFLARED_TOKEN!); // Generic parameter T constrains the config shape const handler = new ConfigHandler(tunnel); handler.on("config", ({ config, version }) => { console.log("Config version:", version); // Output: Config version: 1 for (const rule of config.ingress) { console.log(` Route: ${rule.hostname ?? "(catch-all)"} → ${rule.service}`); } // Output: // Route: app.example.com → http://localhost:8080 // Route: (catch-all) → http_status:404 }); handler.on("error", (err) => { console.error("Config parse error:", err.message); }); ``` ``` -------------------------------- ### Override cloudflared Binary Path at Runtime Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Allows overriding the default `cloudflared` binary path used by the library within the current process. This is useful when providing a custom binary. ```typescript import { use, bin, Tunnel } from "cloudflared"; console.log("Default bin:", bin); // Output: /path/to/node_modules/cloudflared/bin/cloudflared // Point to a custom binary use("/opt/custom/cloudflared"); console.log("New bin:", bin); // Output: /opt/custom/cloudflared // All subsequent Tunnel/service calls now use the custom binary const tunnel = Tunnel.quick("http://localhost:3000"); ``` -------------------------------- ### Create Authenticated Tunnel with Token Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Use `Tunnel.withToken` for named tunnels managed in the Cloudflare dashboard. This requires the CLOUDFLARED_TOKEN environment variable. It allows attaching handlers for configuration changes, tunnel URLs, connection status, and errors. ```typescript import { Tunnel, ConfigHandler } from "cloudflared"; const token = process.env.CLOUDFLARED_TOKEN; if (!token) throw new Error("CLOUDFLARED_TOKEN is required"); const tunnel = Tunnel.withToken(token); // Attach a ConfigHandler to track ingress configuration changes const configHandler = new ConfigHandler(tunnel); configHandler.on("config", ({ config, version }) => { console.log(`Config v${version}:`, config); // Output: Config v1: { ingress: [{ hostname: "app.example.com", service: "http://localhost:8080" }, ...] } }); tunnel.on("url", (url) => { console.log("Tunnel hostname:", url); // Output: Tunnel hostname: app.example.com }); tunnel.on("connected", (conn) => { console.log("Connected:", conn); // Output: Connected: { id: '4db5ec6e-...', ip: '198.41.200.193', location: 'tpe01' } }); tunnel.on("disconnected", (conn) => { console.warn("Disconnected:", conn); }); tunnel.on("error", (err) => { console.error("Tunnel error:", err.message); }); // Stop on SIGINT process.on("SIGINT", () => { const killed = tunnel.stop(); console.log("Tunnel stopped:", killed); }); ``` -------------------------------- ### Read Systemd Journal Entries for cloudflared Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Returns the last n log entries (default 300) from the systemd journal for cloudflared.service. This function is only available on Linux systems running systemd. ```typescript import { service } from "cloudflared"; // Linux with systemd only const recentLogs = service.journal(50); console.log("Last 50 journal entries:\n", recentLogs); // Output: INF Registered tunnel connection connIndex=0 ... ``` -------------------------------- ### service.log / service.err Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Reads the raw contents of the stdout (`log`) or stderr (`err`) log files written by the cloudflared service. ```APIDOC ## `service.log()` / `service.err()` — Read service log files Returns the raw contents of the stdout (`log`) or stderr (`err`) log files written by the cloudflared service. On Linux with systemd, use `service.journal(n)` instead. ```ts import { service } from "cloudflared"; // macOS / Linux SysV only const stdout = service.log(); console.log("Service stdout log:", stdout || "(empty)"); const stderr = service.err(); console.log("Last 500 chars of stderr:", stderr.slice(-500)); ``` ``` -------------------------------- ### Add Custom Output Handler Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Register a function with `tunnel.addHandler()` to process stdout/stderr output. This allows parsing custom log patterns and emitting tunnel events. Use `tunnel.removeHandler()` to unregister. ```typescript import { Tunnel, type OutputHandler } from "cloudflared"; const tunnel = Tunnel.quick("http://localhost:3000"); // Custom handler to detect a specific log pattern const latencyHandler: OutputHandler = (output, t) => { const match = output.match(/rtt=(\d+)ms/); if (match) { const rtt = parseInt(match[1]); if (rtt > 200) { console.warn(`High latency detected: ${rtt}ms`); } } }; tunnel.addHandler(latencyHandler); // Remove it later when no longer needed setTimeout(() => { tunnel.removeHandler(latencyHandler); console.log("Latency handler removed"); }, 60_000); ``` -------------------------------- ### Check and Display Cloudflared Service Status Source: https://github.com/jacoblincool/node-cloudflared/blob/main/README.md Checks if the cloudflared service is running. If it is, it logs the service details including ingress rules and the metrics server address. Otherwise, it indicates that the service is not running. ```javascript import { service } from "cloudflared"; console.log("Cloudflared Service Example."); main(); async function main() { if (service.exists()) { console.log("Service is running."); const current = service.current(); for (const { service, hostname } of current.config.ingress) { console.log(` - ${service} -> ${hostname}`); } console.log("metrics server:", current.metrics); } else { console.log("Service is not running."); } } ``` -------------------------------- ### tunnel.stop() Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Stops a running tunnel by sending a SIGINT signal to the underlying `cloudflared` process. Returns true if the signal was delivered successfully. ```APIDOC ## tunnel.stop() ### Description Sends `SIGINT` to the underlying `cloudflared` process. Returns `true` if the signal was delivered successfully. The `"exit"` event fires when the process terminates. ### Returns - **boolean** - `true` if the signal was delivered successfully, `false` otherwise. ### Example ```ts import { Tunnel } from "cloudflared"; const tunnel = Tunnel.quick("http://localhost:8080"); const url = await new Promise((r) => tunnel.once("url", r)); console.log("Tunnel up at:", url); // Stop after 10 seconds setTimeout(() => { const ok = tunnel.stop(); console.log("Stop signal sent:", ok); // true }, 10_000); tunnel.on("exit", (code) => { console.log("Tunnel process exited, code:", code); // 0 }); ``` ``` -------------------------------- ### tunnel.addHandler(handler) / tunnel.removeHandler(handler) Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Registers or unregisters a custom output handler function. This function is called with every line of stdout/stderr output from the `cloudflared` process, allowing for custom log parsing and event emission. ```APIDOC ## tunnel.addHandler(handler) / tunnel.removeHandler(handler) ### Description Registers a function to be called with every line of stdout/stderr output from the `cloudflared` process. Handlers can parse custom log patterns and emit tunnel events. Use `removeHandler` to unregister. ### Parameters #### Path Parameters - **handler** (OutputHandler) - Required - The function to add or remove. ### Example ```ts import { Tunnel, type OutputHandler } from "cloudflared"; const tunnel = Tunnel.quick("http://localhost:3000"); // Custom handler to detect a specific log pattern const latencyHandler: OutputHandler = (output, t) => { const match = output.match(/rtt=(\d+)ms/); if (match) { const rtt = parseInt(match[1]); if (rtt > 200) { console.warn(`High latency detected: ${rtt}ms`); } } }; tunnel.addHandler(latencyHandler); // Remove it later when no longer needed setTimeout(() => { tunnel.removeHandler(latencyHandler); console.log("Latency handler removed"); }, 60_000); ``` ``` -------------------------------- ### Stop a Running Tunnel Source: https://context7.com/jacoblincool/node-cloudflared/llms.txt Use `tunnel.stop()` to send `SIGINT` to the `cloudflared` process. Returns `true` if the signal was sent. The ` ```typescript import { Tunnel } from "cloudflared"; const tunnel = Tunnel.quick("http://localhost:8080"); const url = await new Promise((r) => tunnel.once("url", r)); console.log("Tunnel up at:", url); // Stop after 10 seconds setTimeout(() => { const ok = tunnel.stop(); console.log("Stop signal sent:", ok); // true }, 10_000); tunnel.on("exit", (code) => { console.log("Tunnel process exited, code:", code); // 0 }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.