2024-02-06 08:48:06 +00:00
|
|
|
import { DataSource, DeepPartial, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
2024-01-16 08:10:14 +00:00
|
|
|
import path from 'path';
|
|
|
|
import debug from 'debug';
|
2024-01-31 13:21:53 +00:00
|
|
|
import assert from 'assert';
|
2024-02-08 09:29:19 +00:00
|
|
|
import { customAlphabet } from 'nanoid';
|
|
|
|
import { lowercase, numbers } from 'nanoid-dictionary';
|
2024-01-16 08:10:14 +00:00
|
|
|
|
2024-01-17 05:23:01 +00:00
|
|
|
import { DatabaseConfig } from './config';
|
2024-01-17 11:29:59 +00:00
|
|
|
import { User } from './entity/User';
|
|
|
|
import { Organization } from './entity/Organization';
|
|
|
|
import { Project } from './entity/Project';
|
2024-02-05 10:51:55 +00:00
|
|
|
import { Deployment } from './entity/Deployment';
|
|
|
|
import { ProjectMember } from './entity/ProjectMember';
|
2024-01-18 08:36:49 +00:00
|
|
|
import { EnvironmentVariable } from './entity/EnvironmentVariable';
|
2024-01-29 12:48:43 +00:00
|
|
|
import { Domain } from './entity/Domain';
|
2024-02-05 09:26:28 +00:00
|
|
|
import { PROJECT_DOMAIN } from './constants';
|
2024-01-16 08:10:14 +00:00
|
|
|
|
2024-01-17 05:23:01 +00:00
|
|
|
const log = debug('snowball:database');
|
|
|
|
|
2024-02-08 09:29:19 +00:00
|
|
|
const nanoid = customAlphabet(lowercase + numbers, 8);
|
|
|
|
|
2024-01-31 13:21:53 +00:00
|
|
|
// TODO: Fix order of methods
|
2024-01-17 05:23:01 +00:00
|
|
|
export class Database {
|
|
|
|
private dataSource: DataSource;
|
|
|
|
|
|
|
|
constructor ({ dbPath }: DatabaseConfig) {
|
|
|
|
this.dataSource = new DataSource({
|
2024-01-16 08:10:14 +00:00
|
|
|
type: 'better-sqlite3',
|
2024-01-17 05:23:01 +00:00
|
|
|
database: dbPath,
|
2024-01-16 08:10:14 +00:00
|
|
|
entities: [path.join(__dirname, '/entity/*')],
|
|
|
|
synchronize: true,
|
|
|
|
logging: false
|
|
|
|
});
|
2024-01-17 05:23:01 +00:00
|
|
|
}
|
2024-01-16 08:10:14 +00:00
|
|
|
|
2024-01-30 10:18:50 +00:00
|
|
|
async init (): Promise<void> {
|
2024-01-17 05:23:01 +00:00
|
|
|
await this.dataSource.initialize();
|
2024-01-16 08:10:14 +00:00
|
|
|
log('database initialized');
|
|
|
|
}
|
2024-01-17 05:23:01 +00:00
|
|
|
|
2024-02-05 10:51:55 +00:00
|
|
|
async getUser (options: FindOneOptions<User>): Promise<User | null> {
|
2024-01-17 05:23:01 +00:00
|
|
|
const userRepository = this.dataSource.getRepository(User);
|
2024-02-05 10:51:55 +00:00
|
|
|
const user = await userRepository.findOne(options);
|
|
|
|
|
|
|
|
return user;
|
|
|
|
}
|
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
async addUser (data: DeepPartial<User>): Promise<User> {
|
2024-02-05 10:51:55 +00:00
|
|
|
const userRepository = this.dataSource.getRepository(User);
|
|
|
|
const user = await userRepository.save(data);
|
2024-01-17 05:23:01 +00:00
|
|
|
|
|
|
|
return user;
|
|
|
|
}
|
2024-01-17 11:29:59 +00:00
|
|
|
|
2024-02-06 13:41:53 +00:00
|
|
|
async updateUser (userId: string, data: DeepPartial<User>): Promise<boolean> {
|
2024-01-31 13:21:53 +00:00
|
|
|
const userRepository = this.dataSource.getRepository(User);
|
2024-02-06 13:41:53 +00:00
|
|
|
const updateResult = await userRepository.update({ id: userId }, data);
|
2024-01-31 13:21:53 +00:00
|
|
|
assert(updateResult.affected);
|
|
|
|
|
|
|
|
return updateResult.affected > 0;
|
|
|
|
}
|
|
|
|
|
2024-02-07 13:11:54 +00:00
|
|
|
async getOrganization (options: FindOneOptions<Organization>): Promise<Organization | null> {
|
|
|
|
const organizationRepository = this.dataSource.getRepository(Organization);
|
|
|
|
const organization = await organizationRepository.findOne(options);
|
|
|
|
|
|
|
|
return organization;
|
|
|
|
}
|
|
|
|
|
2024-02-06 13:41:53 +00:00
|
|
|
async getOrganizationsByUserId (userId: string): Promise<Organization[]> {
|
2024-02-02 08:34:26 +00:00
|
|
|
const organizationRepository = this.dataSource.getRepository(Organization);
|
2024-01-17 11:29:59 +00:00
|
|
|
|
2024-02-02 08:34:26 +00:00
|
|
|
const userOrgs = await organizationRepository.find({
|
2024-01-17 11:29:59 +00:00
|
|
|
where: {
|
2024-02-02 08:34:26 +00:00
|
|
|
userOrganizations: {
|
|
|
|
member: {
|
|
|
|
id: userId
|
|
|
|
}
|
2024-01-17 11:29:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-02-02 08:34:26 +00:00
|
|
|
return userOrgs;
|
2024-01-17 11:29:59 +00:00
|
|
|
}
|
|
|
|
|
2024-01-29 11:01:03 +00:00
|
|
|
async getProjectById (projectId: string): Promise<Project | null> {
|
2024-01-25 06:28:38 +00:00
|
|
|
const projectRepository = this.dataSource.getRepository(Project);
|
|
|
|
|
2024-01-29 11:01:03 +00:00
|
|
|
const project = await projectRepository
|
|
|
|
.createQueryBuilder('project')
|
|
|
|
.leftJoinAndSelect('project.deployments', 'deployments', 'deployments.isCurrent = true')
|
2024-02-05 09:26:28 +00:00
|
|
|
.leftJoinAndSelect('deployments.createdBy', 'user')
|
2024-01-29 11:01:03 +00:00
|
|
|
.leftJoinAndSelect('deployments.domain', 'domain')
|
|
|
|
.leftJoinAndSelect('project.owner', 'owner')
|
2024-02-02 08:34:26 +00:00
|
|
|
.leftJoinAndSelect('project.organization', 'organization')
|
2024-01-29 11:01:03 +00:00
|
|
|
.where('project.id = :projectId', {
|
|
|
|
projectId
|
|
|
|
})
|
|
|
|
.getOne();
|
2024-01-25 06:28:38 +00:00
|
|
|
|
|
|
|
return project;
|
|
|
|
}
|
|
|
|
|
2024-02-07 13:11:54 +00:00
|
|
|
async getProjectsInOrganization (userId: string, organizationSlug: string): Promise<Project[]> {
|
2024-01-29 11:01:03 +00:00
|
|
|
const projectRepository = this.dataSource.getRepository(Project);
|
|
|
|
|
|
|
|
const projects = await projectRepository
|
|
|
|
.createQueryBuilder('project')
|
|
|
|
.leftJoinAndSelect('project.deployments', 'deployments', 'deployments.isCurrent = true')
|
|
|
|
.leftJoinAndSelect('deployments.domain', 'domain')
|
|
|
|
.leftJoin('project.projectMembers', 'projectMembers')
|
2024-02-07 13:11:54 +00:00
|
|
|
.leftJoin('project.organization', 'organization')
|
|
|
|
.where('(project.ownerId = :userId OR projectMembers.userId = :userId) AND organization.slug = :organizationSlug', {
|
2024-01-29 11:01:03 +00:00
|
|
|
userId,
|
2024-02-07 13:11:54 +00:00
|
|
|
organizationSlug
|
2024-01-29 11:01:03 +00:00
|
|
|
})
|
|
|
|
.getMany();
|
|
|
|
|
|
|
|
return projects;
|
|
|
|
}
|
|
|
|
|
2024-01-18 08:36:49 +00:00
|
|
|
async getDeploymentsByProjectId (projectId: string): Promise<Deployment[]> {
|
|
|
|
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
|
|
|
|
|
|
|
const deployments = await deploymentRepository.find({
|
|
|
|
relations: {
|
|
|
|
project: true,
|
2024-01-30 10:18:50 +00:00
|
|
|
domain: true,
|
|
|
|
createdBy: true
|
2024-01-18 08:36:49 +00:00
|
|
|
},
|
|
|
|
where: {
|
|
|
|
project: {
|
|
|
|
id: projectId
|
|
|
|
}
|
2024-01-30 10:18:50 +00:00
|
|
|
},
|
|
|
|
order: {
|
|
|
|
createdAt: 'DESC'
|
2024-01-18 08:36:49 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return deployments;
|
|
|
|
}
|
|
|
|
|
2024-02-05 10:51:55 +00:00
|
|
|
async getDeployment (options: FindOneOptions<Deployment>): Promise<Deployment | null> {
|
|
|
|
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
|
|
|
const deployment = await deploymentRepository.findOne(options);
|
|
|
|
|
|
|
|
return deployment;
|
|
|
|
}
|
|
|
|
|
|
|
|
async getDomains (options: FindManyOptions<Domain>): Promise<Domain[]> {
|
|
|
|
const domainRepository = this.dataSource.getRepository(Domain);
|
|
|
|
const domains = await domainRepository.find(options);
|
|
|
|
|
|
|
|
return domains;
|
|
|
|
}
|
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
async addDeployement (data: DeepPartial<Deployment>): Promise<Deployment> {
|
2024-02-05 10:51:55 +00:00
|
|
|
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
2024-02-08 09:29:19 +00:00
|
|
|
|
|
|
|
const id = nanoid();
|
|
|
|
const url = `${data.project!.name}-${id}.${PROJECT_DOMAIN}`;
|
|
|
|
|
|
|
|
const updatedData = {
|
|
|
|
...data,
|
|
|
|
id,
|
|
|
|
url
|
|
|
|
};
|
|
|
|
const deployment = await deploymentRepository.save(updatedData);
|
2024-02-05 10:51:55 +00:00
|
|
|
|
|
|
|
return deployment;
|
|
|
|
}
|
|
|
|
|
2024-01-22 09:42:08 +00:00
|
|
|
async getProjectMembersByProjectId (projectId: string): Promise<ProjectMember[]> {
|
2024-01-18 08:36:49 +00:00
|
|
|
const projectMemberRepository = this.dataSource.getRepository(ProjectMember);
|
|
|
|
|
|
|
|
const projectMembers = await projectMemberRepository.find({
|
|
|
|
relations: {
|
|
|
|
project: true,
|
|
|
|
member: true
|
|
|
|
},
|
|
|
|
where: {
|
|
|
|
project: {
|
|
|
|
id: projectId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return projectMembers;
|
|
|
|
}
|
|
|
|
|
|
|
|
async getEnvironmentVariablesByProjectId (projectId: string): Promise<EnvironmentVariable[]> {
|
|
|
|
const environmentVariableRepository = this.dataSource.getRepository(EnvironmentVariable);
|
|
|
|
|
|
|
|
const environmentVariables = await environmentVariableRepository.find({
|
|
|
|
where: {
|
|
|
|
project: {
|
|
|
|
id: projectId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return environmentVariables;
|
|
|
|
}
|
2024-01-22 09:42:08 +00:00
|
|
|
|
2024-01-31 11:39:29 +00:00
|
|
|
async removeProjectMemberById (projectMemberId: string): Promise<boolean> {
|
2024-01-22 09:42:08 +00:00
|
|
|
const projectMemberRepository = this.dataSource.getRepository(ProjectMember);
|
2024-01-23 09:31:33 +00:00
|
|
|
|
2024-02-06 13:41:53 +00:00
|
|
|
const deleteResult = await projectMemberRepository.delete({ id: projectMemberId });
|
2024-01-22 09:42:08 +00:00
|
|
|
|
2024-01-31 11:39:29 +00:00
|
|
|
if (deleteResult.affected) {
|
|
|
|
return deleteResult.affected > 0;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async updateProjectMemberById (projectMemberId: string, data: DeepPartial<ProjectMember>): Promise<boolean> {
|
|
|
|
const projectMemberRepository = this.dataSource.getRepository(ProjectMember);
|
2024-02-06 13:41:53 +00:00
|
|
|
const updateResult = await projectMemberRepository.update({ id: projectMemberId }, data);
|
2024-01-31 11:39:29 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return Boolean(updateResult.affected);
|
2024-01-22 09:42:08 +00:00
|
|
|
}
|
2024-01-23 09:31:33 +00:00
|
|
|
|
2024-02-05 10:51:55 +00:00
|
|
|
async addProjectMember (data: DeepPartial<ProjectMember>): Promise<ProjectMember> {
|
2024-02-01 10:04:17 +00:00
|
|
|
const projectMemberRepository = this.dataSource.getRepository(ProjectMember);
|
2024-02-05 10:51:55 +00:00
|
|
|
const newProjectMember = await projectMemberRepository.save(data);
|
2024-02-01 10:04:17 +00:00
|
|
|
|
2024-02-05 10:51:55 +00:00
|
|
|
return newProjectMember;
|
2024-02-01 10:04:17 +00:00
|
|
|
}
|
|
|
|
|
2024-02-05 10:51:55 +00:00
|
|
|
async addEnvironmentVariables (data: DeepPartial<EnvironmentVariable>[]): Promise<EnvironmentVariable[]> {
|
2024-01-23 09:31:33 +00:00
|
|
|
const environmentVariableRepository = this.dataSource.getRepository(EnvironmentVariable);
|
2024-02-05 10:51:55 +00:00
|
|
|
const savedEnvironmentVariables = await environmentVariableRepository.save(data);
|
2024-01-23 09:31:33 +00:00
|
|
|
|
2024-02-05 10:51:55 +00:00
|
|
|
return savedEnvironmentVariables;
|
2024-01-23 09:31:33 +00:00
|
|
|
}
|
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
async updateEnvironmentVariable (environmentVariableId: string, data: DeepPartial<EnvironmentVariable>): Promise<boolean> {
|
2024-01-31 05:06:22 +00:00
|
|
|
const environmentVariableRepository = this.dataSource.getRepository(EnvironmentVariable);
|
2024-02-14 12:05:02 +00:00
|
|
|
const updateResult = await environmentVariableRepository.update({ id: environmentVariableId }, data);
|
2024-01-31 05:06:22 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return Boolean(updateResult.affected);
|
2024-01-31 05:06:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async deleteEnvironmentVariable (environmentVariableId: string): Promise<boolean> {
|
|
|
|
const environmentVariableRepository = this.dataSource.getRepository(EnvironmentVariable);
|
2024-02-06 13:41:53 +00:00
|
|
|
const deleteResult = await environmentVariableRepository.delete({ id: environmentVariableId });
|
2024-01-31 05:06:22 +00:00
|
|
|
|
|
|
|
if (deleteResult.affected) {
|
|
|
|
return deleteResult.affected > 0;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-31 11:39:29 +00:00
|
|
|
async getProjectMemberById (projectMemberId: string): Promise<ProjectMember> {
|
2024-01-23 09:31:33 +00:00
|
|
|
const projectMemberRepository = this.dataSource.getRepository(ProjectMember);
|
|
|
|
|
|
|
|
const projectMemberWithProject = await projectMemberRepository.find({
|
|
|
|
relations: {
|
|
|
|
project: {
|
|
|
|
owner: true
|
|
|
|
},
|
|
|
|
member: true
|
|
|
|
},
|
|
|
|
where: {
|
2024-02-06 13:41:53 +00:00
|
|
|
id: projectMemberId
|
2024-01-23 09:31:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
if (projectMemberWithProject.length === 0) {
|
|
|
|
throw new Error('Member does not exist');
|
|
|
|
}
|
|
|
|
|
|
|
|
return projectMemberWithProject[0];
|
|
|
|
}
|
2024-01-24 14:47:43 +00:00
|
|
|
|
2024-02-06 13:41:53 +00:00
|
|
|
async getProjectsBySearchText (userId: string, searchText: string): Promise<Project[]> {
|
2024-01-24 14:47:43 +00:00
|
|
|
const projectRepository = this.dataSource.getRepository(Project);
|
|
|
|
|
|
|
|
const projects = await projectRepository
|
|
|
|
.createQueryBuilder('project')
|
|
|
|
.leftJoinAndSelect('project.organization', 'organization')
|
|
|
|
.leftJoin('project.projectMembers', 'projectMembers')
|
|
|
|
.where('(project.owner = :userId OR projectMembers.member.id = :userId) AND project.name LIKE :searchText', {
|
|
|
|
userId,
|
|
|
|
searchText: `%${searchText}%`
|
|
|
|
})
|
|
|
|
.getMany();
|
|
|
|
|
|
|
|
return projects;
|
|
|
|
}
|
2024-01-25 05:47:44 +00:00
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
async updateDeploymentById (deploymentId: string, data: DeepPartial<Deployment>): Promise<boolean> {
|
2024-01-25 05:47:44 +00:00
|
|
|
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
2024-02-14 12:05:02 +00:00
|
|
|
const updateResult = await deploymentRepository.update({ id: deploymentId }, data);
|
2024-01-25 06:28:38 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return Boolean(updateResult.affected);
|
2024-01-25 06:28:38 +00:00
|
|
|
}
|
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
async addProject (userId: string, organizationId: string, data: DeepPartial<Project>): Promise<Project> {
|
2024-02-01 12:40:15 +00:00
|
|
|
const projectRepository = this.dataSource.getRepository(Project);
|
|
|
|
|
|
|
|
// TODO: Check if organization exists
|
2024-02-14 12:05:02 +00:00
|
|
|
const newProject = projectRepository.create(data);
|
2024-02-01 12:40:15 +00:00
|
|
|
// TODO: Set default empty array for webhooks in TypeORM
|
|
|
|
newProject.webhooks = [];
|
|
|
|
// TODO: Set icon according to framework
|
|
|
|
newProject.icon = '';
|
|
|
|
|
|
|
|
newProject.owner = Object.assign(new User(), {
|
2024-02-06 13:41:53 +00:00
|
|
|
id: userId
|
2024-02-01 12:40:15 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
newProject.organization = Object.assign(new Organization(), {
|
2024-02-07 13:11:54 +00:00
|
|
|
id: organizationId
|
2024-02-01 12:40:15 +00:00
|
|
|
});
|
|
|
|
|
2024-02-05 09:26:28 +00:00
|
|
|
newProject.subDomain = `${newProject.name}.${PROJECT_DOMAIN}`;
|
|
|
|
|
2024-02-01 12:40:15 +00:00
|
|
|
return projectRepository.save(newProject);
|
|
|
|
}
|
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
async updateProjectById (projectId: string, data: DeepPartial<Project>): Promise<boolean> {
|
2024-01-25 06:28:38 +00:00
|
|
|
const projectRepository = this.dataSource.getRepository(Project);
|
2024-02-14 12:05:02 +00:00
|
|
|
const updateResult = await projectRepository.update({ id: projectId }, data);
|
2024-01-25 05:47:44 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return Boolean(updateResult.affected);
|
2024-01-25 05:47:44 +00:00
|
|
|
}
|
2024-01-25 12:04:13 +00:00
|
|
|
|
2024-01-29 11:01:03 +00:00
|
|
|
async deleteProjectById (projectId: string): Promise<boolean> {
|
|
|
|
const projectRepository = this.dataSource.getRepository(Project);
|
2024-02-01 10:04:17 +00:00
|
|
|
const project = await projectRepository.findOneOrFail({
|
|
|
|
where: {
|
|
|
|
id: projectId
|
|
|
|
},
|
|
|
|
relations: {
|
|
|
|
projectMembers: true
|
|
|
|
}
|
|
|
|
});
|
2024-01-29 11:01:03 +00:00
|
|
|
|
2024-02-01 10:04:17 +00:00
|
|
|
const deleteResult = await projectRepository.softRemove(project);
|
|
|
|
|
|
|
|
return Boolean(deleteResult);
|
2024-01-29 11:01:03 +00:00
|
|
|
}
|
2024-01-29 12:09:51 +00:00
|
|
|
|
2024-02-01 03:34:24 +00:00
|
|
|
async deleteDomainById (domainId: string): Promise<boolean> {
|
|
|
|
const domainRepository = this.dataSource.getRepository(Domain);
|
|
|
|
|
2024-02-06 13:41:53 +00:00
|
|
|
const deleteResult = await domainRepository.softDelete({ id: domainId });
|
2024-02-01 03:34:24 +00:00
|
|
|
|
|
|
|
if (deleteResult.affected) {
|
|
|
|
return deleteResult.affected > 0;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
async addDomain (data: DeepPartial<Domain>): Promise<Domain> {
|
|
|
|
const domainRepository = this.dataSource.getRepository(Domain);
|
|
|
|
const newDomain = await domainRepository.save(data);
|
2024-01-29 12:09:51 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return newDomain;
|
2024-01-29 12:09:51 +00:00
|
|
|
}
|
2024-01-29 12:48:43 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
async getDomain (options: FindOneOptions<Domain>): Promise<Domain | null> {
|
2024-01-29 12:48:43 +00:00
|
|
|
const domainRepository = this.dataSource.getRepository(Domain);
|
2024-02-06 08:48:06 +00:00
|
|
|
const domain = await domainRepository.findOne(options);
|
2024-01-29 12:48:43 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return domain;
|
|
|
|
}
|
2024-01-29 12:48:43 +00:00
|
|
|
|
2024-02-14 12:05:02 +00:00
|
|
|
async updateDomainById (domainId: string, data: DeepPartial<Domain>): Promise<boolean> {
|
2024-02-06 08:48:06 +00:00
|
|
|
const domainRepository = this.dataSource.getRepository(Domain);
|
2024-02-14 12:05:02 +00:00
|
|
|
const updateResult = await domainRepository.update({ id: domainId }, data);
|
2024-01-29 12:48:43 +00:00
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return Boolean(updateResult.affected);
|
2024-01-29 12:48:43 +00:00
|
|
|
}
|
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
async getDomainsByProjectId (projectId: string, filter?: FindOptionsWhere<Domain>): Promise<Domain[]> {
|
2024-01-29 12:48:43 +00:00
|
|
|
const domainRepository = this.dataSource.getRepository(Domain);
|
|
|
|
|
|
|
|
const domains = await domainRepository.find({
|
2024-01-31 12:25:19 +00:00
|
|
|
relations: {
|
|
|
|
redirectTo: true
|
|
|
|
},
|
2024-01-29 12:48:43 +00:00
|
|
|
where: {
|
|
|
|
project: {
|
|
|
|
id: projectId
|
2024-01-31 12:25:19 +00:00
|
|
|
},
|
2024-02-06 08:48:06 +00:00
|
|
|
...filter
|
2024-01-31 12:25:19 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-02-06 08:48:06 +00:00
|
|
|
return domains;
|
2024-01-30 08:31:09 +00:00
|
|
|
}
|
2024-01-17 05:23:01 +00:00
|
|
|
}
|