yxorp 0.1.5 → 0.2.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.
Files changed (63) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +369 -81
  3. package/bin/yxorp.js +13 -22
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +59 -0
  6. package/dist/middleware/bootstrap.middleware.d.ts +15 -0
  7. package/dist/middleware/bootstrap.middleware.js +63 -0
  8. package/dist/middleware/mock.middleware.d.ts +9 -0
  9. package/dist/middleware/mock.middleware.js +54 -0
  10. package/dist/middleware/proxy.middleware.d.ts +15 -0
  11. package/dist/middleware/proxy.middleware.js +26 -0
  12. package/dist/middleware/proxyRes.middleware.d.ts +9 -0
  13. package/dist/middleware/proxyRes.middleware.js +28 -0
  14. package/dist/middleware/rawBody.middleware.d.ts +6 -0
  15. package/dist/middleware/rawBody.middleware.js +24 -0
  16. package/dist/middleware/rewrite.middleware.d.ts +9 -0
  17. package/dist/middleware/rewrite.middleware.js +54 -0
  18. package/dist/middleware/static.middleware.d.ts +12 -0
  19. package/dist/middleware/static.middleware.js +85 -0
  20. package/dist/services/config-resolver.d.ts +6 -0
  21. package/dist/services/config-resolver.js +45 -0
  22. package/dist/services/config.service.d.ts +6 -0
  23. package/dist/services/config.service.js +12 -0
  24. package/dist/services/http-proxy.service.d.ts +14 -0
  25. package/dist/services/http-proxy.service.js +19 -0
  26. package/dist/services/http-server.service.d.ts +15 -0
  27. package/dist/services/http-server.service.js +23 -0
  28. package/dist/services/logger.service.d.ts +7 -0
  29. package/dist/services/logger.service.js +17 -0
  30. package/dist/services/pipeline.service.d.ts +8 -0
  31. package/dist/services/pipeline.service.js +29 -0
  32. package/dist/services/rules-matchers/mock-rules-matcher.service.d.ts +8 -0
  33. package/dist/services/rules-matchers/mock-rules-matcher.service.js +35 -0
  34. package/dist/services/rules-matchers/remote-rules-matcher.service.d.ts +8 -0
  35. package/dist/services/rules-matchers/remote-rules-matcher.service.js +51 -0
  36. package/dist/services/rules-matchers/rewrite-rules-matcher.service.d.ts +8 -0
  37. package/dist/services/rules-matchers/rewrite-rules-matcher.service.js +35 -0
  38. package/dist/services/yxorp-server.service.d.ts +10 -0
  39. package/dist/services/yxorp-server.service.js +49 -0
  40. package/dist/types/yxorp-config.d.ts +54 -0
  41. package/dist/types/yxorp-config.js +2 -0
  42. package/package.json +45 -38
  43. package/.editorconfig +0 -16
  44. package/src/index.ts +0 -48
  45. package/src/middleware/bootstrap.middleware.ts +0 -87
  46. package/src/middleware/mock.middleware.ts +0 -61
  47. package/src/middleware/proxy.middleware.ts +0 -42
  48. package/src/middleware/proxyRes.middleware.ts +0 -34
  49. package/src/middleware/rawBody.middleware.ts +0 -22
  50. package/src/middleware/rewrite.middleware.ts +0 -64
  51. package/src/middleware/static.middleware.ts +0 -113
  52. package/src/services/config.service.ts +0 -26
  53. package/src/services/http-proxy.service.ts +0 -25
  54. package/src/services/http-server.service.ts +0 -24
  55. package/src/services/logger.service.ts +0 -21
  56. package/src/services/pipeline.service.ts +0 -44
  57. package/src/services/rules-matchers/mock-rules-matcher.service.ts +0 -48
  58. package/src/services/rules-matchers/remote-rules-matcher.service.ts +0 -49
  59. package/src/services/rules-matchers/rewrite-rules-matcher.service.ts +0 -48
  60. package/src/services/yxorp-server.service.ts +0 -73
  61. package/src/types/http.d.ts +0 -10
  62. package/src/types/yxorp-config.ts +0 -67
  63. package/tsconfig.json +0 -21
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Kirill Suntsov
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.
1
+ MIT License
2
+
3
+ Copyright (c) 2023-2026 Kirill Suntsov <suntsov.kirill@gmail.com>
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,81 +1,369 @@
1
- # Yxorp
2
- This is a simple CLI reverse proxy utility for rewriting or mocking API data. It is in early development and may contain many bugs 😊
3
-
4
- ## Installation
5
- ```
6
- npm i -g yxorp
7
- ```
8
- ## Usage
9
- Just run yxopr in folder which contains yxopr.json
10
-
11
- ## Config
12
- Simple yxorp.json example:
13
- ```json
14
- {
15
- "#": "The site that will be proxied"
16
- "target": "http://example.com/",
17
- "proxyPort": 3002,
18
- "#": "Makes static path with files in directory",
19
- "staticRules": [
20
- {
21
- "path": "/some-path-on-server",
22
- "directory": "./some-path-with-static-files",
23
- "disable": false
24
- }
25
- ],
26
- "#": "Scripts may be using for set some data for mock scripts",
27
- "scripts": [
28
- "./scripts/some-data.js"
29
- ],
30
- "#": "For matching paths in mockRules and rewriteRules uses https://www.npmjs.com/package/path-to-regex",
31
- "#": "This rules uses to modify API data",
32
- "mockRules": [
33
- {
34
- "method": "GET",
35
- "path": "/api/example-one(.*)",
36
- "script": "./mock/api/example-one.js",
37
- "disable": false
38
- }, {
39
- "method": "GET",
40
- "path": "/api/example-two(.*)",
41
- "file": "./mock/api/example-two.json",
42
- "statusCode": 200,
43
- "disable": false
44
- }
45
- ]
46
- "rewriteRules": [
47
- {
48
- "method": "GET",
49
- "path": "/api/example-one(.*)",
50
- "script": "./rewrite/api/example-one.js",
51
- "disable": false
52
- }, {
53
- "method": "GET",
54
- "path": "/api/example-two(.*)",
55
- "file": "./rewrite/api/example-two.json",
56
- "statusCode": 200,
57
- "disable": false
58
- }
59
- ]
60
- }
61
- ```
62
-
63
- ## Mock script example
64
- ```javascript
65
- var data = {
66
- error: "some error",
67
- };
68
-
69
- res.statusCode = 500;
70
- res.end(Buffer.from(JSON.stringify(data)));
71
- ```
72
-
73
- ## Rewrite script example
74
- ```javascript
75
- const data = JSON.parse(body.toString());
76
-
77
- data.modify = 'from js 123';
78
-
79
- result = Buffer.from(JSON.stringify(data));
80
-
81
- ```
1
+ # Yxorp
2
+
3
+ **Yxorp** is a local reverse proxy for rewriting, mocking, and debugging API responses. Think of it as a lightweight Swiss Army knife for HTTP(S) traffic — useful when you're developing a frontend against an API that's not quite ready, needs some data tweaking, or just returns the wrong thing.
4
+
5
+ It sits between your app and a target server, and you get to decide what happens to every request and response.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm i -g yxorp
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ **1. Create a config file** — `yxorp.json` in your project root:
20
+
21
+ ```json
22
+ {
23
+ "target": "https://api.example.com",
24
+ "proxyPort": 3000
25
+ }
26
+ ```
27
+
28
+ **2. Run it:**
29
+
30
+ ```bash
31
+ yxorp
32
+ ```
33
+
34
+ That's it. Yxorp starts on `http://localhost:3000` and proxies everything to `https://api.example.com`. Open your app, point it at `http://localhost:3000`, and watch the traffic flow.
35
+
36
+ Now the fun part — start adding rules.
37
+
38
+ ---
39
+
40
+ ## Config Resolution
41
+
42
+ Yxorp looks for its config in this order:
43
+
44
+ | Priority | Location | Example |
45
+ |----------|----------|---------|
46
+ | 1 | `--config <path>` flag | `yxorp --config ./proxy/settings.json` |
47
+ | 2 | `./yxorp.json` | In your project root |
48
+ | 3 | `./.yxorp/settings.json` | Inside a hidden `.yxorp` directory |
49
+
50
+ When config lives inside `.yxorp/`, all relative paths (scripts, mock files, static directories) are resolved relative to that directory. This keeps things tidy:
51
+
52
+ ```
53
+ my-project/
54
+ .yxorp/
55
+ settings.json
56
+ mock/
57
+ users.js
58
+ static/
59
+ logo.svg
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Config Reference
65
+
66
+ ### `target` (required)
67
+
68
+ The upstream server everything proxies to by default.
69
+
70
+ ```json
71
+ "target": "https://api.example.com"
72
+ ```
73
+
74
+ ### `proxyPort` (required)
75
+
76
+ Port for the local proxy server.
77
+
78
+ ```json
79
+ "proxyPort": 8080
80
+ ```
81
+
82
+ ### `proxyHeaders`
83
+
84
+ Extra HTTP headers to send with every proxied request to the target server. Useful when the target rejects requests with a missing or unexpected `User-Agent`, `Origin`, or custom header.
85
+
86
+ ```json
87
+ {
88
+ "target": "https://api.example.com",
89
+ "proxyPort": 3000,
90
+ "proxyHeaders": {
91
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
92
+ "origin": "https://example.com"
93
+ }
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ### `scripts`
100
+
101
+ Additional JavaScript files loaded **once at startup**. Use them to set up shared data or helpers for your mock/rewrite scripts.
102
+
103
+ Why `scripts` and not just `require()` inside each mock file? Because mock scripts are hot-reloaded on every request (their module cache is cleared). Any data they `require()` would also need to be re-imported. Scripts loaded via the `scripts` array sidestep this — they run once at startup and can stash data on `globalThis` for all mock/rewrite scripts to use.
104
+
105
+ ```json
106
+ "scripts": [
107
+ "./scripts/seed-data.js"
108
+ ]
109
+ ```
110
+
111
+ ```javascript
112
+ // scripts/seed-data.js — runs once, survives hot-reload
113
+ globalThis.users = [
114
+ { id: 1, name: 'Alice' },
115
+ { id: 2, name: 'Bob' },
116
+ ];
117
+ ```
118
+
119
+ ```javascript
120
+ // mock/user.js — hot-reloaded on every request, but seed-data is untouched
121
+ module.exports = (req, res) => {
122
+ const user = globalThis.users.find(u => u.id === Number(req.params.id));
123
+ res.end(JSON.stringify(user));
124
+ };
125
+ ```
126
+
127
+ As a rule of thumb:
128
+ - **`scripts`** — for data you initialize once (lookup tables, config, seed data)
129
+ - **`require()` inside mock/rewrite files** — for utility helpers you want imported fresh each time
130
+
131
+ ---
132
+
133
+ ### Mock Rules (`mockRules`)
134
+
135
+ Intercept a matching request **before** it reaches the target and respond immediately. The target server never sees it.
136
+
137
+ #### By file — respond with a JSON file:
138
+
139
+ ```json
140
+ {
141
+ "method": "GET",
142
+ "path": "/api/users/:id",
143
+ "file": "./mock/user.json",
144
+ "statusCode": 200
145
+ }
146
+ ```
147
+
148
+ #### By script — dynamic response logic:
149
+
150
+ ```json
151
+ {
152
+ "method": "POST",
153
+ "path": "/api/users",
154
+ "script": "./mock/create-user.js"
155
+ }
156
+ ```
157
+
158
+ The script receives `req` and `res` and does whatever it wants:
159
+
160
+ ```javascript
161
+ // ./mock/create-user.js
162
+ module.exports = (req, res) => {
163
+ res.statusCode = 201;
164
+ res.setHeader('content-type', 'application/json');
165
+ res.end(JSON.stringify({ id: 42, status: 'created' }));
166
+ };
167
+ ```
168
+
169
+ **Hot-reload is built-in** — edit the script file and the next request picks up changes automatically. No restart needed.
170
+
171
+ #### Disable a rule:
172
+
173
+ ```json
174
+ {
175
+ "method": "GET",
176
+ "path": "/api/users/:id",
177
+ "file": "./mock/user.json",
178
+ "disable": true
179
+ }
180
+ ```
181
+
182
+ Disabled rules are skipped, and the request passes through to the next matching middleware (rewrite, then proxy).
183
+
184
+ ---
185
+
186
+ ### Rewrite Rules (`rewriteRules`)
187
+
188
+ Let the request reach the target, then **modify the response** before it gets back to your app.
189
+
190
+ #### By file — replace the entire response body:
191
+
192
+ ```json
193
+ {
194
+ "method": "GET",
195
+ "path": "/api/users/:id",
196
+ "file": "./rewrite/user-override.json",
197
+ "statusCode": 200
198
+ }
199
+ ```
200
+
201
+ #### By script — transform the response body:
202
+
203
+ ```json
204
+ {
205
+ "method": "GET",
206
+ "path": "/api/users/:id",
207
+ "script": "./rewrite/user.js"
208
+ }
209
+ ```
210
+
211
+ The script receives the decoded response body, the proxy response, the original request, and the outgoing response:
212
+
213
+ ```javascript
214
+ // ./rewrite/user.js
215
+ module.exports = (body, proxyRes, req, res) => {
216
+ const data = JSON.parse(body.toString());
217
+ data.processedBy = 'yxorp';
218
+ return Buffer.from(JSON.stringify(data));
219
+ };
220
+ ```
221
+
222
+ Whatever you return becomes the new response body.
223
+
224
+ ---
225
+
226
+ ### Remote Rules (`remoteRules`)
227
+
228
+ Route specific paths to a **different target server** instead of the default one:
229
+
230
+ ```json
231
+ {
232
+ "remoteRules": [
233
+ {
234
+ "path": "/api/legacy/:rest",
235
+ "target": "http://localhost:4000",
236
+ "ws": false
237
+ }
238
+ ]
239
+ }
240
+ ```
241
+
242
+ The `ws` option enables WebSocket proxying for that route.
243
+
244
+ ---
245
+
246
+ ### Static Rules (`staticRules`)
247
+
248
+ Serve local files as if they were on the remote server:
249
+
250
+ ```json
251
+ {
252
+ "staticRules": [
253
+ {
254
+ "path": "/assets",
255
+ "directory": "./static-files"
256
+ }
257
+ ]
258
+ }
259
+ ```
260
+
261
+ Requests to `http://localhost:3000/assets/logo.svg` will serve `./static-files/logo.svg` directly, without hitting the target.
262
+
263
+ Options:
264
+
265
+ | Option | Type | Description |
266
+ |--------|------|-------------|
267
+ | `path` | string | URL path prefix to match |
268
+ | `directory` | string | Local directory to serve files from |
269
+ | `caseInsensitive` | boolean | Ignore filename case when matching |
270
+ | `directoryIndex` | string | Default file for directory requests (e.g. `index.html`) |
271
+ | `disable` | boolean | Skip this rule |
272
+
273
+ ---
274
+
275
+ ### Path Matching
276
+
277
+ All rules use `path-to-regexp` v8 for URL matching — the same library used by Express, Koa, and many other frameworks.
278
+
279
+ | Pattern | Matches | `params` |
280
+ |---------|---------|----------|
281
+ | `/api/users` | `/api/users` exactly | `{}` |
282
+ | `/api/users/:id` | `/api/users/42`, `/api/users/abc` | `{ id: '42' }` |
283
+ | `/api/users/:id/photos` | `/api/users/42/photos` | `{ id: '42' }` |
284
+
285
+ For more advanced patterns, see the [path-to-regexp documentation](https://github.com/pillarjs/path-to-regexp).
286
+
287
+ ---
288
+
289
+ ## Full Example
290
+
291
+ Here's a complete config showing all features in action:
292
+
293
+ ```json
294
+ {
295
+ "target": "https://api.example.com",
296
+ "proxyPort": 3000,
297
+
298
+ "scripts": [
299
+ "./scripts/globals.js"
300
+ ],
301
+
302
+ "staticRules": [
303
+ {
304
+ "path": "/assets",
305
+ "directory": "./static",
306
+ "directoryIndex": "index.html",
307
+ "caseInsensitive": true
308
+ }
309
+ ],
310
+
311
+ "remoteRules": [
312
+ {
313
+ "path": "/api/v1",
314
+ "target": "http://localhost:4000"
315
+ }
316
+ ],
317
+
318
+ "mockRules": [
319
+ {
320
+ "method": "GET",
321
+ "path": "/api/users/:id",
322
+ "file": "./mock/users.json",
323
+ "statusCode": 200
324
+ },
325
+ {
326
+ "method": "POST",
327
+ "path": "/api/users",
328
+ "script": "./mock/create-user.js"
329
+ }
330
+ ],
331
+
332
+ "rewriteRules": [
333
+ {
334
+ "method": "GET",
335
+ "path": "/api/products/:id",
336
+ "script": "./rewrite/product.js"
337
+ }
338
+ ]
339
+ }
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Script Hot-Reload
345
+
346
+ Mock and rewrite scripts are reloaded on every request — **just save the file and the next request uses the new code**. No need to restart Yxorp.
347
+
348
+ This is especially handy during development when you're iterating on API response shapes.
349
+
350
+ ---
351
+
352
+ ## Development
353
+
354
+ ```bash
355
+ # Clone and run in dev mode (with auto-reload)
356
+ npm start
357
+
358
+ # Run tests (integration tests spin up real servers)
359
+ npm test
360
+
361
+ # Build for production
362
+ npm run build
363
+ ```
364
+
365
+ ---
366
+
367
+ ## Why "Yxorp"?
368
+
369
+ Spell it backwards.
package/bin/yxorp.js CHANGED
@@ -1,22 +1,13 @@
1
- #!/usr/bin/env node
2
-
3
- var path = require('path');
4
- var nodemon = require('nodemon');
5
- var nodemonDefaults = require('nodemon/lib/config/defaults');
6
-
7
- var pathToTsNode = path.normalize(__dirname + './../node_modules/.bin/ts-node');
8
- var filepath = path.normalize(__dirname + './../src/index.ts')
9
-
10
- nodemonDefaults.execMap.ts = pathToTsNode;
11
-
12
- nodemon({
13
- script: filepath,
14
- watch: ['yxorp.json']
15
- });
16
-
17
- nodemon.on('quit', function () {
18
- console.log('Yxopr has quit');
19
- process.exit();
20
- }).on('restart', function (files) {
21
- console.log('Yxopr restarts...');
22
- });
1
+ #!/usr/bin/env node
2
+
3
+ try {
4
+ require('../dist/index.js');
5
+ } catch (e) {
6
+ if (e.code === 'MODULE_NOT_FOUND') {
7
+ console.error(
8
+ 'Yxorp is not built. Run `npm run build` first, or use `npm start` for development.'
9
+ );
10
+ process.exit(1);
11
+ }
12
+ throw e;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ var _a;
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const path_1 = __importDefault(require("path"));
8
+ const config_service_1 = require("./services/config.service");
9
+ const logger_service_1 = require("./services/logger.service");
10
+ const remote_rules_matcher_service_1 = require("./services/rules-matchers/remote-rules-matcher.service");
11
+ const rewrite_rules_matcher_service_1 = require("./services/rules-matchers/rewrite-rules-matcher.service");
12
+ const mock_rules_matcher_service_1 = require("./services/rules-matchers/mock-rules-matcher.service");
13
+ const yxorp_server_service_1 = require("./services/yxorp-server.service");
14
+ const config_resolver_1 = require("./services/config-resolver");
15
+ // --- Config resolution ---
16
+ let configDir;
17
+ let config;
18
+ try {
19
+ const resolved = (0, config_resolver_1.resolveConfig)(process.cwd(), process.argv);
20
+ configDir = resolved.configDir;
21
+ config = resolved.config;
22
+ }
23
+ catch (e) {
24
+ console.error(e.message || e);
25
+ process.exit(1);
26
+ }
27
+ // Change CWD to config directory so relative paths in config work correctly
28
+ if (configDir !== process.cwd()) {
29
+ process.chdir(configDir);
30
+ }
31
+ const proxyOptions = {
32
+ target: config.target,
33
+ changeOrigin: true,
34
+ followRedirects: true,
35
+ secure: false,
36
+ ws: true,
37
+ selfHandleResponse: true,
38
+ };
39
+ if (config.proxyHeaders) {
40
+ proxyOptions.headers = config.proxyHeaders;
41
+ }
42
+ const proxyConfig = {
43
+ ...config,
44
+ proxyOptions,
45
+ };
46
+ (_a = config === null || config === void 0 ? void 0 : config.scripts) === null || _a === void 0 ? void 0 : _a.forEach(script => {
47
+ require(path_1.default.resolve(script));
48
+ });
49
+ // Manual composition — no DI container
50
+ const logger = new logger_service_1.LoggerService();
51
+ const appConfig = new config_service_1.Config();
52
+ appConfig.set(proxyConfig);
53
+ const mockRulesMatcher = new mock_rules_matcher_service_1.MockRulesMatcher(appConfig);
54
+ const rewriteRulesMatcher = new rewrite_rules_matcher_service_1.RewriteRulesMatcher(appConfig);
55
+ const remoteRulesMatcher = new remote_rules_matcher_service_1.RemoteRulesMatcher(appConfig);
56
+ const { listen } = (0, yxorp_server_service_1.createServer)(appConfig, logger, rewriteRulesMatcher, mockRulesMatcher, remoteRulesMatcher);
57
+ listen(config.proxyPort, () => {
58
+ console.log(`Yxorp server started successfully on http://localhost:${config.proxyPort}`);
59
+ });
@@ -0,0 +1,15 @@
1
+ import { IncomingMessage } from 'http';
2
+ import { Middleware } from '../services/pipeline.service';
3
+ import { RewriteRulesMatcher } from '../services/rules-matchers/rewrite-rules-matcher.service';
4
+ import { MockRulesMatcher } from '../services/rules-matchers/mock-rules-matcher.service';
5
+ import { LoggerService } from '../services/logger.service';
6
+ export declare class BootstrapMiddleware implements Middleware<[req: IncomingMessage, res: any]> {
7
+ private rewriteRulesMatcher;
8
+ private mockRulesMatcher;
9
+ private logger;
10
+ constructor(rewriteRulesMatcher: RewriteRulesMatcher, mockRulesMatcher: MockRulesMatcher, logger: LoggerService);
11
+ use(req: IncomingMessage, _res: any, next: () => void): void;
12
+ private setRewriteRule;
13
+ private setMockRule;
14
+ private setQueryParams;
15
+ }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BootstrapMiddleware = void 0;
7
+ const qs_1 = __importDefault(require("qs"));
8
+ class BootstrapMiddleware {
9
+ constructor(rewriteRulesMatcher, mockRulesMatcher, logger) {
10
+ this.rewriteRulesMatcher = rewriteRulesMatcher;
11
+ this.mockRulesMatcher = mockRulesMatcher;
12
+ this.logger = logger;
13
+ }
14
+ use(req, _res, next) {
15
+ try {
16
+ this.setRewriteRule(req);
17
+ this.setMockRule(req);
18
+ this.setQueryParams(req);
19
+ next();
20
+ }
21
+ catch (e) {
22
+ this.logger.error(e);
23
+ next();
24
+ }
25
+ }
26
+ setRewriteRule(req) {
27
+ if (!req.url || !req.method) {
28
+ return;
29
+ }
30
+ const rewriteRule = this.rewriteRulesMatcher.match(req.url, req.method);
31
+ if (rewriteRule) {
32
+ req.rewriteRule = rewriteRule;
33
+ const rewriteRuleParams = this.rewriteRulesMatcher.params(req.url, rewriteRule);
34
+ if (rewriteRuleParams) {
35
+ req.rewriteRuleParams = rewriteRuleParams || {};
36
+ }
37
+ }
38
+ }
39
+ setMockRule(req) {
40
+ if (!req.url || !req.method) {
41
+ return;
42
+ }
43
+ const mockRule = this.mockRulesMatcher.match(req.url, req.method);
44
+ if (mockRule) {
45
+ req.mockRule = mockRule;
46
+ const mockRuleParams = this.mockRulesMatcher.params(req.url, mockRule);
47
+ if (mockRuleParams) {
48
+ req.mockRuleParams = mockRuleParams || {};
49
+ }
50
+ }
51
+ }
52
+ setQueryParams(req) {
53
+ if (!req.url) {
54
+ return;
55
+ }
56
+ const url = new URL(req.url, 'http://fake.com');
57
+ const query = qs_1.default.parse(url.search, {
58
+ ignoreQueryPrefix: true,
59
+ });
60
+ req.query = query;
61
+ }
62
+ }
63
+ exports.BootstrapMiddleware = BootstrapMiddleware;
@@ -0,0 +1,9 @@
1
+ /// <reference types="node" />
2
+ import { ServerResponse, IncomingMessage } from 'http';
3
+ import { Middleware } from '../services/pipeline.service';
4
+ import { LoggerService } from '../services/logger.service';
5
+ export declare class MockMiddleware implements Middleware<[req: IncomingMessage, res: ServerResponse]> {
6
+ private logger;
7
+ constructor(logger: LoggerService);
8
+ use(req: IncomingMessage, res: ServerResponse, next: () => void): Promise<void>;
9
+ }