mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-10 17:26:38 +08:00
refactor(repo): consolidate openflare-server to root and move subprojects to internal/apps
- Merge all files inside openflare-server to the repository root directory. - Relocate agent, relay, and flared subprojects from internal/ to internal/apps/. - Combine docker-compose files and update build context paths to root. - Update GitHub workflows and Dockerfiles to refer to new directories and package names. - Rewrite Go package imports across all files. - Resolve database renew test race condition and clean up docs.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
AccessLogCleanupPayload,
|
||||
AccessLogCleanupResult,
|
||||
AccessLogFilters,
|
||||
AccessLogIPSummaryFilters,
|
||||
AccessLogIPSummaryList,
|
||||
AccessLogIPTrend,
|
||||
AccessLogIPTrendFilters,
|
||||
AccessLogList,
|
||||
FoldedAccessLogFilters,
|
||||
FoldedAccessLogIPFilters,
|
||||
FoldedAccessLogIPList,
|
||||
FoldedAccessLogList,
|
||||
} from './types';
|
||||
|
||||
function buildSearchParams(filters: object): Record<string, unknown> {
|
||||
const params: Record<string, unknown> = {};
|
||||
Object.entries(filters as Record<string, string | number | undefined>).forEach(
|
||||
([key, value]) => {
|
||||
if (value === undefined || value === null || value === '') return;
|
||||
params[key] = value;
|
||||
},
|
||||
);
|
||||
return params;
|
||||
}
|
||||
|
||||
export class AccessLogService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/access-logs';
|
||||
|
||||
static list(filters: AccessLogFilters = {}): Promise<AccessLogList> {
|
||||
return this.get<AccessLogList>('/', buildSearchParams(filters));
|
||||
}
|
||||
|
||||
static listFolds(
|
||||
filters: FoldedAccessLogFilters,
|
||||
): Promise<FoldedAccessLogList> {
|
||||
return this.get<FoldedAccessLogList>(
|
||||
'/folds',
|
||||
buildSearchParams(filters),
|
||||
);
|
||||
}
|
||||
|
||||
static listFoldIPs(
|
||||
filters: FoldedAccessLogIPFilters,
|
||||
): Promise<FoldedAccessLogIPList> {
|
||||
return this.get<FoldedAccessLogIPList>(
|
||||
'/folds/ip-summary',
|
||||
buildSearchParams(filters),
|
||||
);
|
||||
}
|
||||
|
||||
static listIPSummaries(
|
||||
filters: AccessLogIPSummaryFilters = {},
|
||||
): Promise<AccessLogIPSummaryList> {
|
||||
return this.get<AccessLogIPSummaryList>(
|
||||
'/ip-summary',
|
||||
buildSearchParams(filters),
|
||||
);
|
||||
}
|
||||
|
||||
static getIPTrend(
|
||||
filters: AccessLogIPTrendFilters,
|
||||
): Promise<AccessLogIPTrend> {
|
||||
return this.get<AccessLogIPTrend>(
|
||||
'/ip-summary/trend',
|
||||
buildSearchParams(filters),
|
||||
);
|
||||
}
|
||||
|
||||
static cleanup(
|
||||
payload: AccessLogCleanupPayload,
|
||||
): Promise<AccessLogCleanupResult> {
|
||||
return this.post<AccessLogCleanupResult>('/cleanup', payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
ApplyLogCleanupPayload,
|
||||
ApplyLogCleanupResult,
|
||||
ApplyLogList,
|
||||
ApplyLogListQuery,
|
||||
} from './types';
|
||||
|
||||
export class ApplyLogService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/apply-logs';
|
||||
|
||||
static list(query: ApplyLogListQuery = {}): Promise<ApplyLogList> {
|
||||
const params: Record<string, unknown> = {};
|
||||
|
||||
const normalizedNodeId = query.node_id?.trim();
|
||||
if (normalizedNodeId) {
|
||||
params.node_id = normalizedNodeId;
|
||||
}
|
||||
if (query.pageNo) {
|
||||
params.pageNo = query.pageNo;
|
||||
}
|
||||
if (query.pageSize) {
|
||||
params.pageSize = query.pageSize;
|
||||
}
|
||||
|
||||
return this.get<ApplyLogList>('/', params);
|
||||
}
|
||||
|
||||
static cleanup(payload: ApplyLogCleanupPayload): Promise<ApplyLogCleanupResult> {
|
||||
return this.post<ApplyLogCleanupResult>('/cleanup', payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
|
||||
export class OpenFlareBaseService extends BaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d';
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type {InternalAxiosRequestConfig} from 'axios';
|
||||
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
ConfigDiffResult,
|
||||
ConfigPreviewResult,
|
||||
ConfigVersionCleanupPayload,
|
||||
ConfigVersionCleanupResult,
|
||||
ConfigVersionDetail,
|
||||
ConfigVersionSummary,
|
||||
} from './types';
|
||||
|
||||
export class ConfigVersionService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/config-versions';
|
||||
|
||||
static list(): Promise<ConfigVersionSummary[]> {
|
||||
return this.get<ConfigVersionSummary[]>('/');
|
||||
}
|
||||
|
||||
static getActive(): Promise<ConfigVersionDetail> {
|
||||
return this.get<ConfigVersionDetail>('/active');
|
||||
}
|
||||
|
||||
static preview(): Promise<ConfigPreviewResult> {
|
||||
return this.get<ConfigPreviewResult>('/preview');
|
||||
}
|
||||
|
||||
static diff(): Promise<ConfigDiffResult> {
|
||||
return this.get<ConfigDiffResult>('/diff');
|
||||
}
|
||||
|
||||
static getById(id: number): Promise<ConfigVersionDetail> {
|
||||
return this.get<ConfigVersionDetail>(`/${id}`);
|
||||
}
|
||||
|
||||
static publish(force?: boolean): Promise<ConfigVersionDetail> {
|
||||
return this.post<ConfigVersionDetail>(
|
||||
'/publish',
|
||||
undefined,
|
||||
force
|
||||
? ({ params: { force: true } } as InternalAxiosRequestConfig)
|
||||
: undefined,
|
||||
);
|
||||
}
|
||||
|
||||
static activate(id: number): Promise<ConfigVersionDetail> {
|
||||
return this.post<ConfigVersionDetail>(`/${id}/activate`);
|
||||
}
|
||||
|
||||
static cleanup(
|
||||
payload: ConfigVersionCleanupPayload,
|
||||
): Promise<ConfigVersionCleanupResult> {
|
||||
return this.post<ConfigVersionCleanupResult>('/cleanup', payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
CompactCapacityTrendPoint,
|
||||
CompactDashboardNodeHealth,
|
||||
CompactDiskIOTrendPoint,
|
||||
CompactDistributionItem,
|
||||
CompactNetworkTrendPoint,
|
||||
CompactTrafficTrendPoint,
|
||||
DashboardCapacity,
|
||||
DashboardNodeHealth,
|
||||
DashboardOverview,
|
||||
DashboardOverviewCompact,
|
||||
DashboardSummary,
|
||||
DashboardTraffic,
|
||||
DistributionItem,
|
||||
} from './types';
|
||||
|
||||
function arrayOrEmpty<T>(value: T[] | null | undefined) {
|
||||
return Array.isArray(value) ? value : [];
|
||||
}
|
||||
|
||||
function isCompactDistributionItem(
|
||||
value: DistributionItem | CompactDistributionItem,
|
||||
): value is CompactDistributionItem {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
function isCompactTrafficTrendPoint(
|
||||
value:
|
||||
| DashboardOverview['trends']['traffic_24h'][number]
|
||||
| CompactTrafficTrendPoint,
|
||||
): value is CompactTrafficTrendPoint {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
function isCompactCapacityTrendPoint(
|
||||
value:
|
||||
| DashboardOverview['trends']['capacity_24h'][number]
|
||||
| CompactCapacityTrendPoint,
|
||||
): value is CompactCapacityTrendPoint {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
function isCompactNetworkTrendPoint(
|
||||
value:
|
||||
| DashboardOverview['trends']['network_24h'][number]
|
||||
| CompactNetworkTrendPoint,
|
||||
): value is CompactNetworkTrendPoint {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
function isCompactDiskIOTrendPoint(
|
||||
value:
|
||||
| DashboardOverview['trends']['disk_io_24h'][number]
|
||||
| CompactDiskIOTrendPoint,
|
||||
): value is CompactDiskIOTrendPoint {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
function isCompactDashboardNode(
|
||||
value: DashboardNodeHealth | CompactDashboardNodeHealth,
|
||||
): value is CompactDashboardNodeHealth {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
function normalizeDistributionItems(
|
||||
items: Array<DistributionItem | CompactDistributionItem> | null | undefined,
|
||||
): DistributionItem[] {
|
||||
return arrayOrEmpty(items).map((item) =>
|
||||
isCompactDistributionItem(item)
|
||||
? { key: String(item[0] ?? ''), value: Number(item[1] ?? 0) }
|
||||
: item,
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeTrafficTrendPoints(
|
||||
items:
|
||||
| Array<
|
||||
| DashboardOverview['trends']['traffic_24h'][number]
|
||||
| CompactTrafficTrendPoint
|
||||
>
|
||||
| null
|
||||
| undefined,
|
||||
) {
|
||||
return arrayOrEmpty(items).map((item) =>
|
||||
isCompactTrafficTrendPoint(item)
|
||||
? {
|
||||
bucket_started_at: String(item[0] ?? ''),
|
||||
request_count: Number(item[1] ?? 0),
|
||||
error_count: Number(item[2] ?? 0),
|
||||
unique_visitor_count: Number(item[3] ?? 0),
|
||||
}
|
||||
: item,
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeCapacityTrendPoints(
|
||||
items:
|
||||
| Array<
|
||||
| DashboardOverview['trends']['capacity_24h'][number]
|
||||
| CompactCapacityTrendPoint
|
||||
>
|
||||
| null
|
||||
| undefined,
|
||||
) {
|
||||
return arrayOrEmpty(items).map((item) =>
|
||||
isCompactCapacityTrendPoint(item)
|
||||
? {
|
||||
bucket_started_at: String(item[0] ?? ''),
|
||||
average_cpu_usage_percent: Number(item[1] ?? 0),
|
||||
average_memory_usage_percent: Number(item[2] ?? 0),
|
||||
reported_nodes: Number(item[3] ?? 0),
|
||||
}
|
||||
: item,
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeNetworkTrendPoints(
|
||||
items:
|
||||
| Array<
|
||||
| DashboardOverview['trends']['network_24h'][number]
|
||||
| CompactNetworkTrendPoint
|
||||
>
|
||||
| null
|
||||
| undefined,
|
||||
) {
|
||||
return arrayOrEmpty(items).map((item) =>
|
||||
isCompactNetworkTrendPoint(item)
|
||||
? {
|
||||
bucket_started_at: String(item[0] ?? ''),
|
||||
network_rx_bytes: Number(item[1] ?? 0),
|
||||
network_tx_bytes: Number(item[2] ?? 0),
|
||||
openresty_rx_bytes: Number(item[3] ?? 0),
|
||||
openresty_tx_bytes: Number(item[4] ?? 0),
|
||||
reported_nodes: Number(item[5] ?? 0),
|
||||
}
|
||||
: item,
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeDiskIOTrendPoints(
|
||||
items:
|
||||
| Array<
|
||||
| DashboardOverview['trends']['disk_io_24h'][number]
|
||||
| CompactDiskIOTrendPoint
|
||||
>
|
||||
| null
|
||||
| undefined,
|
||||
) {
|
||||
return arrayOrEmpty(items).map((item) =>
|
||||
isCompactDiskIOTrendPoint(item)
|
||||
? {
|
||||
bucket_started_at: String(item[0] ?? ''),
|
||||
disk_read_bytes: Number(item[1] ?? 0),
|
||||
disk_write_bytes: Number(item[2] ?? 0),
|
||||
reported_nodes: Number(item[3] ?? 0),
|
||||
}
|
||||
: item,
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeDashboardNodes(
|
||||
items:
|
||||
| Array<DashboardNodeHealth | CompactDashboardNodeHealth>
|
||||
| null
|
||||
| undefined,
|
||||
): DashboardNodeHealth[] {
|
||||
return arrayOrEmpty(items).map((item) =>
|
||||
isCompactDashboardNode(item)
|
||||
? {
|
||||
id: Number(item[0] ?? 0),
|
||||
node_id: String(item[1] ?? ''),
|
||||
name: String(item[2] ?? ''),
|
||||
geo_name: String(item[3] ?? ''),
|
||||
geo_latitude:
|
||||
item[4] === null || item[4] === undefined ? null : Number(item[4]),
|
||||
geo_longitude:
|
||||
item[5] === null || item[5] === undefined ? null : Number(item[5]),
|
||||
status: (item[6] ?? 'pending') as DashboardNodeHealth['status'],
|
||||
openresty_status: (item[7] ??
|
||||
'unknown') as DashboardNodeHealth['openresty_status'],
|
||||
current_version: String(item[8] ?? ''),
|
||||
last_seen_at: String(item[9] ?? ''),
|
||||
active_event_count: Number(item[10] ?? 0),
|
||||
cpu_usage_percent: Number(item[11] ?? 0),
|
||||
memory_usage_percent: Number(item[12] ?? 0),
|
||||
storage_usage_percent: Number(item[13] ?? 0),
|
||||
request_count: Number(item[14] ?? 0),
|
||||
error_count: Number(item[15] ?? 0),
|
||||
unique_visitor_count: Number(item[16] ?? 0),
|
||||
}
|
||||
: item,
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeDashboardOverview(
|
||||
overview: DashboardOverview | DashboardOverviewCompact | null | undefined,
|
||||
): DashboardOverview | null {
|
||||
if (!overview) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const summary = (overview.summary ?? {}) as DashboardSummary;
|
||||
const traffic = (overview.traffic ?? {}) as DashboardTraffic;
|
||||
const capacity = (overview.capacity ?? {}) as DashboardCapacity;
|
||||
|
||||
return {
|
||||
generated_at: String(overview.generated_at ?? ''),
|
||||
summary,
|
||||
traffic,
|
||||
capacity,
|
||||
nodes: normalizeDashboardNodes(overview.nodes),
|
||||
distributions: {
|
||||
source_countries: normalizeDistributionItems(
|
||||
overview.distributions?.source_countries,
|
||||
),
|
||||
status_codes: normalizeDistributionItems(
|
||||
overview.distributions?.status_codes,
|
||||
),
|
||||
top_domains: normalizeDistributionItems(
|
||||
overview.distributions?.top_domains,
|
||||
),
|
||||
},
|
||||
trends: {
|
||||
traffic_24h: normalizeTrafficTrendPoints(overview.trends?.traffic_24h),
|
||||
capacity_24h: normalizeCapacityTrendPoints(overview.trends?.capacity_24h),
|
||||
network_24h: normalizeNetworkTrendPoints(overview.trends?.network_24h),
|
||||
disk_io_24h: normalizeDiskIOTrendPoints(overview.trends?.disk_io_24h),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export class DashboardService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/dashboard';
|
||||
|
||||
static async getOverview(): Promise<DashboardOverview | null> {
|
||||
const overview = await this.get<
|
||||
DashboardOverview | DashboardOverviewCompact
|
||||
>('/overview');
|
||||
return normalizeDashboardOverview(overview);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {DnsAccountItem, DnsAccountMutationPayload} from './types';
|
||||
|
||||
export class DnsAccountService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/dns-accounts';
|
||||
|
||||
static async list(): Promise<DnsAccountItem[]> {
|
||||
return this.get<DnsAccountItem[]>('/');
|
||||
}
|
||||
|
||||
static async create(
|
||||
payload: DnsAccountMutationPayload,
|
||||
): Promise<DnsAccountItem> {
|
||||
return this.post<DnsAccountItem>('/', payload);
|
||||
}
|
||||
|
||||
static async update(
|
||||
id: number,
|
||||
payload: DnsAccountMutationPayload,
|
||||
): Promise<DnsAccountItem> {
|
||||
return this.post<DnsAccountItem>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteById(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
export { OpenFlareBaseService } from './base.service';
|
||||
|
||||
export { NodeService } from './node.service';
|
||||
export { ProxyRouteService } from './proxy-route.service';
|
||||
export { ConfigVersionService } from './config-version.service';
|
||||
export { ApplyLogService } from './apply-log.service';
|
||||
export { DashboardService } from './dashboard.service';
|
||||
export { WafService } from './waf.service';
|
||||
export { WebsiteService } from './website.service';
|
||||
export { TlsCertificateService } from './tls-certificate.service';
|
||||
export { DnsAccountService } from './dns-account.service';
|
||||
export { PagesService } from './pages.service';
|
||||
export { OriginService } from './origin.service';
|
||||
export { AccessLogService } from './access-log.service';
|
||||
export { OptionService } from './option.service';
|
||||
export { UptimeKumaService } from './uptimekuma.service';
|
||||
export { StatusService } from './status.service';
|
||||
|
||||
export type {
|
||||
ApplyLogCleanupPayload,
|
||||
ApplyLogCleanupResult,
|
||||
ApplyLogItem,
|
||||
ApplyLogList,
|
||||
ApplyLogListQuery,
|
||||
ApplyResult,
|
||||
ConfigDiffResult,
|
||||
ConfigOptionDiffItem,
|
||||
ConfigPreviewResult,
|
||||
ConfigVersionCleanupPayload,
|
||||
ConfigVersionCleanupResult,
|
||||
ConfigVersionDetail,
|
||||
ConfigVersionSummary,
|
||||
NodeAgentReleaseInfo,
|
||||
NodeAgentUpdatePayload,
|
||||
NodeBootstrapToken,
|
||||
NodeItem,
|
||||
NodeMutationPayload,
|
||||
NodeHealthEvent,
|
||||
NodeObservability,
|
||||
NodeObservabilityAnalytics,
|
||||
NodeObservabilityTrends,
|
||||
NodeSystemProfile,
|
||||
NodeTrafficReport,
|
||||
NodeStatus,
|
||||
NodeType,
|
||||
OpenrestyStatus,
|
||||
ProxyRouteConfigSection,
|
||||
ProxyRouteCustomHeader,
|
||||
ProxyRouteItem,
|
||||
ProxyRouteMutationPayload,
|
||||
ProxyRoutePoWConfig,
|
||||
ReleaseChannel,
|
||||
SupportFile,
|
||||
DashboardOverview,
|
||||
DashboardNodeHealth,
|
||||
DashboardSummary,
|
||||
DashboardTraffic,
|
||||
DashboardCapacity,
|
||||
DistributionItem,
|
||||
TrafficDistributions,
|
||||
TrafficTrendPoint,
|
||||
CapacityTrendPoint,
|
||||
NetworkTrendPoint,
|
||||
DiskIOTrendPoint,
|
||||
WAFIPGroup,
|
||||
WAFIPGroupAutoTestPayload,
|
||||
WAFIPGroupAutoTestResult,
|
||||
WAFIPGroupPayload,
|
||||
WAFIPGroupSyncResult,
|
||||
WAFIPGroupSubscriptionFormat,
|
||||
WAFIPGroupType,
|
||||
WAFRuleGroup,
|
||||
WAFRuleGroupPayload,
|
||||
WAFSiteRuleGroups,
|
||||
AccessLogCleanupPayload,
|
||||
AccessLogCleanupResult,
|
||||
AccessLogFilters,
|
||||
AccessLogIPSummaryFilters,
|
||||
AccessLogIPSummaryItem,
|
||||
AccessLogIPSummaryList,
|
||||
AccessLogIPTrend,
|
||||
AccessLogIPTrendFilters,
|
||||
AccessLogItem,
|
||||
AccessLogList,
|
||||
FoldedAccessLogFilters,
|
||||
FoldedAccessLogIPFilters,
|
||||
FoldedAccessLogIPList,
|
||||
FoldedAccessLogList,
|
||||
OptionItem,
|
||||
GeoIPLookupResult,
|
||||
DatabaseCleanupPayload,
|
||||
DatabaseCleanupResult,
|
||||
DatabaseCleanupTarget,
|
||||
OpenFlarePublicStatus,
|
||||
OriginDetail,
|
||||
OriginItem,
|
||||
OriginMutationPayload,
|
||||
PagesDeployment,
|
||||
PagesDeploymentFile,
|
||||
PagesProject,
|
||||
PagesProjectPayload,
|
||||
AcmeAccountItem,
|
||||
DnsAccountItem,
|
||||
DnsAccountMutationPayload,
|
||||
ManagedDomainItem,
|
||||
ManagedDomainMatchResult,
|
||||
ManagedDomainMutationPayload,
|
||||
TlsCertificateApplyPayload,
|
||||
TlsCertificateContentItem,
|
||||
TlsCertificateDetailItem,
|
||||
TlsCertificateFileImportPayload,
|
||||
TlsCertificateItem,
|
||||
TlsCertificateMutationPayload,
|
||||
} from './types';
|
||||
|
||||
import {AccessLogService} from './access-log.service';
|
||||
import {ApplyLogService} from './apply-log.service';
|
||||
import {ConfigVersionService} from './config-version.service';
|
||||
import {DashboardService} from './dashboard.service';
|
||||
import {DnsAccountService} from './dns-account.service';
|
||||
import {NodeService} from './node.service';
|
||||
import {OptionService} from './option.service';
|
||||
import {StatusService} from './status.service';
|
||||
import {UptimeKumaService} from './uptimekuma.service';
|
||||
import {OriginService} from './origin.service';
|
||||
import {PagesService} from './pages.service';
|
||||
import {ProxyRouteService} from './proxy-route.service';
|
||||
import {TlsCertificateService} from './tls-certificate.service';
|
||||
import {WafService} from './waf.service';
|
||||
import {WebsiteService} from './website.service';
|
||||
|
||||
export const openflareServices = {
|
||||
node: NodeService,
|
||||
proxyRoute: ProxyRouteService,
|
||||
configVersion: ConfigVersionService,
|
||||
applyLog: ApplyLogService,
|
||||
dashboard: DashboardService,
|
||||
waf: WafService,
|
||||
website: WebsiteService,
|
||||
tlsCertificate: TlsCertificateService,
|
||||
dnsAccount: DnsAccountService,
|
||||
pages: PagesService,
|
||||
origin: OriginService,
|
||||
accessLog: AccessLogService,
|
||||
option: OptionService,
|
||||
uptimeKuma: UptimeKumaService,
|
||||
status: StatusService,
|
||||
} as const;
|
||||
@@ -0,0 +1,78 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
NodeAgentReleaseInfo,
|
||||
NodeAgentUpdatePayload,
|
||||
NodeBootstrapToken,
|
||||
NodeItem,
|
||||
NodeMutationPayload,
|
||||
NodeObservability,
|
||||
ReleaseChannel,
|
||||
} from './types';
|
||||
|
||||
export class NodeService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/nodes';
|
||||
|
||||
static async listNodes(): Promise<NodeItem[]> {
|
||||
return this.get<NodeItem[]>('/');
|
||||
}
|
||||
|
||||
static async createNode(payload: NodeMutationPayload): Promise<NodeItem> {
|
||||
return this.post<NodeItem>('/', payload);
|
||||
}
|
||||
|
||||
static async updateNode(id: number, payload: NodeMutationPayload): Promise<NodeItem> {
|
||||
return this.post<NodeItem>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteNode(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
|
||||
static async getBootstrapToken(): Promise<NodeBootstrapToken> {
|
||||
return this.get<NodeBootstrapToken>('/bootstrap-token');
|
||||
}
|
||||
|
||||
static async rotateBootstrapToken(): Promise<NodeBootstrapToken> {
|
||||
return this.post<NodeBootstrapToken>('/bootstrap-token/rotate');
|
||||
}
|
||||
|
||||
static async requestAgentUpdate(
|
||||
id: number,
|
||||
payload?: NodeAgentUpdatePayload,
|
||||
): Promise<NodeItem> {
|
||||
return this.post<NodeItem>(`/${id}/agent-update`, payload ?? {});
|
||||
}
|
||||
|
||||
static async requestForceSync(id: number): Promise<NodeItem> {
|
||||
return this.post<NodeItem>(`/${id}/force-sync`);
|
||||
}
|
||||
|
||||
static async requestOpenrestyRestart(id: number): Promise<NodeItem> {
|
||||
return this.post<NodeItem>(`/${id}/openresty-restart`);
|
||||
}
|
||||
|
||||
static async getAgentRelease(
|
||||
id: number,
|
||||
channel: ReleaseChannel = 'stable',
|
||||
): Promise<NodeAgentReleaseInfo> {
|
||||
return this.get<NodeAgentReleaseInfo>(`/${id}/agent-release`, { channel });
|
||||
}
|
||||
|
||||
static async getObservability(
|
||||
id: number,
|
||||
options?: { hours?: number; limit?: number },
|
||||
): Promise<NodeObservability> {
|
||||
return this.get<NodeObservability>(`/${id}/observability`, {
|
||||
hours: options?.hours,
|
||||
limit: options?.limit,
|
||||
});
|
||||
}
|
||||
|
||||
static async cleanupHealthEvents(
|
||||
id: number,
|
||||
): Promise<{ node_id: string; deleted_count: number }> {
|
||||
return this.post<{ node_id: string; deleted_count: number }>(
|
||||
`/${id}/observability/cleanup`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
DatabaseCleanupPayload,
|
||||
DatabaseCleanupResult,
|
||||
GeoIPLookupResult,
|
||||
OptionBatchPayload,
|
||||
OptionItem,
|
||||
} from './types';
|
||||
|
||||
export class OptionService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/option';
|
||||
|
||||
static list(): Promise<OptionItem[]> {
|
||||
return this.get<OptionItem[]>('/');
|
||||
}
|
||||
|
||||
static update(key: string, value: string): Promise<void> {
|
||||
return this.post<void>('/update', { key, value });
|
||||
}
|
||||
|
||||
static updateBatch(options: OptionItem[]): Promise<void> {
|
||||
const payload: OptionBatchPayload = { options };
|
||||
return this.post<void>('/update-batch', payload);
|
||||
}
|
||||
|
||||
static lookupGeoIP(provider: string, ip: string): Promise<GeoIPLookupResult> {
|
||||
return this.post<GeoIPLookupResult>('/geoip/lookup', { provider, ip });
|
||||
}
|
||||
|
||||
static cleanupDatabase(
|
||||
payload: DatabaseCleanupPayload,
|
||||
): Promise<DatabaseCleanupResult> {
|
||||
return this.post<DatabaseCleanupResult>('/database/cleanup', payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {OriginDetail, OriginItem, OriginMutationPayload} from './types';
|
||||
|
||||
export class OriginService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/origins';
|
||||
|
||||
static list(): Promise<OriginItem[]> {
|
||||
return this.get<OriginItem[]>('/');
|
||||
}
|
||||
|
||||
static getById(id: number): Promise<OriginDetail> {
|
||||
return this.get<OriginDetail>(`/${id}`);
|
||||
}
|
||||
|
||||
static create(payload: OriginMutationPayload): Promise<OriginItem> {
|
||||
return this.post<OriginItem>('/', payload);
|
||||
}
|
||||
|
||||
static update(
|
||||
id: number,
|
||||
payload: OriginMutationPayload,
|
||||
): Promise<OriginItem> {
|
||||
return this.post<OriginItem>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static deleteById(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import type {AxiosProgressEvent, InternalAxiosRequestConfig} from 'axios';
|
||||
|
||||
import apiClient from '@/lib/services/core/api-client';
|
||||
import type {ApiResponse} from '@/lib/services/core';
|
||||
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
PagesDeployment,
|
||||
PagesDeploymentFile,
|
||||
PagesDeploymentUploadPayload,
|
||||
PagesProject,
|
||||
PagesProjectPayload,
|
||||
} from './types';
|
||||
|
||||
export class PagesService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/pages';
|
||||
|
||||
static listProjects(): Promise<PagesProject[]> {
|
||||
return this.get<PagesProject[]>('/');
|
||||
}
|
||||
|
||||
static getProject(id: number): Promise<PagesProject> {
|
||||
return this.get<PagesProject>(`/${id}`);
|
||||
}
|
||||
|
||||
static createProject(payload: PagesProjectPayload): Promise<PagesProject> {
|
||||
return this.post<PagesProject>('/', payload);
|
||||
}
|
||||
|
||||
static updateProject(
|
||||
id: number,
|
||||
payload: PagesProjectPayload,
|
||||
): Promise<PagesProject> {
|
||||
return this.post<PagesProject>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static deleteProject(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
|
||||
static listDeployments(projectId: number): Promise<PagesDeployment[]> {
|
||||
return this.get<PagesDeployment[]>(`/${projectId}/deployments`);
|
||||
}
|
||||
|
||||
static listDeploymentFiles(
|
||||
projectId: number,
|
||||
deploymentId: number,
|
||||
): Promise<PagesDeploymentFile[]> {
|
||||
return this.get<PagesDeploymentFile[]>(
|
||||
`/${projectId}/deployments/${deploymentId}/files`,
|
||||
);
|
||||
}
|
||||
|
||||
static uploadDeployment(
|
||||
projectId: number,
|
||||
payload: PagesDeploymentUploadPayload,
|
||||
): Promise<PagesDeployment> {
|
||||
const formData = new FormData();
|
||||
formData.append('package', payload.file);
|
||||
formData.append('root_dir', payload.rootDir ?? '');
|
||||
formData.append('entry_file', payload.entryFile ?? 'index.html');
|
||||
|
||||
return this.postFormData<PagesDeployment>(
|
||||
`/${projectId}/deployments/upload`,
|
||||
formData,
|
||||
payload.onProgress,
|
||||
);
|
||||
}
|
||||
|
||||
static activateDeployment(
|
||||
projectId: number,
|
||||
deploymentId: number,
|
||||
): Promise<PagesProject> {
|
||||
return this.post<PagesProject>(
|
||||
`/${projectId}/deployments/${deploymentId}/activate`,
|
||||
);
|
||||
}
|
||||
|
||||
static deleteDeployment(
|
||||
projectId: number,
|
||||
deploymentId: number,
|
||||
): Promise<void> {
|
||||
return this.post<void>(
|
||||
`/${projectId}/deployments/${deploymentId}/delete`,
|
||||
);
|
||||
}
|
||||
|
||||
private static async postFormData<T>(
|
||||
path: string,
|
||||
formData: FormData,
|
||||
onProgress?: (percent: number) => void,
|
||||
): Promise<T> {
|
||||
const response = await apiClient.post<ApiResponse<T>>(
|
||||
this.getFullPath(path),
|
||||
formData,
|
||||
{
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
onUploadProgress: (event: AxiosProgressEvent) => {
|
||||
if (!onProgress || !event.total) return;
|
||||
const percent = Math.round((event.loaded / event.total) * 100);
|
||||
onProgress(percent);
|
||||
},
|
||||
} as InternalAxiosRequestConfig,
|
||||
);
|
||||
|
||||
return response.data.data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {ProxyRouteItem, ProxyRouteMutationPayload} from './types';
|
||||
|
||||
export class ProxyRouteService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/proxy-routes';
|
||||
|
||||
static async list(): Promise<ProxyRouteItem[]> {
|
||||
return this.get<ProxyRouteItem[]>('/');
|
||||
}
|
||||
|
||||
static async getById(id: number): Promise<ProxyRouteItem> {
|
||||
return this.get<ProxyRouteItem>(`/${id}`);
|
||||
}
|
||||
|
||||
static async create(payload: ProxyRouteMutationPayload): Promise<ProxyRouteItem> {
|
||||
return this.post<ProxyRouteItem>('/', payload);
|
||||
}
|
||||
|
||||
static async update(
|
||||
id: number,
|
||||
payload: ProxyRouteMutationPayload,
|
||||
): Promise<ProxyRouteItem> {
|
||||
return this.post<ProxyRouteItem>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteById(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {OpenFlarePublicStatus} from './types';
|
||||
|
||||
export class StatusService extends OpenFlareBaseService {
|
||||
static getPublicStatus(): Promise<OpenFlarePublicStatus> {
|
||||
return this.get<OpenFlarePublicStatus>('/status');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
AcmeAccountItem,
|
||||
TlsCertificateApplyPayload,
|
||||
TlsCertificateContentItem,
|
||||
TlsCertificateDetailItem,
|
||||
TlsCertificateFileImportPayload,
|
||||
TlsCertificateItem,
|
||||
TlsCertificateMutationPayload,
|
||||
} from './types';
|
||||
|
||||
class AcmeAccountApi extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/acme-accounts';
|
||||
|
||||
static getDefault(): Promise<AcmeAccountItem> {
|
||||
return this.get<AcmeAccountItem>('/default');
|
||||
}
|
||||
}
|
||||
|
||||
export class TlsCertificateService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/tls-certificates';
|
||||
|
||||
static async list(): Promise<TlsCertificateItem[]> {
|
||||
return this.get<TlsCertificateItem[]>('/');
|
||||
}
|
||||
|
||||
static async getById(id: number): Promise<TlsCertificateDetailItem> {
|
||||
return this.get<TlsCertificateDetailItem>(`/${id}`);
|
||||
}
|
||||
|
||||
static async getContent(id: number): Promise<TlsCertificateContentItem> {
|
||||
return this.get<TlsCertificateContentItem>(`/${id}/content`);
|
||||
}
|
||||
|
||||
static async create(
|
||||
payload: TlsCertificateMutationPayload,
|
||||
): Promise<TlsCertificateItem> {
|
||||
return this.post<TlsCertificateItem>('/', payload);
|
||||
}
|
||||
|
||||
static async update(
|
||||
id: number,
|
||||
payload: TlsCertificateMutationPayload,
|
||||
): Promise<TlsCertificateItem> {
|
||||
return this.post<TlsCertificateItem>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteById(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
|
||||
static async apply(
|
||||
payload: TlsCertificateApplyPayload,
|
||||
): Promise<TlsCertificateItem> {
|
||||
return this.post<TlsCertificateItem>('/apply', payload);
|
||||
}
|
||||
|
||||
static async renew(id: number): Promise<TlsCertificateItem> {
|
||||
return this.post<TlsCertificateItem>(`/${id}/renew`);
|
||||
}
|
||||
|
||||
static async updateAcme(
|
||||
id: number,
|
||||
payload: TlsCertificateApplyPayload,
|
||||
): Promise<TlsCertificateItem> {
|
||||
return this.post<TlsCertificateItem>(`/${id}/update-acme`, payload);
|
||||
}
|
||||
|
||||
static async convertToAcme(
|
||||
id: number,
|
||||
payload: TlsCertificateApplyPayload,
|
||||
): Promise<TlsCertificateItem> {
|
||||
return this.post<TlsCertificateItem>(`/${id}/convert-acme`, payload);
|
||||
}
|
||||
|
||||
static async importFile(
|
||||
payload: TlsCertificateFileImportPayload,
|
||||
): Promise<TlsCertificateItem> {
|
||||
const formData = new FormData();
|
||||
formData.append('name', payload.name);
|
||||
formData.append('remark', payload.remark);
|
||||
formData.append('cert_file', payload.certFile);
|
||||
formData.append('key_file', payload.keyFile);
|
||||
|
||||
return this.post<TlsCertificateItem>('/import-file', formData);
|
||||
}
|
||||
|
||||
static getDefaultAcmeAccount(): Promise<AcmeAccountItem> {
|
||||
return AcmeAccountApi.getDefault();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
|
||||
export class UptimeKumaService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/uptimekuma';
|
||||
|
||||
static sync(): Promise<void> {
|
||||
return this.post<void>('/sync');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
WAFIPGroup,
|
||||
WAFIPGroupAutoTestPayload,
|
||||
WAFIPGroupAutoTestResult,
|
||||
WAFIPGroupPayload,
|
||||
WAFIPGroupSyncResult,
|
||||
WAFRuleGroup,
|
||||
WAFRuleGroupPayload,
|
||||
WAFSiteRuleGroups,
|
||||
} from './types';
|
||||
|
||||
export class WafService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/waf';
|
||||
|
||||
static async listRuleGroups(): Promise<WAFRuleGroup[]> {
|
||||
return this.get<WAFRuleGroup[]>('/rule-groups');
|
||||
}
|
||||
|
||||
static async getRuleGroup(id: number): Promise<WAFRuleGroup> {
|
||||
return this.get<WAFRuleGroup>(`/rule-groups/${id}`);
|
||||
}
|
||||
|
||||
static async createRuleGroup(payload: WAFRuleGroupPayload): Promise<WAFRuleGroup> {
|
||||
return this.post<WAFRuleGroup>('/rule-groups', payload);
|
||||
}
|
||||
|
||||
static async updateRuleGroup(
|
||||
id: number,
|
||||
payload: WAFRuleGroupPayload,
|
||||
): Promise<WAFRuleGroup> {
|
||||
return this.post<WAFRuleGroup>(`/rule-groups/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteRuleGroup(id: number): Promise<void> {
|
||||
return this.post<void>(`/rule-groups/${id}/delete`);
|
||||
}
|
||||
|
||||
static async updateRuleGroupSites(id: number, ids: number[]): Promise<WAFRuleGroup> {
|
||||
return this.post<WAFRuleGroup>(`/rule-groups/${id}/sites`, { ids });
|
||||
}
|
||||
|
||||
static async listSiteRuleGroups(routeId: number): Promise<WAFSiteRuleGroups> {
|
||||
return this.get<WAFSiteRuleGroups>(`/sites/${routeId}/rule-groups`);
|
||||
}
|
||||
|
||||
static async updateSiteRuleGroups(
|
||||
routeId: number,
|
||||
ids: number[],
|
||||
): Promise<WAFSiteRuleGroups> {
|
||||
return this.post<WAFSiteRuleGroups>(`/sites/${routeId}/rule-groups`, {
|
||||
ids,
|
||||
});
|
||||
}
|
||||
|
||||
static async listIPGroups(): Promise<WAFIPGroup[]> {
|
||||
return this.get<WAFIPGroup[]>('/ip-groups');
|
||||
}
|
||||
|
||||
static async getIPGroup(id: number): Promise<WAFIPGroup> {
|
||||
return this.get<WAFIPGroup>(`/ip-groups/${id}`);
|
||||
}
|
||||
|
||||
static async createIPGroup(payload: WAFIPGroupPayload): Promise<WAFIPGroup> {
|
||||
return this.post<WAFIPGroup>('/ip-groups', payload);
|
||||
}
|
||||
|
||||
static async updateIPGroup(id: number, payload: WAFIPGroupPayload): Promise<WAFIPGroup> {
|
||||
return this.post<WAFIPGroup>(`/ip-groups/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteIPGroup(id: number): Promise<void> {
|
||||
return this.post<void>(`/ip-groups/${id}/delete`);
|
||||
}
|
||||
|
||||
static async testIPGroup(
|
||||
payload: WAFIPGroupAutoTestPayload,
|
||||
): Promise<WAFIPGroupAutoTestResult> {
|
||||
return this.post<WAFIPGroupAutoTestResult>('/ip-groups/test', payload);
|
||||
}
|
||||
|
||||
static async syncIPGroup(id: number): Promise<WAFIPGroupSyncResult> {
|
||||
return this.post<WAFIPGroupSyncResult>(`/ip-groups/${id}/sync`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import {OpenFlareBaseService} from './base.service';
|
||||
import type {
|
||||
ManagedDomainItem,
|
||||
ManagedDomainMatchResult,
|
||||
ManagedDomainMutationPayload,
|
||||
} from './types';
|
||||
|
||||
export class WebsiteService extends OpenFlareBaseService {
|
||||
protected static override readonly basePath: string = '/api/v1/d/managed-domains';
|
||||
|
||||
static async list(): Promise<ManagedDomainItem[]> {
|
||||
return this.get<ManagedDomainItem[]>('/');
|
||||
}
|
||||
|
||||
static async create(
|
||||
payload: ManagedDomainMutationPayload,
|
||||
): Promise<ManagedDomainItem> {
|
||||
return this.post<ManagedDomainItem>('/', payload);
|
||||
}
|
||||
|
||||
static async update(
|
||||
id: number,
|
||||
payload: ManagedDomainMutationPayload,
|
||||
): Promise<ManagedDomainItem> {
|
||||
return this.post<ManagedDomainItem>(`/${id}/update`, payload);
|
||||
}
|
||||
|
||||
static async deleteById(id: number): Promise<void> {
|
||||
return this.post<void>(`/${id}/delete`);
|
||||
}
|
||||
|
||||
static async match(domain: string): Promise<ManagedDomainMatchResult> {
|
||||
return this.get<ManagedDomainMatchResult>('/match', {domain});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user