mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-10-08 17:40:03 +00:00
Refine entity, monitor, alert, settings, observability, and shared operator workflows; add scale guards, route compatibility, release validation, and Product Design coverage. AI assistance: used for draft implementation and test iteration.\nHuman validation: Node 22 production build; 426 frontend files and 3,398 tests; 59-route matrix; release budget 7.84 MiB / 8.00 MiB; focused backend tests and Browser QA.\nRisk notes: local scale proof covers 2,005 entities; sustained concurrent-ingestion SLA remains deployment-specific.
99 lines
3.0 KiB
TypeScript
99 lines
3.0 KiB
TypeScript
import type {
|
|
EntityDefinitionActivity,
|
|
EntityDefinitionFormat,
|
|
EntityDefinitionRequest,
|
|
EntityDefinitionWorkspaceTemplate,
|
|
EntityDto
|
|
} from '@/lib/types';
|
|
|
|
type ApiGetter = <T>(url: string) => Promise<T>;
|
|
type ApiPoster = <T>(url: string, body: EntityDefinitionRequest) => Promise<T>;
|
|
type EntityImportReaders = {
|
|
templates: (limit?: number) => Promise<EntityDefinitionWorkspaceTemplate[]>;
|
|
activities: (limit?: number) => Promise<EntityDefinitionActivity[]>;
|
|
};
|
|
|
|
export function buildImportTemplatesUrl(limit = 8) {
|
|
const params = new URLSearchParams({ limit: String(limit) });
|
|
return `/entities/definition/templates?${params.toString()}`;
|
|
}
|
|
|
|
export function buildImportActivitiesUrl(limit = 8) {
|
|
const params = new URLSearchParams({ limit: String(limit) });
|
|
return `/entities/definition-activities?${params.toString()}`;
|
|
}
|
|
|
|
function isRecoverableImportLoadError(error: unknown) {
|
|
if (!(error instanceof Error)) {
|
|
return false;
|
|
}
|
|
|
|
return error.message.includes('404')
|
|
|| error.message.includes('ECONNRESET')
|
|
|| error.message.includes('socket hang up')
|
|
|| error.message.includes('Backend service unavailable.')
|
|
|| error.message.includes('API request failed: 503');
|
|
}
|
|
|
|
async function loadImportTemplates(apiGet: ApiGetter) {
|
|
try {
|
|
return await apiGet<EntityDefinitionWorkspaceTemplate[]>(buildImportTemplatesUrl());
|
|
} catch (error) {
|
|
if (isRecoverableImportLoadError(error)) {
|
|
return [];
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function loadImportActivities(apiGet: ApiGetter) {
|
|
try {
|
|
return await apiGet<EntityDefinitionActivity[]>(buildImportActivitiesUrl());
|
|
} catch (error) {
|
|
if (isRecoverableImportLoadError(error)) {
|
|
return [];
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function loadImportData(apiGet: ApiGetter) {
|
|
const [templates, activities] = await Promise.all([
|
|
loadImportTemplates(apiGet),
|
|
loadImportActivities(apiGet)
|
|
]);
|
|
|
|
return { templates, activities };
|
|
}
|
|
|
|
export async function loadImportDataFromFacade(readers: EntityImportReaders) {
|
|
const [templates, activities] = await Promise.all([
|
|
readers.templates(8).catch(error => {
|
|
if (isRecoverableImportLoadError(error)) {
|
|
return [];
|
|
}
|
|
throw error;
|
|
}),
|
|
readers.activities(8).catch(error => {
|
|
if (isRecoverableImportLoadError(error)) {
|
|
return [];
|
|
}
|
|
throw error;
|
|
})
|
|
]);
|
|
|
|
return { templates, activities };
|
|
}
|
|
|
|
export function buildDefinitionRequest(content: string, format: EntityDefinitionFormat): EntityDefinitionRequest {
|
|
return { content, format };
|
|
}
|
|
|
|
export async function parseDefinitionBundle(apiPost: ApiPoster, content: string, format: EntityDefinitionFormat) {
|
|
return apiPost<EntityDto[]>('/entities/definition/bundle/parse', buildDefinitionRequest(content, format));
|
|
}
|
|
|
|
export async function createDefinitionBundle(apiPost: ApiPoster, content: string, format: EntityDefinitionFormat) {
|
|
return apiPost<number[]>('/entities/definition/bundle', buildDefinitionRequest(content, format));
|
|
}
|