import type { IntegrationRegistry } from './classes.integrationregistry.js'; import type { IDiscoveryCandidate, IDiscoveryContext, IDiscoveryMatch, TDiscoverySource, } from './types.js'; export class DiscoveryEngine { constructor(private readonly integrationRegistry: IntegrationRegistry) {} public async runActiveDiscovery(contextArg: IDiscoveryContext = {}): Promise { const candidates: IDiscoveryCandidate[] = []; for (const integration of this.integrationRegistry.list()) { const descriptor = integration.discoveryDescriptor; for (const probe of descriptor.getProbes()) { const result = await probe.probe(contextArg); for (const candidate of result.candidates) { candidates.push({ ...candidate, integrationDomain: candidate.integrationDomain ?? integration.domain, }); } } } return candidates; } public async matchExistingData( sourceArg: TDiscoverySource, inputArg: TInput, contextArg: IDiscoveryContext = {} ): Promise { const matches: IDiscoveryMatch[] = []; for (const integration of this.integrationRegistry.list()) { const descriptor = integration.discoveryDescriptor; for (const matcher of descriptor.getMatchers()) { if (matcher.source !== sourceArg) { continue; } const result = await matcher.matches(inputArg, contextArg); if (result.matched) { matches.push(result); } } } return matches; } public async validateCandidate( candidateArg: IDiscoveryCandidate, contextArg: IDiscoveryContext = {} ): Promise { const matches: IDiscoveryMatch[] = []; const integrations = candidateArg.integrationDomain ? this.integrationRegistry.list().filter((integrationArg) => integrationArg.domain === candidateArg.integrationDomain) : this.integrationRegistry.list(); for (const integration of integrations) { for (const validator of integration.discoveryDescriptor.getValidators()) { const result = await validator.validate(candidateArg, contextArg); if (result.matched) { matches.push(result); } } } return matches; } }