@iamken/cloudtunnel 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/README.md +131 -34
- package/dist/index.js +174 -168
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 thanhken
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,57 +1,154 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# ⛅ cloudtunnel
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Expose any local port at a public HTTPS subdomain — on _your own_ Cloudflare domains.**
|
|
6
|
+
|
|
7
|
+
Instant, self-owned tunnel sharing — the tunnel and DNS live in **your** Cloudflare account, so you keep clean, stable URLs and full control.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@iamken/cloudtunnel)
|
|
10
|
+
[](https://github.com/thanhken/cloudtunnel/actions)
|
|
11
|
+
[](#-license)
|
|
12
|
+
[](#-requirements)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
6
15
|
|
|
7
16
|
```bash
|
|
8
17
|
npm i -g @iamken/cloudtunnel
|
|
9
18
|
|
|
10
|
-
cloudtunnel login # once — paste a token
|
|
11
|
-
cloudtunnel 3000 # → https://brave-otter-1a2b.example.com is live
|
|
19
|
+
cloudtunnel login # once — paste a Cloudflare token; account + domain auto-resolved
|
|
20
|
+
cloudtunnel 3000 # → https://brave-otter-1a2b.example.com is live ✨
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## ✨ Why cloudtunnel
|
|
26
|
+
|
|
27
|
+
- 🔗 **Your domains, real subdomains** — routes through native Cloudflare Tunnel to `*.your-domain.com`, not a shared third-party host.
|
|
28
|
+
- ⚡ **One command** — `cloudtunnel 3000` creates the tunnel, DNS, and connector, then prints a live HTTPS URL. It even asks you which domain + subdomain to use.
|
|
29
|
+
- 🧭 **Just two states** — `up` brings a subdomain online; `down` (or Ctrl-C) releases it (deletes the tunnel + DNS). Re-running `up` always starts clean — no leftovers, no conflicts.
|
|
30
|
+
- 🗂️ **Profiles** — save a whole project's services and bring them all up with `cloudtunnel run mb`.
|
|
31
|
+
- 🌙 **Background mode** — `--detach` keeps connectors running after you close the terminal.
|
|
32
|
+
- 🔒 **Secure by default** — token passed via env (never argv), stored `0600`, destructive ops are ownership-gated and re-verified.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🚀 Quickstart
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cloudtunnel login # authenticate once
|
|
40
|
+
cloudtunnel 3000 # asks for domain + subdomain, then goes live
|
|
41
|
+
cloudtunnel 3000 -s api # skip the prompts: api.<your-domain>
|
|
42
|
+
cloudtunnel 3000 -s api -d foo.io # subdomain + domain
|
|
43
|
+
cloudtunnel 3000 --detach # run in the background
|
|
12
44
|
```
|
|
13
45
|
|
|
14
|
-
`cloudtunnel 3000`
|
|
46
|
+
Run `cloudtunnel 3000` with no flags and it guides you:
|
|
15
47
|
|
|
16
|
-
|
|
48
|
+
```
|
|
49
|
+
┌ cloudtunnel
|
|
50
|
+
◇ Choose a domain
|
|
51
|
+
│ ● example.com ○ foo.io
|
|
52
|
+
◇ Subdomain
|
|
53
|
+
│ api (leave blank for a random name)
|
|
54
|
+
◇ Connected
|
|
55
|
+
│
|
|
56
|
+
◇ Live ─────────────────────────────────────────╮
|
|
57
|
+
│ https://api.example.com → http://localhost:3000
|
|
58
|
+
│ Ctrl-C stops and releases this subdomain
|
|
59
|
+
╰─────────────────────────────────────────────────╯
|
|
60
|
+
```
|
|
17
61
|
|
|
18
|
-
|
|
62
|
+
---
|
|
19
63
|
|
|
20
|
-
## Commands
|
|
64
|
+
## 📦 Commands
|
|
21
65
|
|
|
22
|
-
| Command |
|
|
23
|
-
|
|
24
|
-
| `cloudtunnel login` | Authenticate;
|
|
25
|
-
| `cloudtunnel <port>`
|
|
26
|
-
| `cloudtunnel ls
|
|
27
|
-
| `cloudtunnel
|
|
28
|
-
| `cloudtunnel
|
|
29
|
-
| `cloudtunnel status <name>` | Tunnel health + connector state. |
|
|
30
|
-
| `cloudtunnel down [name] [--all]` | Stop connector(s); keep the tunnel + DNS. |
|
|
31
|
-
| `cloudtunnel gc [--yes]` | Prune crash orphans. |
|
|
66
|
+
| Command | What it does |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `cloudtunnel login` | Authenticate; resolve account + list your domains. `--status` to inspect. |
|
|
69
|
+
| `cloudtunnel <port>` · `up` | Bring a subdomain online. `-s/--subdomain`, `-d/--domain`, `--detach`, `-f/--force`, `--proto`. |
|
|
70
|
+
| `cloudtunnel ls` · `ps` | List subdomains — `# · SUBDOMAIN · TARGET · STATE · PID`. `--all` scans the whole account. |
|
|
71
|
+
| `cloudtunnel down <target>` · `rm` · `stop` | Release a subdomain — stop connector + delete tunnel + DNS. `--all`, `--dry-run`, `-f`. |
|
|
72
|
+
| `cloudtunnel logs <target>` | Show a connector's log. `-f` to follow, `-n` for line count. |
|
|
32
73
|
| `cloudtunnel zones` | List the domains in your account. |
|
|
74
|
+
| `cloudtunnel save <profile> <svc…>` | Save a group of services. `svc` = `name:port[:proto]`, or `--from-running`. |
|
|
75
|
+
| `cloudtunnel run <profile> [--detach]` | Bring up every service in a profile at once. |
|
|
76
|
+
| `cloudtunnel profiles [--rm <name>]` | List saved profiles (or delete one). |
|
|
77
|
+
|
|
78
|
+
> A **`<target>`** is a `#` number, a subdomain name, a full hostname, or a tunnel-id prefix — all shown in `ls`. `down` also accepts `rm` / `remove` / `delete` / `stop`.
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
$ cloudtunnel ls
|
|
82
|
+
┌───┬─────────────────────┬────────────────────────┬───────┬───────┐
|
|
83
|
+
│ # │ SUBDOMAIN │ TARGET │ STATE │ PID │
|
|
84
|
+
├───┼─────────────────────┼────────────────────────┼───────┼───────┤
|
|
85
|
+
│ 1 │ api.example.com │ http://localhost:3000 │ up │ 48213 │
|
|
86
|
+
│ 2 │ web.example.com │ https://localhost:5173 │ down │ - │
|
|
87
|
+
└───┴─────────────────────┴────────────────────────┴───────┴───────┘
|
|
88
|
+
|
|
89
|
+
$ cloudtunnel down 1 # release by number
|
|
90
|
+
$ cloudtunnel down --all # release everything
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 🗂️ Profiles
|
|
96
|
+
|
|
97
|
+
Expose a whole project's services with one command:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
cloudtunnel save mb api:3000 web:5173:https # define the group (or: save mb --from-running)
|
|
101
|
+
cloudtunnel run mb --detach # backend + frontend live in the background
|
|
102
|
+
cloudtunnel logs api -f # follow one service's log
|
|
103
|
+
cloudtunnel down --all # release them all
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 🧭 Two states: up & down
|
|
109
|
+
|
|
110
|
+
There are only two states. **`up`** brings a subdomain online (creating the tunnel + DNS). **`down`** — or pressing <kbd>Ctrl-C</kbd> in a foreground `up` — **releases** it: it stops the connector and deletes the tunnel + DNS on Cloudflare. Running `up` again recreates it cleanly (any leftover tunnel record for that name is cleaned up first, so you never hit conflicts).
|
|
111
|
+
|
|
112
|
+
Add **`--detach`** to keep a connector running in the **background** after the CLI exits (and after you close the terminal). Release it later with `cloudtunnel down <target>` (or `--all`) and tail its output with `cloudtunnel logs <target> -f`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 🔑 Authentication
|
|
117
|
+
|
|
118
|
+
Create a **Cloudflare API token** with these scopes (least-privilege — a token limited to the domains you tunnel into is recommended):
|
|
119
|
+
|
|
120
|
+
| Resource | Permission |
|
|
121
|
+
| --- | --- |
|
|
122
|
+
| Account | Cloudflare Tunnel · **Edit** |
|
|
123
|
+
| Account | Account Settings · **Read** |
|
|
124
|
+
| Zone | DNS · **Edit** |
|
|
125
|
+
| Zone | Zone · **Read** |
|
|
126
|
+
|
|
127
|
+
Provide it via (highest precedence first): `CLOUDFLARE_API_TOKEN` env → `cloudtunnel login --token-stdin` → the hidden prompt from `cloudtunnel login`.
|
|
33
128
|
|
|
34
|
-
|
|
129
|
+
> 🔒 The token is **never** passed on the command line (that would leak into `ps` / shell history) and is stored `0600`. Rotate it if a shared host is compromised.
|
|
35
130
|
|
|
36
|
-
|
|
131
|
+
---
|
|
37
132
|
|
|
38
|
-
|
|
39
|
-
- Account · **Account Settings** · Read
|
|
40
|
-
- Zone · **DNS** · Edit
|
|
41
|
-
- Zone · **Zone** · Read
|
|
133
|
+
## ✅ Requirements
|
|
42
134
|
|
|
43
|
-
|
|
135
|
+
- **Node.js ≥ 20**
|
|
136
|
+
- **`cloudflared`** on your `PATH` — install via `brew install cloudflared`, your package manager, or the [releases page](https://github.com/cloudflare/cloudflared/releases).
|
|
137
|
+
<br/>_(Auto-download is built in and fetches a pinned, SHA256-verified binary, but stays disabled until release checksums are pinned — treat `cloudflared` as a prerequisite for now.)_
|
|
44
138
|
|
|
45
|
-
|
|
139
|
+
---
|
|
46
140
|
|
|
47
|
-
|
|
48
|
-
- `cloudflared` on your `PATH` — install via `brew install cloudflared` / your package manager, or from <https://github.com/cloudflare/cloudflared/releases>. (Auto-download is built in and fetches a pinned, SHA256-verified binary, but stays disabled until release checksums are pinned — so treat `cloudflared` as a prerequisite for now.)
|
|
141
|
+
## 🩺 Troubleshooting
|
|
49
142
|
|
|
50
|
-
|
|
143
|
+
| Symptom | Cause & fix |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| **HTTP 1016** / subdomain won't load | The connector isn't running (`STATE = down` in `ls`). Bring it back up: `cloudtunnel <port> -s <name>`. |
|
|
146
|
+
| **`down` says "active connections"** | Handled automatically — cloudtunnel cleans up the connections and retries the delete. |
|
|
147
|
+
| **"grey-clouded" error** | The zone couldn't proxy the record; cfargotunnel routing needs an orange-cloud (proxied) CNAME. |
|
|
148
|
+
| **A DNS record already occupies the name** | Pick another `-s`/`-d`, or pass `-f/--force` to replace a non-tunnel record. |
|
|
51
149
|
|
|
52
|
-
|
|
53
|
-
- **"grey-clouded" error** — the zone couldn't proxy the record; cfargotunnel routing needs an orange-cloud (proxied) CNAME.
|
|
150
|
+
---
|
|
54
151
|
|
|
55
|
-
## License
|
|
152
|
+
## 📄 License
|
|
56
153
|
|
|
57
|
-
MIT
|
|
154
|
+
[MIT](LICENSE) © thanhken
|