@infodb/revx 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 tamuto
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 ADDED
@@ -0,0 +1,376 @@
1
+ # @infodb/revx
2
+
3
+ Reverse proxy CLI tool with YAML configuration. Built with Express and http-proxy-middleware.
4
+
5
+ ## Features
6
+
7
+ - YAML-based configuration
8
+ - Simple reverse proxy setup
9
+ - **Automatic route sorting** - Routes are automatically sorted by specificity (longest paths first)
10
+ - Load balancing (Round-robin, Random, IP-hash)
11
+ - WebSocket support
12
+ - Request/Response header transformation
13
+ - CORS configuration
14
+ - SSL/TLS support
15
+ - Health checks
16
+ - Request ID tracking
17
+ - Environment variable expansion
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install -g @infodb/revx
23
+ # or
24
+ pnpm add -g @infodb/revx
25
+ # or
26
+ npx @infodb/revx
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ 1. Create a configuration file:
32
+
33
+ ```bash
34
+ revx init
35
+ ```
36
+
37
+ This creates a `revx.yaml` file with example configuration.
38
+
39
+ 2. Edit `revx.yaml` to configure your routes:
40
+
41
+ ```yaml
42
+ server:
43
+ port: 3000
44
+
45
+ routes:
46
+ - path: "/api/*"
47
+ target: "http://localhost:4000"
48
+ pathRewrite:
49
+ "^/api": ""
50
+ ```
51
+
52
+ 3. Start the proxy server:
53
+
54
+ ```bash
55
+ revx start
56
+ ```
57
+
58
+ ## Commands
59
+
60
+ ### `revx start [config-file]`
61
+
62
+ Start the reverse proxy server.
63
+
64
+ ```bash
65
+ # Use default config file (revx.yaml)
66
+ revx start
67
+
68
+ # Use custom config file
69
+ revx start my-proxy.yaml
70
+
71
+ # Verbose output
72
+ revx start --verbose
73
+ ```
74
+
75
+ ### `revx validate <config-file>`
76
+
77
+ Validate configuration file.
78
+
79
+ ```bash
80
+ revx validate revx.yaml
81
+
82
+ # Show detailed validation info
83
+ revx validate revx.yaml --verbose
84
+ ```
85
+
86
+ ### `revx init`
87
+
88
+ Create a sample configuration file.
89
+
90
+ ```bash
91
+ # Create default configuration
92
+ revx init
93
+
94
+ # Create simple configuration
95
+ revx init --simple
96
+
97
+ # Specify output file
98
+ revx init --output my-config.yaml
99
+ ```
100
+
101
+ ## Configuration
102
+
103
+ ### Basic Configuration
104
+
105
+ ```yaml
106
+ server:
107
+ port: 3000
108
+ host: 0.0.0.0
109
+ name: "My Reverse Proxy"
110
+
111
+ routes:
112
+ - path: "/api/*"
113
+ target: "http://localhost:4000"
114
+ pathRewrite:
115
+ "^/api": ""
116
+ ```
117
+
118
+ ### Global Settings
119
+
120
+ ```yaml
121
+ global:
122
+ timeout: 30000
123
+
124
+ cors:
125
+ enabled: true
126
+ origin: "*"
127
+ methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
128
+ credentials: true
129
+
130
+ logging:
131
+ enabled: true
132
+ format: "combined" # combined | dev | common | short | tiny
133
+ level: "info" # error | warn | info | debug
134
+ ```
135
+
136
+ ### Route Configuration
137
+
138
+ **Important:** Routes are automatically sorted by specificity when loaded. You don't need to worry about the order in your YAML file - the most specific routes (longest paths) will always be matched first.
139
+
140
+ For example:
141
+ ```yaml
142
+ routes:
143
+ # These will be automatically reordered
144
+ - path: "/" # Will match last
145
+ target: "http://static"
146
+
147
+ - path: "/api/v1/users/*" # Will match first (most specific)
148
+ target: "http://users-api"
149
+
150
+ - path: "/api/*" # Will match after /api/v1/users/*
151
+ target: "http://api"
152
+ ```
153
+
154
+ The automatic sorting order:
155
+ 1. Longest paths first
156
+ 2. Paths with fewer wildcards (more specific)
157
+ 3. Alphabetical order for equal paths
158
+
159
+ #### Simple Proxy
160
+
161
+ ```yaml
162
+ routes:
163
+ - path: "/api/*"
164
+ target: "http://api.example.com"
165
+ changeOrigin: true
166
+ pathRewrite:
167
+ "^/api": ""
168
+ ```
169
+
170
+ #### Load Balancing
171
+
172
+ ```yaml
173
+ routes:
174
+ - path: "/balanced/*"
175
+ targets:
176
+ - "http://server1.example.com"
177
+ - "http://server2.example.com"
178
+ - "http://server3.example.com"
179
+ strategy: "round-robin" # round-robin | random | ip-hash
180
+ pathRewrite:
181
+ "^/balanced": ""
182
+ ```
183
+
184
+ #### WebSocket Proxy
185
+
186
+ ```yaml
187
+ routes:
188
+ - path: "/ws"
189
+ target: "ws://websocket.example.com"
190
+ ws: true
191
+ changeOrigin: true
192
+ ```
193
+
194
+ #### Header Transformation
195
+
196
+ ```yaml
197
+ routes:
198
+ - path: "/transform/*"
199
+ target: "http://backend.example.com"
200
+ transform:
201
+ request:
202
+ headers:
203
+ add:
204
+ X-API-Version: "v2"
205
+ X-Custom-Header: "value"
206
+ remove:
207
+ - "Cookie"
208
+ response:
209
+ headers:
210
+ add:
211
+ X-Proxy-Server: "revx"
212
+ remove:
213
+ - "Server"
214
+ ```
215
+
216
+ #### Custom Options
217
+
218
+ ```yaml
219
+ routes:
220
+ - path: "/api/*"
221
+ target: "http://api.example.com"
222
+ options:
223
+ timeout: 5000
224
+ followRedirects: true
225
+ headers:
226
+ X-Forwarded-Host: "${HOST}"
227
+ ```
228
+
229
+ ### Middleware
230
+
231
+ ```yaml
232
+ middleware:
233
+ - type: "requestId"
234
+ enabled: true
235
+ headerName: "X-Request-ID"
236
+
237
+ - type: "compression"
238
+ enabled: true
239
+ threshold: 1024
240
+ ```
241
+
242
+ ### SSL/TLS
243
+
244
+ ```yaml
245
+ ssl:
246
+ enabled: true
247
+ key: "/path/to/private.key"
248
+ cert: "/path/to/certificate.crt"
249
+ ca: "/path/to/ca.crt" # Optional
250
+ ```
251
+
252
+ ### Environment Variables
253
+
254
+ Use `${VARIABLE_NAME}` syntax to reference environment variables:
255
+
256
+ ```yaml
257
+ server:
258
+ port: ${PORT}
259
+
260
+ routes:
261
+ - path: "/api/*"
262
+ target: "${API_URL}"
263
+ options:
264
+ headers:
265
+ Authorization: "Bearer ${API_TOKEN}"
266
+ ```
267
+
268
+ Then run:
269
+
270
+ ```bash
271
+ PORT=3000 API_URL=http://api.example.com API_TOKEN=secret revx start
272
+ ```
273
+
274
+ ## Examples
275
+
276
+ ### Microservices Gateway
277
+
278
+ ```yaml
279
+ server:
280
+ port: 8080
281
+ name: "Microservices Gateway"
282
+
283
+ routes:
284
+ - path: "/users/*"
285
+ target: "http://user-service:3001"
286
+ pathRewrite:
287
+ "^/users": ""
288
+
289
+ - path: "/products/*"
290
+ target: "http://product-service:3002"
291
+ pathRewrite:
292
+ "^/products": ""
293
+
294
+ - path: "/orders/*"
295
+ target: "http://order-service:3003"
296
+ pathRewrite:
297
+ "^/orders": ""
298
+ ```
299
+
300
+ ### Development Proxy
301
+
302
+ ```yaml
303
+ server:
304
+ port: 3000
305
+
306
+ global:
307
+ cors:
308
+ enabled: true
309
+ origin: "http://localhost:5173"
310
+
311
+ routes:
312
+ - path: "/api/*"
313
+ target: "http://localhost:4000"
314
+ pathRewrite:
315
+ "^/api": ""
316
+
317
+ - path: "/ws"
318
+ target: "ws://localhost:4000"
319
+ ws: true
320
+ ```
321
+
322
+ ### Production Load Balancer
323
+
324
+ ```yaml
325
+ server:
326
+ port: 443
327
+ name: "Production Load Balancer"
328
+
329
+ ssl:
330
+ enabled: true
331
+ key: "/etc/ssl/private/server.key"
332
+ cert: "/etc/ssl/certs/server.crt"
333
+
334
+ routes:
335
+ - path: "/*"
336
+ targets:
337
+ - "http://app-server-1:8080"
338
+ - "http://app-server-2:8080"
339
+ - "http://app-server-3:8080"
340
+ strategy: "round-robin"
341
+ healthCheck:
342
+ enabled: true
343
+ interval: 30000
344
+ path: "/health"
345
+ timeout: 3000
346
+ ```
347
+
348
+ ## Development
349
+
350
+ ```bash
351
+ # Clone the repository
352
+ git clone https://github.com/tamuto/infodb-cli
353
+ cd infodb-cli/revx
354
+
355
+ # Install dependencies
356
+ pnpm install
357
+
358
+ # Build
359
+ pnpm build
360
+
361
+ # Development mode
362
+ pnpm dev
363
+ ```
364
+
365
+ ## License
366
+
367
+ MIT
368
+
369
+ ## Author
370
+
371
+ tamuto <tamuto@infodb.jp>
372
+
373
+ ## Links
374
+
375
+ - [GitHub Repository](https://github.com/tamuto/infodb-cli)
376
+ - [Report Issues](https://github.com/tamuto/infodb-cli/issues)
package/bin/cli.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js';
@@ -0,0 +1,6 @@
1
+ export declare function initCommand(options: {
2
+ simple?: boolean;
3
+ output?: string;
4
+ verbose?: boolean;
5
+ }): Promise<void>;
6
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAsHA,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,iBAwBlG"}
@@ -0,0 +1,139 @@
1
+ import { writeFileSync, existsSync } from 'fs';
2
+ import { resolve } from 'path';
3
+ import { Logger } from '../utils/logger.js';
4
+ const SAMPLE_CONFIG = `# revx.yaml - Reverse Proxy Configuration
5
+
6
+ # Server settings
7
+ server:
8
+ port: 3000
9
+ host: 0.0.0.0
10
+ name: "My Reverse Proxy"
11
+
12
+ # Global configuration
13
+ global:
14
+ # Request timeout in milliseconds
15
+ timeout: 30000
16
+
17
+ # CORS settings
18
+ cors:
19
+ enabled: true
20
+ origin: "*"
21
+ methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
22
+ credentials: true
23
+
24
+ # Logging settings
25
+ logging:
26
+ enabled: true
27
+ format: "combined" # combined | dev | common | short | tiny
28
+ level: "info" # error | warn | info | debug
29
+
30
+ # Route definitions
31
+ routes:
32
+ # Example 1: Simple proxy to API server
33
+ - path: "/api/*"
34
+ target: "http://localhost:4000"
35
+ changeOrigin: true
36
+ pathRewrite:
37
+ "^/api": ""
38
+ options:
39
+ timeout: 5000
40
+ headers:
41
+ X-Forwarded-Host: "\${HOST}"
42
+
43
+ # Example 2: WebSocket proxy
44
+ - path: "/ws"
45
+ target: "ws://localhost:5000"
46
+ ws: true
47
+ changeOrigin: true
48
+
49
+ # Example 3: Load balancing with multiple targets
50
+ - path: "/balanced/*"
51
+ targets:
52
+ - "http://localhost:8001"
53
+ - "http://localhost:8002"
54
+ - "http://localhost:8003"
55
+ strategy: "round-robin" # round-robin | random | ip-hash
56
+ pathRewrite:
57
+ "^/balanced": ""
58
+ healthCheck:
59
+ enabled: true
60
+ interval: 30000
61
+ path: "/health"
62
+ timeout: 3000
63
+
64
+ # Example 4: Request/Response transformation
65
+ - path: "/transform/*"
66
+ target: "http://localhost:6000"
67
+ changeOrigin: true
68
+ transform:
69
+ request:
70
+ headers:
71
+ add:
72
+ X-API-Version: "v2"
73
+ remove:
74
+ - "Cookie"
75
+ response:
76
+ headers:
77
+ add:
78
+ X-Proxy-Server: "revx"
79
+ remove:
80
+ - "Server"
81
+
82
+ # Middleware configuration
83
+ middleware:
84
+ # Request ID middleware
85
+ - type: "requestId"
86
+ enabled: true
87
+ headerName: "X-Request-ID"
88
+
89
+ # Compression middleware
90
+ - type: "compression"
91
+ enabled: true
92
+ threshold: 1024
93
+
94
+ # SSL/TLS settings (optional)
95
+ # ssl:
96
+ # enabled: false
97
+ # key: "/path/to/private.key"
98
+ # cert: "/path/to/certificate.crt"
99
+ `;
100
+ const SIMPLE_CONFIG = `# revx.yaml - Simple Reverse Proxy Configuration
101
+
102
+ server:
103
+ port: 3000
104
+
105
+ routes:
106
+ - path: "/api/*"
107
+ target: "http://localhost:4000"
108
+ pathRewrite:
109
+ "^/api": ""
110
+
111
+ - path: "/auth/*"
112
+ target: "http://localhost:5000"
113
+ pathRewrite:
114
+ "^/auth": ""
115
+ `;
116
+ export async function initCommand(options) {
117
+ const logger = new Logger(options.verbose);
118
+ const outputPath = options.output || 'revx.yaml';
119
+ const fullPath = resolve(process.cwd(), outputPath);
120
+ try {
121
+ if (existsSync(fullPath)) {
122
+ logger.error(`Configuration file already exists: ${fullPath}`);
123
+ logger.info('Use --output to specify a different file name');
124
+ process.exit(1);
125
+ }
126
+ const content = options.simple ? SIMPLE_CONFIG : SAMPLE_CONFIG;
127
+ writeFileSync(fullPath, content, 'utf-8');
128
+ logger.success(`Configuration file created: ${fullPath}`);
129
+ logger.info('Edit the file to configure your reverse proxy settings');
130
+ logger.info(`Start the proxy with: revx start ${outputPath}`);
131
+ }
132
+ catch (error) {
133
+ if (error instanceof Error) {
134
+ logger.error(`Failed to create configuration file: ${error.message}`);
135
+ }
136
+ process.exit(1);
137
+ }
138
+ }
139
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+FrB,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;CAerB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAiE;IACjG,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;IACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;YAC/D,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;QAC/D,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,CAAC,OAAO,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;QACtE,MAAM,CAAC,IAAI,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,wCAAwC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function startCommand(configFile: string | undefined, options: {
2
+ verbose?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAWA,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,YAAc,EAAE,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,iBAoBlG"}