Skip to main content
Glama
project.repository.ts7.17 kB
/** * @fileoverview Project repository implementation * * Concrete implementation of IProjectRepository using DeepSource API. */ import { IProjectRepository } from '../../domain/aggregates/project/project.repository.js'; import { Project } from '../../domain/aggregates/project/project.aggregate.js'; import { ProjectKey } from '../../types/branded.js'; import { ProjectsClient } from '../../client/projects-client.js'; import { ProjectMapper } from '../mappers/project.mapper.js'; import { createLogger } from '../../utils/logging/logger.js'; const logger = createLogger('ProjectRepository'); /** * Concrete implementation of IProjectRepository using DeepSource API * * This repository provides access to Project aggregates by fetching data * from the DeepSource API and mapping it to domain models. * * Note: Since the DeepSource API doesn't support individual project queries * or persistence operations, some methods fetch all projects and filter locally. * This ensures fresh data retrieval on every request as per requirements. */ export class ProjectRepository implements IProjectRepository { constructor(private readonly projectsClient: ProjectsClient) { // projectsClient is stored for use in methods } /** * Finds a project by its unique identifier * * @param id - The project key * @returns The project if found, null otherwise */ async findById(id: ProjectKey): Promise<Project | null> { return this.findByKey(id); } /** * Finds a project by its unique key * * @param key - The project key * @returns The project if found, null otherwise */ async findByKey(key: ProjectKey): Promise<Project | null> { try { logger.debug('Finding project by key', { key }); // Fetch all projects and find the one with matching key const apiProjects = await this.projectsClient.listProjects(); const matchingProject = apiProjects.find((p) => p.key === key); if (!matchingProject) { logger.debug('Project not found', { key }); return null; } const project = ProjectMapper.toDomain(matchingProject); logger.debug('Project found and mapped', { key, name: project.name }); return project; } catch (error) { logger.error('Error finding project by key', { key, error }); throw error; } } /** * Finds all projects * * @returns All projects in the repository */ async findAll(): Promise<Project[]> { try { logger.debug('Finding all projects'); const apiProjects = await this.projectsClient.listProjects(); const projects = ProjectMapper.toDomainList(apiProjects); logger.debug('Projects found', { count: projects.length }); return projects; } catch (error) { logger.error('Error finding all projects', { error }); throw error; } } /** * Finds all active projects * * @returns All projects with ACTIVE status */ async findActive(): Promise<Project[]> { try { logger.debug('Finding active projects'); const allProjects = await this.findAll(); const activeProjects = allProjects.filter((p) => p.status === 'ACTIVE'); logger.debug('Active projects found', { count: activeProjects.length }); return activeProjects; } catch (error) { logger.error('Error finding active projects', { error }); throw error; } } /** * Finds projects by repository provider * * @param provider - The VCS provider (e.g., 'GITHUB', 'GITLAB') * @returns Projects using the specified provider */ async findByProvider(provider: string): Promise<Project[]> { try { logger.debug('Finding projects by provider', { provider }); const allProjects = await this.findAll(); const providerProjects = allProjects.filter((p) => p.repository.provider === provider); logger.debug('Projects found for provider', { provider, count: providerProjects.length, }); return providerProjects; } catch (error) { logger.error('Error finding projects by provider', { provider, error }); throw error; } } /** * Checks if a project exists with the given key * * @param key - The project key to check * @returns True if the project exists, false otherwise */ async exists(key: ProjectKey): Promise<boolean> { try { logger.debug('Checking if project exists', { key }); const project = await this.findByKey(key); const exists = project !== null; logger.debug('Project existence check', { key, exists }); return exists; } catch (error) { logger.error('Error checking project existence', { key, error }); throw error; } } /** * Counts the total number of projects * * @returns The total project count */ async count(): Promise<number> { try { logger.debug('Counting all projects'); const projects = await this.findAll(); const count = projects.length; logger.debug('Total project count', { count }); return count; } catch (error) { logger.error('Error counting projects', { error }); throw error; } } /** * Counts the number of active projects * * @returns The active project count */ async countActive(): Promise<number> { try { logger.debug('Counting active projects'); const activeProjects = await this.findActive(); const count = activeProjects.length; logger.debug('Active project count', { count }); return count; } catch (error) { logger.error('Error counting active projects', { error }); throw error; } } /** * Saves a project * * Note: The DeepSource API doesn't support creating/updating projects * through the GraphQL API. This method is implemented to satisfy the * interface but will throw an error indicating the operation is not supported. * * @param project - The project to save * @throws Error indicating the operation is not supported */ // skipcq: JS-0105 - Repository method required by interface contract async save(project: Project): Promise<void> { logger.warn('Attempted to save project', { key: project.key, name: project.name, }); throw new Error( 'Save operation is not supported by DeepSource API. ' + 'Projects must be created and managed through the DeepSource UI.' ); } /** * Deletes a project * * Note: The DeepSource API doesn't support deleting projects * through the GraphQL API. This method is implemented to satisfy the * interface but will throw an error indicating the operation is not supported. * * @param key - The project key to delete * @throws Error indicating the operation is not supported */ // skipcq: JS-0105 - Repository method required by interface contract async delete(key: ProjectKey): Promise<void> { logger.warn('Attempted to delete project', { key }); throw new Error( 'Delete operation is not supported by DeepSource API. ' + 'Projects must be deleted through the DeepSource UI.' ); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sapientpants/deepsource-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server