interceptr 1.0.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 +287 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +30 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/store.d.ts +65 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +448 -0
- package/dist/config/store.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/ring-buffer.d.ts +15 -0
- package/dist/logging/ring-buffer.d.ts.map +1 -0
- package/dist/logging/ring-buffer.js +64 -0
- package/dist/logging/ring-buffer.js.map +1 -0
- package/dist/logging/sse.d.ts +11 -0
- package/dist/logging/sse.d.ts.map +1 -0
- package/dist/logging/sse.js +23 -0
- package/dist/logging/sse.js.map +1 -0
- package/dist/openapi/parser.d.ts +7 -0
- package/dist/openapi/parser.d.ts.map +1 -0
- package/dist/openapi/parser.js +97 -0
- package/dist/openapi/parser.js.map +1 -0
- package/dist/proxy/handler.d.ts +2 -0
- package/dist/proxy/handler.d.ts.map +1 -0
- package/dist/proxy/handler.js +115 -0
- package/dist/proxy/handler.js.map +1 -0
- package/dist/proxy/lifecycle.d.ts +9 -0
- package/dist/proxy/lifecycle.d.ts.map +1 -0
- package/dist/proxy/lifecycle.js +53 -0
- package/dist/proxy/lifecycle.js.map +1 -0
- package/dist/proxy/matcher.d.ts +9 -0
- package/dist/proxy/matcher.d.ts.map +1 -0
- package/dist/proxy/matcher.js +59 -0
- package/dist/proxy/matcher.js.map +1 -0
- package/dist/proxy.d.ts +3 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +8 -0
- package/dist/proxy.js.map +1 -0
- package/dist/public/assets/favicon-16x16-DulSRrIm.png +0 -0
- package/dist/public/assets/favicon-32x32-BBwAW6Wa.png +0 -0
- package/dist/public/assets/index-BRKg43V6.js +29 -0
- package/dist/public/assets/index-IdN9Napd.css +1 -0
- package/dist/public/assets/logo-full-DJtzE5xc.png +0 -0
- package/dist/public/index.html +19 -0
- package/dist/routes/config.d.ts +4 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +29 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/endpoints.d.ts +4 -0
- package/dist/routes/endpoints.d.ts.map +1 -0
- package/dist/routes/endpoints.js +29 -0
- package/dist/routes/endpoints.js.map +1 -0
- package/dist/routes/helpers.d.ts +2 -0
- package/dist/routes/helpers.d.ts.map +1 -0
- package/dist/routes/helpers.js +7 -0
- package/dist/routes/helpers.js.map +1 -0
- package/dist/routes/logs.d.ts +4 -0
- package/dist/routes/logs.d.ts.map +1 -0
- package/dist/routes/logs.js +32 -0
- package/dist/routes/logs.js.map +1 -0
- package/dist/routes/presets.d.ts +4 -0
- package/dist/routes/presets.d.ts.map +1 -0
- package/dist/routes/presets.js +33 -0
- package/dist/routes/presets.js.map +1 -0
- package/dist/routes/projects.d.ts +4 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +47 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/proxy.d.ts +4 -0
- package/dist/routes/proxy.d.ts.map +1 -0
- package/dist/routes/proxy.js +28 -0
- package/dist/routes/proxy.js.map +1 -0
- package/dist/routes/specs.d.ts +4 -0
- package/dist/routes/specs.d.ts.map +1 -0
- package/dist/routes/specs.js +190 -0
- package/dist/routes/specs.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="logo.png" alt="Interceptr" width="420" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<strong>A local API proxy for intercepting, mocking, and manipulating HTTP traffic during development.</strong>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Import your OpenAPI specs, configure per-endpoint behavior, and switch between environments — all from a clean web UI.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Consolidated Workspace** — Manage endpoints and monitor traffic in a single, high-efficiency two-panel view.
|
|
18
|
+
- **OpenAPI Integration** — Import specs via URL or file upload. Supports OpenAPI 3.0/3.1 (JSON/YAML) with automatic response example generation.
|
|
19
|
+
- **Per-Endpoint & Group Control** — Set proxy modes (Pass, Delay, Mock) for individual endpoints or entire tag groups.
|
|
20
|
+
- **Precision Mocking** — Populate mock responses instantly using examples from your OpenAPI spec, or create custom ones with a built-in JSON editor.
|
|
21
|
+
- **Live Traffic Monitor** — Inspect real-time request/response cycles with a dense, searchable activity feed and detailed inspector drawer.
|
|
22
|
+
- **Multi-Environment Support** — Organize work into projects and switch between multiple specifications (e.g., local, staging) with a single click.
|
|
23
|
+
- **Presets** — Save and restore complete endpoint configurations. Includes built-in quick actions (Pass All, Slow, Errors).
|
|
24
|
+
- **Theme Support** — Professional-grade "Midnight Blue" dark mode and a clean, high-contrast light mode.
|
|
25
|
+
|
|
26
|
+
## Getting Started
|
|
27
|
+
|
|
28
|
+
### Install from npm
|
|
29
|
+
|
|
30
|
+
**Run without installing** (recommended for trying it out):
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx interceptr
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Install globally** and run anytime:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g interceptr
|
|
40
|
+
interceptr
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Once running, open [http://localhost:3001](http://localhost:3001) in your browser to access the management UI. The proxy listens on [http://localhost:4000](http://localhost:4000) — point your app there to start intercepting traffic.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### Development (from source)
|
|
48
|
+
|
|
49
|
+
#### Prerequisites
|
|
50
|
+
|
|
51
|
+
- **Node.js** >= 22
|
|
52
|
+
- **pnpm** >= 10
|
|
53
|
+
|
|
54
|
+
#### Install & Run
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Install dependencies
|
|
58
|
+
pnpm install
|
|
59
|
+
|
|
60
|
+
# Start both servers in dev mode
|
|
61
|
+
pnpm dev
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This starts:
|
|
65
|
+
- **Management UI** at [http://localhost:5173](http://localhost:5173)
|
|
66
|
+
- **Management API** at [http://localhost:3001](http://localhost:3001)
|
|
67
|
+
- **Proxy server** at [http://localhost:4000](http://localhost:4000)
|
|
68
|
+
|
|
69
|
+
#### Lint
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Lint all packages
|
|
73
|
+
pnpm lint
|
|
74
|
+
|
|
75
|
+
# Lint a specific package
|
|
76
|
+
pnpm --filter interceptr lint
|
|
77
|
+
pnpm --filter @interceptr/web lint
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### Production Build & Run
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Build all packages
|
|
84
|
+
pnpm build
|
|
85
|
+
|
|
86
|
+
# Run the built app
|
|
87
|
+
pnpm start
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Usage
|
|
91
|
+
|
|
92
|
+
### 1. Global Navigation
|
|
93
|
+
|
|
94
|
+
All primary controls are in the top header:
|
|
95
|
+
- **Project Switcher**: Create or switch between different projects.
|
|
96
|
+
- **Spec Selector**: Import, reimport, configure upstream URLs, and toggle active specifications.
|
|
97
|
+
- **Proxy Control**: Start/Stop the proxy engine and monitor listener status.
|
|
98
|
+
- **System Settings**: Access project renaming, port configuration, data export/import, and version info.
|
|
99
|
+
|
|
100
|
+
### 2. Endpoints Registry (Left Panel)
|
|
101
|
+
|
|
102
|
+
Configure how traffic is handled per endpoint or by group:
|
|
103
|
+
|
|
104
|
+
| Mode | Behavior |
|
|
105
|
+
|---|---|
|
|
106
|
+
| **Pass** | Forwards the request to the upstream server unchanged. |
|
|
107
|
+
| **Delay** | Simulates latency. Configure milliseconds and optional jitter. |
|
|
108
|
+
| **Mock** | Overrides the response. Use "Spec Defined Responses" to instantly populate data from your OpenAPI definitions. |
|
|
109
|
+
|
|
110
|
+
**Group Actions**: Apply a mode to all endpoints in a tag group with a single click.
|
|
111
|
+
|
|
112
|
+
### 3. Traffic Monitor (Right Panel)
|
|
113
|
+
|
|
114
|
+
Monitor flows in real-time:
|
|
115
|
+
- **Live Stream**: View incoming requests as they hit the proxy.
|
|
116
|
+
- **Filters**: Isolate traffic by Method, Status Code range (2xx/4xx/5xx), or Proxy Mode.
|
|
117
|
+
- **Inspector**: Click any entry to open a detail drawer showing full request/response headers and formatted JSON bodies.
|
|
118
|
+
- **Clear Logs**: Remove all recorded entries from the buffer.
|
|
119
|
+
|
|
120
|
+
### 4. Presets
|
|
121
|
+
|
|
122
|
+
Use the **Preset Bar** to quickly apply complete configurations.
|
|
123
|
+
|
|
124
|
+
**Built-in quick actions:**
|
|
125
|
+
- **Pass All**: Instant bypass for all endpoints.
|
|
126
|
+
- **Slow**: Set all endpoints to a 2000ms delay.
|
|
127
|
+
- **Errors**: Set all endpoints to return a 500 mock response.
|
|
128
|
+
|
|
129
|
+
**Saved presets:**
|
|
130
|
+
- Save your current endpoint configuration under a custom name.
|
|
131
|
+
- Apply any saved preset to instantly restore that configuration.
|
|
132
|
+
|
|
133
|
+
### 5. Point Your App at the Proxy
|
|
134
|
+
|
|
135
|
+
Point your application to `http://localhost:4000` (or your configured port). Traffic will be intercepted and manipulated based on your active registry settings.
|
|
136
|
+
|
|
137
|
+
## Testing
|
|
138
|
+
|
|
139
|
+
### Run All Tests
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pnpm test
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Backend (apps/server)
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Run tests
|
|
149
|
+
pnpm --filter interceptr test
|
|
150
|
+
|
|
151
|
+
# Run with coverage
|
|
152
|
+
pnpm --filter interceptr test:coverage
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Frontend (apps/web)
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Run tests
|
|
159
|
+
pnpm --filter @interceptr/web test
|
|
160
|
+
|
|
161
|
+
# Run with coverage
|
|
162
|
+
pnpm --filter @interceptr/web test:coverage
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Architecture
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
┌─────────────────────────────────────────────┐
|
|
169
|
+
│ pnpm monorepo │
|
|
170
|
+
├──────────────┬──────────────┬───────────────┤
|
|
171
|
+
│ apps/server │ apps/web │ packages/ │
|
|
172
|
+
│ │ │ shared │
|
|
173
|
+
│ Hono API │ React 19 │ TypeScript │
|
|
174
|
+
│ :3001 │ Vite :5173 │ types │
|
|
175
|
+
│ │ │ │
|
|
176
|
+
│ Proxy │ Tailwind v4 │ │
|
|
177
|
+
│ :4000 │ OKLCH Theme │ │
|
|
178
|
+
│ │ TanStack │ │
|
|
179
|
+
└──────────────┴──────────────┴───────────────┘
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
| Component | Stack |
|
|
183
|
+
|---|---|
|
|
184
|
+
| **Management API** | Hono on port 3001 |
|
|
185
|
+
| **Proxy Server** | Hono on port 4000 |
|
|
186
|
+
| **Frontend** | React 19, Vite, Tailwind v4 (OKLCH), TanStack Query, React Router v7 |
|
|
187
|
+
| **Shared** | TypeScript types |
|
|
188
|
+
| **Storage** | JSON files in `data/` directory |
|
|
189
|
+
| **Live Feed** | Server-Sent Events (SSE) |
|
|
190
|
+
| **Testing** | Vitest, Testing Library, jsdom |
|
|
191
|
+
| **Linting** | ESLint 10, typescript-eslint, eslint-plugin-react-hooks |
|
|
192
|
+
| **Releases** | semantic-release (Conventional Commits) |
|
|
193
|
+
|
|
194
|
+
## API Reference
|
|
195
|
+
|
|
196
|
+
The management API runs on port 3001. All endpoints are prefixed with `/api`.
|
|
197
|
+
|
|
198
|
+
### Projects
|
|
199
|
+
|
|
200
|
+
| Method | Path | Description |
|
|
201
|
+
|---|---|---|
|
|
202
|
+
| `GET` | `/projects` | List all projects |
|
|
203
|
+
| `POST` | `/projects` | Create a project (body: `{name}`) |
|
|
204
|
+
| `GET` | `/projects/active` | Get active project with specs |
|
|
205
|
+
| `PUT` | `/projects/active` | Switch active project (body: `{projectId}`) |
|
|
206
|
+
| `PUT` | `/projects/:id` | Rename a project (body: `{name}`) |
|
|
207
|
+
| `DELETE` | `/projects/:id` | Delete a project |
|
|
208
|
+
|
|
209
|
+
### Specs
|
|
210
|
+
|
|
211
|
+
| Method | Path | Description |
|
|
212
|
+
|---|---|---|
|
|
213
|
+
| `GET` | `/specs` | List specs in the active project |
|
|
214
|
+
| `POST` | `/specs` | Upload a spec (body: `{spec, name, upstreamUrl?}`) |
|
|
215
|
+
| `POST` | `/specs/url` | Import a spec from URL (body: `{url, name}`) |
|
|
216
|
+
| `POST` | `/specs/:id/reimport` | Reimport from source URL or new body |
|
|
217
|
+
| `PUT` | `/specs/:id` | Update spec metadata (body: `{name?, upstreamUrl?, active?}`) |
|
|
218
|
+
| `PUT` | `/specs/:id/toggle` | Toggle spec active state |
|
|
219
|
+
| `DELETE` | `/specs/:id` | Delete a spec |
|
|
220
|
+
|
|
221
|
+
### Endpoints
|
|
222
|
+
|
|
223
|
+
| Method | Path | Description |
|
|
224
|
+
|---|---|---|
|
|
225
|
+
| `GET` | `/endpoints` | List endpoints (query: `?specId=...`) |
|
|
226
|
+
| `PUT` | `/endpoints/:id` | Update endpoint config |
|
|
227
|
+
| `PUT` | `/endpoints/bulk` | Bulk update endpoints (body: `{[id]: Partial<EndpointConfig>}`) |
|
|
228
|
+
|
|
229
|
+
The endpoint config body supports a `conditionalRules` array for request-time overrides. Each rule has a `type` of `nth-request`, `random-failure`, or `header-match`, and a `response` to serve when triggered. These rules are evaluated before the endpoint's base mode.
|
|
230
|
+
|
|
231
|
+
### Presets
|
|
232
|
+
|
|
233
|
+
| Method | Path | Description |
|
|
234
|
+
|---|---|---|
|
|
235
|
+
| `GET` | `/presets` | List saved presets |
|
|
236
|
+
| `POST` | `/presets` | Save a preset (body: `{name, description?, endpoints}`) |
|
|
237
|
+
| `DELETE` | `/presets/:name` | Delete a preset |
|
|
238
|
+
| `POST` | `/presets/:name/apply` | Apply a preset to all endpoints |
|
|
239
|
+
|
|
240
|
+
### Logs
|
|
241
|
+
|
|
242
|
+
| Method | Path | Description |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `GET` | `/logs` | Fetch recent logs (query: `?limit=100`) |
|
|
245
|
+
| `GET` | `/logs/stream` | SSE stream for live logs |
|
|
246
|
+
| `DELETE` | `/logs` | Clear all logs |
|
|
247
|
+
|
|
248
|
+
### Proxy
|
|
249
|
+
|
|
250
|
+
| Method | Path | Description |
|
|
251
|
+
|---|---|---|
|
|
252
|
+
| `GET` | `/proxy/status` | Proxy running status (`{running, port}`) |
|
|
253
|
+
| `POST` | `/proxy/start` | Start the proxy server |
|
|
254
|
+
| `POST` | `/proxy/stop` | Stop the proxy server |
|
|
255
|
+
|
|
256
|
+
### Config
|
|
257
|
+
|
|
258
|
+
| Method | Path | Description |
|
|
259
|
+
|---|---|---|
|
|
260
|
+
| `GET` | `/config` | Get global config |
|
|
261
|
+
| `PUT` | `/config` | Update global config (body: `{proxyPort?}`) |
|
|
262
|
+
| `GET` | `/config/export` | Export all data as JSON |
|
|
263
|
+
| `POST` | `/config/import` | Import configuration from JSON |
|
|
264
|
+
|
|
265
|
+
### Health
|
|
266
|
+
|
|
267
|
+
| Method | Path | Description |
|
|
268
|
+
|---|---|---|
|
|
269
|
+
| `GET` | `/health` | Health check — returns `{status: "ok", version}` |
|
|
270
|
+
|
|
271
|
+
## Data Storage
|
|
272
|
+
|
|
273
|
+
All data is stored as JSON files in the `data/` directory:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
data/
|
|
277
|
+
global.json # Global config + project list
|
|
278
|
+
logs.json # Persisted activity logs (ring buffer)
|
|
279
|
+
projects/
|
|
280
|
+
<project-id>.json # Specs, endpoints, and presets per project
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Logs are kept in a 500-entry ring buffer that persists across server restarts. All writes are debounced (1 second) to avoid excessive disk I/O.
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
[MIT License](LICENSE)
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,eAAO,MAAM,GAAG,4EAAa,CAAC"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { version } from './version.js';
|
|
5
|
+
import { cors } from 'hono/cors';
|
|
6
|
+
import { logger } from 'hono/logger';
|
|
7
|
+
import { serveStatic } from '@hono/node-server/serve-static';
|
|
8
|
+
import specs from './routes/specs.js';
|
|
9
|
+
import endpoints from './routes/endpoints.js';
|
|
10
|
+
import config from './routes/config.js';
|
|
11
|
+
import logs from './routes/logs.js';
|
|
12
|
+
import presets from './routes/presets.js';
|
|
13
|
+
import projects from './routes/projects.js';
|
|
14
|
+
import proxy from './routes/proxy.js';
|
|
15
|
+
export const app = new Hono();
|
|
16
|
+
app.use('*', cors());
|
|
17
|
+
app.use('*', logger());
|
|
18
|
+
app.route('/api/projects', projects);
|
|
19
|
+
app.route('/api/specs', specs);
|
|
20
|
+
app.route('/api/endpoints', endpoints);
|
|
21
|
+
app.route('/api/config', config);
|
|
22
|
+
app.route('/api/logs', logs);
|
|
23
|
+
app.route('/api/presets', presets);
|
|
24
|
+
app.route('/api/proxy', proxy);
|
|
25
|
+
app.get('/api/health', (c) => c.json({ data: { status: 'ok', version } }));
|
|
26
|
+
const publicDir = fileURLToPath(new URL('./public', import.meta.url));
|
|
27
|
+
if (existsSync(publicDir)) {
|
|
28
|
+
app.use('/*', serveStatic({ root: publicDir }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAC9C,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,kBAAkB,CAAC;AACpC,OAAO,OAAO,MAAM,qBAAqB,CAAC;AAC1C,OAAO,QAAQ,MAAM,sBAAsB,CAAC;AAC5C,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAE9B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AACrB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;AAEvB,GAAG,CAAC,KAAK,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AACrC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAC/B,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;AACvC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AACjC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AAC7B,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AACnC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAE/B,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAE3E,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACtE,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;IAC1B,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { serve } from '@hono/node-server';
|
|
3
|
+
import { app } from './app.js';
|
|
4
|
+
import { store } from './config/store.js';
|
|
5
|
+
import { logBuffer } from './logging/ring-buffer.js';
|
|
6
|
+
import { recompileRoutes } from './routes/helpers.js';
|
|
7
|
+
import { startProxy, stopProxy } from './proxy/lifecycle.js';
|
|
8
|
+
import { version } from './version.js';
|
|
9
|
+
const MANAGEMENT_PORT = 3001;
|
|
10
|
+
function banner(lines) {
|
|
11
|
+
const width = Math.max(...lines.map((l) => l.length)) + 4;
|
|
12
|
+
const pad = (s) => `║ ${s.padEnd(width - 4)} ║`;
|
|
13
|
+
const rule = '═'.repeat(width - 2);
|
|
14
|
+
return [`╔${rule}╗`, ...lines.map(pad), `╚${rule}╝`].join('\n');
|
|
15
|
+
}
|
|
16
|
+
console.log('\n' + banner([
|
|
17
|
+
`Interceptr v${version}`,
|
|
18
|
+
'',
|
|
19
|
+
`Management UI http://localhost:${MANAGEMENT_PORT}`,
|
|
20
|
+
]) + '\n');
|
|
21
|
+
await store.load();
|
|
22
|
+
logBuffer.load();
|
|
23
|
+
recompileRoutes();
|
|
24
|
+
serve({ fetch: app.fetch, port: MANAGEMENT_PORT }, () => {
|
|
25
|
+
console.log(`Management API running at http://localhost:${MANAGEMENT_PORT}`);
|
|
26
|
+
});
|
|
27
|
+
await startProxy();
|
|
28
|
+
async function shutdown() {
|
|
29
|
+
console.log('\nShutting down...');
|
|
30
|
+
await stopProxy();
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
process.on('SIGINT', shutdown);
|
|
34
|
+
process.on('SIGTERM', shutdown);
|
|
35
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,SAAS,MAAM,CAAC,KAAe;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC;IACxB,eAAe,OAAO,EAAE;IACxB,EAAE;IACF,mCAAmC,eAAe,EAAE;CACrD,CAAC,GAAG,IAAI,CAAC,CAAC;AAEX,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AACnB,SAAS,CAAC,IAAI,EAAE,CAAC;AACjB,eAAe,EAAE,CAAC;AAElB,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE;IACtD,OAAO,CAAC,GAAG,CAAC,8CAA8C,eAAe,EAAE,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,EAAE,CAAC;AAEnB,KAAK,UAAU,QAAQ;IACrB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,SAAS,EAAE,CAAC;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { EndpointConfig, GlobalConfig, Preset, Project, ProjectSpec } from '@interceptr/shared';
|
|
2
|
+
export declare class ConfigStore {
|
|
3
|
+
private proxyPort;
|
|
4
|
+
private projects;
|
|
5
|
+
private activeProjectId;
|
|
6
|
+
private specs;
|
|
7
|
+
private endpoints;
|
|
8
|
+
private presets;
|
|
9
|
+
private globalSaveTimer;
|
|
10
|
+
private projectSaveTimer;
|
|
11
|
+
load(): Promise<void>;
|
|
12
|
+
private fileExists;
|
|
13
|
+
private migrate;
|
|
14
|
+
private loadProjectData;
|
|
15
|
+
private scheduleGlobalSave;
|
|
16
|
+
private scheduleProjectSave;
|
|
17
|
+
private persistGlobal;
|
|
18
|
+
private persistProject;
|
|
19
|
+
getConfig(): GlobalConfig;
|
|
20
|
+
setConfig(config: Partial<GlobalConfig>): GlobalConfig;
|
|
21
|
+
listProjects(): Project[];
|
|
22
|
+
getActiveProjectId(): string | null;
|
|
23
|
+
createProject(name: string): Project;
|
|
24
|
+
renameProject(id: string, name: string): Project | undefined;
|
|
25
|
+
deleteProject(id: string): Promise<boolean>;
|
|
26
|
+
switchProject(projectId: string): Promise<boolean>;
|
|
27
|
+
getActiveProject(): (Project & {
|
|
28
|
+
specs: ProjectSpec[];
|
|
29
|
+
}) | null;
|
|
30
|
+
getSpecs(): ProjectSpec[];
|
|
31
|
+
getSpec(specId: string): ProjectSpec | undefined;
|
|
32
|
+
addSpec(spec: ProjectSpec, endpoints: EndpointConfig[]): void;
|
|
33
|
+
updateSpec(specId: string, updates: Partial<Pick<ProjectSpec, 'name' | 'upstreamUrl' | 'active'>>): ProjectSpec | undefined;
|
|
34
|
+
reimportSpec(specId: string, metadata: ProjectSpec['metadata'], newEndpoints: EndpointConfig[]): boolean;
|
|
35
|
+
removeSpec(specId: string): boolean;
|
|
36
|
+
getSpecUpstreamUrl(specId: string): string | undefined;
|
|
37
|
+
getEndpoints(): EndpointConfig[];
|
|
38
|
+
getActiveEndpoints(): EndpointConfig[];
|
|
39
|
+
getEndpoint(id: string): EndpointConfig | undefined;
|
|
40
|
+
setEndpoint(id: string, config: Partial<EndpointConfig>): EndpointConfig | undefined;
|
|
41
|
+
setEndpoints(endpoints: EndpointConfig[]): void;
|
|
42
|
+
bulkUpdateEndpoints(updates: Record<string, Partial<EndpointConfig>>): EndpointConfig[];
|
|
43
|
+
getPresets(): Preset[];
|
|
44
|
+
getPreset(name: string): Preset | undefined;
|
|
45
|
+
setPreset(preset: Preset): void;
|
|
46
|
+
deletePreset(name: string): boolean;
|
|
47
|
+
applyPreset(name: string): EndpointConfig[];
|
|
48
|
+
exportData(): {
|
|
49
|
+
version: number;
|
|
50
|
+
config: GlobalConfig;
|
|
51
|
+
project: Project | undefined;
|
|
52
|
+
specs: ProjectSpec[];
|
|
53
|
+
endpoints: EndpointConfig[];
|
|
54
|
+
presets: Preset[];
|
|
55
|
+
exportedAt: string;
|
|
56
|
+
};
|
|
57
|
+
importData(data: {
|
|
58
|
+
config?: GlobalConfig;
|
|
59
|
+
endpoints?: EndpointConfig[];
|
|
60
|
+
presets?: Preset[];
|
|
61
|
+
specs?: ProjectSpec[];
|
|
62
|
+
}): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
export declare const store: ConfigStore;
|
|
65
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/config/store.ts"],"names":[],"mappings":"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"}
|