Enhance CDN Manager: Add Cloudflare API token support, update documentation, and introduce new routes for managing nodes, aliases, and topology. Improve UI components and status badges for better user experience.
quality / commitlint (push) Skipped
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / web (push) Successful in 53s
quality / api (push) Successful in 49s
CD / quality (push) Successful in 1m57s
CD / publish (push) Successful in 27s
quality / commitlint (push) Skipped
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / web (push) Successful in 53s
quality / api (push) Successful in 49s
CD / quality (push) Successful in 1m57s
CD / publish (push) Successful in 27s
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
import { queryOptions } from '@tanstack/react-query'
|
||||
import type {
|
||||
Alias,
|
||||
AliasCreate,
|
||||
AliasPatch,
|
||||
AliasRetarget,
|
||||
BindExport,
|
||||
DashboardStats,
|
||||
Location,
|
||||
Node,
|
||||
NodeCreate,
|
||||
NodePatch,
|
||||
Topology,
|
||||
Zone,
|
||||
ZoneCreate,
|
||||
ZonePatch,
|
||||
SyncJob,
|
||||
CfZone,
|
||||
} from '@cdnmanager/shared'
|
||||
import { api } from '@/lib/api-client'
|
||||
|
||||
export const fleetKeys = {
|
||||
all: ['fleet'] as const,
|
||||
locations: () => [...fleetKeys.all, 'locations'] as const,
|
||||
zones: () => [...fleetKeys.all, 'zones'] as const,
|
||||
cfZones: () => [...fleetKeys.all, 'cf-zones'] as const,
|
||||
nodes: (filters?: Record<string, string | undefined>) =>
|
||||
[...fleetKeys.all, 'nodes', filters ?? {}] as const,
|
||||
node: (id: string) => [...fleetKeys.all, 'node', id] as const,
|
||||
aliases: (filters?: Record<string, string | undefined>) =>
|
||||
[...fleetKeys.all, 'aliases', filters ?? {}] as const,
|
||||
alias: (id: string) => [...fleetKeys.all, 'alias', id] as const,
|
||||
dashboard: () => [...fleetKeys.all, 'dashboard'] as const,
|
||||
topology: (zoneId?: string) =>
|
||||
[...fleetKeys.all, 'topology', zoneId ?? 'all'] as const,
|
||||
syncJobs: (zoneId: string) =>
|
||||
[...fleetKeys.all, 'sync-jobs', zoneId] as const,
|
||||
bindExport: (zoneId: string) =>
|
||||
[...fleetKeys.all, 'bind', zoneId] as const,
|
||||
namingPreview: (params: Record<string, string>) =>
|
||||
[...fleetKeys.all, 'naming', params] as const,
|
||||
}
|
||||
|
||||
function qs(filters?: Record<string, string | undefined>) {
|
||||
if (!filters) return ''
|
||||
const p = new URLSearchParams()
|
||||
for (const [k, v] of Object.entries(filters)) {
|
||||
if (v) p.set(k, v)
|
||||
}
|
||||
const s = p.toString()
|
||||
return s ? `?${s}` : ''
|
||||
}
|
||||
|
||||
export const locationsQueryOptions = () =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.locations(),
|
||||
queryFn: () => api.get<Location[]>('/api/v1/locations'),
|
||||
})
|
||||
|
||||
export const zonesQueryOptions = () =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.zones(),
|
||||
queryFn: () => api.get<Zone[]>('/api/v1/zones'),
|
||||
})
|
||||
|
||||
export const cfZonesQueryOptions = () =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.cfZones(),
|
||||
queryFn: () => api.get<CfZone[]>('/api/v1/cloudflare/zones'),
|
||||
retry: false,
|
||||
})
|
||||
|
||||
export const nodesQueryOptions = (filters?: Record<string, string | undefined>) =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.nodes(filters),
|
||||
queryFn: () => api.get<Node[]>(`/api/v1/nodes${qs(filters)}`),
|
||||
})
|
||||
|
||||
export const aliasesQueryOptions = (
|
||||
filters?: Record<string, string | undefined>,
|
||||
) =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.aliases(filters),
|
||||
queryFn: () => api.get<Alias[]>(`/api/v1/aliases${qs(filters)}`),
|
||||
})
|
||||
|
||||
export const dashboardStatsQueryOptions = () =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.dashboard(),
|
||||
queryFn: () => api.get<DashboardStats>('/api/v1/dashboard/stats'),
|
||||
staleTime: 15_000,
|
||||
})
|
||||
|
||||
export const topologyQueryOptions = (zoneId?: string) =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.topology(zoneId),
|
||||
queryFn: () =>
|
||||
api.get<Topology>(
|
||||
`/api/v1/topology${zoneId ? `?zoneId=${encodeURIComponent(zoneId)}` : ''}`,
|
||||
),
|
||||
})
|
||||
|
||||
export const syncJobsQueryOptions = (zoneId: string) =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.syncJobs(zoneId),
|
||||
queryFn: () => api.get<SyncJob[]>(`/api/v1/zones/${zoneId}/sync-jobs`),
|
||||
enabled: Boolean(zoneId),
|
||||
})
|
||||
|
||||
export const bindExportQueryOptions = (zoneId: string) =>
|
||||
queryOptions({
|
||||
queryKey: fleetKeys.bindExport(zoneId),
|
||||
queryFn: () =>
|
||||
api.get<BindExport>(`/api/v1/zones/${zoneId}/export/bind`),
|
||||
enabled: Boolean(zoneId),
|
||||
})
|
||||
|
||||
export async function createZone(body: ZoneCreate) {
|
||||
return api.post<Zone>('/api/v1/zones', body)
|
||||
}
|
||||
|
||||
export async function patchZone(id: string, body: ZonePatch) {
|
||||
return api.patch<Zone>(`/api/v1/zones/${id}`, body)
|
||||
}
|
||||
|
||||
export async function removeZone(id: string) {
|
||||
return api.delete(`/api/v1/zones/${id}`)
|
||||
}
|
||||
|
||||
export async function syncZone(id: string) {
|
||||
return api.post<SyncJob>(`/api/v1/zones/${id}/sync`, {})
|
||||
}
|
||||
|
||||
export async function applyZone(id: string, opIds?: string[]) {
|
||||
return api.post<SyncJob>(`/api/v1/zones/${id}/apply`, { opIds })
|
||||
}
|
||||
|
||||
export async function createNode(body: NodeCreate) {
|
||||
return api.post<Node>('/api/v1/nodes', body)
|
||||
}
|
||||
|
||||
export async function patchNode(id: string, body: NodePatch) {
|
||||
return api.patch<Node>(`/api/v1/nodes/${id}`, body)
|
||||
}
|
||||
|
||||
export async function removeNode(id: string) {
|
||||
return api.delete(`/api/v1/nodes/${id}`)
|
||||
}
|
||||
|
||||
export async function createAlias(body: AliasCreate) {
|
||||
return api.post<Alias>('/api/v1/aliases', body)
|
||||
}
|
||||
|
||||
export async function patchAlias(id: string, body: AliasPatch) {
|
||||
return api.patch<Alias>(`/api/v1/aliases/${id}`, body)
|
||||
}
|
||||
|
||||
export async function retargetAliasApi(id: string, body: AliasRetarget) {
|
||||
return api.post<Alias>(`/api/v1/aliases/${id}/retarget`, body)
|
||||
}
|
||||
|
||||
export async function removeAlias(id: string) {
|
||||
return api.delete(`/api/v1/aliases/${id}`)
|
||||
}
|
||||
|
||||
export async function ignoreOrphan(
|
||||
zoneId: string,
|
||||
recordName: string,
|
||||
recordType: string,
|
||||
) {
|
||||
return api.post(`/api/v1/zones/${zoneId}/orphans/ignore`, {
|
||||
recordName,
|
||||
recordType,
|
||||
})
|
||||
}
|
||||
|
||||
export async function previewHostname(params: {
|
||||
zoneId: string
|
||||
locationId: string
|
||||
role: string
|
||||
indexNum?: number
|
||||
providerTag?: string
|
||||
}) {
|
||||
const p = new URLSearchParams({
|
||||
zoneId: params.zoneId,
|
||||
locationId: params.locationId,
|
||||
role: params.role,
|
||||
indexNum: String(params.indexNum ?? 1),
|
||||
})
|
||||
if (params.providerTag) p.set('providerTag', params.providerTag)
|
||||
return api.get<{ hostname: string }>(`/api/v1/naming/preview?${p}`)
|
||||
}
|
||||
Reference in New Issue
Block a user