feat: enhance API client with pagination and new data fetching functions. Implement apiPageAll for paginated API requests, and add functions to fetch all revision prefixes and module source catalogs based on module type. Update type definitions to support new response structures, improving data handling in the application.
CI / changes (push) Successful in 6s
CI / openapi (push) Has been skipped
CI / go (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m11s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m12s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / docker-go-prime (push) Has been skipped
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been skipped
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been skipped
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been skipped
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been skipped
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been skipped
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been skipped
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been skipped
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been skipped

This commit is contained in:
Denozordec
2026-04-06 20:34:49 +07:00
parent 1c5a9c91bb
commit 9f0b1281f2
5 changed files with 470 additions and 15 deletions
+62 -1
View File
@@ -1,5 +1,14 @@
import { browser } from '$app/environment';
import type { JobRow } from './types.js';
import type {
AsEntriesResponse,
CdnSourcesResponse,
DomainEntriesResponse,
IpRangeEntriesResponse,
JobRow,
ModuleType,
RevisionPrefix,
RevisionPrefixesResponse
} from './types.js';
export const TOKEN_STORAGE_KEY = 'evobgp_api_token';
@@ -122,3 +131,55 @@ export async function waitForJob(
}
throw new Error(`Таймаут ожидания задачи ${jobId}`);
}
export async function apiPageAll<T>(path: string, limit = 500): Promise<T[]> {
const items: T[] = [];
let cursor: string | null = null;
while (true) {
const [basePath, rawQuery = ''] = path.split('?');
const query = new URLSearchParams(rawQuery);
if (!query.has('limit')) query.set('limit', String(limit));
if (cursor) query.set('cursor', cursor);
else query.delete('cursor');
const page = await apiJSON<{ items?: T[]; next_cursor?: string | null; has_more?: boolean }>(
`${basePath}?${query.toString()}`
);
items.push(...(page.items ?? []));
if (!page.has_more || !page.next_cursor) break;
cursor = page.next_cursor;
}
return items;
}
export async function fetchRevisionPrefixesAll(revisionId: string): Promise<RevisionPrefix[]> {
const items = await apiPageAll<RevisionPrefix>(`/v1/revisions/${revisionId}/prefixes`);
return items;
}
export async function fetchModuleSourceCatalog(moduleId: string, moduleType: ModuleType) {
if (moduleType === 'DOMAINS') {
const entries = await apiPageAll<DomainEntriesResponse['items'][number]>(
`/v1/modules/${moduleId}/domain-entries`
);
return { domains: entries };
}
if (moduleType === 'AS_PREFIXES') {
const entries = await apiPageAll<AsEntriesResponse['items'][number]>(
`/v1/modules/${moduleId}/as-entries`
);
return { asns: entries };
}
if (moduleType === 'CDN_CIDRS') {
const entries = await apiPageAll<CdnSourcesResponse['items'][number]>(
`/v1/modules/${moduleId}/cdn-sources`
);
return { cdnSources: entries };
}
if (moduleType === 'IP_RANGES') {
const entries = await apiPageAll<IpRangeEntriesResponse['items'][number]>(
`/v1/modules/${moduleId}/ip-range-entries`
);
return { ipRanges: entries };
}
return {};
}
+2
View File
@@ -179,6 +179,8 @@ export type RevisionsResponse = Page<RevisionRow>;
export type RevisionPrefix = {
/** Обычно CIDR; для AS-модуля в снимке ревизии — строка вида `as:<номер_asn>`. */
prefix: string;
/** Источник материализации (например, domain:<fqdn>, as:<asn>, cdn:<source_id>, ip_range). */
source?: string;
community_id?: string | null;
};
export type RevisionPrefixesResponse = Page<RevisionPrefix>;