@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 +21 -0
- package/README.md +376 -0
- package/bin/cli.js +2 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +139 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/start.d.ts +4 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +160 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/validate.d.ts +4 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +50 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +107 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +102 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +58 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/proxy.d.ts +24 -0
- package/dist/utils/proxy.d.ts.map +1 -0
- package/dist/utils/proxy.js +134 -0
- package/dist/utils/proxy.js.map +1 -0
- package/package.json +60 -0
- package/sample/revx.simple.yaml +15 -0
- package/sample/revx.yaml +95 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import morgan from 'morgan';
|
|
4
|
+
import { createServer } from 'http';
|
|
5
|
+
import { createServer as createHttpsServer } from 'https';
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
7
|
+
import { ConfigLoader } from '../utils/config.js';
|
|
8
|
+
import { ProxyManager } from '../utils/proxy.js';
|
|
9
|
+
import { Logger } from '../utils/logger.js';
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
11
|
+
export async function startCommand(configFile = 'revx.yaml', options) {
|
|
12
|
+
const logger = new Logger(options.verbose);
|
|
13
|
+
const configLoader = new ConfigLoader(logger);
|
|
14
|
+
try {
|
|
15
|
+
logger.info(`Loading configuration from: ${configFile}`);
|
|
16
|
+
const config = configLoader.load(configFile);
|
|
17
|
+
const app = express();
|
|
18
|
+
const proxyManager = new ProxyManager(logger);
|
|
19
|
+
setupMiddleware(app, config, logger);
|
|
20
|
+
setupRoutes(app, config, proxyManager, logger);
|
|
21
|
+
await startServer(app, config, logger);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (error instanceof Error) {
|
|
25
|
+
logger.error(`Failed to start server: ${error.message}`);
|
|
26
|
+
}
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function setupMiddleware(app, config, logger) {
|
|
31
|
+
if (config.global?.cors?.enabled !== false) {
|
|
32
|
+
const corsOptions = {
|
|
33
|
+
origin: config.global?.cors?.origin || '*',
|
|
34
|
+
methods: config.global?.cors?.methods || ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
35
|
+
credentials: config.global?.cors?.credentials ?? true
|
|
36
|
+
};
|
|
37
|
+
app.use(cors(corsOptions));
|
|
38
|
+
logger.verbose('CORS enabled', corsOptions);
|
|
39
|
+
}
|
|
40
|
+
const requestIdMiddleware = config.middleware?.find(m => m.type === 'requestId');
|
|
41
|
+
if (requestIdMiddleware?.enabled !== false) {
|
|
42
|
+
const headerName = requestIdMiddleware?.headerName || 'X-Request-ID';
|
|
43
|
+
app.use((req, res, next) => {
|
|
44
|
+
const requestId = randomUUID();
|
|
45
|
+
req.headers[headerName.toLowerCase()] = requestId;
|
|
46
|
+
res.setHeader(headerName, requestId);
|
|
47
|
+
next();
|
|
48
|
+
});
|
|
49
|
+
logger.verbose('Request ID middleware enabled');
|
|
50
|
+
}
|
|
51
|
+
if (config.global?.logging?.enabled !== false) {
|
|
52
|
+
const format = config.global?.logging?.format || 'combined';
|
|
53
|
+
app.use(morgan(format));
|
|
54
|
+
logger.verbose(`Logging middleware enabled: ${format}`);
|
|
55
|
+
}
|
|
56
|
+
const compressionMiddleware = config.middleware?.find(m => m.type === 'compression');
|
|
57
|
+
if (compressionMiddleware?.enabled) {
|
|
58
|
+
logger.verbose('Compression middleware enabled');
|
|
59
|
+
}
|
|
60
|
+
app.use(express.json());
|
|
61
|
+
app.use(express.urlencoded({ extended: true }));
|
|
62
|
+
}
|
|
63
|
+
function setupRoutes(app, config, proxyManager, logger) {
|
|
64
|
+
config.routes.forEach((route) => {
|
|
65
|
+
if (route.cors) {
|
|
66
|
+
const routeCorsOptions = {
|
|
67
|
+
origin: route.cors.origin || '*',
|
|
68
|
+
methods: route.cors.methods || ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
69
|
+
credentials: route.cors.credentials ?? true
|
|
70
|
+
};
|
|
71
|
+
app.use(route.path, cors(routeCorsOptions));
|
|
72
|
+
logger.verbose(`Route-specific CORS for ${route.path}`, routeCorsOptions);
|
|
73
|
+
}
|
|
74
|
+
const proxyMiddleware = proxyManager.createProxyMiddleware(route);
|
|
75
|
+
app.use(route.path, proxyMiddleware);
|
|
76
|
+
});
|
|
77
|
+
app.get('/health', (req, res) => {
|
|
78
|
+
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
79
|
+
});
|
|
80
|
+
app.use((req, res) => {
|
|
81
|
+
res.status(404).json({
|
|
82
|
+
error: 'Not Found',
|
|
83
|
+
message: `No route matches ${req.method} ${req.path}`
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
app.use((err, req, res, next) => {
|
|
87
|
+
logger.error(`Server error: ${err.message}`);
|
|
88
|
+
if (!res.headersSent) {
|
|
89
|
+
res.status(500).json({
|
|
90
|
+
error: 'Internal Server Error',
|
|
91
|
+
message: err.message
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
async function startServer(app, config, logger) {
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
const port = config.server.port;
|
|
99
|
+
const host = config.server.host || '0.0.0.0';
|
|
100
|
+
let server;
|
|
101
|
+
if (config.ssl?.enabled) {
|
|
102
|
+
try {
|
|
103
|
+
const httpsOptions = {
|
|
104
|
+
key: readFileSync(config.ssl.key, 'utf-8'),
|
|
105
|
+
cert: readFileSync(config.ssl.cert, 'utf-8'),
|
|
106
|
+
ca: config.ssl.ca ? readFileSync(config.ssl.ca, 'utf-8') : undefined
|
|
107
|
+
};
|
|
108
|
+
server = createHttpsServer(httpsOptions, app);
|
|
109
|
+
logger.info('SSL/TLS enabled');
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (error instanceof Error) {
|
|
113
|
+
reject(new Error(`Failed to load SSL certificates: ${error.message}`));
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
server = createServer(app);
|
|
120
|
+
}
|
|
121
|
+
server.listen(port, host, () => {
|
|
122
|
+
const protocol = config.ssl?.enabled ? 'https' : 'http';
|
|
123
|
+
logger.server(`${config.server.name || 'Reverse Proxy'} started`);
|
|
124
|
+
logger.success(`Listening on ${protocol}://${host}:${port}`);
|
|
125
|
+
logger.info('');
|
|
126
|
+
logger.info('Configured routes:');
|
|
127
|
+
config.routes.forEach((route) => {
|
|
128
|
+
const target = route.target || `${route.targets?.length} targets`;
|
|
129
|
+
logger.info(` ${route.path} -> ${target}`);
|
|
130
|
+
});
|
|
131
|
+
logger.info('');
|
|
132
|
+
logger.info('Press Ctrl+C to stop the server');
|
|
133
|
+
resolve();
|
|
134
|
+
});
|
|
135
|
+
server.on('error', (error) => {
|
|
136
|
+
if (error.code === 'EADDRINUSE') {
|
|
137
|
+
reject(new Error(`Port ${port} is already in use`));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
reject(error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
process.on('SIGINT', () => {
|
|
144
|
+
logger.info('');
|
|
145
|
+
logger.info('Shutting down server...');
|
|
146
|
+
server.close(() => {
|
|
147
|
+
logger.success('Server stopped');
|
|
148
|
+
process.exit(0);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
process.on('SIGTERM', () => {
|
|
152
|
+
logger.info('Received SIGTERM signal');
|
|
153
|
+
server.close(() => {
|
|
154
|
+
logger.success('Server stopped');
|
|
155
|
+
process.exit(0);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAGA,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,iBAkDvF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ConfigLoader } from '../utils/config.js';
|
|
2
|
+
import { Logger } from '../utils/logger.js';
|
|
3
|
+
export async function validateCommand(configFile, options) {
|
|
4
|
+
const logger = new Logger(options.verbose);
|
|
5
|
+
const configLoader = new ConfigLoader(logger);
|
|
6
|
+
try {
|
|
7
|
+
logger.info(`Validating configuration file: ${configFile}`);
|
|
8
|
+
const config = configLoader.load(configFile);
|
|
9
|
+
logger.success('Configuration is valid');
|
|
10
|
+
logger.info('');
|
|
11
|
+
logger.info('Configuration summary:');
|
|
12
|
+
logger.info(` Server: ${config.server.host || '0.0.0.0'}:${config.server.port}`);
|
|
13
|
+
logger.info(` Routes: ${config.routes.length}`);
|
|
14
|
+
if (options.verbose) {
|
|
15
|
+
logger.info('');
|
|
16
|
+
logger.info('Route details:');
|
|
17
|
+
config.routes.forEach((route, index) => {
|
|
18
|
+
logger.info(` ${index + 1}. ${route.path}`);
|
|
19
|
+
if (route.target) {
|
|
20
|
+
logger.info(` Target: ${route.target}`);
|
|
21
|
+
}
|
|
22
|
+
else if (route.targets) {
|
|
23
|
+
logger.info(` Targets: ${route.targets.length} (${route.strategy || 'round-robin'})`);
|
|
24
|
+
route.targets.forEach((target, i) => {
|
|
25
|
+
logger.info(` ${i + 1}. ${target}`);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
if (config.middleware && config.middleware.length > 0) {
|
|
30
|
+
logger.info('');
|
|
31
|
+
logger.info('Middleware:');
|
|
32
|
+
config.middleware.forEach((mw, index) => {
|
|
33
|
+
const status = mw.enabled === false ? 'disabled' : 'enabled';
|
|
34
|
+
logger.info(` ${index + 1}. ${mw.type} (${status})`);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (config.ssl?.enabled) {
|
|
38
|
+
logger.info('');
|
|
39
|
+
logger.info('SSL: enabled');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (error instanceof Error) {
|
|
45
|
+
logger.error(`Validation failed: ${error.message}`);
|
|
46
|
+
}
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { startCommand } from './commands/start.js';
|
|
4
|
+
import { validateCommand } from './commands/validate.js';
|
|
5
|
+
import { initCommand } from './commands/init.js';
|
|
6
|
+
const program = new Command();
|
|
7
|
+
program
|
|
8
|
+
.name('revx')
|
|
9
|
+
.description('Reverse proxy CLI tool with YAML configuration')
|
|
10
|
+
.version('0.1.0');
|
|
11
|
+
program
|
|
12
|
+
.command('start')
|
|
13
|
+
.description('Start the reverse proxy server')
|
|
14
|
+
.argument('[config-file]', 'Configuration file path', 'revx.yaml')
|
|
15
|
+
.option('--verbose', 'Verbose output')
|
|
16
|
+
.action(startCommand);
|
|
17
|
+
program
|
|
18
|
+
.command('validate')
|
|
19
|
+
.description('Validate configuration file')
|
|
20
|
+
.argument('<config-file>', 'Configuration file path')
|
|
21
|
+
.option('--verbose', 'Verbose output')
|
|
22
|
+
.action(validateCommand);
|
|
23
|
+
program
|
|
24
|
+
.command('init')
|
|
25
|
+
.description('Create a sample configuration file')
|
|
26
|
+
.option('--simple', 'Create a simple configuration file')
|
|
27
|
+
.option('--output <file>', 'Output file path', 'revx.yaml')
|
|
28
|
+
.option('--verbose', 'Verbose output')
|
|
29
|
+
.action(initCommand);
|
|
30
|
+
program.parse();
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,QAAQ,CAAC,eAAe,EAAE,yBAAyB,EAAE,WAAW,CAAC;KACjE,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC;KACrC,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,QAAQ,CAAC,eAAe,EAAE,yBAAyB,CAAC;KACpD,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC;KACrC,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,UAAU,EAAE,oCAAoC,CAAC;KACxD,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,CAAC;KAC1D,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC;KACrC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Logger } from './logger.js';
|
|
2
|
+
export interface CorsConfig {
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
origin?: string | string[];
|
|
5
|
+
methods?: string[];
|
|
6
|
+
credentials?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface RateLimitConfig {
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
windowMs?: number;
|
|
11
|
+
max?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface LoggingConfig {
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
format?: 'combined' | 'dev' | 'common' | 'short' | 'tiny';
|
|
16
|
+
level?: 'error' | 'warn' | 'info' | 'debug';
|
|
17
|
+
}
|
|
18
|
+
export interface GlobalConfig {
|
|
19
|
+
timeout?: number;
|
|
20
|
+
cors?: CorsConfig;
|
|
21
|
+
logging?: LoggingConfig;
|
|
22
|
+
rateLimit?: RateLimitConfig;
|
|
23
|
+
}
|
|
24
|
+
export interface ServerConfig {
|
|
25
|
+
port: number;
|
|
26
|
+
host?: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface RouteOptions {
|
|
30
|
+
timeout?: number;
|
|
31
|
+
followRedirects?: boolean;
|
|
32
|
+
headers?: Record<string, string>;
|
|
33
|
+
}
|
|
34
|
+
export interface CacheConfig {
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
ttl?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface AuthConfig {
|
|
39
|
+
type?: 'bearer' | 'basic' | 'apikey';
|
|
40
|
+
headerName?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface HealthCheckConfig {
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
interval?: number;
|
|
45
|
+
path?: string;
|
|
46
|
+
timeout?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface TransformConfig {
|
|
49
|
+
request?: {
|
|
50
|
+
headers?: {
|
|
51
|
+
add?: Record<string, string>;
|
|
52
|
+
remove?: string[];
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
response?: {
|
|
56
|
+
headers?: {
|
|
57
|
+
add?: Record<string, string>;
|
|
58
|
+
remove?: string[];
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export interface RouteConfig {
|
|
63
|
+
path: string;
|
|
64
|
+
target?: string;
|
|
65
|
+
targets?: string[];
|
|
66
|
+
changeOrigin?: boolean;
|
|
67
|
+
pathRewrite?: Record<string, string>;
|
|
68
|
+
ws?: boolean;
|
|
69
|
+
strategy?: 'round-robin' | 'random' | 'ip-hash';
|
|
70
|
+
options?: RouteOptions;
|
|
71
|
+
cors?: CorsConfig;
|
|
72
|
+
cache?: CacheConfig;
|
|
73
|
+
auth?: AuthConfig;
|
|
74
|
+
healthCheck?: HealthCheckConfig;
|
|
75
|
+
transform?: TransformConfig;
|
|
76
|
+
}
|
|
77
|
+
export interface MiddlewareConfig {
|
|
78
|
+
type: string;
|
|
79
|
+
enabled?: boolean;
|
|
80
|
+
paths?: string[];
|
|
81
|
+
config?: Record<string, any>;
|
|
82
|
+
headerName?: string;
|
|
83
|
+
threshold?: number;
|
|
84
|
+
}
|
|
85
|
+
export interface SslConfig {
|
|
86
|
+
enabled?: boolean;
|
|
87
|
+
key?: string;
|
|
88
|
+
cert?: string;
|
|
89
|
+
ca?: string;
|
|
90
|
+
}
|
|
91
|
+
export interface RevxConfig {
|
|
92
|
+
server: ServerConfig;
|
|
93
|
+
global?: GlobalConfig;
|
|
94
|
+
routes: RouteConfig[];
|
|
95
|
+
middleware?: MiddlewareConfig[];
|
|
96
|
+
ssl?: SslConfig;
|
|
97
|
+
}
|
|
98
|
+
export declare class ConfigLoader {
|
|
99
|
+
private logger;
|
|
100
|
+
constructor(logger: Logger);
|
|
101
|
+
load(configPath: string): RevxConfig;
|
|
102
|
+
private expandEnvironmentVariables;
|
|
103
|
+
private sortRoutesBySpecificity;
|
|
104
|
+
private validateConfig;
|
|
105
|
+
private validateRoute;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import YAML from 'yaml';
|
|
4
|
+
export class ConfigLoader {
|
|
5
|
+
constructor(logger) {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
}
|
|
8
|
+
load(configPath) {
|
|
9
|
+
const fullPath = resolve(process.cwd(), configPath);
|
|
10
|
+
this.logger.verbose('Loading configuration file', { path: fullPath });
|
|
11
|
+
if (!existsSync(fullPath)) {
|
|
12
|
+
throw new Error(`Configuration file not found: ${fullPath}`);
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const fileContent = readFileSync(fullPath, 'utf-8');
|
|
16
|
+
const expandedContent = this.expandEnvironmentVariables(fileContent);
|
|
17
|
+
const config = YAML.parse(expandedContent);
|
|
18
|
+
this.sortRoutesBySpecificity(config);
|
|
19
|
+
this.validateConfig(config);
|
|
20
|
+
return config;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error instanceof Error) {
|
|
24
|
+
throw new Error(`Failed to load configuration: ${error.message}`);
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
expandEnvironmentVariables(content) {
|
|
30
|
+
return content.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
31
|
+
const value = process.env[varName];
|
|
32
|
+
if (value === undefined) {
|
|
33
|
+
this.logger.warning(`Environment variable not found: ${varName}, using empty string`);
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
sortRoutesBySpecificity(config) {
|
|
40
|
+
if (!config.routes || config.routes.length === 0) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
config.routes.sort((a, b) => {
|
|
44
|
+
const pathA = a.path;
|
|
45
|
+
const pathB = b.path;
|
|
46
|
+
// 1. パスの長さで降順ソート(長いパスが先)
|
|
47
|
+
const lengthDiff = pathB.length - pathA.length;
|
|
48
|
+
if (lengthDiff !== 0) {
|
|
49
|
+
return lengthDiff;
|
|
50
|
+
}
|
|
51
|
+
// 2. ワイルドカードの数で昇順ソート(ワイルドカードが少ない方が具体的)
|
|
52
|
+
const wildcardCountA = (pathA.match(/\*/g) || []).length;
|
|
53
|
+
const wildcardCountB = (pathB.match(/\*/g) || []).length;
|
|
54
|
+
const wildcardDiff = wildcardCountA - wildcardCountB;
|
|
55
|
+
if (wildcardDiff !== 0) {
|
|
56
|
+
return wildcardDiff;
|
|
57
|
+
}
|
|
58
|
+
// 3. 辞書順でソート
|
|
59
|
+
return pathA.localeCompare(pathB);
|
|
60
|
+
});
|
|
61
|
+
this.logger.verbose('Routes sorted by specificity', {
|
|
62
|
+
routes: config.routes.map(r => r.path)
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
validateConfig(config) {
|
|
66
|
+
if (!config.server) {
|
|
67
|
+
throw new Error('Server configuration is required');
|
|
68
|
+
}
|
|
69
|
+
if (!config.server.port) {
|
|
70
|
+
throw new Error('Server port is required');
|
|
71
|
+
}
|
|
72
|
+
if (!config.routes || !Array.isArray(config.routes)) {
|
|
73
|
+
throw new Error('Routes configuration is required and must be an array');
|
|
74
|
+
}
|
|
75
|
+
if (config.routes.length === 0) {
|
|
76
|
+
throw new Error('At least one route must be configured');
|
|
77
|
+
}
|
|
78
|
+
for (const route of config.routes) {
|
|
79
|
+
this.validateRoute(route);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
validateRoute(route) {
|
|
83
|
+
if (!route.path) {
|
|
84
|
+
throw new Error('Route path is required');
|
|
85
|
+
}
|
|
86
|
+
if (!route.target && !route.targets) {
|
|
87
|
+
throw new Error(`Route ${route.path} must have either target or targets`);
|
|
88
|
+
}
|
|
89
|
+
if (route.target && route.targets) {
|
|
90
|
+
throw new Error(`Route ${route.path} cannot have both target and targets`);
|
|
91
|
+
}
|
|
92
|
+
if (route.targets) {
|
|
93
|
+
if (!Array.isArray(route.targets) || route.targets.length === 0) {
|
|
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
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class Logger {
|
|
2
|
+
private isVerbose;
|
|
3
|
+
constructor(isVerbose?: boolean);
|
|
4
|
+
info(message: string): void;
|
|
5
|
+
success(message: string): void;
|
|
6
|
+
error(message: string): void;
|
|
7
|
+
warning(message: string): void;
|
|
8
|
+
verbose(message: string, data?: any): void;
|
|
9
|
+
debug(message: string, data?: any): void;
|
|
10
|
+
server(message: string): void;
|
|
11
|
+
request(method: string, path: string): void;
|
|
12
|
+
private getMethodColor;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,qBAAa,MAAM;IACL,OAAO,CAAC,SAAS;gBAAT,SAAS,GAAE,OAAe;IAE9C,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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export class Logger {
|
|
3
|
+
constructor(isVerbose = false) {
|
|
4
|
+
this.isVerbose = isVerbose;
|
|
5
|
+
}
|
|
6
|
+
info(message) {
|
|
7
|
+
console.log(chalk.blue('ℹ'), message);
|
|
8
|
+
}
|
|
9
|
+
success(message) {
|
|
10
|
+
console.log(chalk.green('✓'), message);
|
|
11
|
+
}
|
|
12
|
+
error(message) {
|
|
13
|
+
console.error(chalk.red('✗'), message);
|
|
14
|
+
}
|
|
15
|
+
warning(message) {
|
|
16
|
+
console.warn(chalk.yellow('⚠'), message);
|
|
17
|
+
}
|
|
18
|
+
verbose(message, data) {
|
|
19
|
+
if (this.isVerbose) {
|
|
20
|
+
console.log(chalk.gray('🔍'), chalk.gray(message));
|
|
21
|
+
if (data) {
|
|
22
|
+
console.log(chalk.gray(JSON.stringify(data, null, 2)));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
debug(message, data) {
|
|
27
|
+
if (this.isVerbose) {
|
|
28
|
+
console.log(chalk.magenta('🐛'), chalk.magenta(message));
|
|
29
|
+
if (data) {
|
|
30
|
+
console.log(chalk.magenta(JSON.stringify(data, null, 2)));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
server(message) {
|
|
35
|
+
console.log(chalk.cyan('🚀'), message);
|
|
36
|
+
}
|
|
37
|
+
request(method, path) {
|
|
38
|
+
const methodColor = this.getMethodColor(method);
|
|
39
|
+
console.log(chalk.gray('→'), methodColor(method.padEnd(7)), chalk.white(path));
|
|
40
|
+
}
|
|
41
|
+
getMethodColor(method) {
|
|
42
|
+
switch (method.toUpperCase()) {
|
|
43
|
+
case 'GET':
|
|
44
|
+
return chalk.green;
|
|
45
|
+
case 'POST':
|
|
46
|
+
return chalk.blue;
|
|
47
|
+
case 'PUT':
|
|
48
|
+
return chalk.yellow;
|
|
49
|
+
case 'DELETE':
|
|
50
|
+
return chalk.red;
|
|
51
|
+
case 'PATCH':
|
|
52
|
+
return chalk.magenta;
|
|
53
|
+
default:
|
|
54
|
+
return chalk.white;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +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,YAAqB,KAAK;QAA1B,cAAS,GAAT,SAAS,CAAiB;IAAG,CAAC;IAElD,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,SAAS,EAAE,CAAC;YACnB,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,SAAS,EAAE,CAAC;YACnB,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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RouteConfig } from './config.js';
|
|
2
|
+
import { Logger } from './logger.js';
|
|
3
|
+
import { Request } from 'express';
|
|
4
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
5
|
+
export declare class LoadBalancer {
|
|
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;
|
|
16
|
+
}
|
|
17
|
+
export declare class ProxyManager {
|
|
18
|
+
private logger;
|
|
19
|
+
private loadBalancers;
|
|
20
|
+
constructor(logger: Logger);
|
|
21
|
+
createProxyMiddleware(route: RouteConfig): import("http-proxy-middleware").RequestHandler<IncomingMessage, ServerResponse<IncomingMessage>, (err?: any) => void>;
|
|
22
|
+
getLoadBalancer(path: string): LoadBalancer | undefined;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/utils/proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAY,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEvD,qBAAa,YAAY;IAKrB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAmC;gBAG7C,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,aAAa,GAAG,QAAQ,GAAG,SAAS,YAAgB,EAC9D,MAAM,EAAE,MAAM;IAKxB,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM;IA4BhC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKnC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKjC,OAAO,CAAC,QAAQ;CASjB;AAED,qBAAa,YAAY;IAGX,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,aAAa,CAAwC;gBAEzC,MAAM,EAAE,MAAM;IAElC,qBAAqB,CAAC,KAAK,EAAE,WAAW;IAyFxC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAGxD"}
|