344 lines
8.4 KiB
TypeScript
344 lines
8.4 KiB
TypeScript
|
import type {
|
||
|
IRouteConfig,
|
||
|
IRouteMatch,
|
||
|
IRouteAction,
|
||
|
IRouteTarget,
|
||
|
IRouteTls,
|
||
|
IRouteRedirect,
|
||
|
IRouteSecurity,
|
||
|
IRouteAdvanced
|
||
|
} from './models/route-types.js';
|
||
|
|
||
|
/**
|
||
|
* Basic helper function to create a route configuration
|
||
|
*/
|
||
|
export function createRoute(
|
||
|
match: IRouteMatch,
|
||
|
action: IRouteAction,
|
||
|
metadata?: {
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
priority?: number;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
return {
|
||
|
match,
|
||
|
action,
|
||
|
...metadata
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a basic HTTP route configuration
|
||
|
*/
|
||
|
export function createHttpRoute(
|
||
|
options: {
|
||
|
ports?: number | number[]; // Default: 80
|
||
|
domains?: string | string[];
|
||
|
path?: string;
|
||
|
target: IRouteTarget;
|
||
|
headers?: Record<string, string>;
|
||
|
security?: IRouteSecurity;
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
priority?: number;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
return createRoute(
|
||
|
{
|
||
|
ports: options.ports || 80,
|
||
|
...(options.domains ? { domains: options.domains } : {}),
|
||
|
...(options.path ? { path: options.path } : {})
|
||
|
},
|
||
|
{
|
||
|
type: 'forward',
|
||
|
target: options.target,
|
||
|
...(options.headers || options.security ? {
|
||
|
advanced: {
|
||
|
...(options.headers ? { headers: options.headers } : {})
|
||
|
},
|
||
|
...(options.security ? { security: options.security } : {})
|
||
|
} : {})
|
||
|
},
|
||
|
{
|
||
|
name: options.name || 'HTTP Route',
|
||
|
description: options.description,
|
||
|
priority: options.priority,
|
||
|
tags: options.tags
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create an HTTPS route configuration with TLS termination
|
||
|
*/
|
||
|
export function createHttpsRoute(
|
||
|
options: {
|
||
|
ports?: number | number[]; // Default: 443
|
||
|
domains: string | string[];
|
||
|
path?: string;
|
||
|
target: IRouteTarget;
|
||
|
tlsMode?: 'terminate' | 'terminate-and-reencrypt';
|
||
|
certificate?: 'auto' | { key: string; cert: string };
|
||
|
headers?: Record<string, string>;
|
||
|
security?: IRouteSecurity;
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
priority?: number;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
return createRoute(
|
||
|
{
|
||
|
ports: options.ports || 443,
|
||
|
domains: options.domains,
|
||
|
...(options.path ? { path: options.path } : {})
|
||
|
},
|
||
|
{
|
||
|
type: 'forward',
|
||
|
target: options.target,
|
||
|
tls: {
|
||
|
mode: options.tlsMode || 'terminate',
|
||
|
certificate: options.certificate || 'auto'
|
||
|
},
|
||
|
...(options.headers || options.security ? {
|
||
|
advanced: {
|
||
|
...(options.headers ? { headers: options.headers } : {})
|
||
|
},
|
||
|
...(options.security ? { security: options.security } : {})
|
||
|
} : {})
|
||
|
},
|
||
|
{
|
||
|
name: options.name || 'HTTPS Route',
|
||
|
description: options.description,
|
||
|
priority: options.priority,
|
||
|
tags: options.tags
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create an HTTPS passthrough route configuration
|
||
|
*/
|
||
|
export function createPassthroughRoute(
|
||
|
options: {
|
||
|
ports?: number | number[]; // Default: 443
|
||
|
domains?: string | string[];
|
||
|
target: IRouteTarget;
|
||
|
security?: IRouteSecurity;
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
priority?: number;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
return createRoute(
|
||
|
{
|
||
|
ports: options.ports || 443,
|
||
|
...(options.domains ? { domains: options.domains } : {})
|
||
|
},
|
||
|
{
|
||
|
type: 'forward',
|
||
|
target: options.target,
|
||
|
tls: {
|
||
|
mode: 'passthrough'
|
||
|
},
|
||
|
...(options.security ? { security: options.security } : {})
|
||
|
},
|
||
|
{
|
||
|
name: options.name || 'HTTPS Passthrough Route',
|
||
|
description: options.description,
|
||
|
priority: options.priority,
|
||
|
tags: options.tags
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a redirect route configuration
|
||
|
*/
|
||
|
export function createRedirectRoute(
|
||
|
options: {
|
||
|
ports?: number | number[]; // Default: 80
|
||
|
domains?: string | string[];
|
||
|
path?: string;
|
||
|
redirectTo: string;
|
||
|
statusCode?: 301 | 302 | 307 | 308;
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
priority?: number;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
return createRoute(
|
||
|
{
|
||
|
ports: options.ports || 80,
|
||
|
...(options.domains ? { domains: options.domains } : {}),
|
||
|
...(options.path ? { path: options.path } : {})
|
||
|
},
|
||
|
{
|
||
|
type: 'redirect',
|
||
|
redirect: {
|
||
|
to: options.redirectTo,
|
||
|
status: options.statusCode || 301
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: options.name || 'Redirect Route',
|
||
|
description: options.description,
|
||
|
priority: options.priority,
|
||
|
tags: options.tags
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create an HTTP to HTTPS redirect route configuration
|
||
|
*/
|
||
|
export function createHttpToHttpsRedirect(
|
||
|
options: {
|
||
|
domains: string | string[];
|
||
|
statusCode?: 301 | 302 | 307 | 308;
|
||
|
name?: string;
|
||
|
priority?: number;
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
const domainArray = Array.isArray(options.domains) ? options.domains : [options.domains];
|
||
|
|
||
|
return createRedirectRoute({
|
||
|
ports: 80,
|
||
|
domains: options.domains,
|
||
|
redirectTo: 'https://{domain}{path}',
|
||
|
statusCode: options.statusCode || 301,
|
||
|
name: options.name || `HTTP to HTTPS Redirect for ${domainArray.join(', ')}`,
|
||
|
priority: options.priority || 100 // High priority for redirects
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a block route configuration
|
||
|
*/
|
||
|
export function createBlockRoute(
|
||
|
options: {
|
||
|
ports: number | number[];
|
||
|
domains?: string | string[];
|
||
|
clientIp?: string[];
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
priority?: number;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
return createRoute(
|
||
|
{
|
||
|
ports: options.ports,
|
||
|
...(options.domains ? { domains: options.domains } : {}),
|
||
|
...(options.clientIp ? { clientIp: options.clientIp } : {})
|
||
|
},
|
||
|
{
|
||
|
type: 'block'
|
||
|
},
|
||
|
{
|
||
|
name: options.name || 'Block Route',
|
||
|
description: options.description,
|
||
|
priority: options.priority || 1000, // Very high priority for blocks
|
||
|
tags: options.tags
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a load balancer route configuration
|
||
|
*/
|
||
|
export function createLoadBalancerRoute(
|
||
|
options: {
|
||
|
ports?: number | number[]; // Default: 443
|
||
|
domains: string | string[];
|
||
|
path?: string;
|
||
|
targets: string[]; // Array of host names/IPs for load balancing
|
||
|
targetPort: number;
|
||
|
tlsMode?: 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
|
||
|
certificate?: 'auto' | { key: string; cert: string };
|
||
|
headers?: Record<string, string>;
|
||
|
security?: IRouteSecurity;
|
||
|
name?: string;
|
||
|
description?: string;
|
||
|
tags?: string[];
|
||
|
}
|
||
|
): IRouteConfig {
|
||
|
const useTls = options.tlsMode !== undefined;
|
||
|
const defaultPort = useTls ? 443 : 80;
|
||
|
|
||
|
return createRoute(
|
||
|
{
|
||
|
ports: options.ports || defaultPort,
|
||
|
domains: options.domains,
|
||
|
...(options.path ? { path: options.path } : {})
|
||
|
},
|
||
|
{
|
||
|
type: 'forward',
|
||
|
target: {
|
||
|
host: options.targets,
|
||
|
port: options.targetPort
|
||
|
},
|
||
|
...(useTls ? {
|
||
|
tls: {
|
||
|
mode: options.tlsMode!,
|
||
|
...(options.tlsMode !== 'passthrough' && options.certificate ? {
|
||
|
certificate: options.certificate
|
||
|
} : {})
|
||
|
}
|
||
|
} : {}),
|
||
|
...(options.headers || options.security ? {
|
||
|
advanced: {
|
||
|
...(options.headers ? { headers: options.headers } : {})
|
||
|
},
|
||
|
...(options.security ? { security: options.security } : {})
|
||
|
} : {})
|
||
|
},
|
||
|
{
|
||
|
name: options.name || 'Load Balanced Route',
|
||
|
description: options.description || `Load balancing across ${options.targets.length} backends`,
|
||
|
tags: options.tags
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a complete HTTPS server configuration with HTTP redirect
|
||
|
*/
|
||
|
export function createHttpsServer(
|
||
|
options: {
|
||
|
domains: string | string[];
|
||
|
target: IRouteTarget;
|
||
|
certificate?: 'auto' | { key: string; cert: string };
|
||
|
security?: IRouteSecurity;
|
||
|
addHttpRedirect?: boolean;
|
||
|
name?: string;
|
||
|
}
|
||
|
): IRouteConfig[] {
|
||
|
const routes: IRouteConfig[] = [];
|
||
|
const domainArray = Array.isArray(options.domains) ? options.domains : [options.domains];
|
||
|
|
||
|
// Add HTTPS route
|
||
|
routes.push(createHttpsRoute({
|
||
|
domains: options.domains,
|
||
|
target: options.target,
|
||
|
certificate: options.certificate || 'auto',
|
||
|
security: options.security,
|
||
|
name: options.name || `HTTPS Server for ${domainArray.join(', ')}`
|
||
|
}));
|
||
|
|
||
|
// Add HTTP to HTTPS redirect if requested
|
||
|
if (options.addHttpRedirect !== false) {
|
||
|
routes.push(createHttpToHttpsRedirect({
|
||
|
domains: options.domains,
|
||
|
name: `HTTP to HTTPS Redirect for ${domainArray.join(', ')}`,
|
||
|
priority: 100
|
||
|
}));
|
||
|
}
|
||
|
|
||
|
return routes;
|
||
|
}
|