Files
dcrouter/ts_apiclient/classes.route.ts

167 lines
4.9 KiB
TypeScript
Raw Normal View History

import * as interfaces from '../ts_interfaces/index.js';
import type { IRouteConfig } from '@push.rocks/smartproxy';
import type { DcRouterApiClient } from './classes.dcrouterapiclient.js';
export class Route {
private clientRef: DcRouterApiClient;
// Data from IMergedRoute
public routeConfig: IRouteConfig;
public id: string;
public enabled: boolean;
public origin: 'config' | 'email' | 'dns' | 'api';
public createdAt?: number;
public updatedAt?: number;
// Convenience accessors
public get name(): string {
return this.routeConfig.name || '';
}
constructor(clientRef: DcRouterApiClient, data: interfaces.data.IMergedRoute) {
this.clientRef = clientRef;
this.routeConfig = data.route;
this.id = data.id;
this.enabled = data.enabled;
this.origin = data.origin;
this.createdAt = data.createdAt;
this.updatedAt = data.updatedAt;
}
public async update(changes: Partial<IRouteConfig>): Promise<void> {
const response = await this.clientRef.request<interfaces.requests.IReq_UpdateRoute>(
'updateRoute',
this.clientRef.buildRequestPayload({ id: this.id, route: changes }) as any,
);
if (!response.success) {
throw new Error(response.message || 'Failed to update route');
}
}
public async delete(): Promise<void> {
const response = await this.clientRef.request<interfaces.requests.IReq_DeleteRoute>(
'deleteRoute',
this.clientRef.buildRequestPayload({ id: this.id }) as any,
);
if (!response.success) {
throw new Error(response.message || 'Failed to delete route');
}
}
public async toggle(enabled: boolean): Promise<void> {
const response = await this.clientRef.request<interfaces.requests.IReq_ToggleRoute>(
'toggleRoute',
this.clientRef.buildRequestPayload({ id: this.id, enabled }) as any,
);
if (!response.success) {
throw new Error(response.message || 'Failed to toggle route');
}
this.enabled = enabled;
}
}
export class RouteBuilder {
private clientRef: DcRouterApiClient;
private routeConfig: Partial<IRouteConfig> = {};
private isEnabled: boolean = true;
constructor(clientRef: DcRouterApiClient) {
this.clientRef = clientRef;
}
public setName(name: string): this {
this.routeConfig.name = name;
return this;
}
public setMatch(match: IRouteConfig['match']): this {
this.routeConfig.match = match;
return this;
}
public setAction(action: IRouteConfig['action']): this {
this.routeConfig.action = action;
return this;
}
public setTls(tls: IRouteConfig['action']['tls']): this {
if (!this.routeConfig.action) {
this.routeConfig.action = { type: 'forward' } as IRouteConfig['action'];
}
this.routeConfig.action!.tls = tls;
return this;
}
public setEnabled(enabled: boolean): this {
this.isEnabled = enabled;
return this;
}
public async save(): Promise<Route> {
const response = await this.clientRef.request<interfaces.requests.IReq_CreateRoute>(
'createRoute',
this.clientRef.buildRequestPayload({
route: this.routeConfig as IRouteConfig,
enabled: this.isEnabled,
}) as any,
);
if (!response.success) {
throw new Error(response.message || 'Failed to create route');
}
// Return a Route instance by re-fetching the list
const { routes } = await new RouteManager(this.clientRef).list();
const created = routes.find((r) => r.id === response.routeId);
if (created) {
return created;
}
// Fallback: construct from known data
return new Route(this.clientRef, {
route: this.routeConfig as IRouteConfig,
id: response.routeId || '',
enabled: this.isEnabled,
origin: 'api',
});
}
}
export class RouteManager {
private clientRef: DcRouterApiClient;
constructor(clientRef: DcRouterApiClient) {
this.clientRef = clientRef;
}
public async list(): Promise<{ routes: Route[]; warnings: interfaces.data.IRouteWarning[] }> {
const response = await this.clientRef.request<interfaces.requests.IReq_GetMergedRoutes>(
'getMergedRoutes',
this.clientRef.buildRequestPayload() as any,
);
return {
routes: response.routes.map((r) => new Route(this.clientRef, r)),
warnings: response.warnings,
};
}
public async create(routeConfig: IRouteConfig, enabled?: boolean): Promise<Route> {
const response = await this.clientRef.request<interfaces.requests.IReq_CreateRoute>(
'createRoute',
this.clientRef.buildRequestPayload({ route: routeConfig, enabled: enabled ?? true }) as any,
);
if (!response.success) {
throw new Error(response.message || 'Failed to create route');
}
return new Route(this.clientRef, {
route: routeConfig,
id: response.routeId || '',
enabled: enabled ?? true,
origin: 'api',
});
}
public build(): RouteBuilder {
return new RouteBuilder(this.clientRef);
}
}