@infodb/revx 0.2.2 → 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 +314 -118
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +68 -64
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +63 -64
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +14 -17
- package/dist/commands/validate.js.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/utils/config.d.ts +6 -63
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +10 -11
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/logger.d.ts +3 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +7 -4
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/proxy.d.ts +7 -16
- package/dist/utils/proxy.d.ts.map +1 -1
- package/dist/utils/proxy.js +12 -101
- package/dist/utils/proxy.js.map +1 -1
- package/dist/utils/vite-middleware.d.ts +14 -0
- package/dist/utils/vite-middleware.d.ts.map +1 -0
- package/dist/utils/vite-middleware.js +63 -0
- package/dist/utils/vite-middleware.js.map +1 -0
- package/package.json +11 -6
- package/sample/revx.mixed.yaml +63 -0
- package/sample/revx.simple.yaml +4 -4
- package/sample/revx.vite.yaml +56 -0
- package/sample/revx.yaml +9 -58
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC1D,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAElC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;IAyBpC,OAAO,CAAC,0BAA0B;IAWlC,OAAO,CAAC,uBAAuB;IAgC/B,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,aAAa;CAuBtB"}
|
package/dist/utils/config.js
CHANGED
|
@@ -83,19 +83,18 @@ export class ConfigLoader {
|
|
|
83
83
|
if (!route.path) {
|
|
84
84
|
throw new Error('Route path is required');
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
const hasTarget = !!route.target;
|
|
87
|
+
const hasStatic = !!route.static;
|
|
88
|
+
const hasVite = !!route.vite;
|
|
89
|
+
const routeTypes = [hasTarget, hasStatic, hasVite].filter(Boolean).length;
|
|
90
|
+
if (routeTypes === 0) {
|
|
91
|
+
throw new Error(`Route ${route.path} must have either target, static, or vite`);
|
|
88
92
|
}
|
|
89
|
-
if (
|
|
90
|
-
throw new Error(`Route ${route.path}
|
|
93
|
+
if (routeTypes > 1) {
|
|
94
|
+
throw new Error(`Route ${route.path} can only have one of: target, static, or vite`);
|
|
91
95
|
}
|
|
92
|
-
if (route.
|
|
93
|
-
|
|
94
|
-
throw new Error(`Route ${route.path} targets must be a non-empty array`);
|
|
95
|
-
}
|
|
96
|
-
if (route.strategy && !['round-robin', 'random', 'ip-hash'].includes(route.strategy)) {
|
|
97
|
-
throw new Error(`Route ${route.path} has invalid strategy: ${route.strategy}`);
|
|
98
|
-
}
|
|
96
|
+
if (hasVite && !route.vite.root) {
|
|
97
|
+
throw new Error(`Route ${route.path} vite configuration requires 'root' field`);
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
}
|
package/dist/utils/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare class Logger {
|
|
2
|
-
private
|
|
3
|
-
constructor(
|
|
2
|
+
private verboseMode;
|
|
3
|
+
constructor(verboseMode?: boolean);
|
|
4
|
+
isVerbose(): boolean;
|
|
4
5
|
info(message: string): void;
|
|
5
6
|
success(message: string): void;
|
|
6
7
|
error(message: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,qBAAa,MAAM;IACL,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,qBAAa,MAAM;IACL,OAAO,CAAC,WAAW;gBAAX,WAAW,GAAE,OAAe;IAEhD,SAAS,IAAI,OAAO;IAIpB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAS1C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IASxC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3C,OAAO,CAAC,cAAc;CAgBvB"}
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
export class Logger {
|
|
3
|
-
constructor(
|
|
4
|
-
this.
|
|
3
|
+
constructor(verboseMode = false) {
|
|
4
|
+
this.verboseMode = verboseMode;
|
|
5
|
+
}
|
|
6
|
+
isVerbose() {
|
|
7
|
+
return this.verboseMode;
|
|
5
8
|
}
|
|
6
9
|
info(message) {
|
|
7
10
|
console.log(chalk.blue('ℹ'), message);
|
|
@@ -16,7 +19,7 @@ export class Logger {
|
|
|
16
19
|
console.warn(chalk.yellow('⚠'), message);
|
|
17
20
|
}
|
|
18
21
|
verbose(message, data) {
|
|
19
|
-
if (this.
|
|
22
|
+
if (this.verboseMode) {
|
|
20
23
|
console.log(chalk.gray('🔍'), chalk.gray(message));
|
|
21
24
|
if (data) {
|
|
22
25
|
console.log(chalk.gray(JSON.stringify(data, null, 2)));
|
|
@@ -24,7 +27,7 @@ export class Logger {
|
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
debug(message, data) {
|
|
27
|
-
if (this.
|
|
30
|
+
if (this.verboseMode) {
|
|
28
31
|
console.log(chalk.magenta('🐛'), chalk.magenta(message));
|
|
29
32
|
if (data) {
|
|
30
33
|
console.log(chalk.magenta(JSON.stringify(data, null, 2)));
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,OAAO,MAAM;IACjB,YAAoB,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,OAAO,MAAM;IACjB,YAAoB,cAAuB,KAAK;QAA5B,gBAAW,GAAX,WAAW,CAAiB;IAAG,CAAC;IAEpD,SAAS;QACP,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC,OAAe;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,OAAe;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAe;QACnB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,CAAC,OAAe;QACrB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,OAAe,EAAE,IAAU;QACjC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACnD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAU;QAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YACzD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,CAAC,MAAc,EAAE,IAAY;QAClC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACjF,CAAC;IAEO,cAAc,CAAC,MAAc;QACnC,QAAQ,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,KAAK,KAAK;gBACR,OAAO,KAAK,CAAC,KAAK,CAAC;YACrB,KAAK,MAAM;gBACT,OAAO,KAAK,CAAC,IAAI,CAAC;YACpB,KAAK,KAAK;gBACR,OAAO,KAAK,CAAC,MAAM,CAAC;YACtB,KAAK,QAAQ;gBACX,OAAO,KAAK,CAAC,GAAG,CAAC;YACnB,KAAK,OAAO;gBACV,OAAO,KAAK,CAAC,OAAO,CAAC;YACvB;gBACE,OAAO,KAAK,CAAC,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;CACF"}
|
package/dist/utils/proxy.d.ts
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
|
+
import { RequestHandler } from 'http-proxy-middleware';
|
|
1
2
|
import { RouteConfig } from './config.js';
|
|
2
3
|
import { Logger } from './logger.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
private targets;
|
|
7
|
-
private strategy;
|
|
8
|
-
private logger;
|
|
9
|
-
private currentIndex;
|
|
10
|
-
private targetHealth;
|
|
11
|
-
constructor(targets: string[], strategy: "round-robin" | "random" | "ip-hash" | undefined, logger: Logger);
|
|
12
|
-
getTarget(req?: Request): string;
|
|
13
|
-
markUnhealthy(target: string): void;
|
|
14
|
-
markHealthy(target: string): void;
|
|
15
|
-
private hashCode;
|
|
4
|
+
export interface ProxyInfo {
|
|
5
|
+
middleware: RequestHandler;
|
|
6
|
+
route: RouteConfig;
|
|
16
7
|
}
|
|
17
8
|
export declare class ProxyManager {
|
|
18
9
|
private logger;
|
|
19
|
-
private
|
|
10
|
+
private proxies;
|
|
20
11
|
constructor(logger: Logger);
|
|
21
|
-
createProxyMiddleware(route: RouteConfig):
|
|
22
|
-
|
|
12
|
+
createProxyMiddleware(route: RouteConfig): RequestHandler;
|
|
13
|
+
getProxies(): ProxyInfo[];
|
|
23
14
|
}
|
|
24
15
|
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,qBAAa,YAAY;IAGX,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,OAAO,CAAmB;gBAEd,MAAM,EAAE,MAAM;IAElC,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc;IAqDzD,UAAU,IAAI,SAAS,EAAE;CAG1B"}
|
package/dist/utils/proxy.js
CHANGED
|
@@ -1,117 +1,33 @@
|
|
|
1
1
|
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
2
|
-
export class LoadBalancer {
|
|
3
|
-
constructor(targets, strategy = 'round-robin', logger) {
|
|
4
|
-
this.targets = targets;
|
|
5
|
-
this.strategy = strategy;
|
|
6
|
-
this.logger = logger;
|
|
7
|
-
this.currentIndex = 0;
|
|
8
|
-
this.targetHealth = new Map();
|
|
9
|
-
targets.forEach(target => this.targetHealth.set(target, true));
|
|
10
|
-
}
|
|
11
|
-
getTarget(req) {
|
|
12
|
-
const healthyTargets = this.targets.filter(t => this.targetHealth.get(t));
|
|
13
|
-
if (healthyTargets.length === 0) {
|
|
14
|
-
this.logger.warning('All targets are unhealthy, using first target');
|
|
15
|
-
return this.targets[0];
|
|
16
|
-
}
|
|
17
|
-
switch (this.strategy) {
|
|
18
|
-
case 'random':
|
|
19
|
-
return healthyTargets[Math.floor(Math.random() * healthyTargets.length)];
|
|
20
|
-
case 'ip-hash':
|
|
21
|
-
if (req) {
|
|
22
|
-
const ip = req.ip || req.socket.remoteAddress || '';
|
|
23
|
-
const hash = this.hashCode(ip);
|
|
24
|
-
return healthyTargets[Math.abs(hash) % healthyTargets.length];
|
|
25
|
-
}
|
|
26
|
-
return healthyTargets[0];
|
|
27
|
-
case 'round-robin':
|
|
28
|
-
default:
|
|
29
|
-
const target = healthyTargets[this.currentIndex % healthyTargets.length];
|
|
30
|
-
this.currentIndex = (this.currentIndex + 1) % healthyTargets.length;
|
|
31
|
-
return target;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
markUnhealthy(target) {
|
|
35
|
-
this.targetHealth.set(target, false);
|
|
36
|
-
this.logger.warning(`Target marked as unhealthy: ${target}`);
|
|
37
|
-
}
|
|
38
|
-
markHealthy(target) {
|
|
39
|
-
this.targetHealth.set(target, true);
|
|
40
|
-
this.logger.verbose(`Target marked as healthy: ${target}`);
|
|
41
|
-
}
|
|
42
|
-
hashCode(str) {
|
|
43
|
-
let hash = 0;
|
|
44
|
-
for (let i = 0; i < str.length; i++) {
|
|
45
|
-
const char = str.charCodeAt(i);
|
|
46
|
-
hash = ((hash << 5) - hash) + char;
|
|
47
|
-
hash = hash & hash;
|
|
48
|
-
}
|
|
49
|
-
return hash;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
2
|
export class ProxyManager {
|
|
53
3
|
constructor(logger) {
|
|
54
4
|
this.logger = logger;
|
|
55
|
-
this.
|
|
5
|
+
this.proxies = [];
|
|
56
6
|
}
|
|
57
7
|
createProxyMiddleware(route) {
|
|
58
8
|
const options = {
|
|
59
9
|
pathFilter: route.path,
|
|
10
|
+
target: route.target,
|
|
60
11
|
changeOrigin: route.changeOrigin ?? true,
|
|
61
12
|
ws: route.ws ?? false,
|
|
62
13
|
pathRewrite: route.pathRewrite,
|
|
63
|
-
timeout: route.options?.timeout,
|
|
64
|
-
followRedirects: route.options?.followRedirects,
|
|
65
|
-
// Let http-proxy-middleware handle responses naturally
|
|
66
14
|
preserveHeaderKeyCase: true,
|
|
67
15
|
autoRewrite: true,
|
|
68
|
-
// Increase limits to handle large responses from dev servers
|
|
69
|
-
proxyTimeout: route.options?.timeout || 30000,
|
|
70
16
|
on: {
|
|
71
17
|
proxyReq: (proxyReq, req) => {
|
|
72
|
-
if (route.options?.headers) {
|
|
73
|
-
Object.entries(route.options.headers).forEach(([key, value]) => {
|
|
74
|
-
proxyReq.setHeader(key, value);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
if (route.transform?.request?.headers?.add) {
|
|
78
|
-
Object.entries(route.transform.request.headers.add).forEach(([key, value]) => {
|
|
79
|
-
proxyReq.setHeader(key, value);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
if (route.transform?.request?.headers?.remove) {
|
|
83
|
-
route.transform.request.headers.remove.forEach(header => {
|
|
84
|
-
proxyReq.removeHeader(header);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
18
|
this.logger.verbose('Proxy request', {
|
|
88
19
|
method: req.method,
|
|
89
20
|
path: req.url,
|
|
90
|
-
target:
|
|
21
|
+
target: route.target
|
|
91
22
|
});
|
|
92
23
|
},
|
|
93
24
|
proxyRes: (proxyRes, req, res) => {
|
|
94
|
-
if (route.transform?.response?.headers?.add) {
|
|
95
|
-
Object.entries(route.transform.response.headers.add).forEach(([key, value]) => {
|
|
96
|
-
proxyRes.headers[key.toLowerCase()] = value;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
if (route.transform?.response?.headers?.remove) {
|
|
100
|
-
route.transform.response.headers.remove.forEach(header => {
|
|
101
|
-
delete proxyRes.headers[header.toLowerCase()];
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
25
|
this.logger.verbose('Proxy response', {
|
|
105
26
|
statusCode: proxyRes.statusCode,
|
|
106
27
|
path: req.url
|
|
107
28
|
});
|
|
108
29
|
},
|
|
109
30
|
error: (err, req, res) => {
|
|
110
|
-
// Ignore CONTENT_LENGTH_MISMATCH errors - they're usually benign with streaming responses
|
|
111
|
-
if (err.message && err.message.includes('CONTENT_LENGTH_MISMATCH')) {
|
|
112
|
-
this.logger.verbose(`Ignoring CONTENT_LENGTH_MISMATCH for ${req.url}`);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
31
|
this.logger.error(`Proxy error: ${err.message}`);
|
|
116
32
|
const serverRes = res;
|
|
117
33
|
if (!serverRes.headersSent) {
|
|
@@ -124,22 +40,17 @@ export class ProxyManager {
|
|
|
124
40
|
}
|
|
125
41
|
}
|
|
126
42
|
};
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
};
|
|
133
|
-
this.logger.info(`Load balancer configured for ${route.path} with ${route.targets.length} targets (${route.strategy || 'round-robin'})`);
|
|
134
|
-
}
|
|
135
|
-
else if (route.target) {
|
|
136
|
-
options.target = route.target;
|
|
137
|
-
this.logger.info(`Proxy configured: ${route.path} -> ${route.target}`);
|
|
43
|
+
const middleware = createProxyMiddleware(options);
|
|
44
|
+
// Store proxy info for WebSocket upgrade handling
|
|
45
|
+
this.proxies.push({ middleware, route });
|
|
46
|
+
this.logger.info(`Proxy configured: ${route.path} -> ${route.target}`);
|
|
47
|
+
if (route.ws) {
|
|
48
|
+
this.logger.verbose(`WebSocket enabled for: ${route.path}`);
|
|
138
49
|
}
|
|
139
|
-
return
|
|
50
|
+
return middleware;
|
|
140
51
|
}
|
|
141
|
-
|
|
142
|
-
return this.
|
|
52
|
+
getProxies() {
|
|
53
|
+
return this.proxies;
|
|
143
54
|
}
|
|
144
55
|
}
|
|
145
56
|
//# sourceMappingURL=proxy.js.map
|
package/dist/utils/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAA2B,MAAM,uBAAuB,CAAC;AAUvF,MAAM,OAAO,YAAY;IAGvB,YAAoB,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QAF1B,YAAO,GAAgB,EAAE,CAAC;IAEG,CAAC;IAEtC,qBAAqB,CAAC,KAAkB;QACtC,MAAM,OAAO,GAAY;YACvB,UAAU,EAAE,KAAK,CAAC,IAAI;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;YACxC,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,KAAK;YACrB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,qBAAqB,EAAE,IAAI;YAC3B,WAAW,EAAE,IAAI;YAEjB,EAAE,EAAE;gBACF,QAAQ,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;oBAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE;wBACnC,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,IAAI,EAAE,GAAG,CAAC,GAAG;wBACb,MAAM,EAAE,KAAK,CAAC,MAAM;qBACrB,CAAC,CAAC;gBACL,CAAC;gBAED,QAAQ,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;oBAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE;wBACpC,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,IAAI,EAAE,GAAG,CAAC,GAAG;qBACd,CAAC,CAAC;gBACL,CAAC;gBAED,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;oBACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;oBACjD,MAAM,SAAS,GAAG,GAAqB,CAAC;oBACxC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;wBAC3B,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;oBACnE,CAAC;oBACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;wBAC3B,KAAK,EAAE,aAAa;wBACpB,OAAO,EAAE,yBAAyB;qBACnC,CAAC,CAAC,CAAC;gBACN,CAAC;aACF;SACF,CAAC;QAEF,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAElD,kDAAkD;QAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAEzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,0BAA0B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViteDevServer } from 'vite';
|
|
2
|
+
import { RequestHandler } from 'express';
|
|
3
|
+
import { RouteConfig } from './config.js';
|
|
4
|
+
import { Logger } from './logger.js';
|
|
5
|
+
export declare class ViteMiddlewareManager {
|
|
6
|
+
private logger;
|
|
7
|
+
private viteServers;
|
|
8
|
+
constructor(logger: Logger);
|
|
9
|
+
createViteMiddleware(route: RouteConfig): Promise<RequestHandler>;
|
|
10
|
+
cleanup(): Promise<void>;
|
|
11
|
+
getServer(path: string): ViteDevServer | undefined;
|
|
12
|
+
getServerCount(): number;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=vite-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-middleware.d.ts","sourceRoot":"","sources":["../../src/utils/vite-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA8B,MAAM,MAAM,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,qBAAa,qBAAqB;IAGpB,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,WAAW,CAAyC;gBAExC,MAAM,EAAE,MAAM;IAE5B,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IA+CjE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIlD,cAAc,IAAI,MAAM;CAGzB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createServer } from 'vite';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
export class ViteMiddlewareManager {
|
|
5
|
+
constructor(logger) {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
this.viteServers = new Map();
|
|
8
|
+
}
|
|
9
|
+
async createViteMiddleware(route) {
|
|
10
|
+
if (!route.vite) {
|
|
11
|
+
throw new Error('Route does not have vite configuration');
|
|
12
|
+
}
|
|
13
|
+
const rootPath = resolve(process.cwd(), route.vite.root);
|
|
14
|
+
if (!existsSync(rootPath)) {
|
|
15
|
+
this.logger.error(`Vite root directory does not exist: ${rootPath}`);
|
|
16
|
+
throw new Error(`Vite root directory not found: ${rootPath}`);
|
|
17
|
+
}
|
|
18
|
+
this.logger.info(`Creating Vite middleware: ${route.path} -> ${rootPath}`);
|
|
19
|
+
const viteConfig = {
|
|
20
|
+
root: rootPath,
|
|
21
|
+
base: route.vite.base || route.path,
|
|
22
|
+
configFile: route.vite.configFile,
|
|
23
|
+
server: {
|
|
24
|
+
middlewareMode: true,
|
|
25
|
+
hmr: {
|
|
26
|
+
// Use the parent server's port for HMR
|
|
27
|
+
clientPort: undefined,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
// Suppress Vite's own logging since we're using our logger
|
|
31
|
+
logLevel: this.logger.isVerbose() ? 'info' : 'warn',
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
const vite = await createServer(viteConfig);
|
|
35
|
+
this.viteServers.set(route.path, vite);
|
|
36
|
+
this.logger.verbose(`Vite server created for ${route.path}`, {
|
|
37
|
+
root: rootPath,
|
|
38
|
+
base: viteConfig.base,
|
|
39
|
+
});
|
|
40
|
+
return vite.middlewares;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
this.logger.error(`Failed to create Vite server for ${route.path}: ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async cleanup() {
|
|
50
|
+
this.logger.info('Closing Vite servers...');
|
|
51
|
+
const closePromises = Array.from(this.viteServers.values()).map((vite) => vite.close());
|
|
52
|
+
await Promise.all(closePromises);
|
|
53
|
+
this.viteServers.clear();
|
|
54
|
+
this.logger.verbose('All Vite servers closed');
|
|
55
|
+
}
|
|
56
|
+
getServer(path) {
|
|
57
|
+
return this.viteServers.get(path);
|
|
58
|
+
}
|
|
59
|
+
getServerCount() {
|
|
60
|
+
return this.viteServers.size;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=vite-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-middleware.js","sourceRoot":"","sources":["../../src/utils/vite-middleware.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infodb/revx",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Multi-Vite project development server - Host multiple Vite apps on a single port with unified routing",
|
|
5
5
|
"homepage": "https://github.com/tamuto/infodb-cli/",
|
|
6
6
|
"bugs": "https://github.com/tamuto/infodb-cli/issues",
|
|
7
7
|
"repository": {
|
|
@@ -10,12 +10,16 @@
|
|
|
10
10
|
"directory": "revx"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
|
+
"vite",
|
|
14
|
+
"multi-project",
|
|
15
|
+
"monorepo",
|
|
16
|
+
"dev-server",
|
|
17
|
+
"vite-middleware",
|
|
18
|
+
"hmr",
|
|
13
19
|
"reverse-proxy",
|
|
14
|
-
"
|
|
15
|
-
"cli",
|
|
20
|
+
"webpack",
|
|
16
21
|
"express",
|
|
17
|
-
"yaml"
|
|
18
|
-
"http-proxy"
|
|
22
|
+
"yaml"
|
|
19
23
|
],
|
|
20
24
|
"author": "tamuto <tamuto@infodb.jp>",
|
|
21
25
|
"license": "MIT",
|
|
@@ -39,6 +43,7 @@
|
|
|
39
43
|
"express": "^5.1.0",
|
|
40
44
|
"http-proxy-middleware": "^3.0.3",
|
|
41
45
|
"morgan": "^1.10.0",
|
|
46
|
+
"vite": "^6.0.7",
|
|
42
47
|
"yaml": "^2.8.1"
|
|
43
48
|
},
|
|
44
49
|
"devDependencies": {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# revx.mixed.yaml - Mixed Development Servers Example
|
|
2
|
+
# Use this when you have Vite apps alongside webpack/Parcel/other dev servers
|
|
3
|
+
|
|
4
|
+
# Server settings
|
|
5
|
+
server:
|
|
6
|
+
port: 3000
|
|
7
|
+
host: 0.0.0.0
|
|
8
|
+
name: "Mixed Dev Server (Vite + webpack)"
|
|
9
|
+
maxSockets: 512
|
|
10
|
+
|
|
11
|
+
# Global configuration
|
|
12
|
+
global:
|
|
13
|
+
cors:
|
|
14
|
+
enabled: true
|
|
15
|
+
origin: "*"
|
|
16
|
+
|
|
17
|
+
logging:
|
|
18
|
+
enabled: true
|
|
19
|
+
format: "dev"
|
|
20
|
+
|
|
21
|
+
# Route definitions
|
|
22
|
+
routes:
|
|
23
|
+
# New Vite app (native middleware)
|
|
24
|
+
- path: "/new-app"
|
|
25
|
+
vite:
|
|
26
|
+
root: "./apps/new-app"
|
|
27
|
+
base: "/new-app"
|
|
28
|
+
|
|
29
|
+
# Another Vite app
|
|
30
|
+
- path: "/dashboard"
|
|
31
|
+
vite:
|
|
32
|
+
root: "./apps/dashboard"
|
|
33
|
+
base: "/dashboard"
|
|
34
|
+
|
|
35
|
+
# Legacy webpack dev server (reverse proxy)
|
|
36
|
+
- path: "/legacy/*"
|
|
37
|
+
target: "http://localhost:8080"
|
|
38
|
+
ws: true # Enable WebSocket for webpack HMR
|
|
39
|
+
changeOrigin: true
|
|
40
|
+
|
|
41
|
+
# Parcel dev server (reverse proxy)
|
|
42
|
+
- path: "/old-app/*"
|
|
43
|
+
target: "http://localhost:1234"
|
|
44
|
+
ws: true
|
|
45
|
+
changeOrigin: true
|
|
46
|
+
|
|
47
|
+
# Backend API
|
|
48
|
+
- path: "/api/*"
|
|
49
|
+
target: "http://localhost:4000"
|
|
50
|
+
changeOrigin: true
|
|
51
|
+
pathRewrite:
|
|
52
|
+
"^/api": ""
|
|
53
|
+
|
|
54
|
+
# Static documentation
|
|
55
|
+
- path: "/docs"
|
|
56
|
+
static: "./public/docs"
|
|
57
|
+
|
|
58
|
+
# Usage:
|
|
59
|
+
# 1. Start webpack dev server: cd apps/legacy && npm run dev (on :8080)
|
|
60
|
+
# 2. Start Parcel: cd apps/old-app && npm run dev (on :1234)
|
|
61
|
+
# 3. Start backend API: cd api && npm run dev (on :4000)
|
|
62
|
+
# 4. Start revx: revx start revx.mixed.yaml
|
|
63
|
+
# 5. Access all apps at http://localhost:3000
|
package/sample/revx.simple.yaml
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# revx.vite.yaml - Multi-Vite Project Configuration Example
|
|
2
|
+
|
|
3
|
+
# Server settings
|
|
4
|
+
server:
|
|
5
|
+
port: 3000
|
|
6
|
+
host: 0.0.0.0
|
|
7
|
+
name: "Multi-Vite Dev Server"
|
|
8
|
+
# Increase max sockets for better performance with Vite
|
|
9
|
+
maxSockets: 512
|
|
10
|
+
|
|
11
|
+
# Global configuration
|
|
12
|
+
global:
|
|
13
|
+
# CORS settings
|
|
14
|
+
cors:
|
|
15
|
+
enabled: true
|
|
16
|
+
origin: "*"
|
|
17
|
+
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
|
18
|
+
credentials: true
|
|
19
|
+
|
|
20
|
+
# Logging settings
|
|
21
|
+
logging:
|
|
22
|
+
enabled: true
|
|
23
|
+
format: "dev" # dev format is good for development
|
|
24
|
+
|
|
25
|
+
# Route definitions
|
|
26
|
+
routes:
|
|
27
|
+
# Example 1: Vite project 1 (SPA at /app1)
|
|
28
|
+
- path: "/app1"
|
|
29
|
+
vite:
|
|
30
|
+
root: "./projects/app1"
|
|
31
|
+
base: "/app1"
|
|
32
|
+
# Optional: specify custom vite config file
|
|
33
|
+
# configFile: "./projects/app1/vite.config.ts"
|
|
34
|
+
|
|
35
|
+
# Example 2: Vite project 2 (SPA at /app2)
|
|
36
|
+
- path: "/app2"
|
|
37
|
+
vite:
|
|
38
|
+
root: "./projects/app2"
|
|
39
|
+
base: "/app2"
|
|
40
|
+
|
|
41
|
+
# Example 3: Backend API proxy
|
|
42
|
+
- path: "/api/*"
|
|
43
|
+
target: "http://localhost:4000"
|
|
44
|
+
changeOrigin: true
|
|
45
|
+
pathRewrite:
|
|
46
|
+
"^/api": ""
|
|
47
|
+
|
|
48
|
+
# Example 4: Admin dashboard (static files)
|
|
49
|
+
- path: "/admin/*"
|
|
50
|
+
static: "./admin/dist"
|
|
51
|
+
|
|
52
|
+
# Example 5: Root Vite project (catches remaining routes)
|
|
53
|
+
# - path: "/*"
|
|
54
|
+
# vite:
|
|
55
|
+
# root: "./projects/main"
|
|
56
|
+
# base: "/"
|