@viaalink/caddy-api-client 0.0.0-stage → 0.10.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/LICENSE +21 -0
- package/README.md +671 -2
- package/dist/caddy/index.d.ts +5 -0
- package/dist/caddy/index.js +5 -0
- package/dist/caddy-http-DLxwstYo.d.ts +2735 -0
- package/dist/caddy-http.zod-Cx-dcFkE.d.ts +2243 -0
- package/dist/caddy-types.d.ts +941 -0
- package/dist/caddy-types.js +1 -0
- package/dist/client-Bf2QoSWQ.d.ts +6712 -0
- package/dist/generated/extension-assets.d.ts +92 -0
- package/dist/generated/extension-assets.js +302 -0
- package/dist/index-BijF7qR9.d.ts +336 -0
- package/dist/index-BmimANG7.d.ts +1920 -0
- package/dist/index-Q5Jc47QL.d.ts +3025 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +6 -0
- package/dist/mitm/index.d.ts +218 -0
- package/dist/mitm/index.js +2 -0
- package/dist/plugins/caddy-dns/index.d.ts +2 -0
- package/dist/plugins/caddy-dns/index.js +1 -0
- package/dist/plugins/caddy-security/index.d.ts +3 -0
- package/dist/plugins/caddy-security/index.js +2 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/index.js +2 -0
- package/dist/types-DIjkvykh.d.ts +1041 -0
- package/package.json +168 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Viaalink
|
|
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,3 +1,672 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @viaalink/caddy-api-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeScript client for Caddy Admin API with MITMproxy integration.
|
|
4
|
+
Maintained by [Viaalink](https://github.com/viaalink).
|
|
5
|
+
|
|
6
|
+
Package pages:
|
|
7
|
+
|
|
8
|
+
- npm: https://www.npmjs.com/package/@viaalink/caddy-api-client
|
|
9
|
+
- Yarn Classic: https://classic.yarnpkg.com/en/package/@viaalink/caddy-api-client
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- ✅ **Type-safe Caddy API client** - Full TypeScript support with Zod validation
|
|
14
|
+
- ✅ **Route builders** - Composable functions for building Caddy routes
|
|
15
|
+
- ✅ **Domain management** - TLS automation with Let's Encrypt
|
|
16
|
+
- ✅ **Load balancing** - Health checks and multiple upstream support
|
|
17
|
+
- ✅ **MITMweb integration** - Traffic inspection for tunnels
|
|
18
|
+
- ✅ **Minimal dependencies** - Only peer dependency: `zod` for runtime validation
|
|
19
|
+
|
|
20
|
+
## Caddy Version Compatibility
|
|
21
|
+
|
|
22
|
+
| npm Package | Caddy | caddy-security | Notes |
|
|
23
|
+
| ------------ | ------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| 0.9.x–0.10.x | v2.11.4 | v1.1.64 | Current — 0.9.0: security-dense dependency bump, `caddy-dns` DNS provider plugin sources, first public vscode-extension release. 0.10.0: test-coverage-only, no dependency changes |
|
|
25
|
+
| 0.6.x–0.8.0 | v2.11.2 | v1.1.59 | First `caddy-dns` plugin (0.8.0) |
|
|
26
|
+
| 0.4.x–0.5.x | v2.10.2 | v1.1.31 | First plugin framework release |
|
|
27
|
+
| 0.3.x | v2.10.2 | — | Self-contained type generation |
|
|
28
|
+
| 0.1.x–0.2.x | — | — | Used external caddy-json-types |
|
|
29
|
+
|
|
30
|
+
See [DEPENDENCIES.md](./DEPENDENCIES.md) for full version details including commit hashes.
|
|
31
|
+
|
|
32
|
+
## Live Demo
|
|
33
|
+
|
|
34
|
+
Experience the library in action with our interactive demo showing dynamic MITMproxy traffic inspection via Caddy Admin API.
|
|
35
|
+
|
|
36
|
+
The demo showcases:
|
|
37
|
+
|
|
38
|
+
- **Split-screen view**: Interactive search UI + MITMproxy Web UI
|
|
39
|
+
- **Zero-downtime route switching**: Toggle monitoring without restarts
|
|
40
|
+
- **Library-powered routing**: All route configuration via `caddy-api-client`
|
|
41
|
+
|
|
42
|
+
Run locally: `docker compose -f demo/docker-compose.yml up -d` → http://localhost:9080/dashboard
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @viaalink/caddy-api-client zod
|
|
48
|
+
# or
|
|
49
|
+
yarn add @viaalink/caddy-api-client zod
|
|
50
|
+
# or
|
|
51
|
+
bun add @viaalink/caddy-api-client zod
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { CaddyClient, buildServiceRoutes } from "@viaalink/caddy-api-client/caddy";
|
|
58
|
+
|
|
59
|
+
// Create client
|
|
60
|
+
const client = new CaddyClient({
|
|
61
|
+
adminUrl: "http://127.0.0.1:2019",
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Build routes with type-safe builders
|
|
65
|
+
const routes = buildServiceRoutes({
|
|
66
|
+
host: "api.localhost",
|
|
67
|
+
dial: "127.0.0.1:3000",
|
|
68
|
+
securityHeaders: {
|
|
69
|
+
enableHsts: true,
|
|
70
|
+
frameOptions: "DENY",
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Add routes to Caddy
|
|
75
|
+
await client.addRoutes("https_server", routes);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **⚠️ Important:** Always use our type-safe builder functions instead of constructing raw Caddy JSON objects. Our builders provide:
|
|
79
|
+
>
|
|
80
|
+
> - ✅ Full TypeScript type checking and IDE autocomplete
|
|
81
|
+
> - ✅ Runtime Zod schema validation
|
|
82
|
+
> - ✅ Protection against common configuration errors
|
|
83
|
+
> - ✅ Clear documentation and examples
|
|
84
|
+
>
|
|
85
|
+
> **Raw Caddy JSON is error-prone and breaks easily.** Our builders are tested, validated, and prevent mistakes.
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
### Basic Route Management
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { CaddyClient, buildServiceRoutes } from "@viaalink/caddy-api-client/caddy";
|
|
93
|
+
|
|
94
|
+
const client = new CaddyClient();
|
|
95
|
+
|
|
96
|
+
// Build host-based route
|
|
97
|
+
const routes = buildServiceRoutes({
|
|
98
|
+
host: "api.localhost",
|
|
99
|
+
dial: "127.0.0.1:3000",
|
|
100
|
+
serviceId: "my-api",
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Add routes
|
|
104
|
+
for (const route of routes) {
|
|
105
|
+
await client.addRoute("https_server", route);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Get all routes
|
|
109
|
+
const allRoutes = await client.getRoutes("https_server");
|
|
110
|
+
|
|
111
|
+
// Remove routes by hostname
|
|
112
|
+
const removed = await client.removeRoutesByHost("old-api.localhost");
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Path-based Routes
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { buildServiceRoutes } from "@viaalink/caddy-api-client/caddy";
|
|
119
|
+
|
|
120
|
+
const routes = buildServiceRoutes({
|
|
121
|
+
path: "/api",
|
|
122
|
+
pathRouteHost: "example.localhost",
|
|
123
|
+
dial: "127.0.0.1:3000",
|
|
124
|
+
stripPrefix: true, // Strip /api before forwarding
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Load Balancing
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { CaddyClient, buildLoadBalancerRoute } from "@viaalink/caddy-api-client/caddy";
|
|
132
|
+
|
|
133
|
+
const client = new CaddyClient();
|
|
134
|
+
|
|
135
|
+
const lbRoute = buildLoadBalancerRoute({
|
|
136
|
+
host: "api.localhost",
|
|
137
|
+
upstreams: ["127.0.0.1:3000", "127.0.0.1:3001", "127.0.0.1:3002"],
|
|
138
|
+
policy: "round_robin", // or "first", "random", "least_conn"
|
|
139
|
+
healthCheckPath: "/health",
|
|
140
|
+
healthCheckInterval: "10s",
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
await client.addRoute("https_server", lbRoute);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Security Headers
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { buildServiceRoutes } from "@viaalink/caddy-api-client/caddy";
|
|
150
|
+
|
|
151
|
+
const routes = buildServiceRoutes({
|
|
152
|
+
host: "secure.localhost",
|
|
153
|
+
dial: "127.0.0.1:3000",
|
|
154
|
+
securityHeaders: {
|
|
155
|
+
enableHsts: true,
|
|
156
|
+
hstsMaxAge: 31536000, // 1 year
|
|
157
|
+
frameOptions: "DENY",
|
|
158
|
+
enableCompression: true,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Basic Authentication
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { buildServiceRoutes } from "@viaalink/caddy-api-client/caddy";
|
|
167
|
+
|
|
168
|
+
const routes = buildServiceRoutes({
|
|
169
|
+
host: "admin.localhost",
|
|
170
|
+
dial: "127.0.0.1:3000",
|
|
171
|
+
basicAuth: {
|
|
172
|
+
enabled: true,
|
|
173
|
+
username: "admin",
|
|
174
|
+
passwordHash: "$2y$10$...", // bcrypt hash
|
|
175
|
+
realm: "Admin Area",
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### MITMproxy Integration
|
|
181
|
+
|
|
182
|
+
Transparently inspect HTTP traffic for debugging production services **without modifying client or backend code, and without service restarts.**
|
|
183
|
+
|
|
184
|
+
#### Quick Start
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# 1. Start MITMproxy in Docker
|
|
188
|
+
docker run -d \
|
|
189
|
+
-p 8082:8080 \
|
|
190
|
+
-p 8081:8081 \
|
|
191
|
+
--name mitmproxy \
|
|
192
|
+
mitmproxy/mitmproxy:10.4.2 \
|
|
193
|
+
mitmweb \
|
|
194
|
+
--mode reverse:http://your-backend:3000 \
|
|
195
|
+
--web-host 0.0.0.0 \
|
|
196
|
+
--listen-host 0.0.0.0 \
|
|
197
|
+
--no-web-open-browser \
|
|
198
|
+
--set keep_host_header=true
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// 2. Enable traffic inspection (zero downtime)
|
|
203
|
+
import { CaddyClient, buildMitmproxyRoute } from "@viaalink/caddy-api-client/caddy";
|
|
204
|
+
|
|
205
|
+
const client = new CaddyClient({ adminUrl: "http://localhost:2019" });
|
|
206
|
+
|
|
207
|
+
const route = buildMitmproxyRoute({
|
|
208
|
+
host: "api.example.com",
|
|
209
|
+
mitmproxyHost: "localhost",
|
|
210
|
+
mitmproxyPort: 8082,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await client.addRoute("https_server", route, "api_debug");
|
|
214
|
+
|
|
215
|
+
// 3. View captured traffic at http://localhost:8081
|
|
216
|
+
|
|
217
|
+
// 4. Disable when done (zero downtime)
|
|
218
|
+
await client.removeRouteById("https_server", "api_debug");
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### Hot-Swapping Between Direct and Proxied Routing
|
|
222
|
+
|
|
223
|
+
Use `buildMitmproxyRoutePair()` to easily toggle traffic inspection on/off:
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { CaddyClient, buildMitmproxyRoutePair } from "@viaalink/caddy-api-client/caddy";
|
|
227
|
+
|
|
228
|
+
const client = new CaddyClient({ adminUrl: "http://localhost:2019" });
|
|
229
|
+
|
|
230
|
+
// Create both direct and proxied routes
|
|
231
|
+
const routes = buildMitmproxyRoutePair({
|
|
232
|
+
host: "api.example.com",
|
|
233
|
+
backendHost: "api-service",
|
|
234
|
+
backendPort: 3000,
|
|
235
|
+
mitmproxyHost: "localhost",
|
|
236
|
+
mitmproxyPort: 8082,
|
|
237
|
+
routeId: "api_route",
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Start with direct routing (no inspection)
|
|
241
|
+
await client.addRoute("https_server", routes.direct, routes.direct["@id"]);
|
|
242
|
+
|
|
243
|
+
// Hot-swap to enable inspection (zero downtime)
|
|
244
|
+
await client.removeRouteById("https_server", routes.direct["@id"]);
|
|
245
|
+
await client.addRoute("https_server", routes.proxied, routes.proxied["@id"]);
|
|
246
|
+
|
|
247
|
+
// Hot-swap back to disable inspection
|
|
248
|
+
await client.removeRouteById("https_server", routes.proxied["@id"]);
|
|
249
|
+
await client.addRoute("https_server", routes.direct, routes.direct["@id"]);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### Load Balancing with MITMproxy
|
|
253
|
+
|
|
254
|
+
Route some traffic through MITMproxy while keeping the rest direct:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { CaddyClient, buildLoadBalancerRoute } from "@viaalink/caddy-api-client/caddy";
|
|
258
|
+
|
|
259
|
+
const client = new CaddyClient();
|
|
260
|
+
const lbRoute = buildLoadBalancerRoute({
|
|
261
|
+
host: "api.localhost",
|
|
262
|
+
upstreams: [
|
|
263
|
+
"localhost:8082", // MITMproxy (captures traffic)
|
|
264
|
+
"localhost:3000", // Direct to backend
|
|
265
|
+
],
|
|
266
|
+
policy: "round_robin",
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
await client.addRoute("https_server", lbRoute);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Docker Compose Setup
|
|
273
|
+
|
|
274
|
+
```yaml
|
|
275
|
+
services:
|
|
276
|
+
mitmproxy:
|
|
277
|
+
image: mitmproxy/mitmproxy:10.4.2
|
|
278
|
+
ports:
|
|
279
|
+
- "8082:8080" # Proxy port
|
|
280
|
+
- "8081:8081" # Web UI
|
|
281
|
+
command: >
|
|
282
|
+
mitmweb
|
|
283
|
+
--mode reverse:http://backend:3000
|
|
284
|
+
--web-host 0.0.0.0
|
|
285
|
+
--web-port 8081
|
|
286
|
+
--listen-host 0.0.0.0
|
|
287
|
+
--listen-port 8080
|
|
288
|
+
--no-web-open-browser
|
|
289
|
+
--set keep_host_header=true
|
|
290
|
+
restart: unless-stopped
|
|
291
|
+
|
|
292
|
+
backend:
|
|
293
|
+
image: your-backend-image
|
|
294
|
+
ports:
|
|
295
|
+
- "3000:3000"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Features:**
|
|
299
|
+
|
|
300
|
+
- ✅ Zero client/backend code changes
|
|
301
|
+
- ✅ Zero service restarts required
|
|
302
|
+
- ✅ Hot-swappable at runtime
|
|
303
|
+
- ✅ Complete request/response inspection
|
|
304
|
+
- ✅ Web UI for viewing captured traffic
|
|
305
|
+
- ✅ Production-safe (tested with concurrent requests)
|
|
306
|
+
|
|
307
|
+
**Troubleshooting:** See the [MITMproxy Troubleshooting Guide](https://github.com/viaalink/asd-caddy-api-client/blob/main/docs/mitmproxy-troubleshooting.md) for common issues and solutions.
|
|
308
|
+
|
|
309
|
+
### Domain Management
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { addDomainWithAutoTls, deleteDomain } from "@viaalink/caddy-api-client/caddy";
|
|
313
|
+
|
|
314
|
+
// Add domain with automatic TLS (Let's Encrypt)
|
|
315
|
+
const domain = await addDomainWithAutoTls({
|
|
316
|
+
domain: "example.com",
|
|
317
|
+
target: "127.0.0.1",
|
|
318
|
+
targetPort: 3000,
|
|
319
|
+
enableHsts: true,
|
|
320
|
+
redirectMode: "permanent",
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Delete domain
|
|
324
|
+
await deleteDomain({ domain: "example.com" });
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## API Reference
|
|
328
|
+
|
|
329
|
+
### CaddyClient
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
class CaddyClient {
|
|
333
|
+
constructor(options?: CaddyClientOptions);
|
|
334
|
+
|
|
335
|
+
// Configuration
|
|
336
|
+
getConfig(): Promise<unknown>;
|
|
337
|
+
reload(): Promise<void>;
|
|
338
|
+
stop(): Promise<void>; // Gracefully stop Caddy server
|
|
339
|
+
adapt(config: string, adapter?: string): Promise<unknown>; // Convert Caddyfile to JSON
|
|
340
|
+
|
|
341
|
+
// Routes
|
|
342
|
+
getRoutes(server: string): Promise<CaddyRoute[]>;
|
|
343
|
+
addRoute(server: string, route: CaddyRoute): Promise<boolean>;
|
|
344
|
+
addRoutes(server: string, routes: CaddyRoute[]): Promise<{ added: number; skipped: number }>;
|
|
345
|
+
patchRoutes(server: string, routes: CaddyRoute[]): Promise<void>;
|
|
346
|
+
insertRoute(
|
|
347
|
+
server: string,
|
|
348
|
+
route: CaddyRoute,
|
|
349
|
+
position?: "beginning" | "end" | "after-health-checks"
|
|
350
|
+
): Promise<void>;
|
|
351
|
+
replaceRouteById(server: string, id: string, newRoute: CaddyRoute): Promise<boolean>;
|
|
352
|
+
removeRouteById(server: string, id: string): Promise<boolean>;
|
|
353
|
+
removeRoutesByHost(hostname: string, server?: string): Promise<number>;
|
|
354
|
+
|
|
355
|
+
// Servers
|
|
356
|
+
getServers(): Promise<unknown>;
|
|
357
|
+
getServerConfig(server: string): Promise<Record<string, unknown>>;
|
|
358
|
+
patchServer(serverConfig: Record<string, unknown>): Promise<void>;
|
|
359
|
+
|
|
360
|
+
// Upstreams (reverse proxy status)
|
|
361
|
+
getUpstreams(): Promise<UpstreamStatus[]>; // Get health/status of upstream servers
|
|
362
|
+
|
|
363
|
+
// Version
|
|
364
|
+
getVersion(): Promise<unknown>;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Route Builders
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// Service routes (host + path based)
|
|
372
|
+
buildServiceRoutes(options: ServiceRouteOptions): CaddyRoute[];
|
|
373
|
+
|
|
374
|
+
// Individual route types
|
|
375
|
+
buildHealthCheckRoute(options: HealthCheckRouteOptions): CaddyRoute;
|
|
376
|
+
buildHostRoute(options: HostRouteOptions): CaddyRoute;
|
|
377
|
+
buildPathRoute(options: PathRouteOptions): CaddyRoute;
|
|
378
|
+
buildLoadBalancerRoute(options: LoadBalancerRouteOptions): CaddyRoute;
|
|
379
|
+
|
|
380
|
+
// New handler routes (v0.3.0)
|
|
381
|
+
buildFileServerRoute(options: FileServerRouteOptions): CaddyRoute;
|
|
382
|
+
buildTemplatesRoute(options: TemplatesRouteOptions): CaddyRoute;
|
|
383
|
+
buildErrorRoute(options: ErrorRouteOptions): CaddyRoute;
|
|
384
|
+
|
|
385
|
+
// MITMproxy integration
|
|
386
|
+
buildMitmproxyRoute(options: MitmproxyRouteOptions): CaddyRoute;
|
|
387
|
+
buildMitmproxyRoutePair(options: MitmproxyRoutePairOptions): { direct: CaddyRoute; proxied: CaddyRoute };
|
|
388
|
+
|
|
389
|
+
// Handlers
|
|
390
|
+
buildReverseProxyHandler(dial: DialAddress): CaddyRouteHandler;
|
|
391
|
+
buildSecurityHeadersHandler(headers: SecurityHeaders): CaddyRouteHandler;
|
|
392
|
+
buildBasicAuthHandler(auth: BasicAuthOptions): CaddyRouteHandler;
|
|
393
|
+
buildRewriteHandler(prefix: string): CaddyRouteHandler;
|
|
394
|
+
buildCompressionHandler(options?: CompressionOptions): CaddyRouteHandler;
|
|
395
|
+
buildIngressTagHeadersHandler(tag: string): CaddyRouteHandler;
|
|
396
|
+
buildIframeHeadersHandler(allowedOrigin?: string): CaddyRouteHandler;
|
|
397
|
+
|
|
398
|
+
// New handlers (v0.3.0)
|
|
399
|
+
buildRequestBodyHandler(options: RequestBodyHandlerOptions): CaddyRouteHandler;
|
|
400
|
+
buildVarsHandler(options: VarsHandlerOptions): CaddyRouteHandler;
|
|
401
|
+
buildMapHandler(options: MapHandlerOptions): CaddyRouteHandler;
|
|
402
|
+
buildTracingHandler(options?: TracingHandlerOptions): CaddyRouteHandler;
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### MITMweb Functions
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
// Installation & status
|
|
409
|
+
isMitmproxyInstalled(): Promise<boolean>;
|
|
410
|
+
getMitmproxyVersion(): Promise<string | null>;
|
|
411
|
+
autoInstallMitmproxy(): Promise<boolean>;
|
|
412
|
+
|
|
413
|
+
// Process management
|
|
414
|
+
startMitmweb(options?: MitmwebOptions): Promise<{ pid, webUrl, proxyUrl, pidFile }>;
|
|
415
|
+
stopMitmweb(workingDir?: string): Promise<void>;
|
|
416
|
+
getMitmwebStatus(workingDir?: string): MitmwebStatus;
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Domain Management
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
addDomainWithAutoTls(options: AddDomainWithAutoTlsOptions): Promise<DomainConfig>;
|
|
423
|
+
addDomainWithTls(options: AddDomainWithTlsOptions): Promise<DomainConfig>;
|
|
424
|
+
updateDomain(options: UpdateDomainOptions): Promise<DomainConfig>;
|
|
425
|
+
deleteDomain(options: DeleteDomainOptions): Promise<void>;
|
|
426
|
+
getDomainConfig(domain: Domain, adminUrl?: string): Promise<DomainConfig | null>;
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Advanced Schemas
|
|
430
|
+
|
|
431
|
+
Zod-validated schemas for advanced Caddy configurations:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import {
|
|
435
|
+
// Duration (Go format)
|
|
436
|
+
CaddyDurationSchema, // "10s", "1m30s", or nanoseconds
|
|
437
|
+
|
|
438
|
+
// Health checks
|
|
439
|
+
ActiveHealthChecksSchema, // uri, interval, timeout, expect_status, expect_body
|
|
440
|
+
PassiveHealthChecksSchema, // fail_duration, max_fails, unhealthy_status
|
|
441
|
+
HealthChecksSchema, // Combined active + passive
|
|
442
|
+
|
|
443
|
+
// Load balancing
|
|
444
|
+
LoadBalancingSchema, // selection_policy, retries, try_duration
|
|
445
|
+
UpstreamSchema, // dial, max_requests
|
|
446
|
+
|
|
447
|
+
// Route matching
|
|
448
|
+
ExtendedRouteMatcherSchema, // client_ip, remote_ip, path_regexp, expression, not
|
|
449
|
+
|
|
450
|
+
// Handler
|
|
451
|
+
ReverseProxyHandlerSchema, // Full reverse proxy with health checks + load balancing
|
|
452
|
+
} from "@viaalink/caddy-api-client";
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Handler Types (v0.3.0)
|
|
456
|
+
|
|
457
|
+
Full TypeScript support for all 20 Caddy HTTP handlers with Zod validation:
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
import {
|
|
461
|
+
// File serving
|
|
462
|
+
FileServerHandlerSchema, // Static files with browse, precompressed
|
|
463
|
+
TemplatesHandlerSchema, // Server-side template rendering
|
|
464
|
+
|
|
465
|
+
// Request manipulation
|
|
466
|
+
RewriteHandlerSchema, // URI rewriting
|
|
467
|
+
RequestBodyHandlerSchema, // Body size limits
|
|
468
|
+
VarsHandlerSchema, // Set request variables
|
|
469
|
+
MapHandlerSchema, // Variable mapping
|
|
470
|
+
|
|
471
|
+
// Response handling
|
|
472
|
+
StaticResponseHandlerSchema, // Return static content
|
|
473
|
+
HeadersHandlerSchema, // Modify headers
|
|
474
|
+
EncodeHandlerSchema, // Compression (gzip, zstd, br)
|
|
475
|
+
ErrorHandlerSchema, // Trigger error handling
|
|
476
|
+
|
|
477
|
+
// Proxy & routing
|
|
478
|
+
ReverseProxyHandlerSchema, // Proxy to upstreams
|
|
479
|
+
SubrouteHandlerSchema, // Nested routes
|
|
480
|
+
InvokeHandlerSchema, // Call named routes
|
|
481
|
+
|
|
482
|
+
// Interception
|
|
483
|
+
InterceptHandlerSchema, // Response interception
|
|
484
|
+
CopyResponseHandlerSchema, // Copy subrequest response
|
|
485
|
+
CopyResponseHeadersHandlerSchema, // Copy headers
|
|
486
|
+
|
|
487
|
+
// Utilities
|
|
488
|
+
AuthenticationHandlerSchema, // HTTP basic auth
|
|
489
|
+
PushHandlerSchema, // HTTP/2 server push
|
|
490
|
+
TracingHandlerSchema, // Distributed tracing
|
|
491
|
+
LogAppendHandlerSchema, // Custom log fields
|
|
492
|
+
} from "@viaalink/caddy-api-client";
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Route builders for common patterns:**
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
import {
|
|
499
|
+
buildFileServerRoute, // Serve static files
|
|
500
|
+
buildTemplatesRoute, // Template processing
|
|
501
|
+
buildErrorRoute, // Error responses
|
|
502
|
+
buildRequestBodyHandler, // Body limits
|
|
503
|
+
buildVarsHandler, // Set variables
|
|
504
|
+
buildMapHandler, // Variable mapping
|
|
505
|
+
buildTracingHandler, // Tracing spans
|
|
506
|
+
} from "@viaalink/caddy-api-client/caddy";
|
|
507
|
+
|
|
508
|
+
// Example: Serve static files with browsing
|
|
509
|
+
const fileRoute = buildFileServerRoute({
|
|
510
|
+
path: "/static/*",
|
|
511
|
+
root: "/var/www/static",
|
|
512
|
+
browse: true,
|
|
513
|
+
hidePatterns: [".git", ".env"],
|
|
514
|
+
precompressed: true,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// Example: Template rendering
|
|
518
|
+
const templateRoute = buildTemplatesRoute({
|
|
519
|
+
path: "/*.html",
|
|
520
|
+
fileRoot: "/var/www/templates",
|
|
521
|
+
mimeTypes: ["text/html"],
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// Example: Variable mapping for routing
|
|
525
|
+
const mapHandler = buildMapHandler({
|
|
526
|
+
source: "{http.request.uri.path}",
|
|
527
|
+
destinations: ["{backend}"],
|
|
528
|
+
mappings: [
|
|
529
|
+
{ input: "/api/*", outputs: ["api-server"] },
|
|
530
|
+
{ input: "/admin/*", outputs: ["admin-server"] },
|
|
531
|
+
],
|
|
532
|
+
defaults: ["default-server"],
|
|
533
|
+
});
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Extended Caddy Types
|
|
537
|
+
|
|
538
|
+
For advanced configurations beyond our Zod-validated builders, we re-export comprehensive type definitions from [caddy-json-types](https://github.com/CafuChino/caddy-json-types):
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
import type {
|
|
542
|
+
IConfig,
|
|
543
|
+
IModulesCaddyhttpRoute,
|
|
544
|
+
IModulesCaddyhttpReverseproxyHandler,
|
|
545
|
+
IModulesCaddytlsConnectionPolicy,
|
|
546
|
+
} from "@viaalink/caddy-api-client/caddy-types";
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**Includes 591 types covering:**
|
|
550
|
+
|
|
551
|
+
- Full Caddy JSON configuration structure
|
|
552
|
+
- 50+ DNS providers for ACME challenges
|
|
553
|
+
- Layer 4 (TCP/UDP) proxy configuration
|
|
554
|
+
- PKI/CA management types
|
|
555
|
+
- Storage backends (Redis, S3, DynamoDB, etc.)
|
|
556
|
+
- All HTTP handlers, matchers, and encoders
|
|
557
|
+
|
|
558
|
+
## Error Handling
|
|
559
|
+
|
|
560
|
+
The library provides custom error classes:
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
import {
|
|
564
|
+
CaddyApiError,
|
|
565
|
+
ValidationError,
|
|
566
|
+
NetworkError,
|
|
567
|
+
TimeoutError,
|
|
568
|
+
DomainNotFoundError,
|
|
569
|
+
MitmproxyNotInstalledError,
|
|
570
|
+
} from "@viaalink/caddy-api-client";
|
|
571
|
+
|
|
572
|
+
try {
|
|
573
|
+
await client.addRoute("https_server", route);
|
|
574
|
+
} catch (error) {
|
|
575
|
+
if (error instanceof ValidationError) {
|
|
576
|
+
console.error("Invalid route configuration:", error.errors);
|
|
577
|
+
} else if (error instanceof CaddyApiError) {
|
|
578
|
+
console.error(`Caddy API error (${error.statusCode}):`, error.responseBody);
|
|
579
|
+
} else if (error instanceof NetworkError) {
|
|
580
|
+
console.error("Network error:", error.cause);
|
|
581
|
+
} else if (error instanceof TimeoutError) {
|
|
582
|
+
console.error(`Request timed out after ${error.timeoutMs}ms`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
## Examples
|
|
588
|
+
|
|
589
|
+
### Tested Examples (Always Current)
|
|
590
|
+
|
|
591
|
+
Our **integration tests** serve as comprehensive, tested examples that are verified in CI:
|
|
592
|
+
|
|
593
|
+
- **[caddy-mitmproxy-flow.integration.test.ts](./src/__tests__/integration/caddy-mitmproxy-flow.integration.test.ts)** - Complete MITMproxy integration patterns
|
|
594
|
+
- **[asd-scenarios.integration.test.ts](./src/__tests__/integration/asd-scenarios.integration.test.ts)** - Production routing scenarios (load balancing, multi-host, path-based)
|
|
595
|
+
- **[critical-modules.integration.test.ts](./src/__tests__/integration/critical-modules.integration.test.ts)** - All route builders, domain management, TLS
|
|
596
|
+
|
|
597
|
+
**Run examples locally:**
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
# Start services
|
|
601
|
+
docker compose -f docker-compose.test.yml up -d
|
|
602
|
+
|
|
603
|
+
# Run all integration tests (86+ examples)
|
|
604
|
+
INTEGRATION_TEST=true bun test src/__tests__/integration/
|
|
605
|
+
|
|
606
|
+
# Run specific example file
|
|
607
|
+
INTEGRATION_TEST=true bun test src/__tests__/integration/caddy-mitmproxy-flow.integration.test.ts
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### Standalone Examples
|
|
611
|
+
|
|
612
|
+
See the [`examples/`](./examples/) directory for standalone examples (require published package):
|
|
613
|
+
|
|
614
|
+
- [`basic-usage.ts`](./examples/basic-usage.ts) - Basic route management
|
|
615
|
+
- [`load-balancer.ts`](./examples/load-balancer.ts) - Load balancing with health checks
|
|
616
|
+
- [`mitmproxy-integration.ts`](./examples/mitmproxy-integration.ts) - Traffic inspection with MITMproxy
|
|
617
|
+
|
|
618
|
+
## API Documentation
|
|
619
|
+
|
|
620
|
+
📚 **[View Full API Documentation](https://viaalink.github.io/asd-caddy-api-client/)** ← Auto-generated from source code
|
|
621
|
+
|
|
622
|
+
Full API documentation is generated using TypeDoc and hosted on GitHub Pages. It includes detailed information for all exported functions, classes, and types with examples.
|
|
623
|
+
|
|
624
|
+
**Generate locally:**
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
bun run docs:build # Generate docs
|
|
628
|
+
bun run docs:serve # Generate and open in browser
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
## Development
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
# Install dependencies
|
|
635
|
+
bun install
|
|
636
|
+
|
|
637
|
+
# Build
|
|
638
|
+
bun run build
|
|
639
|
+
|
|
640
|
+
# Test
|
|
641
|
+
bun run test
|
|
642
|
+
|
|
643
|
+
# Type check
|
|
644
|
+
bun run typecheck
|
|
645
|
+
|
|
646
|
+
# Lint
|
|
647
|
+
bun run lint
|
|
648
|
+
|
|
649
|
+
# Format
|
|
650
|
+
bun run format
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
## Contributing
|
|
654
|
+
|
|
655
|
+
Contributions are welcome! Please [open an issue](https://github.com/viaalink/asd-caddy-api-client/issues) or submit a pull request if you have any improvements or fixes.
|
|
656
|
+
|
|
657
|
+
1. Fork the repository
|
|
658
|
+
2. Create a new branch (`git checkout -b my-feature-branch`)
|
|
659
|
+
3. Make your changes
|
|
660
|
+
4. Commit your changes (`git commit -am 'Add new feature'`)
|
|
661
|
+
5. Push to the branch (`git push origin my-feature-branch`)
|
|
662
|
+
6. Create a new Pull Request
|
|
663
|
+
|
|
664
|
+
## License
|
|
665
|
+
|
|
666
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
667
|
+
|
|
668
|
+
## Acknowledgements
|
|
669
|
+
|
|
670
|
+
This project is not affiliated with or endorsed by the Caddy project. It is an independent project created to improve the developer experience when working with Caddy JSON configurations in TypeScript.
|
|
671
|
+
|
|
672
|
+
For more information on Caddy and its configuration options, please visit the [official Caddy documentation](https://caddyserver.com/docs/).
|