@lopatnov/conduit 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Readme.md CHANGED
@@ -1,99 +1,265 @@
1
1
  # @lopatnov/conduit
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@lopatnov/conduit.svg)](https://www.npmjs.com/package/@lopatnov/conduit)
4
- [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/lopatnov/conduit/blob/main/LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/@lopatnov/conduit.svg)](https://www.npmjs.com/package/@lopatnov/conduit)
4
+ [![npm downloads](https://img.shields.io/npm/dt/@lopatnov/conduit.svg)](https://www.npmjs.com/package/@lopatnov/conduit)
5
+ [![GitHub stars](https://img.shields.io/github/stars/lopatnov/conduit)](https://github.com/lopatnov/conduit/stargazers)
6
+ [![License](https://img.shields.io/github/license/lopatnov/conduit)](https://github.com/lopatnov/conduit/blob/main/LICENSE)
7
+ [![GitHub](https://img.shields.io/badge/source-GitHub-181717.svg)](https://github.com/lopatnov/conduit)
5
8
 
6
- **High-performance reverse proxy and static file server** — powered by [Cloudflare Pingora](https://github.com/cloudflare/pingora). Runs as a native Rust binary, distributed via npm for convenience.
9
+ > **High-performance reverse proxy and static file server** — one JSON config, one binary,
10
+ > zero runtime dependencies.
7
11
 
8
- - **Single binary** — no Node.js runtime needed after install
9
- - **One JSON file** describes your entire server
10
- - Static file server, reverse proxy, TLS termination, HTTP/2, IP filtering, redirects
11
- - Hot-reload in dev and Auto-TLS (Let's Encrypt) in production — [coming soon](https://github.com/lopatnov/conduit#implementation-status)
12
- - Drop-in upgrade path from `express-reverse-proxy`
12
+ Built on [Cloudflare Pingora](https://github.com/cloudflare/pingora). Routes ~1 trillion
13
+ requests/day in production at Cloudflare. Distributed as a native Rust binary via npm for
14
+ convenience.
13
15
 
14
- ## Installation
16
+ ---
17
+
18
+ ## Getting Started
19
+
20
+ **No installation needed:**
15
21
 
16
22
  ```bash
17
- # Use without installing
18
- npx @lopatnov/conduit
23
+ npx @lopatnov/conduit init # interactive setup wizard
24
+ npx @lopatnov/conduit # start
25
+ ```
19
26
 
20
- # Or install globally
27
+ **Install globally** then just type `conduit`:
28
+
29
+ ```bash
21
30
  npm install -g @lopatnov/conduit
31
+ conduit init
32
+ conduit
22
33
  ```
23
34
 
24
- The `postinstall` script automatically downloads the correct pre-built binary for your
25
- platform from [GitHub Releases](https://github.com/lopatnov/conduit/releases).
35
+ > **How it works:** `postinstall` downloads the correct pre-built native binary for your
36
+ > platform from [GitHub Releases](https://github.com/lopatnov/conduit/releases).
37
+ > No compilation. Node.js is only needed for the download step — the server itself is a
38
+ > standalone Rust binary.
26
39
 
27
- To skip the download (e.g., you built from source and placed the binary yourself):
40
+ ---
28
41
 
29
- ```bash
30
- CONDUIT_SKIP_DOWNLOAD=1 npm install @lopatnov/conduit
42
+ ## Minimal Config
43
+
44
+ Create `conduit.json`:
45
+
46
+ ```json
47
+ {
48
+ "port": 3000,
49
+ "proxy": { "/api": "http://localhost:4000" }
50
+ }
31
51
  ```
32
52
 
33
- ## Quick Start
53
+ Run:
34
54
 
35
55
  ```bash
36
- # Interactive setup wizard
37
- conduit init
38
-
39
- # Start the server
40
56
  conduit
57
+ ```
58
+
59
+ `GET /api/users` → `http://localhost:4000/api/users`. Done.
60
+
61
+ ---
62
+
63
+ ## Common Recipes
64
+
65
+ ### Serve static files
66
+
67
+ ```json
68
+ { "port": 3000, "static": "./dist" }
69
+ ```
41
70
 
42
- # Validate config without starting
43
- conduit validate
71
+ ### Reverse proxy to a backend
72
+
73
+ ```json
74
+ { "port": 3000, "proxy": "http://localhost:4000" }
44
75
  ```
45
76
 
46
- Minimal `conduit.json`:
77
+ ### SPA + API (most common)
47
78
 
48
79
  ```json
49
80
  {
50
81
  "port": 3000,
51
82
  "static": "./dist",
52
- "proxy": { "/api": "http://localhost:4000" }
83
+ "proxy": { "/api": "http://localhost:4000" },
84
+ "fallback": { "status": 200, "file": "./dist/index.html" }
53
85
  }
54
86
  ```
55
87
 
56
- ## CLI
88
+ ### Dev server with hot reload
57
89
 
58
- ```bash
59
- conduit start server (reads conduit.json)
60
- conduit -c <file> use a specific config file
61
- conduit init interactive wizard
62
- conduit validate validate config (exit 0 = OK)
63
- conduit probe HEAD to every upstream
64
- conduit fmt [--write] pretty-print config
65
- conduit reload hot-reload config (no restart)
66
- conduit status server status
67
- conduit upstreams upstream health and latency
68
- conduit shutdown graceful shutdown
69
- conduit --version
90
+ ```json
91
+ {
92
+ "port": 3000,
93
+ "logging": "dev",
94
+ "hotReload": true,
95
+ "cors": true,
96
+ "static": "./src",
97
+ "proxy": { "/api": "http://localhost:4000" },
98
+ "fallback": { "status": 200, "file": "./src/index.html" }
99
+ }
70
100
  ```
71
101
 
72
- ## Supported Platforms
102
+ ### Load-balanced backend with health checks
103
+
104
+ ```json
105
+ {
106
+ "port": 8080,
107
+ "proxy": {
108
+ "/api": {
109
+ "targets": ["http://api1:4000", "http://api2:4000", "http://api3:4000"],
110
+ "strategy": "least-conn",
111
+ "healthCheck": { "path": "/health", "intervalSecs": 10 },
112
+ "retry": { "attempts": 3, "conditions": ["connection_error", "5xx"] }
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ ### Production SPA with Auto-TLS (Let's Encrypt)
119
+
120
+ ```json
121
+ {
122
+ "port": 443,
123
+ "tls": { "acme": { "email": "admin@example.com" } },
124
+ "compression": true,
125
+ "securityHeaders": true,
126
+ "static": "./dist",
127
+ "staticOptions": { "maxAge": "7d", "preCompressed": true },
128
+ "proxy": {
129
+ "/api": {
130
+ "targets": ["http://api1:4000", "http://api2:4000"],
131
+ "strategy": "least-conn",
132
+ "stripPrefix": true,
133
+ "retry": { "attempts": 3, "conditions": ["connection_error", "5xx"] },
134
+ "cache": { "store": "memory", "ttlSecs": 60, "skipIfCookie": true }
135
+ }
136
+ },
137
+ "rateLimit": { "windowSecs": 60, "limit": 200 },
138
+ "healthCheck": true,
139
+ "metrics": { "path": "/__metrics__", "token": "$METRICS_TOKEN" },
140
+ "fallback": {
141
+ "byAccept": {
142
+ "html": { "status": 200, "file": "./dist/index.html" },
143
+ "json": { "status": 404, "body": { "error": "Not Found" } }
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ ### Multiple sites from one process
150
+
151
+ ```json
152
+ [
153
+ {
154
+ "host": "app.example.com",
155
+ "port": 443,
156
+ "tls": { "cert": "$CERT", "key": "$KEY" },
157
+ "static": "./dist",
158
+ "proxy": { "/api": "http://api:4000" }
159
+ },
160
+ {
161
+ "host": "admin.example.com",
162
+ "port": 443,
163
+ "tls": { "cert": "$CERT", "key": "$KEY" },
164
+ "basicAuth": { "users": { "admin": "$ADMIN_PASS" }, "challenge": true },
165
+ "static": "./admin-ui"
166
+ }
167
+ ]
168
+ ```
73
169
 
74
- | Platform | Architecture | Supported |
75
- | -------- | --------------------- | --------- |
76
- | Linux | x86-64 | ✅ |
77
- | Linux | ARM64 | ✅ |
78
- | macOS | x86-64 (Intel) | ✅ |
79
- | macOS | ARM64 (Apple Silicon) | ✅ |
80
- | Windows | x86-64 | ✅ |
170
+ ---
81
171
 
82
- ## Alternatives
172
+ ## CLI Reference
83
173
 
84
- If the binary download fails or your platform is not supported, install from source:
174
+ ```text
175
+ conduit start server (reads conduit.json)
176
+ conduit -c <file> use a specific config file
177
+ conduit --version print version
178
+
179
+ conduit init interactive setup wizard
180
+ conduit validate validate config (exit 0 = OK)
181
+ conduit probe HEAD each upstream, show latency
182
+ conduit fmt [--write] pretty-print config to stdout or file
183
+
184
+ conduit reload hot-reload config without restart
185
+ conduit status show uptime and inflight requests
186
+ conduit upstreams list upstream health and latency
187
+ conduit upstreams add --route PATH --target URL
188
+ conduit shutdown graceful shutdown
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Features
194
+
195
+ | Feature | Details |
196
+ | --- | --- |
197
+ | **Static files** | ETag, Last-Modified, Range, dotfile control, pre-compressed `.br`/`.gz` |
198
+ | **Compression** | gzip + brotli (async, streaming) |
199
+ | **Reverse proxy** | 7 load-balancing strategies; upstream health checks; retry on failure |
200
+ | **Proxy cache** | Memory, Redis, or disk store; Vary headers; skip-paths |
201
+ | **Auto-TLS** | Let's Encrypt via ACME — automatic issue and renewal |
202
+ | **HTTP/2** | ALPN negotiation; H/2 upstream support |
203
+ | **WebSocket** | Transparent proxying |
204
+ | **Hot config reload** | `conduit reload` — zero-downtime, no restart |
205
+ | **IP filtering** | CIDR allow/deny lists; trust X-Forwarded-For |
206
+ | **Rate limiting** | Token-bucket, keyed by IP or header; Redis-backed for clusters |
207
+ | **Auth** | Basic auth + API key, per-route skip-paths |
208
+ | **CORS** | Origin allow-list, credentials, preflight |
209
+ | **Security headers** | CSP, HSTS, X-Frame-Options, Referrer-Policy |
210
+ | **Health check** | `/__health__` with optional upstream status |
211
+ | **Prometheus** | `/__metrics__` — request counters, duration histograms, cache metrics |
212
+ | **File upload** | `multipart/form-data` — UUID filenames, MIME validation |
213
+ | **Redirects** | Named params (`:slug`), 301/302/307/308 |
214
+ | **Advanced routing** | Glob path + method + header + query predicates |
215
+ | **Virtual hosting** | Multiple sites (`host` matching) in one process |
216
+ | **SPA fallback** | Per-Accept-type fallback rules |
217
+ | **Structured logging** | `dev`, `combined`, `json`, `short`, `common` formats |
218
+ | **Rhai scripting** | Inline middleware scripts for custom logic |
219
+
220
+ ---
221
+
222
+ ## Supported Platforms
223
+
224
+ | Platform | Architecture |
225
+ | --- | --- |
226
+ | Linux | x86-64 (glibc) |
227
+ | Linux | x86-64 (musl / Docker) |
228
+ | Linux | ARM64 |
229
+ | macOS | Intel (x86-64) |
230
+ | macOS | Apple Silicon (ARM64) |
231
+ | Windows | x86-64 |
232
+
233
+ Unsupported platform? Install from source:
85
234
 
86
235
  ```bash
87
236
  cargo install lopatnov-conduit
88
237
  ```
89
238
 
90
- Or download a pre-built binary directly from
91
- [GitHub Releases](https://github.com/lopatnov/conduit/releases).
239
+ ---
240
+
241
+ ## Links
242
+
243
+ - 📦 [npm package](https://www.npmjs.com/package/@lopatnov/conduit)
244
+ - 🦀 [crates.io package](https://crates.io/crates/lopatnov-conduit)
245
+ - 📖 [Full documentation & source](https://github.com/lopatnov/conduit)
246
+ - 🐛 [Report a bug](https://github.com/lopatnov/conduit/issues)
247
+ - 💬 [Discussions](https://github.com/lopatnov/conduit/discussions)
248
+
249
+ ---
250
+
251
+ ## Contributing
252
+
253
+ Contributions are welcome! Read [CONTRIBUTING.md](https://github.com/lopatnov/conduit/blob/main/CONTRIBUTING.md)
254
+ before opening a pull request.
92
255
 
93
- ## Documentation
256
+ Bug reports → [GitHub Issues](https://github.com/lopatnov/conduit/issues).
257
+ Security vulnerabilities → [GitHub Security Advisories](https://github.com/lopatnov/conduit/security/advisories).
258
+ Found it useful? A ⭐ on GitHub helps others discover the project.
94
259
 
95
- Full documentation: <https://github.com/lopatnov/conduit>
260
+ ---
96
261
 
97
262
  ## License
98
263
 
99
- [Apache 2.0](https://github.com/lopatnov/conduit/blob/main/LICENSE)
264
+ [Apache 2.0](https://github.com/lopatnov/conduit/blob/main/LICENSE) ©
265
+ 2024–2026 [Oleksandr Lopatnov](https://github.com/lopatnov)
package/package.json CHANGED
@@ -1,19 +1,29 @@
1
1
  {
2
2
  "name": "@lopatnov/conduit",
3
- "version": "0.2.0",
4
- "description": "High-performance reverse proxy and static file server powered by Cloudflare Pingora",
3
+ "version": "0.3.0",
4
+ "description": "High-performance reverse proxy and static file server built on Cloudflare Pingora. One JSON config, one binary, no runtime dependencies. TLS, HTTP/2, load balancing, Prometheus metrics, hot reload.",
5
5
  "keywords": [
6
6
  "reverse-proxy",
7
7
  "proxy",
8
- "static-server",
8
+ "static-file-server",
9
+ "web-server",
10
+ "dev-server",
9
11
  "http",
10
12
  "https",
11
13
  "http2",
14
+ "websocket",
15
+ "tls",
12
16
  "load-balancer",
17
+ "load-balancing",
18
+ "hot-reload",
19
+ "cors",
20
+ "rate-limiting",
21
+ "prometheus",
22
+ "health-check",
13
23
  "rust",
14
24
  "pingora"
15
25
  ],
16
- "homepage": "https://github.com/lopatnov/conduit#readme",
26
+ "homepage": "https://lopatnov.github.io/conduit/",
17
27
  "bugs": {
18
28
  "url": "https://github.com/lopatnov/conduit/issues"
19
29
  },
@@ -36,5 +46,9 @@
36
46
  },
37
47
  "engines": {
38
48
  "node": ">=18.0.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public",
52
+ "registry": "https://registry.npmjs.org/"
39
53
  }
40
54
  }